Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
17084944 | 614 days ago | 7.5069971 ETH | ||||
17084944 | 614 days ago | 7.5069971 ETH | ||||
16995820 | 627 days ago | 5.40331143 ETH | ||||
16995820 | 627 days ago | 5.40331143 ETH | ||||
16955829 | 632 days ago | 5.60469568 ETH | ||||
16955829 | 632 days ago | 5.60469568 ETH | ||||
16918517 | 637 days ago | 13.71959547 ETH | ||||
16918517 | 637 days ago | 13.71959547 ETH | ||||
16821564 | 651 days ago | 30.4463337 ETH | ||||
16821564 | 651 days ago | 30.4463337 ETH | ||||
16700993 | 668 days ago | 35.58844798 ETH | ||||
16700993 | 668 days ago | 35.58844798 ETH | ||||
16587436 | 684 days ago | 37.65029936 ETH | ||||
16587436 | 684 days ago | 37.65029936 ETH | ||||
16506613 | 695 days ago | 22.04995489 ETH | ||||
16506613 | 695 days ago | 22.04995489 ETH | ||||
16454066 | 703 days ago | 32.74319497 ETH | ||||
16454066 | 703 days ago | 32.74319497 ETH | ||||
16390005 | 712 days ago | 8.28093957 ETH | ||||
16390005 | 712 days ago | 8.28093957 ETH | ||||
16374464 | 714 days ago | 19.49371791 ETH | ||||
16374464 | 714 days ago | 19.49371791 ETH | ||||
16351523 | 717 days ago | 21.00281461 ETH | ||||
16351523 | 717 days ago | 21.00281461 ETH | ||||
16322387 | 721 days ago | 30.24348741 ETH |
Loading...
Loading
Contract Name:
StrategyConvexstETH
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-06-03 */ // SPDX-License-Identifier: AGPL-3.0 pragma solidity 0.6.12; pragma experimental ABIEncoderV2; // Global Enums and Structs struct StrategyParams { uint256 performanceFee; uint256 activation; uint256 debtRatio; uint256 rateLimit; uint256 lastReport; uint256 totalDebt; uint256 totalGain; uint256 totalLoss; } // Part: IBaseFee interface IBaseFee { function isCurrentBaseFeeAcceptable() external view returns (bool); } // Part: IConvexDeposit interface IConvexDeposit { // deposit into convex, receive a tokenized deposit. parameter to stake immediately (we always do this). function deposit( uint256 _pid, uint256 _amount, bool _stake ) external returns (bool); // burn a tokenized deposit (Convex deposit tokens) to receive curve lp tokens back function withdraw(uint256 _pid, uint256 _amount) external returns (bool); // give us info about a pool based on its pid function poolInfo(uint256) external view returns ( address, address, address, address, address, bool ); } // Part: IConvexRewards interface IConvexRewards { // strategy's staked balance in the synthetix staking contract function balanceOf(address account) external view returns (uint256); // read how much claimable CRV a strategy has function earned(address account) external view returns (uint256); // stake a convex tokenized deposit function stake(uint256 _amount) external returns (bool); // withdraw to a convex tokenized deposit, probably never need to use this function withdraw(uint256 _amount, bool _claim) external returns (bool); // withdraw directly to curve LP token, this is what we primarily use function withdrawAndUnwrap(uint256 _amount, bool _claim) external returns (bool); // claim rewards, with an option to claim extra rewards or not function getReward(address _account, bool _claimExtras) external returns (bool); // check if we have rewards on a pool function extraRewardsLength() external view returns (uint256); // if we have rewards, see what the address is function extraRewards(uint256 _reward) external view returns (address); // read our rewards token function rewardToken() external view returns (address); // check our reward period finish function periodFinish() external view returns (uint256); } // Part: IOracle interface IOracle { function latestAnswer() external view returns (uint256); } // Part: IUniswapV2Router01 interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external returns ( uint256 amountA, uint256 amountB, uint256 liquidity ); function addLiquidityETH( address token, uint256 amountTokenDesired, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external payable returns ( uint256 amountToken, uint256 amountETH, uint256 liquidity ); function removeLiquidity( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external returns (uint256 amountA, uint256 amountB); function removeLiquidityETH( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external returns (uint256 amountToken, uint256 amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountA, uint256 amountB); function removeLiquidityETHWithPermit( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountToken, uint256 amountETH); function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactETHForTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); function swapTokensForExactETH( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactTokensForETH( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapETHForExactTokens( uint256 amountOut, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); function quote( uint256 amountA, uint256 reserveA, uint256 reserveB ) external pure returns (uint256 amountB); function getAmountOut( uint256 amountIn, uint256 reserveIn, uint256 reserveOut ) external pure returns (uint256 amountOut); function getAmountIn( uint256 amountOut, uint256 reserveIn, uint256 reserveOut ) external pure returns (uint256 amountIn); function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts); } // Part: IWeth interface IWeth { function withdraw(uint256 wad) external; } // Part: OpenZeppelin/[email protected]/Address /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // Part: OpenZeppelin/[email protected]/IERC20 /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // Part: OpenZeppelin/[email protected]/Math /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } } // Part: OpenZeppelin/[email protected]/SafeMath /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // Part: yearn/[email protected]/HealthCheck interface HealthCheck { function check( uint256 profit, uint256 loss, uint256 debtPayment, uint256 debtOutstanding, uint256 totalDebt ) external view returns (bool); } // Part: ICurveFi interface ICurveFi is IERC20 { function get_virtual_price() external view returns (uint256); function coins(uint256) external view returns (address); function add_liquidity( // EURt uint256[2] calldata amounts, uint256 min_mint_amount ) external payable; function add_liquidity( // Compound, sAave uint256[2] calldata amounts, uint256 min_mint_amount, bool _use_underlying ) external payable returns (uint256); function add_liquidity( // Iron Bank, Aave uint256[3] calldata amounts, uint256 min_mint_amount, bool _use_underlying ) external payable returns (uint256); function add_liquidity( // 3Crv Metapools address pool, uint256[4] calldata amounts, uint256 min_mint_amount ) external; function add_liquidity( // Y and yBUSD uint256[4] calldata amounts, uint256 min_mint_amount, bool _use_underlying ) external payable returns (uint256); function add_liquidity( // 3pool uint256[3] calldata amounts, uint256 min_mint_amount ) external payable; function add_liquidity( // sUSD uint256[4] calldata amounts, uint256 min_mint_amount ) external payable; function remove_liquidity_imbalance( uint256[2] calldata amounts, uint256 max_burn_amount ) external; function remove_liquidity(uint256 _amount, uint256[2] calldata amounts) external; function remove_liquidity_one_coin( uint256 _token_amount, int128 i, uint256 min_amount ) external; function exchange( // CRV-ETH and CVX-ETH uint256 from, uint256 to, uint256 _from_amount, uint256 _min_to_amount, bool use_eth ) external; function exchange( // sETH int128 from, int128 to, uint256 _from_amount, uint256 _min_to_amount ) external payable returns (uint256); function balances(uint256) external view returns (uint256); function price_oracle() external view returns (uint256); function get_dy( int128 from, int128 to, uint256 _from_amount ) external view returns (uint256); // EURt function calc_token_amount(uint256[2] calldata _amounts, bool _is_deposit) external view returns (uint256); // 3Crv Metapools function calc_token_amount( address _pool, uint256[4] calldata _amounts, bool _is_deposit ) external view returns (uint256); // sUSD, Y pool, etc function calc_token_amount(uint256[4] calldata _amounts, bool _is_deposit) external view returns (uint256); // 3pool, Iron Bank, etc function calc_token_amount(uint256[3] calldata _amounts, bool _is_deposit) external view returns (uint256); function calc_withdraw_one_coin(uint256 amount, int128 i) external view returns (uint256); } // Part: IUniswapV2Router02 interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external returns (uint256 amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; } // Part: OpenZeppelin/[email protected]/SafeERC20 /** * @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 SafeMath for uint256; 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' // solhint-disable-next-line max-line-length 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).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _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 // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // Part: yearn/[email protected]/VaultAPI interface VaultAPI is IERC20 { function apiVersion() external view returns (string memory); function withdraw(uint256 shares, address recipient) external; function token() external view returns (address); function strategies(address _strategy) external view returns (StrategyParams memory); /** * View how much the Vault would increase this Strategy's borrow limit, * based on its present performance (since its last report). Can be used to * determine expectedReturn in your Strategy. */ function creditAvailable() external view returns (uint256); /** * View how much the Vault would like to pull back from the Strategy, * based on its present performance (since its last report). Can be used to * determine expectedReturn in your Strategy. */ function debtOutstanding() external view returns (uint256); /** * View how much the Vault expect this Strategy to return at the current * block, based on its present performance (since its last report). Can be * used to determine expectedReturn in your Strategy. */ function expectedReturn() external view returns (uint256); /** * This is the main contact point where the Strategy interacts with the * Vault. It is critical that this call is handled as intended by the * Strategy. Therefore, this function will be called by BaseStrategy to * make sure the integration is correct. */ function report( uint256 _gain, uint256 _loss, uint256 _debtPayment ) external returns (uint256); /** * This function should only be used in the scenario where the Strategy is * being retired but no migration of the positions are possible, or in the * extreme scenario that the Strategy needs to be put into "Emergency Exit" * mode in order for it to exit as quickly as possible. The latter scenario * could be for any reason that is considered "critical" that the Strategy * exits its position as fast as possible, such as a sudden change in * market conditions leading to losses, or an imminent failure in an * external dependency. */ function revokeStrategy() external; /** * View the governance address of the Vault to assert privileged functions * can only be called by governance. The Strategy serves the Vault, so it * is subject to governance defined by the Vault. */ function governance() external view returns (address); } // Part: yearn/[email protected]/BaseStrategy /** * @title Yearn Base Strategy * @author yearn.finance * @notice * BaseStrategy implements all of the required functionality to interoperate * closely with the Vault contract. This contract should be inherited and the * abstract methods implemented to adapt the Strategy to the particular needs * it has to create a return. * * Of special interest is the relationship between `harvest()` and * `vault.report()'. `harvest()` may be called simply because enough time has * elapsed since the last report, and not because any funds need to be moved * or positions adjusted. This is critical so that the Vault may maintain an * accurate picture of the Strategy's performance. See `vault.report()`, * `harvest()`, and `harvestTrigger()` for further details. */ abstract contract BaseStrategy { using SafeMath for uint256; // health checks bool public doHealthCheck; address public healthCheck; /** * @notice * Used to track which version of `StrategyAPI` this Strategy * implements. * @dev The Strategy's version must match the Vault's `API_VERSION`. * @return A string which holds the current API version of this contract. */ function apiVersion() public pure returns (string memory) { return "0.3.0"; } /** * @notice This Strategy's name. * @dev * You can use this field to manage the "version" of this Strategy, e.g. * `StrategySomethingOrOtherV1`. However, "API Version" is managed by * `apiVersion()` function above. * @return This Strategy's name. */ function name() external virtual view returns (string memory); /** * @notice * The amount (priced in want) of the total assets managed by this strategy should not count * towards Yearn's TVL calculations. * @dev * You can override this field to set it to a non-zero value if some of the assets of this * Strategy is somehow delegated inside another part of of Yearn's ecosystem e.g. another Vault. * Note that this value must be strictly less than or equal to the amount provided by * `estimatedTotalAssets()` below, as the TVL calc will be total assets minus delegated assets. * @return * The amount of assets this strategy manages that should not be included in Yearn's Total Value * Locked (TVL) calculation across it's ecosystem. */ function delegatedAssets() external virtual view returns (uint256) { return 0; } VaultAPI public vault; address public strategist; address public rewards; address public keeper; IERC20 public want; // So indexers can keep track of this event Harvested(uint256 profit, uint256 loss, uint256 debtPayment, uint256 debtOutstanding); event UpdatedStrategist(address newStrategist); event UpdatedKeeper(address newKeeper); event UpdatedRewards(address rewards); event UpdatedReportDelay(uint256 delay); event UpdatedProfitFactor(uint256 profitFactor); event UpdatedDebtThreshold(uint256 debtThreshold); event EmergencyExitEnabled(); // The maximum number of seconds between harvest calls. See // `setMaxReportDelay()` for more details. uint256 public maxReportDelay = 86400; // ~ once a day // The minimum multiple that `callCost` must be above the credit/profit to // be "justifiable". See `setProfitFactor()` for more details. uint256 public profitFactor = 100; // Use this to adjust the threshold at which running a debt causes a // harvest trigger. See `setDebtThreshold()` for more details. uint256 public debtThreshold = 0; // See note on `setEmergencyExit()`. bool public emergencyExit; // modifiers modifier onlyAuthorized() { require(msg.sender == strategist || msg.sender == governance(), "!authorized"); _; } modifier onlyStrategist() { require(msg.sender == strategist, "!strategist"); _; } modifier onlyGovernance() { require(msg.sender == governance(), "!authorized"); _; } modifier onlyKeepers() { require(msg.sender == keeper || msg.sender == strategist || msg.sender == governance(), "!authorized"); _; } constructor(address _vault) public { _initialize(_vault, msg.sender, msg.sender, msg.sender); } /** * @notice * Initializes the Strategy, this is called only once, when the * contract is deployed. * @dev `_vault` should implement `VaultAPI`. * @param _vault The address of the Vault responsible for this Strategy. */ function _initialize( address _vault, address _strategist, address _rewards, address _keeper ) internal { require(address(want) == address(0), "Strategy already initialized"); vault = VaultAPI(_vault); want = IERC20(vault.token()); want.approve(_vault, uint256(-1)); // Give Vault unlimited access (might save gas) strategist = _strategist; rewards = _rewards; keeper = _keeper; vault.approve(rewards, uint256(-1)); // Allow rewards to be pulled } function setHealthCheck(address _healthCheck) external onlyGovernance { healthCheck = _healthCheck; } function setDoHealthCheck(bool _doHealthCheck) external onlyGovernance { doHealthCheck = _doHealthCheck; } /** * @notice * Used to change `strategist`. * * This may only be called by governance or the existing strategist. * @param _strategist The new address to assign as `strategist`. */ function setStrategist(address _strategist) external onlyAuthorized { require(_strategist != address(0)); strategist = _strategist; emit UpdatedStrategist(_strategist); } /** * @notice * Used to change `keeper`. * * `keeper` is the only address that may call `tend()` or `harvest()`, * other than `governance()` or `strategist`. However, unlike * `governance()` or `strategist`, `keeper` may *only* call `tend()` * and `harvest()`, and no other authorized functions, following the * principle of least privilege. * * This may only be called by governance or the strategist. * @param _keeper The new address to assign as `keeper`. */ function setKeeper(address _keeper) external onlyAuthorized { require(_keeper != address(0)); keeper = _keeper; emit UpdatedKeeper(_keeper); } /** * @notice * Used to change `rewards`. Any distributed rewards will cease flowing * to the old address and begin flowing to this address once the change * is in effect. * * This may only be called by the strategist. * @param _rewards The address to use for collecting rewards. */ function setRewards(address _rewards) external onlyStrategist { require(_rewards != address(0)); rewards = _rewards; emit UpdatedRewards(_rewards); } /** * @notice * Used to change `maxReportDelay`. `maxReportDelay` is the maximum number * of blocks that should pass for `harvest()` to be called. * * For external keepers (such as the Keep3r network), this is the maximum * time between jobs to wait. (see `harvestTrigger()` * for more details.) * * This may only be called by governance or the strategist. * @param _delay The maximum number of seconds to wait between harvests. */ function setMaxReportDelay(uint256 _delay) external onlyAuthorized { maxReportDelay = _delay; emit UpdatedReportDelay(_delay); } /** * @notice * Used to change `profitFactor`. `profitFactor` is used to determine * if it's worthwhile to harvest, given gas costs. (See `harvestTrigger()` * for more details.) * * This may only be called by governance or the strategist. * @param _profitFactor A ratio to multiply anticipated * `harvest()` gas cost against. */ function setProfitFactor(uint256 _profitFactor) external onlyAuthorized { profitFactor = _profitFactor; emit UpdatedProfitFactor(_profitFactor); } /** * @notice * Sets how far the Strategy can go into loss without a harvest and report * being required. * * By default this is 0, meaning any losses would cause a harvest which * will subsequently report the loss to the Vault for tracking. (See * `harvestTrigger()` for more details.) * * This may only be called by governance or the strategist. * @param _debtThreshold How big of a loss this Strategy may carry without * being required to report to the Vault. */ function setDebtThreshold(uint256 _debtThreshold) external onlyAuthorized { debtThreshold = _debtThreshold; emit UpdatedDebtThreshold(_debtThreshold); } /** * Resolve governance address from Vault contract, used to make assertions * on protected functions in the Strategy. */ function governance() internal view returns (address) { return vault.governance(); } /** * @notice * Provide an accurate estimate for the total amount of assets * (principle + return) that this Strategy is currently managing, * denominated in terms of `want` tokens. * * This total should be "realizable" e.g. the total value that could * *actually* be obtained from this Strategy if it were to divest its * entire position based on current on-chain conditions. * @dev * Care must be taken in using this function, since it relies on external * systems, which could be manipulated by the attacker to give an inflated * (or reduced) value produced by this function, based on current on-chain * conditions (e.g. this function is possible to influence through * flashloan attacks, oracle manipulations, or other DeFi attack * mechanisms). * * It is up to governance to use this function to correctly order this * Strategy relative to its peers in the withdrawal queue to minimize * losses for the Vault based on sudden withdrawals. This value should be * higher than the total debt of the Strategy and higher than its expected * value to be "safe". * @return The estimated total assets in this Strategy. */ function estimatedTotalAssets() public virtual view returns (uint256); /* * @notice * Provide an indication of whether this strategy is currently "active" * in that it is managing an active position, or will manage a position in * the future. This should correlate to `harvest()` activity, so that Harvest * events can be tracked externally by indexing agents. * @return True if the strategy is actively managing a position. */ function isActive() public view returns (bool) { return vault.strategies(address(this)).debtRatio > 0 || estimatedTotalAssets() > 0; } /** * Perform any Strategy unwinding or other calls necessary to capture the * "free return" this Strategy has generated since the last time its core * position(s) were adjusted. Examples include unwrapping extra rewards. * This call is only used during "normal operation" of a Strategy, and * should be optimized to minimize losses as much as possible. * * This method returns any realized profits and/or realized losses * incurred, and should return the total amounts of profits/losses/debt * payments (in `want` tokens) for the Vault's accounting (e.g. * `want.balanceOf(this) >= _debtPayment + _profit - _loss`). * * `_debtOutstanding` will be 0 if the Strategy is not past the configured * debt limit, otherwise its value will be how far past the debt limit * the Strategy is. The Strategy's debt limit is configured in the Vault. * * NOTE: `_debtPayment` should be less than or equal to `_debtOutstanding`. * It is okay for it to be less than `_debtOutstanding`, as that * should only used as a guide for how much is left to pay back. * Payments should be made to minimize loss from slippage, debt, * withdrawal fees, etc. * * See `vault.debtOutstanding()`. */ function prepareReturn(uint256 _debtOutstanding) internal virtual returns ( uint256 _profit, uint256 _loss, uint256 _debtPayment ); /** * Perform any adjustments to the core position(s) of this Strategy given * what change the Vault made in the "investable capital" available to the * Strategy. Note that all "free capital" in the Strategy after the report * was made is available for reinvestment. Also note that this number * could be 0, and you should handle that scenario accordingly. * * See comments regarding `_debtOutstanding` on `prepareReturn()`. */ function adjustPosition(uint256 _debtOutstanding) internal virtual; /** * Liquidate up to `_amountNeeded` of `want` of this strategy's positions, * irregardless of slippage. Any excess will be re-invested with `adjustPosition()`. * This function should return the amount of `want` tokens made available by the * liquidation. If there is a difference between them, `_loss` indicates whether the * difference is due to a realized loss, or if there is some other sitution at play * (e.g. locked funds). This function is used during emergency exit instead of * `prepareReturn()` to liquidate all of the Strategy's positions back to the Vault. * * NOTE: The invariant `_amountFreed + _loss <= _amountNeeded` should always be maintained */ function liquidatePosition(uint256 _amountNeeded) internal virtual returns (uint256 _liquidatedAmount, uint256 _loss); /** * `Harvest()` calls this function after shares are created during * `vault.report()`. You can customize this function to any share * distribution mechanism you want. * * See `vault.report()` for further details. */ function distributeRewards() internal virtual { // Transfer 100% of newly-minted shares awarded to this contract to the rewards address. uint256 balance = vault.balanceOf(address(this)); if (balance > 0) { vault.transfer(rewards, balance); } } /** * @notice * Provide a signal to the keeper that `tend()` should be called. The * keeper will provide the estimated gas cost that they would pay to call * `tend()`, and this function should use that estimate to make a * determination if calling it is "worth it" for the keeper. This is not * the only consideration into issuing this trigger, for example if the * position would be negatively affected if `tend()` is not called * shortly, then this can return `true` even if the keeper might be * "at a loss" (keepers are always reimbursed by Yearn). * @dev * `callCost` must be priced in terms of `want`. * * This call and `harvestTrigger()` should never return `true` at the same * time. * @param callCost The keeper's estimated cast cost to call `tend()`. * @return `true` if `tend()` should be called, `false` otherwise. */ function tendTrigger(uint256 callCost) public virtual view returns (bool) { // We usually don't need tend, but if there are positions that need // active maintainence, overriding this function is how you would // signal for that. return false; } /** * @notice * Adjust the Strategy's position. The purpose of tending isn't to * realize gains, but to maximize yield by reinvesting any returns. * * See comments on `adjustPosition()`. * * This may only be called by governance, the strategist, or the keeper. */ function tend() external onlyKeepers { // Don't take profits with this call, but adjust for better gains adjustPosition(vault.debtOutstanding()); } /** * @notice * Provide a signal to the keeper that `harvest()` should be called. The * keeper will provide the estimated gas cost that they would pay to call * `harvest()`, and this function should use that estimate to make a * determination if calling it is "worth it" for the keeper. This is not * the only consideration into issuing this trigger, for example if the * position would be negatively affected if `harvest()` is not called * shortly, then this can return `true` even if the keeper might be "at a * loss" (keepers are always reimbursed by Yearn). * @dev * `callCost` must be priced in terms of `want`. * * This call and `tendTrigger` should never return `true` at the * same time. * * See `maxReportDelay`, `profitFactor`, `debtThreshold` to adjust the * strategist-controlled parameters that will influence whether this call * returns `true` or not. These parameters will be used in conjunction * with the parameters reported to the Vault (see `params`) to determine * if calling `harvest()` is merited. * * It is expected that an external system will check `harvestTrigger()`. * This could be a script run off a desktop or cloud bot (e.g. * https://github.com/iearn-finance/yearn-vaults/blob/master/scripts/keep.py), * or via an integration with the Keep3r network (e.g. * https://github.com/Macarse/GenericKeep3rV2/blob/master/contracts/keep3r/GenericKeep3rV2.sol). * @param callCost The keeper's estimated cast cost to call `harvest()`. * @return `true` if `harvest()` should be called, `false` otherwise. */ function harvestTrigger(uint256 callCost) public virtual view returns (bool) { StrategyParams memory params = vault.strategies(address(this)); // Should not trigger if Strategy is not activated if (params.activation == 0) return false; // Should trigger if hasn't been called in a while if (block.timestamp.sub(params.lastReport) >= maxReportDelay) return true; // If some amount is owed, pay it back // NOTE: Since debt is based on deposits, it makes sense to guard against large // changes to the value from triggering a harvest directly through user // behavior. This should ensure reasonable resistance to manipulation // from user-initiated withdrawals as the outstanding debt fluctuates. uint256 outstanding = vault.debtOutstanding(); if (outstanding > debtThreshold) return true; // Check for profits and losses uint256 total = estimatedTotalAssets(); // Trigger if we have a loss to report if (total.add(debtThreshold) < params.totalDebt) return true; uint256 profit = 0; if (total > params.totalDebt) profit = total.sub(params.totalDebt); // We've earned a profit! // Otherwise, only trigger if it "makes sense" economically (gas cost // is <N% of value moved) uint256 credit = vault.creditAvailable(); return (profitFactor.mul(callCost) < credit.add(profit)); } /** * @notice * Harvests the Strategy, recognizing any profits or losses and adjusting * the Strategy's position. * * In the rare case the Strategy is in emergency shutdown, this will exit * the Strategy's position. * * This may only be called by governance, the strategist, or the keeper. * @dev * When `harvest()` is called, the Strategy reports to the Vault (via * `vault.report()`), so in some cases `harvest()` must be called in order * to take in profits, to borrow newly available funds from the Vault, or * otherwise adjust its position. In other cases `harvest()` must be * called to report to the Vault on the Strategy's position, especially if * any losses have occurred. */ function harvest() external onlyKeepers { uint256 profit = 0; uint256 loss = 0; uint256 debtOutstanding = vault.debtOutstanding(); uint256 debtPayment = 0; if (emergencyExit) { // Free up as much capital as possible uint256 totalAssets = estimatedTotalAssets(); // NOTE: use the larger of total assets or debt outstanding to book losses properly (debtPayment, loss) = liquidatePosition(totalAssets > debtOutstanding ? totalAssets : debtOutstanding); // NOTE: take up any remainder here as profit if (debtPayment > debtOutstanding) { profit = debtPayment.sub(debtOutstanding); debtPayment = debtOutstanding; } } else { // Free up returns for Vault to pull (profit, loss, debtPayment) = prepareReturn(debtOutstanding); } // Allow Vault to take up to the "harvested" balance of this contract, // which is the amount it has earned since the last time it reported to // the Vault. uint256 totalDebt = vault.strategies(address(this)).totalDebt; debtOutstanding = vault.report(profit, loss, debtPayment); // Distribute any reward shares earned by the strategy on this report distributeRewards(); // Check if free returns are left, and re-invest them adjustPosition(debtOutstanding); // call healthCheck contract if (doHealthCheck && healthCheck != address(0)) { require( HealthCheck(healthCheck).check( profit, loss, debtPayment, debtOutstanding, totalDebt ), "!healthcheck" ); } else { doHealthCheck = true; } emit Harvested(profit, loss, debtPayment, debtOutstanding); } /** * @notice * Withdraws `_amountNeeded` to `vault`. * * This may only be called by the Vault. * @param _amountNeeded How much `want` to withdraw. * @return _loss Any realized losses */ function withdraw(uint256 _amountNeeded) external returns (uint256 _loss) { require(msg.sender == address(vault), "!vault"); // Liquidate as much as possible to `want`, up to `_amount` uint256 amountFreed; (amountFreed, _loss) = liquidatePosition(_amountNeeded); // sanity check require(_amountNeeded == amountFreed.add(_loss), "!withdraw"); // Send it directly back (NOTE: Using `msg.sender` saves some gas here) want.transfer(msg.sender, amountFreed); // NOTE: Reinvest anything leftover on next `tend`/`harvest` } /** * Do anything necessary to prepare this Strategy for migration, such as * transferring any reserve or LP tokens, CDPs, or other tokens or stores of * value. */ function prepareMigration(address _newStrategy) internal virtual; /** * @notice * Transfers all `want` from this Strategy to `_newStrategy`. * * This may only be called by governance or the Vault. * @dev * The new Strategy's Vault must be the same as this Strategy's Vault. * @param _newStrategy The Strategy to migrate to. */ function migrate(address _newStrategy) external { require(msg.sender == address(vault) || msg.sender == governance()); require(BaseStrategy(_newStrategy).vault() == vault); prepareMigration(_newStrategy); want.transfer(_newStrategy, want.balanceOf(address(this))); } /** * @notice * Activates emergency exit. Once activated, the Strategy will exit its * position upon the next harvest, depositing all funds into the Vault as * quickly as is reasonable given on-chain conditions. * * This may only be called by governance or the strategist. * @dev * See `vault.setEmergencyShutdown()` and `harvest()` for further details. */ function setEmergencyExit() external onlyAuthorized { emergencyExit = true; vault.revokeStrategy(); emit EmergencyExitEnabled(); } /** * Override this to add all tokens/tokenized positions this contract * manages on a *persistent* basis (e.g. not just for swapping back to * want ephemerally). * * NOTE: Do *not* include `want`, already included in `sweep` below. * * Example: * * function protectedTokens() internal override view returns (address[] memory) { * address[] memory protected = new address[](3); * protected[0] = tokenA; * protected[1] = tokenB; * protected[2] = tokenC; * return protected; * } */ function protectedTokens() internal virtual view returns (address[] memory); /** * @notice * Removes tokens from this Strategy that are not the type of tokens * managed by this Strategy. This may be used in case of accidentally * sending the wrong kind of token to this Strategy. * * Tokens will be sent to `governance()`. * * This will fail if an attempt is made to sweep `want`, or any tokens * that are protected by this Strategy. * * This may only be called by governance. * @dev * Implement `protectedTokens()` to specify any additional tokens that * should be protected from sweeping in addition to `want`. * @param _token The token to transfer out of this vault. */ function sweep(address _token) external onlyGovernance { require(_token != address(want), "!want"); require(_token != address(vault), "!shares"); address[] memory _protectedTokens = protectedTokens(); for (uint256 i; i < _protectedTokens.length; i++) require(_token != _protectedTokens[i], "!protected"); IERC20(_token).transfer(governance(), IERC20(_token).balanceOf(address(this))); } } // Part: StrategyConvexBase abstract contract StrategyConvexBase is BaseStrategy { using SafeERC20 for IERC20; using Address for address; using SafeMath for uint256; /* ========== STATE VARIABLES ========== */ // these should stay the same across different wants. // convex stuff address internal constant depositContract = 0xF403C135812408BFbE8713b5A23a04b3D48AAE31; // this is the deposit contract that all pools use, aka booster IConvexRewards public rewardsContract; // This is unique to each curve pool address public virtualRewardsPool; // This is only if we have bonus rewards uint256 public pid; // this is unique to each pool // keepCRV stuff uint256 public keepCRV; // the percentage of CRV we re-lock for boost (in basis points) uint256 public keepCVX; // the percentage of CVX we keep for boosting yield (in basis points) address public keepCVXDestination; // where we send the CVX we are keeping address internal constant voter = 0xF147b8125d2ef93FB6965Db97D6746952a133934; // Yearn's veCRV voter, we send some extra CRV here uint256 internal constant FEE_DENOMINATOR = 10000; // this means all of our fee values are in basis points // Swap stuff address internal constant sushiswap = 0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F; // we use this to sell our bonus token IERC20 internal constant crv = IERC20(0xD533a949740bb3306d119CC777fa900bA034cd52); IERC20 internal constant convexToken = IERC20(0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B); IERC20 internal constant weth = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); // keeper stuff uint256 public harvestProfitMin; // minimum size in USD (6 decimals) that we want to harvest uint256 public harvestProfitMax; // maximum size in USD (6 decimals) that we want to harvest uint256 public creditThreshold; // amount of credit in underlying tokens that will automatically trigger a harvest bool internal forceHarvestTriggerOnce; // only set this to true when we want to trigger our keepers to harvest for us string internal stratName; // convex-specific variables bool public claimRewards; // boolean if we should always claim rewards when withdrawing, usually via withdrawAndUnwrap (generally this should be false) /* ========== CONSTRUCTOR ========== */ constructor(address _vault) public BaseStrategy(_vault) {} /* ========== VIEWS ========== */ function name() external view override returns (string memory) { return stratName; } /// @notice How much want we have staked in Convex function stakedBalance() public view returns (uint256) { return rewardsContract.balanceOf(address(this)); } /// @notice Balance of want sitting in our strategy function balanceOfWant() public view returns (uint256) { return want.balanceOf(address(this)); } /// @notice How much CRV we can claim from the staking contract function claimableBalance() public view returns (uint256) { return rewardsContract.earned(address(this)); } function estimatedTotalAssets() public view override returns (uint256) { return balanceOfWant().add(stakedBalance()); } /* ========== MUTATIVE FUNCTIONS ========== */ function adjustPosition(uint256 _debtOutstanding) internal override { if (emergencyExit) { return; } // Send all of our Curve pool tokens to be deposited uint256 _toInvest = balanceOfWant(); // deposit into convex and stake immediately (but only if we have something to invest) if (_toInvest > 0) { IConvexDeposit(depositContract).deposit(pid, _toInvest, true); } } function liquidatePosition(uint256 _amountNeeded) internal override returns (uint256 _liquidatedAmount, uint256 _loss) { uint256 _wantBal = balanceOfWant(); if (_amountNeeded > _wantBal) { uint256 _stakedBal = stakedBalance(); if (_stakedBal > 0) { rewardsContract.withdrawAndUnwrap( Math.min(_stakedBal, _amountNeeded.sub(_wantBal)), claimRewards ); } uint256 _withdrawnBal = balanceOfWant(); _liquidatedAmount = Math.min(_amountNeeded, _withdrawnBal); _loss = _amountNeeded.sub(_liquidatedAmount); } else { // we have enough balance to cover the liquidation available return (_amountNeeded, 0); } } // in case we need to exit into the convex deposit token, this will allow us to do that // make sure to check claimRewards before this step if needed // plan to have gov sweep convex deposit tokens from strategy after this function withdrawToConvexDepositTokens() external onlyAuthorized { uint256 _stakedBal = stakedBalance(); if (_stakedBal > 0) { rewardsContract.withdraw(_stakedBal, claimRewards); } } // we don't want for these tokens to be swept out. We allow gov to sweep out cvx vault tokens; we would only be holding these if things were really, really rekt. function protectedTokens() internal view override returns (address[] memory) {} /* ========== SETTERS ========== */ // These functions are useful for setting parameters of the strategy that may need to be adjusted. // Set the amount of CRV to be locked in Yearn's veCRV voter from each harvest. Default is 10%. Option to keep CVX as well. function setKeep( uint256 _keepCRV, uint256 _keepCVX, address _keepCVXDestination ) external onlyGovernance { require(_keepCRV <= 10_000 && _keepCVX <= 10_000); keepCRV = _keepCRV; keepCVX = _keepCVX; keepCVXDestination = _keepCVXDestination; } // We usually don't need to claim rewards on withdrawals, but might change our mind for migrations etc function setClaimRewards(bool _claimRewards) external onlyAuthorized { claimRewards = _claimRewards; } // This allows us to manually harvest with our keeper as needed function setForceHarvestTriggerOnce(bool _forceHarvestTriggerOnce) external onlyAuthorized { forceHarvestTriggerOnce = _forceHarvestTriggerOnce; } } // File: StrategyConvexstETH.sol contract StrategyConvexstETH is StrategyConvexBase { /* ========== STATE VARIABLES ========== */ // these will likely change across different wants. // Curve stuff ICurveFi public curve; // Curve Pool, this is our pool specific to this vault bool public checkEarmark; // this determines if we should check if we need to earmark rewards before harvesting // use Curve to sell our CVX and CRV rewards to WETH ICurveFi internal constant crveth = ICurveFi(0x8301AE4fc9c624d1D396cbDAa1ed877821D7C511); // use curve's new CRV-ETH crypto pool to sell our CRV ICurveFi internal constant cvxeth = ICurveFi(0xB576491F1E6e5E62f1d8F26062Ee822B40B0E0d4); // use curve's new CVX-ETH crypto pool to sell our CVX // use this to check on our claimable profit IERC20 internal constant usdt = IERC20(0xdAC17F958D2ee523a2206206994597C13D831ec7); // rewards token info. we can have more than 1 reward token but this is rare, so we don't include this in the template IERC20 public rewardsToken; bool public hasRewards; address[] internal rewardsPath; // check for cloning bool internal isOriginal = true; /* ========== CONSTRUCTOR ========== */ constructor( address _vault, uint256 _pid, address _curvePool, string memory _name ) public StrategyConvexBase(_vault) { _initializeStrat(_pid, _curvePool, _name); } /* ========== CLONING ========== */ // this is called by our original strategy, as well as any clones function _initializeStrat( uint256 _pid, address _curvePool, string memory _name ) internal { // make sure that we haven't initialized this before require(address(curve) == address(0)); // already initialized. // You can set these parameters on deployment to whatever you want maxReportDelay = 21 days; // 21 days in seconds, if we hit this then harvestTrigger = True healthCheck = 0xDDCea799fF1699e98EDF118e0629A974Df7DF012; // health.ychad.eth harvestProfitMin = 60000e6; harvestProfitMax = 120000e6; creditThreshold = 4000 * 1e18; // roughly $1m in ETH keepCRV = 1000; // default of 10% keepCVXDestination = 0x93A62dA5a14C80f265DAbC077fCEE437B1a0Efde; // default to treasury // want = Curve LP want.approve(address(depositContract), type(uint256).max); convexToken.approve(address(cvxeth), type(uint256).max); crv.approve(address(crveth), type(uint256).max); // this is the pool specific to this vault curve = ICurveFi(_curvePool); // setup our rewards contract pid = _pid; // this is the pool ID on convex, we use this to determine what the reweardsContract address is (address lptoken, , , address _rewardsContract, , ) = IConvexDeposit(depositContract).poolInfo(_pid); // set up our rewardsContract rewardsContract = IConvexRewards(_rewardsContract); // check that our LP token based on our pid matches our want require(address(lptoken) == address(want)); // set our strategy's name stratName = _name; } /* ========== MUTATIVE FUNCTIONS ========== */ function prepareReturn(uint256 _debtOutstanding) internal override returns ( uint256 _profit, uint256 _loss, uint256 _debtPayment ) { // this claims our CRV, CVX, and any extra tokens like SNX or ANKR. no harm leaving this true even if no extra rewards currently. rewardsContract.getReward(address(this), true); uint256 crvBalance = crv.balanceOf(address(this)); uint256 convexBalance = convexToken.balanceOf(address(this)); uint256 _sendToVoter = crvBalance.mul(keepCRV).div(FEE_DENOMINATOR); if (_sendToVoter > 0) { crv.safeTransfer(voter, _sendToVoter); crvBalance = crv.balanceOf(address(this)); } uint256 _cvxToKeep = convexBalance.mul(keepCVX).div(FEE_DENOMINATOR); if (_cvxToKeep > 0) { convexToken.safeTransfer(keepCVXDestination, _cvxToKeep); convexBalance = convexToken.balanceOf(address(this)); } // claim and sell our rewards if we have them if (hasRewards) { uint256 _rewardsBalance = IERC20(rewardsToken).balanceOf(address(this)); if (_rewardsBalance > 0) { _sellRewards(_rewardsBalance); } } // do this even if we have zero balances so we can sell WETH from rewards _sellCrvAndCvx(crvBalance, convexBalance); // deposit our ETH to the pool uint256 ethBalance = address(this).balance; if (ethBalance > 0) { curve.add_liquidity{value: ethBalance}([ethBalance, 0], 0); } // debtOustanding will only be > 0 in the event of revoking or if we need to rebalance from a withdrawal or lowering the debtRatio if (_debtOutstanding > 0) { uint256 _stakedBal = stakedBalance(); if (_stakedBal > 0) { rewardsContract.withdrawAndUnwrap( Math.min(_stakedBal, _debtOutstanding), claimRewards ); } uint256 _withdrawnBal = balanceOfWant(); _debtPayment = Math.min(_debtOutstanding, _withdrawnBal); } // serious loss should never happen, but if it does (for instance, if Curve is hacked), let's record it accurately uint256 assets = estimatedTotalAssets(); uint256 debt = vault.strategies(address(this)).totalDebt; // if assets are greater than debt, things are working great! if (assets > debt) { _profit = assets.sub(debt); uint256 _wantBal = balanceOfWant(); if (_profit.add(_debtPayment) > _wantBal) { // this should only be hit following donations to strategy liquidatePosition(assets); } } // if assets are less than debt, we are in trouble else { _loss = debt.sub(assets); } // we're done harvesting, so reset our trigger if we used it forceHarvestTriggerOnce = false; } // migrate our want token to a new strategy if needed, make sure to check claimRewards first // also send over any CRV or CVX that is claimed; for migrations we definitely want to claim function prepareMigration(address _newStrategy) internal override { uint256 _stakedBal = stakedBalance(); if (_stakedBal > 0) { rewardsContract.withdrawAndUnwrap(_stakedBal, claimRewards); } crv.safeTransfer(_newStrategy, crv.balanceOf(address(this))); convexToken.safeTransfer( _newStrategy, convexToken.balanceOf(address(this)) ); } // Sells our CRV -> WETH and CVX -> WETH on Curve, and the unwraps this and any other WETH from our rewards. function _sellCrvAndCvx(uint256 _crvAmount, uint256 _convexAmount) internal { if (_convexAmount > 1e17) { // don't want to swap dust or we might revert cvxeth.exchange(1, 0, _convexAmount, 0, false); } if (_crvAmount > 1e17) { // don't want to swap dust or we might revert crveth.exchange(1, 0, _crvAmount, 0, false); } uint256 wethBalance = weth.balanceOf(address(this)); if (wethBalance > 0) { IWeth(address(weth)).withdraw(wethBalance); } } // Sells our harvested reward token into the selected output. function _sellRewards(uint256 _amount) internal { IUniswapV2Router02(sushiswap).swapExactTokensForTokens( _amount, uint256(0), rewardsPath, address(this), block.timestamp ); } /* ========== KEEP3RS ========== */ // use this to determine when to harvest function harvestTrigger(uint256 callCostinEth) public view override returns (bool) { // Should not trigger if strategy is not active (no assets and no debtRatio). This means we don't need to adjust keeper job. if (!isActive()) { return false; } // only check if we need to earmark on vaults we know are problematic if (checkEarmark) { // don't harvest if we need to earmark convex rewards if (needsEarmarkReward()) { return false; } } // harvest if we have a profit to claim at our upper limit without considering gas price uint256 claimableProfit = claimableProfitInUsdt(); if (claimableProfit > harvestProfitMax) { return true; } // check if the base fee gas price is higher than we allow. if it is, block harvests. if (!isBaseFeeAcceptable()) { return false; } // trigger if we want to manually harvest, but only if our gas price is acceptable if (forceHarvestTriggerOnce) { return true; } // harvest if we have a sufficient profit to claim, but only if our gas price is acceptable if (claimableProfit > harvestProfitMin) { return true; } StrategyParams memory params = vault.strategies(address(this)); // harvest no matter what once we reach our maxDelay if (block.timestamp.sub(params.lastReport) > maxReportDelay) { return true; } // harvest our credit if it's above our threshold if (vault.creditAvailable() > creditThreshold) { return true; } // otherwise, we don't harvest return false; } /// @notice The value in dollars that our claimable rewards are worth (in USDT, 6 decimals). function claimableProfitInUsdt() public view returns (uint256) { // calculations pulled directly from CVX's contract for minting CVX per CRV claimed uint256 totalCliffs = 1_000; uint256 maxSupply = 100 * 1_000_000 * 1e18; // 100mil uint256 reductionPerCliff = 100_000 * 1e18; // 100,000 uint256 supply = convexToken.totalSupply(); uint256 mintableCvx; uint256 cliff = supply.div(reductionPerCliff); uint256 _claimableBal = claimableBalance(); //mint if below total cliffs if (cliff < totalCliffs) { //for reduction% take inverse of current cliff uint256 reduction = totalCliffs.sub(cliff); //reduce mintableCvx = _claimableBal.mul(reduction).div(totalCliffs); //supply cap check uint256 amtTillMax = maxSupply.sub(supply); if (mintableCvx > amtTillMax) { mintableCvx = amtTillMax; } } // our chainlink oracle returns prices normalized to 8 decimals, we convert it to 6 IOracle ethOracle = IOracle(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419); uint256 ethPrice = ethOracle.latestAnswer().div(1e2); // 1e8 div 1e2 = 1e6 uint256 crvPrice = crveth.price_oracle().mul(ethPrice).div(1e18); // 1e18 mul 1e6 div 1e18 = 1e6 uint256 cvxPrice = cvxeth.price_oracle().mul(ethPrice).div(1e18); // 1e18 mul 1e6 div 1e18 = 1e6 uint256 crvValue = crvPrice.mul(_claimableBal).div(1e18); // 1e6 mul 1e18 div 1e18 = 1e6 uint256 cvxValue = cvxPrice.mul(mintableCvx).div(1e18); // 1e6 mul 1e18 div 1e18 = 1e6 // get the value of our rewards token if we have one uint256 rewardsValue; if (hasRewards) { address[] memory usd_path = new address[](3); usd_path[0] = address(rewardsToken); usd_path[1] = address(weth); usd_path[2] = address(usdt); uint256 _claimableBonusBal = IConvexRewards(virtualRewardsPool).earned(address(this)); if (_claimableBonusBal > 0) { uint256[] memory rewardSwap = IUniswapV2Router02(sushiswap).getAmountsOut( _claimableBonusBal, usd_path ); rewardsValue = rewardSwap[rewardSwap.length - 1]; } } return crvValue.add(cvxValue).add(rewardsValue); } // check if the current baseFee is below our external target function isBaseFeeAcceptable() internal view returns (bool) { return IBaseFee(0xb5e1CAcB567d98faaDB60a1fD4820720141f064F) .isCurrentBaseFeeAcceptable(); } /// @notice True if someone needs to earmark rewards on Convex before keepers harvest again function needsEarmarkReward() public view returns (bool needsEarmark) { // check if there is any CRV we need to earmark uint256 crvExpiry = rewardsContract.periodFinish(); if (crvExpiry < block.timestamp) { return true; } else if (hasRewards) { // check if there is any bonus reward we need to earmark uint256 rewardsExpiry = IConvexRewards(virtualRewardsPool).periodFinish(); return rewardsExpiry < block.timestamp; } } // include so our contract plays nicely with ether receive() external payable {} /* ========== SETTERS ========== */ // These functions are useful for setting parameters of the strategy that may need to be adjusted. // Use to add, update or remove rewards function updateRewards(bool _hasRewards, uint256 _rewardsIndex) external onlyGovernance { if ( address(rewardsToken) != address(0) && address(rewardsToken) != address(convexToken) ) { rewardsToken.approve(sushiswap, uint256(0)); } if (_hasRewards == false) { hasRewards = false; rewardsToken = IERC20(address(0)); virtualRewardsPool = address(0); } else { // update with our new token. get this via our virtualRewardsPool virtualRewardsPool = rewardsContract.extraRewards(_rewardsIndex); address _rewardsToken = IConvexRewards(virtualRewardsPool).rewardToken(); rewardsToken = IERC20(_rewardsToken); // approve, setup our path, and turn on rewards rewardsToken.approve(sushiswap, type(uint256).max); rewardsPath = [address(rewardsToken), address(weth)]; hasRewards = true; } } // Min profit to start checking for harvests if gas is good, max will harvest no matter gas (both in USDT, 6 decimals). // Credit threshold is in want token, and will trigger a harvest if credit is large enough. check earmark to look at convex's booster. function setHarvestTriggerParams( uint256 _harvestProfitMin, uint256 _harvestProfitMax, uint256 _creditThreshold, bool _checkEarmark ) external onlyAuthorized { harvestProfitMin = _harvestProfitMin; harvestProfitMax = _harvestProfitMax; creditThreshold = _creditThreshold; checkEarmark = _checkEarmark; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_curvePool","type":"address"},{"internalType":"string","name":"_name","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[],"name":"EmergencyExitEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"profit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"loss","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"debtPayment","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"debtOutstanding","type":"uint256"}],"name":"Harvested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"debtThreshold","type":"uint256"}],"name":"UpdatedDebtThreshold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newKeeper","type":"address"}],"name":"UpdatedKeeper","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"profitFactor","type":"uint256"}],"name":"UpdatedProfitFactor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"delay","type":"uint256"}],"name":"UpdatedReportDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"rewards","type":"address"}],"name":"UpdatedRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newStrategist","type":"address"}],"name":"UpdatedStrategist","type":"event"},{"inputs":[],"name":"apiVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"balanceOfWant","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkEarmark","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimRewards","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimableBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimableProfitInUsdt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creditThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curve","outputs":[{"internalType":"contract ICurveFi","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"debtThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"delegatedAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"doHealthCheck","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emergencyExit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"estimatedTotalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"harvestProfitMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvestProfitMin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"callCostinEth","type":"uint256"}],"name":"harvestTrigger","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hasRewards","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"healthCheck","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"keepCRV","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"keepCVX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"keepCVXDestination","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"keeper","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxReportDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newStrategy","type":"address"}],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"needsEarmarkReward","outputs":[{"internalType":"bool","name":"needsEarmark","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"profitFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewards","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsContract","outputs":[{"internalType":"contract IConvexRewards","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_claimRewards","type":"bool"}],"name":"setClaimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_debtThreshold","type":"uint256"}],"name":"setDebtThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_doHealthCheck","type":"bool"}],"name":"setDoHealthCheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setEmergencyExit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_forceHarvestTriggerOnce","type":"bool"}],"name":"setForceHarvestTriggerOnce","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_harvestProfitMin","type":"uint256"},{"internalType":"uint256","name":"_harvestProfitMax","type":"uint256"},{"internalType":"uint256","name":"_creditThreshold","type":"uint256"},{"internalType":"bool","name":"_checkEarmark","type":"bool"}],"name":"setHarvestTriggerParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_healthCheck","type":"address"}],"name":"setHealthCheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_keepCRV","type":"uint256"},{"internalType":"uint256","name":"_keepCVX","type":"uint256"},{"internalType":"address","name":"_keepCVXDestination","type":"address"}],"name":"setKeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_keeper","type":"address"}],"name":"setKeeper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_delay","type":"uint256"}],"name":"setMaxReportDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_profitFactor","type":"uint256"}],"name":"setProfitFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewards","type":"address"}],"name":"setRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategist","type":"address"}],"name":"setStrategist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"strategist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"callCost","type":"uint256"}],"name":"tendTrigger","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_hasRewards","type":"bool"},{"internalType":"uint256","name":"_rewardsIndex","type":"uint256"}],"name":"updateRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"contract VaultAPI","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"virtualRewardsPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"want","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountNeeded","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"_loss","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawToConvexDepositTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405262015180600655606460075560006008556017805460ff191660011790553480156200002f57600080fd5b5060405162004c4838038062004c488339810160408190526200005291620007c1565b838062000062813380806200007c565b50620000729050838383620002b0565b505050506200095c565b6005546001600160a01b031615620000b15760405162461bcd60e51b8152600401620000a890620008c2565b60405180910390fd5b600180546001600160a01b0319166001600160a01b03868116919091179182905560408051637e062a3560e11b81529051929091169163fc0c546a91600480820192602092909190829003018186803b1580156200010e57600080fd5b505afa15801562000123573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000149919062000710565b600580546001600160a01b0319166001600160a01b03928316179081905560405163095ea7b360e01b815291169063095ea7b3906200019190879060001990600401620008a9565b602060405180830381600087803b158015620001ac57600080fd5b505af1158015620001c1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001e7919062000887565b50600280546001600160a01b038086166001600160a01b03199283161790925560038054858416908316179081905560048054858516931692909217825560015460405163095ea7b360e01b81529084169363095ea7b3936200025393909116916000199101620008a9565b602060405180830381600087803b1580156200026e57600080fd5b505af115801562000283573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002a9919062000887565b5050505050565b60145461010090046001600160a01b031615620002cc57600080fd5b621baf8060065560008054610100600160a81b03191674ddcea799ff1699e98edf118e0629a974df7df01200179055640df8475800600f55641bf08eb00060105568d8d726b7177a8000006011556103e8600c55600e80547393a62da5a14c80f265dabc077fcee437b1a0efde6001600160a01b031990911617905560055460405163095ea7b360e01b81526001600160a01b039091169063095ea7b390620003929073f403c135812408bfbe8713b5a23a04b3d48aae319060001990600401620008a9565b602060405180830381600087803b158015620003ad57600080fd5b505af1158015620003c2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003e8919062000887565b5060405163095ea7b360e01b8152734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b9063095ea7b3906200043a9073b576491f1e6e5e62f1d8f26062ee822b40b0e0d49060001990600401620008a9565b602060405180830381600087803b1580156200045557600080fd5b505af11580156200046a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000490919062000887565b5060405163095ea7b360e01b815273d533a949740bb3306d119cc777fa900ba034cd529063095ea7b390620004e290738301ae4fc9c624d1d396cbdaa1ed877821d7c5119060001990600401620008a9565b602060405180830381600087803b158015620004fd57600080fd5b505af115801562000512573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000538919062000887565b5060148054610100600160a81b0319166101006001600160a01b03851602179055600b839055604051631526fe2760e01b8152600090819073f403c135812408bfbe8713b5a23a04b3d48aae3190631526fe27906200059c908890600401620008f9565b60c06040518083038186803b158015620005b557600080fd5b505afa158015620005ca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005f0919062000735565b5050600980546001600160a01b0380841661010002610100600160a81b031990921691909117909155600554949650909450808616931692909214915062000639905057600080fd5b82516200064e90601390602086019062000656565b505050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200069957805160ff1916838001178555620006c9565b82800160010185558215620006c9579182015b82811115620006c9578251825591602001919060010190620006ac565b50620006d7929150620006db565b5090565b5b80821115620006d75760008155600101620006dc565b80516001600160a01b03811681146200070a57600080fd5b92915050565b60006020828403121562000722578081fd5b6200072e8383620006f2565b9392505050565b60008060008060008060c087890312156200074e578182fd5b6200075a8888620006f2565b95506200076b8860208901620006f2565b94506200077c8860408901620006f2565b93506200078d8860608901620006f2565b92506200079e8860808901620006f2565b915060a08701518015158114620007b3578182fd5b809150509295509295509295565b60008060008060808587031215620007d7578384fd5b620007e38686620006f2565b935060208501519250620007fb8660408701620006f2565b60608601519092506001600160401b038082111562000818578283fd5b818701915087601f8301126200082c578283fd5b8151818111156200083b578384fd5b62000850601f8201601f191660200162000902565b915080825288602082850101111562000867578384fd5b6200087a81602084016020860162000929565b5094979396509194505050565b60006020828403121562000899578081fd5b815180151581146200072e578182fd5b6001600160a01b03929092168252602082015260400190565b6020808252601c908201527f537472617465677920616c726561647920696e697469616c697a656400000000604082015260600190565b90815260200190565b6040518181016001600160401b03811182821017156200092157600080fd5b604052919050565b60005b83811015620009465781810151838201526020016200092c565b8381111562000956576000848401525b50505050565b6142dc806200096c6000396000f3fe60806040526004361061037a5760003560e01c80637fef901a116101d1578063c7b9d53011610102578063ed882c2b116100a0578063f09338df1161006f578063f09338df146108e4578063f1068454146108f9578063fbfa77cf1461090e578063fcf2d0ad1461092357610381565b8063ed882c2b1461087a578063ef86b23c1461089a578063efbb5cb0146108af578063f017c92f146108c457610381565b8063dbad1ab1116100dc578063dbad1ab114610810578063ec2f105014610830578063ec38a86214610845578063ecf04e151461086557610381565b8063c7b9d530146107bb578063ce5494bb146107db578063d1af0c7d146107fb57610381565b8063ac00ff261161016f578063b4d48fd411610149578063b4d48fd41461075c578063ba28e59c1461077c578063c1a3d44c14610791578063c4f45423146107a657610381565b8063ac00ff2614610712578063aced166114610732578063b252720b1461074757610381565b806391397ab4116101ab57806391397ab4146106a85780639ec5a894146106c8578063a98f9296146106dd578063aa5480cf146106fd57610381565b80637fef901a146106695780638cdfe1661461067e5780638e6350e21461069357610381565b80632e1a7d4d116102ab5780635641ec0311610249578063650d188011610223578063650d1880146105ff5780636718835f1461061f5780637165485d14610634578063748747e61461064957610381565b80635641ec03146105c05780635b9f0016146105d55780635fbeb25f146105ea57610381565b80633b7c6e2f116102855780633b7c6e2f1461056c578063440368a3146105815780634641257d146105965780634b31217e146105ab57610381565b80632e1a7d4d1461052257806334659dc514610542578063372500ab1461055757610381565b80631d12f28b11610318578063220cce97116102f2578063220cce97146104c157806322f3e2d4146104d657806325829410146104f857806328b7ccf71461050d57610381565b80631d12f28b146104755780631f1fcd511461048a5780631fe4a686146104ac57610381565b80630ada4dab116103545780630ada4dab146103f55780630f969b87146104155780631111fe1c1461043557806311bc82451461045557610381565b806301681a621461038657806306cfb3c0146103a857806306fdde03146103d357610381565b3661038157005b600080fd5b34801561039257600080fd5b506103a66103a1366004613b65565b610938565b005b3480156103b457600080fd5b506103bd610b42565b6040516103ca91906140be565b60405180910390f35b3480156103df57600080fd5b506103e8611064565b6040516103ca9190613e7b565b34801561040157600080fd5b506103a6610410366004613c32565b6110fa565b34801561042157600080fd5b506103a6610430366004613d07565b61115a565b34801561044157600080fd5b506103a6610450366004613d37565b6111e7565b34801561046157600080fd5b506103a6610470366004613b65565b611266565b34801561048157600080fd5b506103bd6112c6565b34801561049657600080fd5b5061049f6112cc565b6040516103ca9190613dcb565b3480156104b857600080fd5b5061049f6112db565b3480156104cd57600080fd5b5061049f6112ea565b3480156104e257600080fd5b506104eb6112fe565b6040516103ca9190613e4b565b34801561050457600080fd5b506103e86113a0565b34801561051957600080fd5b506103bd6113bf565b34801561052e57600080fd5b506103bd61053d366004613d07565b6113c5565b34801561054e57600080fd5b506103a66114b4565b34801561056357600080fd5b506104eb6115a5565b34801561057857600080fd5b506103bd6115ae565b34801561058d57600080fd5b506103a66115b4565b3480156105a257600080fd5b506103a661169b565b3480156105b757600080fd5b506103bd611a34565b3480156105cc57600080fd5b506104eb611a3a565b3480156105e157600080fd5b506103bd611a43565b3480156105f657600080fd5b506103bd611ac9565b34801561060b57600080fd5b506104eb61061a366004613d07565b611acf565b34801561062b57600080fd5b506104eb611ad7565b34801561064057600080fd5b5061049f611ae0565b34801561065557600080fd5b506103a6610664366004613b65565b611af4565b34801561067557600080fd5b506103bd611b9f565b34801561068a57600080fd5b506103bd611ba5565b34801561069f57600080fd5b506103bd611bab565b3480156106b457600080fd5b506103a66106c3366004613d07565b611bb0565b3480156106d457600080fd5b5061049f611c32565b3480156106e957600080fd5b506103a66106f8366004613c32565b611c41565b34801561070957600080fd5b506103bd611ca1565b34801561071e57600080fd5b506103a661072d366004613c32565b611ca7565b34801561073e57600080fd5b5061049f611cf2565b34801561075357600080fd5b5061049f611d01565b34801561076857600080fd5b506103a6610777366004613d6f565b611d15565b34801561078857600080fd5b5061049f611d8f565b34801561079d57600080fd5b506103bd611d9e565b3480156107b257600080fd5b506103bd611dcf565b3480156107c757600080fd5b506103a66107d6366004613b65565b611e03565b3480156107e757600080fd5b506103a66107f6366004613b65565b611eae565b34801561080757600080fd5b5061049f61202a565b34801561081c57600080fd5b506103a661082b366004613c6a565b612039565b34801561083c57600080fd5b506104eb612397565b34801561085157600080fd5b506103a6610860366004613b65565b6123a7565b34801561087157600080fd5b506104eb61242f565b34801561088657600080fd5b506104eb610895366004613d07565b61243f565b3480156108a657600080fd5b5061049f612635565b3480156108bb57600080fd5b506103bd612644565b3480156108d057600080fd5b506103a66108df366004613d07565b612659565b3480156108f057600080fd5b506104eb6126db565b34801561090557600080fd5b506103bd612817565b34801561091a57600080fd5b5061049f61281d565b34801561092f57600080fd5b506103a661282c565b610940612910565b6001600160a01b0316336001600160a01b0316146109795760405162461bcd60e51b81526004016109709061402b565b60405180910390fd5b6005546001600160a01b03828116911614156109a75760405162461bcd60e51b815260040161097090613ed3565b6001546001600160a01b03828116911614156109d55760405162461bcd60e51b815260040161097090613fd3565b60606109df61298d565b905060005b8151811015610a3a578181815181106109f957fe5b60200260200101516001600160a01b0316836001600160a01b03161415610a325760405162461bcd60e51b81526004016109709061409a565b6001016109e4565b50816001600160a01b031663a9059cbb610a52612910565b6040516370a0823160e01b81526001600160a01b038616906370a0823190610a7e903090600401613dcb565b60206040518083038186803b158015610a9657600080fd5b505afa158015610aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ace9190613d1f565b6040518363ffffffff1660e01b8152600401610aeb929190613dfa565b602060405180830381600087803b158015610b0557600080fd5b505af1158015610b19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3d9190613c4e565b505050565b6000806103e8905060006a52b7d2dcc80cd2e40000009050600069152d02c7e14af680000090506000734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b6001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610bb857600080fd5b505afa158015610bcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf09190613d1f565b9050600080610bff8385612992565b90506000610c0b611dcf565b905086821015610c56576000610c2188846129dd565b9050610c3788610c318484612a1f565b90612992565b93506000610c4588876129dd565b905080851115610c53578094505b50505b6000735f4ec3df9cbd43714fe2740f5e3616155c5b841990506000610ce76064836001600160a01b03166350d25bcd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610caf57600080fd5b505afa158015610cc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c319190613d1f565b90506000610d86670de0b6b3a7640000610c3184738301ae4fc9c624d1d396cbdaa1ed877821d7c5116001600160a01b03166386fc88d36040518163ffffffff1660e01b815260040160206040518083038186803b158015610d4857600080fd5b505afa158015610d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d809190613d1f565b90612a1f565b90506000610de7670de0b6b3a7640000610c318573b576491f1e6e5e62f1d8f26062ee822b40b0e0d46001600160a01b03166386fc88d36040518163ffffffff1660e01b815260040160206040518083038186803b158015610d4857600080fd5b90506000610e01670de0b6b3a7640000610c318589612a1f565b90506000610e1b670de0b6b3a7640000610c31858c612a1f565b601554909150600090600160a01b900460ff161561103c5760408051600380825260808201909252606091602082018380368337505060155482519293506001600160a01b031691839150600090610e6f57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281600181518110610eb157fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073dac17f958d2ee523a2206206994597c13d831ec781600281518110610ef357fe5b6001600160a01b039283166020918202929092010152600a546040516246613160e11b81526000929190911690628cc26290610f33903090600401613dcb565b60206040518083038186803b158015610f4b57600080fd5b505afa158015610f5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f839190613d1f565b905080156110395760405163d06ca61f60e01b815260609073d9e1ce17f2641f24ae83637ab66a2cca9c378b9f9063d06ca61f90610fc790859087906004016140c7565b60006040518083038186803b158015610fdf57600080fd5b505afa158015610ff3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261101b9190810190613b9d565b90508060018251038151811061102d57fe5b60200260200101519350505b50505b6110508161104a8585612a59565b90612a59565b9e5050505050505050505050505050505b90565b60138054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156110f05780601f106110c5576101008083540402835291602001916110f0565b820191906000526020600020905b8154815290600101906020018083116110d357829003601f168201915b5050505050905090565b6002546001600160a01b031633148061112b5750611116612910565b6001600160a01b0316336001600160a01b0316145b6111475760405162461bcd60e51b81526004016109709061402b565b6012805460ff1916911515919091179055565b6002546001600160a01b031633148061118b5750611176612910565b6001600160a01b0316336001600160a01b0316145b6111a75760405162461bcd60e51b81526004016109709061402b565b60088190556040517fa68ba126373d04c004c5748c300c9fca12bd444b3d4332e261f3bd2bac4a8600906111dc9083906140be565b60405180910390a150565b6111ef612910565b6001600160a01b0316336001600160a01b03161461121f5760405162461bcd60e51b81526004016109709061402b565b612710831115801561123357506127108211155b61123c57600080fd5b600c92909255600d55600e80546001600160a01b0319166001600160a01b03909216919091179055565b61126e612910565b6001600160a01b0316336001600160a01b03161461129e5760405162461bcd60e51b81526004016109709061402b565b600080546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b60085481565b6005546001600160a01b031681565b6002546001600160a01b031681565b60095461010090046001600160a01b031681565b6001546040516339ebf82360e01b815260009182916001600160a01b03909116906339ebf82390611333903090600401613dcb565b6101006040518083038186803b15801561134c57600080fd5b505afa158015611360573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113849190613c95565b60400151118061139b57506000611399612644565b115b905090565b6040805180820190915260058152640302e332e360dc1b602082015290565b60065481565b6001546000906001600160a01b031633146113f25760405162461bcd60e51b815260040161097090613fb3565b60006113fd83612a7e565b9250905061140b8183612a59565b83146114295760405162461bcd60e51b815260040161097090613f4f565b60055460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061145b9033908590600401613dfa565b602060405180830381600087803b15801561147557600080fd5b505af1158015611489573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ad9190613c4e565b5050919050565b6002546001600160a01b03163314806114e557506114d0612910565b6001600160a01b0316336001600160a01b0316145b6115015760405162461bcd60e51b81526004016109709061402b565b600061150b611a43565b905080156115a257600954601454604051631c683a1b60e11b81526101009092046001600160a01b0316916338d074369161154e91859160ff169060040161411d565b602060405180830381600087803b15801561156857600080fd5b505af115801561157c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a09190613c4e565b505b50565b60145460ff1681565b60105481565b6004546001600160a01b03163314806115d757506002546001600160a01b031633145b806115fa57506115e5612910565b6001600160a01b0316336001600160a01b0316145b6116165760405162461bcd60e51b81526004016109709061402b565b6001546040805163bf3759b560e01b81529051611699926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b15801561165c57600080fd5b505afa158015611670573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116949190613d1f565b612b8b565b565b6004546001600160a01b03163314806116be57506002546001600160a01b031633145b806116e157506116cc612910565b6001600160a01b0316336001600160a01b0316145b6116fd5760405162461bcd60e51b81526004016109709061402b565b6000806000600160009054906101000a90046001600160a01b03166001600160a01b031663bf3759b56040518163ffffffff1660e01b815260040160206040518083038186803b15801561175057600080fd5b505afa158015611764573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117889190613d1f565b60095490915060009060ff16156117de5760006117a3612644565b90506117bc8382116117b557836117b7565b815b612a7e565b94509150828211156117d8576117d282846129dd565b94508291505b506117ef565b6117e782612beb565b919550935090505b6001546040516339ebf82360e01b81526000916001600160a01b0316906339ebf82390611820903090600401613dcb565b6101006040518083038186803b15801561183957600080fd5b505afa15801561184d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118719190613c95565b60a001516001546040516328766ebf60e21b81529192506001600160a01b03169063a1d9bafc906118aa908890889087906004016141b8565b602060405180830381600087803b1580156118c457600080fd5b505af11580156118d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118fc9190613d1f565b9250611906613256565b61190f83612b8b565b60005460ff168015611930575060005461010090046001600160a01b031615155b156119e25760005460405163c70fa00b60e01b81526101009091046001600160a01b03169063c70fa00b9061197190889088908790899088906004016141e9565b60206040518083038186803b15801561198957600080fd5b505afa15801561199d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c19190613c4e565b6119dd5760405162461bcd60e51b815260040161097090613f29565b6119f0565b6000805460ff191660011790555b7f4c0f499ffe6befa0ca7c826b0916cf87bea98de658013e76938489368d60d50985858486604051611a2594939291906141ce565b60405180910390a15050505050565b600d5481565b60095460ff1681565b6009546040516370a0823160e01b815260009161010090046001600160a01b0316906370a0823190611a79903090600401613dcb565b60206040518083038186803b158015611a9157600080fd5b505afa158015611aa5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139b9190613d1f565b600f5481565b60005b919050565b60005460ff1681565b60145461010090046001600160a01b031681565b6002546001600160a01b0316331480611b255750611b10612910565b6001600160a01b0316336001600160a01b0316145b611b415760405162461bcd60e51b81526004016109709061402b565b6001600160a01b038116611b5457600080fd5b600480546001600160a01b0319166001600160a01b0383161790556040517f2f202ddb4a2e345f6323ed90f8fc8559d770a7abbbeee84dde8aca3351fe7154906111dc908390613dcb565b600c5481565b60075481565b600090565b6002546001600160a01b0316331480611be15750611bcc612910565b6001600160a01b0316336001600160a01b0316145b611bfd5760405162461bcd60e51b81526004016109709061402b565b60078190556040517fd94596337df4c2f0f44d30a7fc5db1c7bb60d9aca4185ed77c6fd96eb45ec298906111dc9083906140be565b6003546001600160a01b031681565b6002546001600160a01b0316331480611c725750611c5d612910565b6001600160a01b0316336001600160a01b0316145b611c8e5760405162461bcd60e51b81526004016109709061402b565b6014805460ff1916911515919091179055565b60115481565b611caf612910565b6001600160a01b0316336001600160a01b031614611cdf5760405162461bcd60e51b81526004016109709061402b565b6000805460ff1916911515919091179055565b6004546001600160a01b031681565b60005461010090046001600160a01b031681565b6002546001600160a01b0316331480611d465750611d31612910565b6001600160a01b0316336001600160a01b0316145b611d625760405162461bcd60e51b81526004016109709061402b565b600f9390935560109190915560115560148054911515600160a81b0260ff60a81b19909216919091179055565b600a546001600160a01b031681565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a0823190611a79903090600401613dcb565b6009546040516246613160e11b815260009161010090046001600160a01b031690628cc26290611a79903090600401613dcb565b6002546001600160a01b0316331480611e345750611e1f612910565b6001600160a01b0316336001600160a01b0316145b611e505760405162461bcd60e51b81526004016109709061402b565b6001600160a01b038116611e6357600080fd5b600280546001600160a01b0319166001600160a01b0383161790556040517f352ececae6d7d1e6d26bcf2c549dfd55be1637e9b22dc0cf3b71ddb36097a6b4906111dc908390613dcb565b6001546001600160a01b0316331480611edf5750611eca612910565b6001600160a01b0316336001600160a01b0316145b611ee857600080fd5b6001546040805163fbfa77cf60e01b815290516001600160a01b039283169284169163fbfa77cf916004808301926020929190829003018186803b158015611f2f57600080fd5b505afa158015611f43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f679190613b81565b6001600160a01b031614611f7a57600080fd5b611f8381613315565b6005546040516370a0823160e01b81526001600160a01b039091169063a9059cbb90839083906370a0823190611fbd903090600401613dcb565b60206040518083038186803b158015611fd557600080fd5b505afa158015611fe9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061200d9190613d1f565b6040518363ffffffff1660e01b815260040161154e929190613dfa565b6015546001600160a01b031681565b612041612910565b6001600160a01b0316336001600160a01b0316146120715760405162461bcd60e51b81526004016109709061402b565b6015546001600160a01b0316158015906120aa57506015546001600160a01b0316734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b14155b1561214a5760155460405163095ea7b360e01b81526001600160a01b039091169063095ea7b3906120f69073d9e1ce17f2641f24ae83637ab66a2cca9c378b9f90600090600401613dfa565b602060405180830381600087803b15801561211057600080fd5b505af1158015612124573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121489190613c4e565b505b8161217457601580546001600160a81b0319169055600a80546001600160a01b03191690556115a0565b600954604051632061aa2360e11b81526101009091046001600160a01b0316906340c35446906121a89084906004016140be565b60206040518083038186803b1580156121c057600080fd5b505afa1580156121d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f89190613b81565b600a80546001600160a01b0319166001600160a01b0392831617908190556040805163f7c618c160e01b81529051600093929092169163f7c618c191600480820192602092909190829003018186803b15801561225457600080fd5b505afa158015612268573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061228c9190613b81565b601580546001600160a01b0319166001600160a01b03838116919091179182905560405163095ea7b360e01b8152929350169063095ea7b3906122eb9073d9e1ce17f2641f24ae83637ab66a2cca9c378b9f9060001990600401613dfa565b602060405180830381600087803b15801561230557600080fd5b505af1158015612319573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233d9190613c4e565b50604080518082019091526015546001600160a01b0316815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2602082015261237e906016906002613aa0565b50506015805460ff60a01b1916600160a01b1790555050565b601454600160a81b900460ff1681565b6002546001600160a01b031633146123d15760405162461bcd60e51b815260040161097090613eae565b6001600160a01b0381166123e457600080fd5b600380546001600160a01b0319166001600160a01b0383161790556040517fafbb66abf8f3b719799940473a4052a3717cdd8e40fb6c8a3faadab316b1a069906111dc908390613dcb565b601554600160a01b900460ff1681565b60006124496112fe565b61245557506000611ad2565b601454600160a81b900460ff161561247c5761246f6126db565b1561247c57506000611ad2565b6000612486610b42565b905060105481111561249c576001915050611ad2565b6124a4613508565b6124b2576000915050611ad2565b60125460ff16156124c7576001915050611ad2565b600f548111156124db576001915050611ad2565b6124e3613b01565b6001546040516339ebf82360e01b81526001600160a01b03909116906339ebf82390612513903090600401613dcb565b6101006040518083038186803b15801561252c57600080fd5b505afa158015612540573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125649190613c95565b90506006546125808260800151426129dd90919063ffffffff16565b111561259157600192505050611ad2565b601154600160009054906101000a90046001600160a01b03166001600160a01b031663112c1f9b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156125e257600080fd5b505afa1580156125f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061261a9190613d1f565b111561262b57600192505050611ad2565b5060009392505050565b600e546001600160a01b031681565b600061139b612651611a43565b61104a611d9e565b6002546001600160a01b031633148061268a5750612675612910565b6001600160a01b0316336001600160a01b0316145b6126a65760405162461bcd60e51b81526004016109709061402b565b60068190556040517f4aaf232568bff365c53cad69bdb6e83014e79df80216ceba8ee01769723dfd68906111dc9083906140be565b600080600960019054906101000a90046001600160a01b03166001600160a01b031663ebe2b12b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561272c57600080fd5b505afa158015612740573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127649190613d1f565b905042811015612778576001915050611061565b601554600160a01b900460ff161561281357600a546040805163ebe2b12b60e01b815290516000926001600160a01b03169163ebe2b12b916004808301926020929190829003018186803b1580156127cf57600080fd5b505afa1580156127e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128079190613d1f565b42119250611061915050565b5090565b600b5481565b6001546001600160a01b031681565b6002546001600160a01b031633148061285d5750612848612910565b6001600160a01b0316336001600160a01b0316145b6128795760405162461bcd60e51b81526004016109709061402b565b6009805460ff19166001908117909155546040805163507257cd60e11b815290516001600160a01b039092169163a0e4af9a9160048082019260009290919082900301818387803b1580156128cd57600080fd5b505af11580156128e1573d6000803e3d6000fd5b50506040517f97e963041e952738788b9d4871d854d282065b8f90a464928d6528f2e9a4fd0b925060009150a1565b60015460408051635aa6e67560e01b815290516000926001600160a01b031691635aa6e675916004808301926020929190829003018186803b15801561295557600080fd5b505afa158015612969573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139b9190613b81565b606090565b60006129d483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061358f565b90505b92915050565b60006129d483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506135c6565b600082612a2e575060006129d7565b82820282848281612a3b57fe5b04146129d45760405162461bcd60e51b815260040161097090613f72565b6000828201838110156129d45760405162461bcd60e51b815260040161097090613ef2565b6000806000612a8b611d9e565b905080841115612b77576000612a9f611a43565b90508015612b4c5760095461010090046001600160a01b031663c32e7202612ad083612acb89876129dd565b6135f2565b6014546040516001600160e01b031960e085901b168152612af8929160ff169060040161411d565b602060405180830381600087803b158015612b1257600080fd5b505af1158015612b26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b4a9190613c4e565b505b6000612b56611d9e565b9050612b6286826135f2565b9450612b6e86866129dd565b93505050612b84565b8360009250925050612b86565b505b915091565b60095460ff1615612b9b576115a2565b6000612ba5611d9e565b905080156115a057600b546040516321d0683360e11b815273f403c135812408bfbe8713b5a23a04b3d48aae31916343a0d06691610aeb919085906001906004016141a0565b600954604051637050ccd960e01b81526000918291829161010090046001600160a01b031690637050ccd990612c28903090600190600401613ddf565b602060405180830381600087803b158015612c4257600080fd5b505af1158015612c56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c7a9190613c4e565b506040516370a0823160e01b815260009073d533a949740bb3306d119cc777fa900ba034cd52906370a0823190612cb5903090600401613dcb565b60206040518083038186803b158015612ccd57600080fd5b505afa158015612ce1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d059190613d1f565b6040516370a0823160e01b8152909150600090734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906370a0823190612d42903090600401613dcb565b60206040518083038186803b158015612d5a57600080fd5b505afa158015612d6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d929190613d1f565b90506000612db1612710610c31600c5486612a1f90919063ffffffff16565b90508015612e7657612dec73d533a949740bb3306d119cc777fa900ba034cd5273f147b8125d2ef93fb6965db97d6746952a13393483613608565b6040516370a0823160e01b815273d533a949740bb3306d119cc777fa900ba034cd52906370a0823190612e23903090600401613dcb565b60206040518083038186803b158015612e3b57600080fd5b505afa158015612e4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e739190613d1f565b92505b6000612e93612710610c31600d5486612a1f90919063ffffffff16565b90508015612f5157600e54612ec790734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906001600160a01b031683613608565b6040516370a0823160e01b8152734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906370a0823190612efe903090600401613dcb565b60206040518083038186803b158015612f1657600080fd5b505afa158015612f2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f4e9190613d1f565b92505b601554600160a01b900460ff1615612ff7576015546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612f94903090600401613dcb565b60206040518083038186803b158015612fac57600080fd5b505afa158015612fc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe49190613d1f565b90508015612ff557612ff58161365e565b505b61300184846136f5565b478015613086576014546040805180820182528381526000602082018190529151630b4c7e4d60e01b81526101009093046001600160a01b031692630b4c7e4d92859261305392909190600401613e13565b6000604051808303818588803b15801561306c57600080fd5b505af1158015613080573d6000803e3d6000fd5b50505050505b8815613155576000613096611a43565b9050801561313a5760095461010090046001600160a01b031663c32e72026130be838d6135f2565b6014546040516001600160e01b031960e085901b1681526130e6929160ff169060040161411d565b602060405180830381600087803b15801561310057600080fd5b505af1158015613114573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131389190613c4e565b505b6000613144611d9e565b90506131508b826135f2565b975050505b600061315f612644565b6001546040516339ebf82360e01b81529192506000916001600160a01b03909116906339ebf82390613195903090600401613dcb565b6101006040518083038186803b1580156131ae57600080fd5b505afa1580156131c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131e69190613c95565b60a0015190508082111561322f576131fe82826129dd565b9950600061320a611d9e565b9050806132178c8b612a59565b11156132295761322683612a7e565b50505b5061323c565b61323981836129dd565b98505b50506012805460ff19169055509597949650929450505050565b6001546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613287903090600401613dcb565b60206040518083038186803b15801561329f57600080fd5b505afa1580156132b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d79190613d1f565b905080156115a25760015460035460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9261154e929116908590600401613dfa565b600061331f611a43565b905080156133b657600954601454604051636197390160e11b81526101009092046001600160a01b03169163c32e72029161336291859160ff169060040161411d565b602060405180830381600087803b15801561337c57600080fd5b505af1158015613390573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133b49190613c4e565b505b6040516370a0823160e01b815261345f90839073d533a949740bb3306d119cc777fa900ba034cd52906370a08231906133f3903090600401613dcb565b60206040518083038186803b15801561340b57600080fd5b505afa15801561341f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134439190613d1f565b73d533a949740bb3306d119cc777fa900ba034cd529190613608565b6040516370a0823160e01b81526115a0908390734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906370a082319061349c903090600401613dcb565b60206040518083038186803b1580156134b457600080fd5b505afa1580156134c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134ec9190613d1f565b734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b9190613608565b600073b5e1cacb567d98faadb60a1fd4820720141f064f6001600160a01b03166334a9e75c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561355757600080fd5b505afa15801561356b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139b9190613c4e565b600081836135b05760405162461bcd60e51b81526004016109709190613e7b565b5060008385816135bc57fe5b0495945050505050565b600081848411156135ea5760405162461bcd60e51b81526004016109709190613e7b565b505050900390565b600081831061360157816129d4565b5090919050565b610b3d8363a9059cbb60e01b8484604051602401613627929190613dfa565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526138fd565b6040516338ed173960e01b815273d9e1ce17f2641f24ae83637ab66a2cca9c378b9f906338ed17399061369f9084906000906016903090429060040161412d565b600060405180830381600087803b1580156136b957600080fd5b505af11580156136cd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115a09190810190613b9d565b67016345785d8a00008111156137795760405163394747c560e01b815273b576491f1e6e5e62f1d8f26062ee822b40b0e0d49063394747c59061374690600190600090869082908190600401613e56565b600060405180830381600087803b15801561376057600080fd5b505af1158015613774573d6000803e3d6000fd5b505050505b67016345785d8a00008211156137fd5760405163394747c560e01b8152738301ae4fc9c624d1d396cbdaa1ed877821d7c5119063394747c5906137ca90600190600090879082908190600401613e56565b600060405180830381600087803b1580156137e457600080fd5b505af11580156137f8573d6000803e3d6000fd5b505050505b6040516370a0823160e01b815260009073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2906370a0823190613837903090600401613dcb565b60206040518083038186803b15801561384f57600080fd5b505afa158015613863573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138879190613d1f565b90508015610b3d57604051632e1a7d4d60e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d906138c69084906004016140be565b600060405180830381600087803b1580156138e057600080fd5b505af11580156138f4573d6000803e3d6000fd5b50505050505050565b6060613952826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661398c9092919063ffffffff16565b805190915015610b3d57808060200190518101906139709190613c4e565b610b3d5760405162461bcd60e51b815260040161097090614050565b606061399b84846000856139a3565b949350505050565b60606139ae85613a67565b6139ca5760405162461bcd60e51b815260040161097090613ff4565b60006060866001600160a01b031685876040516139e79190613daf565b60006040518083038185875af1925050503d8060008114613a24576040519150601f19603f3d011682016040523d82523d6000602084013e613a29565b606091505b50915091508115613a3d57915061399b9050565b805115613a4d5780518082602001fd5b8360405162461bcd60e51b81526004016109709190613e7b565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061399b575050151592915050565b828054828255906000526020600020908101928215613af5579160200282015b82811115613af557825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613ac0565b50612813929150613b46565b60405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b808211156128135780546001600160a01b0319168155600101613b47565b600060208284031215613b76578081fd5b81356129d481614283565b600060208284031215613b92578081fd5b81516129d481614283565b60006020808385031215613baf578182fd5b825167ffffffffffffffff811115613bc5578283fd5b8301601f81018513613bd5578283fd5b8051613be8613be382614233565b61420c565b8181528381019083850185840285018601891015613c04578687fd5b8694505b83851015613c26578051835260019490940193918501918501613c08565b50979650505050505050565b600060208284031215613c43578081fd5b81356129d481614298565b600060208284031215613c5f578081fd5b81516129d481614298565b60008060408385031215613c7c578081fd5b8235613c8781614298565b946020939093013593505050565b6000610100808385031215613ca8578182fd5b613cb18161420c565b9050825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201528091505092915050565b600060208284031215613d18578081fd5b5035919050565b600060208284031215613d30578081fd5b5051919050565b600080600060608486031215613d4b578081fd5b83359250602084013591506040840135613d6481614283565b809150509250925092565b60008060008060808587031215613d84578081fd5b8435935060208501359250604085013591506060850135613da481614298565b939692955090935050565b60008251613dc1818460208701614253565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039290921682521515602082015260400190565b6001600160a01b03929092168252602082015260400190565b60608101818460005b6002811015613e3b578151835260209283019290910190600101613e1c565b5050508260408301529392505050565b901515815260200190565b9485526020850193909352604084019190915260608301521515608082015260a00190565b6000602082528251806020840152613e9a816040850160208701614253565b601f01601f19169190910160400192915050565b6020808252600b908201526a085cdd1c985d1959da5cdd60aa1b604082015260600190565b602080825260059082015264085dd85b9d60da1b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252600c908201526b216865616c7468636865636b60a01b604082015260600190565b60208082526009908201526821776974686472617760b81b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b602080825260069082015265085d985d5b1d60d21b604082015260600190565b6020808252600790820152662173686172657360c81b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252600b908201526a08585d5d1a1bdc9a5e995960aa1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600a9082015269085c1c9bdd1958dd195960b21b604082015260600190565b90815260200190565b60006040820184835260206040818501528185518084526060860191508287019350845b818110156141105784516001600160a01b0316835293830193918301916001016140eb565b5090979650505050505050565b9182521515602082015260400190565b600060a082018783526020878185015260a0604085015281875480845260c0860191508885528285209350845b8181101561417f5784546001600160a01b03168352600194850194928401920161415a565b50506001600160a01b03969096166060850152505050608001529392505050565b92835260208301919091521515604082015260600190565b9283526020830191909152604082015260600190565b93845260208401929092526040830152606082015260800190565b948552602085019390935260408401919091526060830152608082015260a00190565b60405181810167ffffffffffffffff8111828210171561422b57600080fd5b604052919050565b600067ffffffffffffffff821115614249578081fd5b5060209081020190565b60005b8381101561426e578181015183820152602001614256565b8381111561427d576000848401525b50505050565b6001600160a01b03811681146115a257600080fd5b80151581146115a257600080fdfea264697066735822122038d8aa59fccb902e8d93aa5239e24e4aab5c3f1e7b0e6a65a8802b9c01e3e6fd64736f6c634300060c0033000000000000000000000000dcd90c7f6324cfa40d7169ef80b12031770b43250000000000000000000000000000000000000000000000000000000000000019000000000000000000000000dc24316b9ae028f1497c275eb9192a3ea0f67022000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000135374726174656779436f6e766578737445544800000000000000000000000000
Deployed Bytecode
0x60806040526004361061037a5760003560e01c80637fef901a116101d1578063c7b9d53011610102578063ed882c2b116100a0578063f09338df1161006f578063f09338df146108e4578063f1068454146108f9578063fbfa77cf1461090e578063fcf2d0ad1461092357610381565b8063ed882c2b1461087a578063ef86b23c1461089a578063efbb5cb0146108af578063f017c92f146108c457610381565b8063dbad1ab1116100dc578063dbad1ab114610810578063ec2f105014610830578063ec38a86214610845578063ecf04e151461086557610381565b8063c7b9d530146107bb578063ce5494bb146107db578063d1af0c7d146107fb57610381565b8063ac00ff261161016f578063b4d48fd411610149578063b4d48fd41461075c578063ba28e59c1461077c578063c1a3d44c14610791578063c4f45423146107a657610381565b8063ac00ff2614610712578063aced166114610732578063b252720b1461074757610381565b806391397ab4116101ab57806391397ab4146106a85780639ec5a894146106c8578063a98f9296146106dd578063aa5480cf146106fd57610381565b80637fef901a146106695780638cdfe1661461067e5780638e6350e21461069357610381565b80632e1a7d4d116102ab5780635641ec0311610249578063650d188011610223578063650d1880146105ff5780636718835f1461061f5780637165485d14610634578063748747e61461064957610381565b80635641ec03146105c05780635b9f0016146105d55780635fbeb25f146105ea57610381565b80633b7c6e2f116102855780633b7c6e2f1461056c578063440368a3146105815780634641257d146105965780634b31217e146105ab57610381565b80632e1a7d4d1461052257806334659dc514610542578063372500ab1461055757610381565b80631d12f28b11610318578063220cce97116102f2578063220cce97146104c157806322f3e2d4146104d657806325829410146104f857806328b7ccf71461050d57610381565b80631d12f28b146104755780631f1fcd511461048a5780631fe4a686146104ac57610381565b80630ada4dab116103545780630ada4dab146103f55780630f969b87146104155780631111fe1c1461043557806311bc82451461045557610381565b806301681a621461038657806306cfb3c0146103a857806306fdde03146103d357610381565b3661038157005b600080fd5b34801561039257600080fd5b506103a66103a1366004613b65565b610938565b005b3480156103b457600080fd5b506103bd610b42565b6040516103ca91906140be565b60405180910390f35b3480156103df57600080fd5b506103e8611064565b6040516103ca9190613e7b565b34801561040157600080fd5b506103a6610410366004613c32565b6110fa565b34801561042157600080fd5b506103a6610430366004613d07565b61115a565b34801561044157600080fd5b506103a6610450366004613d37565b6111e7565b34801561046157600080fd5b506103a6610470366004613b65565b611266565b34801561048157600080fd5b506103bd6112c6565b34801561049657600080fd5b5061049f6112cc565b6040516103ca9190613dcb565b3480156104b857600080fd5b5061049f6112db565b3480156104cd57600080fd5b5061049f6112ea565b3480156104e257600080fd5b506104eb6112fe565b6040516103ca9190613e4b565b34801561050457600080fd5b506103e86113a0565b34801561051957600080fd5b506103bd6113bf565b34801561052e57600080fd5b506103bd61053d366004613d07565b6113c5565b34801561054e57600080fd5b506103a66114b4565b34801561056357600080fd5b506104eb6115a5565b34801561057857600080fd5b506103bd6115ae565b34801561058d57600080fd5b506103a66115b4565b3480156105a257600080fd5b506103a661169b565b3480156105b757600080fd5b506103bd611a34565b3480156105cc57600080fd5b506104eb611a3a565b3480156105e157600080fd5b506103bd611a43565b3480156105f657600080fd5b506103bd611ac9565b34801561060b57600080fd5b506104eb61061a366004613d07565b611acf565b34801561062b57600080fd5b506104eb611ad7565b34801561064057600080fd5b5061049f611ae0565b34801561065557600080fd5b506103a6610664366004613b65565b611af4565b34801561067557600080fd5b506103bd611b9f565b34801561068a57600080fd5b506103bd611ba5565b34801561069f57600080fd5b506103bd611bab565b3480156106b457600080fd5b506103a66106c3366004613d07565b611bb0565b3480156106d457600080fd5b5061049f611c32565b3480156106e957600080fd5b506103a66106f8366004613c32565b611c41565b34801561070957600080fd5b506103bd611ca1565b34801561071e57600080fd5b506103a661072d366004613c32565b611ca7565b34801561073e57600080fd5b5061049f611cf2565b34801561075357600080fd5b5061049f611d01565b34801561076857600080fd5b506103a6610777366004613d6f565b611d15565b34801561078857600080fd5b5061049f611d8f565b34801561079d57600080fd5b506103bd611d9e565b3480156107b257600080fd5b506103bd611dcf565b3480156107c757600080fd5b506103a66107d6366004613b65565b611e03565b3480156107e757600080fd5b506103a66107f6366004613b65565b611eae565b34801561080757600080fd5b5061049f61202a565b34801561081c57600080fd5b506103a661082b366004613c6a565b612039565b34801561083c57600080fd5b506104eb612397565b34801561085157600080fd5b506103a6610860366004613b65565b6123a7565b34801561087157600080fd5b506104eb61242f565b34801561088657600080fd5b506104eb610895366004613d07565b61243f565b3480156108a657600080fd5b5061049f612635565b3480156108bb57600080fd5b506103bd612644565b3480156108d057600080fd5b506103a66108df366004613d07565b612659565b3480156108f057600080fd5b506104eb6126db565b34801561090557600080fd5b506103bd612817565b34801561091a57600080fd5b5061049f61281d565b34801561092f57600080fd5b506103a661282c565b610940612910565b6001600160a01b0316336001600160a01b0316146109795760405162461bcd60e51b81526004016109709061402b565b60405180910390fd5b6005546001600160a01b03828116911614156109a75760405162461bcd60e51b815260040161097090613ed3565b6001546001600160a01b03828116911614156109d55760405162461bcd60e51b815260040161097090613fd3565b60606109df61298d565b905060005b8151811015610a3a578181815181106109f957fe5b60200260200101516001600160a01b0316836001600160a01b03161415610a325760405162461bcd60e51b81526004016109709061409a565b6001016109e4565b50816001600160a01b031663a9059cbb610a52612910565b6040516370a0823160e01b81526001600160a01b038616906370a0823190610a7e903090600401613dcb565b60206040518083038186803b158015610a9657600080fd5b505afa158015610aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ace9190613d1f565b6040518363ffffffff1660e01b8152600401610aeb929190613dfa565b602060405180830381600087803b158015610b0557600080fd5b505af1158015610b19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3d9190613c4e565b505050565b6000806103e8905060006a52b7d2dcc80cd2e40000009050600069152d02c7e14af680000090506000734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b6001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610bb857600080fd5b505afa158015610bcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf09190613d1f565b9050600080610bff8385612992565b90506000610c0b611dcf565b905086821015610c56576000610c2188846129dd565b9050610c3788610c318484612a1f565b90612992565b93506000610c4588876129dd565b905080851115610c53578094505b50505b6000735f4ec3df9cbd43714fe2740f5e3616155c5b841990506000610ce76064836001600160a01b03166350d25bcd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610caf57600080fd5b505afa158015610cc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c319190613d1f565b90506000610d86670de0b6b3a7640000610c3184738301ae4fc9c624d1d396cbdaa1ed877821d7c5116001600160a01b03166386fc88d36040518163ffffffff1660e01b815260040160206040518083038186803b158015610d4857600080fd5b505afa158015610d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d809190613d1f565b90612a1f565b90506000610de7670de0b6b3a7640000610c318573b576491f1e6e5e62f1d8f26062ee822b40b0e0d46001600160a01b03166386fc88d36040518163ffffffff1660e01b815260040160206040518083038186803b158015610d4857600080fd5b90506000610e01670de0b6b3a7640000610c318589612a1f565b90506000610e1b670de0b6b3a7640000610c31858c612a1f565b601554909150600090600160a01b900460ff161561103c5760408051600380825260808201909252606091602082018380368337505060155482519293506001600160a01b031691839150600090610e6f57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281600181518110610eb157fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073dac17f958d2ee523a2206206994597c13d831ec781600281518110610ef357fe5b6001600160a01b039283166020918202929092010152600a546040516246613160e11b81526000929190911690628cc26290610f33903090600401613dcb565b60206040518083038186803b158015610f4b57600080fd5b505afa158015610f5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f839190613d1f565b905080156110395760405163d06ca61f60e01b815260609073d9e1ce17f2641f24ae83637ab66a2cca9c378b9f9063d06ca61f90610fc790859087906004016140c7565b60006040518083038186803b158015610fdf57600080fd5b505afa158015610ff3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261101b9190810190613b9d565b90508060018251038151811061102d57fe5b60200260200101519350505b50505b6110508161104a8585612a59565b90612a59565b9e5050505050505050505050505050505b90565b60138054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156110f05780601f106110c5576101008083540402835291602001916110f0565b820191906000526020600020905b8154815290600101906020018083116110d357829003601f168201915b5050505050905090565b6002546001600160a01b031633148061112b5750611116612910565b6001600160a01b0316336001600160a01b0316145b6111475760405162461bcd60e51b81526004016109709061402b565b6012805460ff1916911515919091179055565b6002546001600160a01b031633148061118b5750611176612910565b6001600160a01b0316336001600160a01b0316145b6111a75760405162461bcd60e51b81526004016109709061402b565b60088190556040517fa68ba126373d04c004c5748c300c9fca12bd444b3d4332e261f3bd2bac4a8600906111dc9083906140be565b60405180910390a150565b6111ef612910565b6001600160a01b0316336001600160a01b03161461121f5760405162461bcd60e51b81526004016109709061402b565b612710831115801561123357506127108211155b61123c57600080fd5b600c92909255600d55600e80546001600160a01b0319166001600160a01b03909216919091179055565b61126e612910565b6001600160a01b0316336001600160a01b03161461129e5760405162461bcd60e51b81526004016109709061402b565b600080546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b60085481565b6005546001600160a01b031681565b6002546001600160a01b031681565b60095461010090046001600160a01b031681565b6001546040516339ebf82360e01b815260009182916001600160a01b03909116906339ebf82390611333903090600401613dcb565b6101006040518083038186803b15801561134c57600080fd5b505afa158015611360573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113849190613c95565b60400151118061139b57506000611399612644565b115b905090565b6040805180820190915260058152640302e332e360dc1b602082015290565b60065481565b6001546000906001600160a01b031633146113f25760405162461bcd60e51b815260040161097090613fb3565b60006113fd83612a7e565b9250905061140b8183612a59565b83146114295760405162461bcd60e51b815260040161097090613f4f565b60055460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061145b9033908590600401613dfa565b602060405180830381600087803b15801561147557600080fd5b505af1158015611489573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ad9190613c4e565b5050919050565b6002546001600160a01b03163314806114e557506114d0612910565b6001600160a01b0316336001600160a01b0316145b6115015760405162461bcd60e51b81526004016109709061402b565b600061150b611a43565b905080156115a257600954601454604051631c683a1b60e11b81526101009092046001600160a01b0316916338d074369161154e91859160ff169060040161411d565b602060405180830381600087803b15801561156857600080fd5b505af115801561157c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a09190613c4e565b505b50565b60145460ff1681565b60105481565b6004546001600160a01b03163314806115d757506002546001600160a01b031633145b806115fa57506115e5612910565b6001600160a01b0316336001600160a01b0316145b6116165760405162461bcd60e51b81526004016109709061402b565b6001546040805163bf3759b560e01b81529051611699926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b15801561165c57600080fd5b505afa158015611670573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116949190613d1f565b612b8b565b565b6004546001600160a01b03163314806116be57506002546001600160a01b031633145b806116e157506116cc612910565b6001600160a01b0316336001600160a01b0316145b6116fd5760405162461bcd60e51b81526004016109709061402b565b6000806000600160009054906101000a90046001600160a01b03166001600160a01b031663bf3759b56040518163ffffffff1660e01b815260040160206040518083038186803b15801561175057600080fd5b505afa158015611764573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117889190613d1f565b60095490915060009060ff16156117de5760006117a3612644565b90506117bc8382116117b557836117b7565b815b612a7e565b94509150828211156117d8576117d282846129dd565b94508291505b506117ef565b6117e782612beb565b919550935090505b6001546040516339ebf82360e01b81526000916001600160a01b0316906339ebf82390611820903090600401613dcb565b6101006040518083038186803b15801561183957600080fd5b505afa15801561184d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118719190613c95565b60a001516001546040516328766ebf60e21b81529192506001600160a01b03169063a1d9bafc906118aa908890889087906004016141b8565b602060405180830381600087803b1580156118c457600080fd5b505af11580156118d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118fc9190613d1f565b9250611906613256565b61190f83612b8b565b60005460ff168015611930575060005461010090046001600160a01b031615155b156119e25760005460405163c70fa00b60e01b81526101009091046001600160a01b03169063c70fa00b9061197190889088908790899088906004016141e9565b60206040518083038186803b15801561198957600080fd5b505afa15801561199d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c19190613c4e565b6119dd5760405162461bcd60e51b815260040161097090613f29565b6119f0565b6000805460ff191660011790555b7f4c0f499ffe6befa0ca7c826b0916cf87bea98de658013e76938489368d60d50985858486604051611a2594939291906141ce565b60405180910390a15050505050565b600d5481565b60095460ff1681565b6009546040516370a0823160e01b815260009161010090046001600160a01b0316906370a0823190611a79903090600401613dcb565b60206040518083038186803b158015611a9157600080fd5b505afa158015611aa5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139b9190613d1f565b600f5481565b60005b919050565b60005460ff1681565b60145461010090046001600160a01b031681565b6002546001600160a01b0316331480611b255750611b10612910565b6001600160a01b0316336001600160a01b0316145b611b415760405162461bcd60e51b81526004016109709061402b565b6001600160a01b038116611b5457600080fd5b600480546001600160a01b0319166001600160a01b0383161790556040517f2f202ddb4a2e345f6323ed90f8fc8559d770a7abbbeee84dde8aca3351fe7154906111dc908390613dcb565b600c5481565b60075481565b600090565b6002546001600160a01b0316331480611be15750611bcc612910565b6001600160a01b0316336001600160a01b0316145b611bfd5760405162461bcd60e51b81526004016109709061402b565b60078190556040517fd94596337df4c2f0f44d30a7fc5db1c7bb60d9aca4185ed77c6fd96eb45ec298906111dc9083906140be565b6003546001600160a01b031681565b6002546001600160a01b0316331480611c725750611c5d612910565b6001600160a01b0316336001600160a01b0316145b611c8e5760405162461bcd60e51b81526004016109709061402b565b6014805460ff1916911515919091179055565b60115481565b611caf612910565b6001600160a01b0316336001600160a01b031614611cdf5760405162461bcd60e51b81526004016109709061402b565b6000805460ff1916911515919091179055565b6004546001600160a01b031681565b60005461010090046001600160a01b031681565b6002546001600160a01b0316331480611d465750611d31612910565b6001600160a01b0316336001600160a01b0316145b611d625760405162461bcd60e51b81526004016109709061402b565b600f9390935560109190915560115560148054911515600160a81b0260ff60a81b19909216919091179055565b600a546001600160a01b031681565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a0823190611a79903090600401613dcb565b6009546040516246613160e11b815260009161010090046001600160a01b031690628cc26290611a79903090600401613dcb565b6002546001600160a01b0316331480611e345750611e1f612910565b6001600160a01b0316336001600160a01b0316145b611e505760405162461bcd60e51b81526004016109709061402b565b6001600160a01b038116611e6357600080fd5b600280546001600160a01b0319166001600160a01b0383161790556040517f352ececae6d7d1e6d26bcf2c549dfd55be1637e9b22dc0cf3b71ddb36097a6b4906111dc908390613dcb565b6001546001600160a01b0316331480611edf5750611eca612910565b6001600160a01b0316336001600160a01b0316145b611ee857600080fd5b6001546040805163fbfa77cf60e01b815290516001600160a01b039283169284169163fbfa77cf916004808301926020929190829003018186803b158015611f2f57600080fd5b505afa158015611f43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f679190613b81565b6001600160a01b031614611f7a57600080fd5b611f8381613315565b6005546040516370a0823160e01b81526001600160a01b039091169063a9059cbb90839083906370a0823190611fbd903090600401613dcb565b60206040518083038186803b158015611fd557600080fd5b505afa158015611fe9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061200d9190613d1f565b6040518363ffffffff1660e01b815260040161154e929190613dfa565b6015546001600160a01b031681565b612041612910565b6001600160a01b0316336001600160a01b0316146120715760405162461bcd60e51b81526004016109709061402b565b6015546001600160a01b0316158015906120aa57506015546001600160a01b0316734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b14155b1561214a5760155460405163095ea7b360e01b81526001600160a01b039091169063095ea7b3906120f69073d9e1ce17f2641f24ae83637ab66a2cca9c378b9f90600090600401613dfa565b602060405180830381600087803b15801561211057600080fd5b505af1158015612124573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121489190613c4e565b505b8161217457601580546001600160a81b0319169055600a80546001600160a01b03191690556115a0565b600954604051632061aa2360e11b81526101009091046001600160a01b0316906340c35446906121a89084906004016140be565b60206040518083038186803b1580156121c057600080fd5b505afa1580156121d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f89190613b81565b600a80546001600160a01b0319166001600160a01b0392831617908190556040805163f7c618c160e01b81529051600093929092169163f7c618c191600480820192602092909190829003018186803b15801561225457600080fd5b505afa158015612268573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061228c9190613b81565b601580546001600160a01b0319166001600160a01b03838116919091179182905560405163095ea7b360e01b8152929350169063095ea7b3906122eb9073d9e1ce17f2641f24ae83637ab66a2cca9c378b9f9060001990600401613dfa565b602060405180830381600087803b15801561230557600080fd5b505af1158015612319573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233d9190613c4e565b50604080518082019091526015546001600160a01b0316815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2602082015261237e906016906002613aa0565b50506015805460ff60a01b1916600160a01b1790555050565b601454600160a81b900460ff1681565b6002546001600160a01b031633146123d15760405162461bcd60e51b815260040161097090613eae565b6001600160a01b0381166123e457600080fd5b600380546001600160a01b0319166001600160a01b0383161790556040517fafbb66abf8f3b719799940473a4052a3717cdd8e40fb6c8a3faadab316b1a069906111dc908390613dcb565b601554600160a01b900460ff1681565b60006124496112fe565b61245557506000611ad2565b601454600160a81b900460ff161561247c5761246f6126db565b1561247c57506000611ad2565b6000612486610b42565b905060105481111561249c576001915050611ad2565b6124a4613508565b6124b2576000915050611ad2565b60125460ff16156124c7576001915050611ad2565b600f548111156124db576001915050611ad2565b6124e3613b01565b6001546040516339ebf82360e01b81526001600160a01b03909116906339ebf82390612513903090600401613dcb565b6101006040518083038186803b15801561252c57600080fd5b505afa158015612540573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125649190613c95565b90506006546125808260800151426129dd90919063ffffffff16565b111561259157600192505050611ad2565b601154600160009054906101000a90046001600160a01b03166001600160a01b031663112c1f9b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156125e257600080fd5b505afa1580156125f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061261a9190613d1f565b111561262b57600192505050611ad2565b5060009392505050565b600e546001600160a01b031681565b600061139b612651611a43565b61104a611d9e565b6002546001600160a01b031633148061268a5750612675612910565b6001600160a01b0316336001600160a01b0316145b6126a65760405162461bcd60e51b81526004016109709061402b565b60068190556040517f4aaf232568bff365c53cad69bdb6e83014e79df80216ceba8ee01769723dfd68906111dc9083906140be565b600080600960019054906101000a90046001600160a01b03166001600160a01b031663ebe2b12b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561272c57600080fd5b505afa158015612740573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127649190613d1f565b905042811015612778576001915050611061565b601554600160a01b900460ff161561281357600a546040805163ebe2b12b60e01b815290516000926001600160a01b03169163ebe2b12b916004808301926020929190829003018186803b1580156127cf57600080fd5b505afa1580156127e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128079190613d1f565b42119250611061915050565b5090565b600b5481565b6001546001600160a01b031681565b6002546001600160a01b031633148061285d5750612848612910565b6001600160a01b0316336001600160a01b0316145b6128795760405162461bcd60e51b81526004016109709061402b565b6009805460ff19166001908117909155546040805163507257cd60e11b815290516001600160a01b039092169163a0e4af9a9160048082019260009290919082900301818387803b1580156128cd57600080fd5b505af11580156128e1573d6000803e3d6000fd5b50506040517f97e963041e952738788b9d4871d854d282065b8f90a464928d6528f2e9a4fd0b925060009150a1565b60015460408051635aa6e67560e01b815290516000926001600160a01b031691635aa6e675916004808301926020929190829003018186803b15801561295557600080fd5b505afa158015612969573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139b9190613b81565b606090565b60006129d483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061358f565b90505b92915050565b60006129d483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506135c6565b600082612a2e575060006129d7565b82820282848281612a3b57fe5b04146129d45760405162461bcd60e51b815260040161097090613f72565b6000828201838110156129d45760405162461bcd60e51b815260040161097090613ef2565b6000806000612a8b611d9e565b905080841115612b77576000612a9f611a43565b90508015612b4c5760095461010090046001600160a01b031663c32e7202612ad083612acb89876129dd565b6135f2565b6014546040516001600160e01b031960e085901b168152612af8929160ff169060040161411d565b602060405180830381600087803b158015612b1257600080fd5b505af1158015612b26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b4a9190613c4e565b505b6000612b56611d9e565b9050612b6286826135f2565b9450612b6e86866129dd565b93505050612b84565b8360009250925050612b86565b505b915091565b60095460ff1615612b9b576115a2565b6000612ba5611d9e565b905080156115a057600b546040516321d0683360e11b815273f403c135812408bfbe8713b5a23a04b3d48aae31916343a0d06691610aeb919085906001906004016141a0565b600954604051637050ccd960e01b81526000918291829161010090046001600160a01b031690637050ccd990612c28903090600190600401613ddf565b602060405180830381600087803b158015612c4257600080fd5b505af1158015612c56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c7a9190613c4e565b506040516370a0823160e01b815260009073d533a949740bb3306d119cc777fa900ba034cd52906370a0823190612cb5903090600401613dcb565b60206040518083038186803b158015612ccd57600080fd5b505afa158015612ce1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d059190613d1f565b6040516370a0823160e01b8152909150600090734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906370a0823190612d42903090600401613dcb565b60206040518083038186803b158015612d5a57600080fd5b505afa158015612d6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d929190613d1f565b90506000612db1612710610c31600c5486612a1f90919063ffffffff16565b90508015612e7657612dec73d533a949740bb3306d119cc777fa900ba034cd5273f147b8125d2ef93fb6965db97d6746952a13393483613608565b6040516370a0823160e01b815273d533a949740bb3306d119cc777fa900ba034cd52906370a0823190612e23903090600401613dcb565b60206040518083038186803b158015612e3b57600080fd5b505afa158015612e4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e739190613d1f565b92505b6000612e93612710610c31600d5486612a1f90919063ffffffff16565b90508015612f5157600e54612ec790734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906001600160a01b031683613608565b6040516370a0823160e01b8152734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906370a0823190612efe903090600401613dcb565b60206040518083038186803b158015612f1657600080fd5b505afa158015612f2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f4e9190613d1f565b92505b601554600160a01b900460ff1615612ff7576015546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612f94903090600401613dcb565b60206040518083038186803b158015612fac57600080fd5b505afa158015612fc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fe49190613d1f565b90508015612ff557612ff58161365e565b505b61300184846136f5565b478015613086576014546040805180820182528381526000602082018190529151630b4c7e4d60e01b81526101009093046001600160a01b031692630b4c7e4d92859261305392909190600401613e13565b6000604051808303818588803b15801561306c57600080fd5b505af1158015613080573d6000803e3d6000fd5b50505050505b8815613155576000613096611a43565b9050801561313a5760095461010090046001600160a01b031663c32e72026130be838d6135f2565b6014546040516001600160e01b031960e085901b1681526130e6929160ff169060040161411d565b602060405180830381600087803b15801561310057600080fd5b505af1158015613114573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131389190613c4e565b505b6000613144611d9e565b90506131508b826135f2565b975050505b600061315f612644565b6001546040516339ebf82360e01b81529192506000916001600160a01b03909116906339ebf82390613195903090600401613dcb565b6101006040518083038186803b1580156131ae57600080fd5b505afa1580156131c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131e69190613c95565b60a0015190508082111561322f576131fe82826129dd565b9950600061320a611d9e565b9050806132178c8b612a59565b11156132295761322683612a7e565b50505b5061323c565b61323981836129dd565b98505b50506012805460ff19169055509597949650929450505050565b6001546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613287903090600401613dcb565b60206040518083038186803b15801561329f57600080fd5b505afa1580156132b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d79190613d1f565b905080156115a25760015460035460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9261154e929116908590600401613dfa565b600061331f611a43565b905080156133b657600954601454604051636197390160e11b81526101009092046001600160a01b03169163c32e72029161336291859160ff169060040161411d565b602060405180830381600087803b15801561337c57600080fd5b505af1158015613390573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133b49190613c4e565b505b6040516370a0823160e01b815261345f90839073d533a949740bb3306d119cc777fa900ba034cd52906370a08231906133f3903090600401613dcb565b60206040518083038186803b15801561340b57600080fd5b505afa15801561341f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134439190613d1f565b73d533a949740bb3306d119cc777fa900ba034cd529190613608565b6040516370a0823160e01b81526115a0908390734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b906370a082319061349c903090600401613dcb565b60206040518083038186803b1580156134b457600080fd5b505afa1580156134c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134ec9190613d1f565b734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b9190613608565b600073b5e1cacb567d98faadb60a1fd4820720141f064f6001600160a01b03166334a9e75c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561355757600080fd5b505afa15801561356b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139b9190613c4e565b600081836135b05760405162461bcd60e51b81526004016109709190613e7b565b5060008385816135bc57fe5b0495945050505050565b600081848411156135ea5760405162461bcd60e51b81526004016109709190613e7b565b505050900390565b600081831061360157816129d4565b5090919050565b610b3d8363a9059cbb60e01b8484604051602401613627929190613dfa565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526138fd565b6040516338ed173960e01b815273d9e1ce17f2641f24ae83637ab66a2cca9c378b9f906338ed17399061369f9084906000906016903090429060040161412d565b600060405180830381600087803b1580156136b957600080fd5b505af11580156136cd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115a09190810190613b9d565b67016345785d8a00008111156137795760405163394747c560e01b815273b576491f1e6e5e62f1d8f26062ee822b40b0e0d49063394747c59061374690600190600090869082908190600401613e56565b600060405180830381600087803b15801561376057600080fd5b505af1158015613774573d6000803e3d6000fd5b505050505b67016345785d8a00008211156137fd5760405163394747c560e01b8152738301ae4fc9c624d1d396cbdaa1ed877821d7c5119063394747c5906137ca90600190600090879082908190600401613e56565b600060405180830381600087803b1580156137e457600080fd5b505af11580156137f8573d6000803e3d6000fd5b505050505b6040516370a0823160e01b815260009073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2906370a0823190613837903090600401613dcb565b60206040518083038186803b15801561384f57600080fd5b505afa158015613863573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138879190613d1f565b90508015610b3d57604051632e1a7d4d60e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d906138c69084906004016140be565b600060405180830381600087803b1580156138e057600080fd5b505af11580156138f4573d6000803e3d6000fd5b50505050505050565b6060613952826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661398c9092919063ffffffff16565b805190915015610b3d57808060200190518101906139709190613c4e565b610b3d5760405162461bcd60e51b815260040161097090614050565b606061399b84846000856139a3565b949350505050565b60606139ae85613a67565b6139ca5760405162461bcd60e51b815260040161097090613ff4565b60006060866001600160a01b031685876040516139e79190613daf565b60006040518083038185875af1925050503d8060008114613a24576040519150601f19603f3d011682016040523d82523d6000602084013e613a29565b606091505b50915091508115613a3d57915061399b9050565b805115613a4d5780518082602001fd5b8360405162461bcd60e51b81526004016109709190613e7b565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061399b575050151592915050565b828054828255906000526020600020908101928215613af5579160200282015b82811115613af557825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613ac0565b50612813929150613b46565b60405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b808211156128135780546001600160a01b0319168155600101613b47565b600060208284031215613b76578081fd5b81356129d481614283565b600060208284031215613b92578081fd5b81516129d481614283565b60006020808385031215613baf578182fd5b825167ffffffffffffffff811115613bc5578283fd5b8301601f81018513613bd5578283fd5b8051613be8613be382614233565b61420c565b8181528381019083850185840285018601891015613c04578687fd5b8694505b83851015613c26578051835260019490940193918501918501613c08565b50979650505050505050565b600060208284031215613c43578081fd5b81356129d481614298565b600060208284031215613c5f578081fd5b81516129d481614298565b60008060408385031215613c7c578081fd5b8235613c8781614298565b946020939093013593505050565b6000610100808385031215613ca8578182fd5b613cb18161420c565b9050825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201528091505092915050565b600060208284031215613d18578081fd5b5035919050565b600060208284031215613d30578081fd5b5051919050565b600080600060608486031215613d4b578081fd5b83359250602084013591506040840135613d6481614283565b809150509250925092565b60008060008060808587031215613d84578081fd5b8435935060208501359250604085013591506060850135613da481614298565b939692955090935050565b60008251613dc1818460208701614253565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039290921682521515602082015260400190565b6001600160a01b03929092168252602082015260400190565b60608101818460005b6002811015613e3b578151835260209283019290910190600101613e1c565b5050508260408301529392505050565b901515815260200190565b9485526020850193909352604084019190915260608301521515608082015260a00190565b6000602082528251806020840152613e9a816040850160208701614253565b601f01601f19169190910160400192915050565b6020808252600b908201526a085cdd1c985d1959da5cdd60aa1b604082015260600190565b602080825260059082015264085dd85b9d60da1b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252600c908201526b216865616c7468636865636b60a01b604082015260600190565b60208082526009908201526821776974686472617760b81b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b602080825260069082015265085d985d5b1d60d21b604082015260600190565b6020808252600790820152662173686172657360c81b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252600b908201526a08585d5d1a1bdc9a5e995960aa1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600a9082015269085c1c9bdd1958dd195960b21b604082015260600190565b90815260200190565b60006040820184835260206040818501528185518084526060860191508287019350845b818110156141105784516001600160a01b0316835293830193918301916001016140eb565b5090979650505050505050565b9182521515602082015260400190565b600060a082018783526020878185015260a0604085015281875480845260c0860191508885528285209350845b8181101561417f5784546001600160a01b03168352600194850194928401920161415a565b50506001600160a01b03969096166060850152505050608001529392505050565b92835260208301919091521515604082015260600190565b9283526020830191909152604082015260600190565b93845260208401929092526040830152606082015260800190565b948552602085019390935260408401919091526060830152608082015260a00190565b60405181810167ffffffffffffffff8111828210171561422b57600080fd5b604052919050565b600067ffffffffffffffff821115614249578081fd5b5060209081020190565b60005b8381101561426e578181015183820152602001614256565b8381111561427d576000848401525b50505050565b6001600160a01b03811681146115a257600080fd5b80151581146115a257600080fdfea264697066735822122038d8aa59fccb902e8d93aa5239e24e4aab5c3f1e7b0e6a65a8802b9c01e3e6fd64736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000dcd90c7f6324cfa40d7169ef80b12031770b43250000000000000000000000000000000000000000000000000000000000000019000000000000000000000000dc24316b9ae028f1497c275eb9192a3ea0f67022000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000135374726174656779436f6e766578737445544800000000000000000000000000
-----Decoded View---------------
Arg [0] : _vault (address): 0xdCD90C7f6324cfa40d7169ef80b12031770B4325
Arg [1] : _pid (uint256): 25
Arg [2] : _curvePool (address): 0xDC24316b9AE028F1497c275EB9192a3Ea0f67022
Arg [3] : _name (string): StrategyConvexstETH
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 000000000000000000000000dcd90c7f6324cfa40d7169ef80b12031770b4325
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000019
Arg [2] : 000000000000000000000000dc24316b9ae028f1497c275eb9192a3ea0f67022
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000013
Arg [5] : 5374726174656779436f6e766578737445544800000000000000000000000000
Deployed Bytecode Sourcemap
67204:15721:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60111:440;;;;;;;;;;-1:-1:-1;60111:440:0;;;;;:::i;:::-;;:::i;:::-;;77463:2530;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63119:98;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;66978:183::-;;;;;;;;;;-1:-1:-1;66978:183:0;;;;;:::i;:::-;;:::i;42684:175::-;;;;;;;;;;-1:-1:-1;42684:175:0;;;;;:::i;:::-;;:::i;66352:317::-;;;;;;;;;;-1:-1:-1;66352:317:0;;;;;:::i;:::-;;:::i;38955:115::-;;;;;;;;;;-1:-1:-1;38955:115:0;;;;;:::i;:::-;;:::i;37329:32::-;;;;;;;;;;;;;:::i;36305:18::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;36214:25::-;;;;;;;;;;;;;:::i;61046:37::-;;;;;;;;;;;;;:::i;44883:148::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;34854:91::-;;;;;;;;;;;;;:::i;36935:37::-;;;;;;;;;;;;;:::i;56608:602::-;;;;;;;;;;-1:-1:-1;56608:602:0;;;;;:::i;:::-;;:::i;65544:227::-;;;;;;;;;;;;;:::i;62806:24::-;;;;;;;;;;;;;:::i;62395:31::-;;;;;;;;;;;;;:::i;50133:170::-;;;;;;;;;;;;;:::i;54349:2015::-;;;;;;;;;;;;;:::i;61381:22::-;;;;;;;;;;;;;:::i;37412:25::-;;;;;;;;;;;;;:::i;63281:121::-;;;;;;;;;;;;;:::i;62297:31::-;;;;;;;;;;;;;:::i;49518:286::-;;;;;;;;;;-1:-1:-1;49518:286:0;;;;;:::i;:::-;;:::i;34511:25::-;;;;;;;;;;;;;:::i;67390:21::-;;;;;;;;;;;;;:::i;40187:174::-;;;;;;;;;;-1:-1:-1;40187:174:0;;;;;:::i;:::-;;:::i;61288:22::-;;;;;;;;;;;;;:::i;37145:33::-;;;;;;;;;;;;;:::i;36084:94::-;;;;;;;;;;;;;:::i;41958:169::-;;;;;;;;;;-1:-1:-1;41958:169:0;;;;;:::i;:::-;;:::i;36246:22::-;;;;;;;;;;;;;:::i;66785:116::-;;;;;;;;;;-1:-1:-1;66785:116:0;;;;;:::i;:::-;;:::i;62493:30::-;;;;;;;;;;;;;:::i;39078:120::-;;;;;;;;;;-1:-1:-1;39078:120:0;;;;;:::i;:::-;;:::i;36275:21::-;;;;;;;;;;;;;:::i;34543:26::-;;;;;;;;;;;;;:::i;82536:386::-;;;;;;;;;;-1:-1:-1;82536:386:0;;;;;:::i;:::-;;:::i;61127:33::-;;;;;;;;;;;;;:::i;63467:110::-;;;;;;;;;;;;;:::i;63654:121::-;;;;;;;;;;;;;:::i;39431:202::-;;;;;;;;;;-1:-1:-1;39431:202:0;;;;;:::i;:::-;;:::i;57801:307::-;;;;;;;;;;-1:-1:-1;57801:307:0;;;;;:::i;:::-;;:::i;68246:26::-;;;;;;;;;;;;;:::i;81204:1059::-;;;;;;;;;;-1:-1:-1;81204:1059:0;;;;;:::i;:::-;;:::i;67475:24::-;;;;;;;;;;;;;:::i;40709:181::-;;;;;;;;;;-1:-1:-1;40709:181:0;;;;;:::i;:::-;;:::i;68279:22::-;;;;;;;;;;;;;:::i;75499:1858::-;;;;;;;;;;-1:-1:-1;75499:1858:0;;;;;:::i;:::-;;:::i;61480:33::-;;;;;;;;;;;;;:::i;63783:133::-;;;;;;;;;;;;;:::i;41407:151::-;;;;;;;;;;-1:-1:-1;41407:151:0;;;;;:::i;:::-;;:::i;80370:539::-;;;;;;;;;;;;;:::i;61208:18::-;;;;;;;;;;;;;:::i;36186:21::-;;;;;;;;;;;;;:::i;58537:164::-;;;;;;;;;;;;;:::i;60111:440::-;37779:12;:10;:12::i;:::-;-1:-1:-1;;;;;37765:26:0;:10;-1:-1:-1;;;;;37765:26:0;;37757:50;;;;-1:-1:-1;;;37757:50:0;;;;;;;:::i;:::-;;;;;;;;;60203:4:::1;::::0;-1:-1:-1;;;;;60185:23:0;;::::1;60203:4:::0;::::1;60185:23;;60177:41;;;;-1:-1:-1::0;;;60177:41:0::1;;;;;;;:::i;:::-;60255:5;::::0;-1:-1:-1;;;;;60237:24:0;;::::1;60255:5:::0;::::1;60237:24;;60229:44;;;;-1:-1:-1::0;;;60229:44:0::1;;;;;;;:::i;:::-;60286:33;60322:17;:15;:17::i;:::-;60286:53;;60355:9;60350:102;60370:16;:23;60366:1;:27;60350:102;;;60418:16;60435:1;60418:19;;;;;;;;;;;;;;-1:-1:-1::0;;;;;60408:29:0::1;:6;-1:-1:-1::0;;;;;60408:29:0::1;;;60400:52;;;;-1:-1:-1::0;;;60400:52:0::1;;;;;;;:::i;:::-;60395:3;;60350:102;;;;60472:6;-1:-1:-1::0;;;;;60465:23:0::1;;60489:12;:10;:12::i;:::-;60503:39;::::0;-1:-1:-1;;;60503:39:0;;-1:-1:-1;;;;;60503:24:0;::::1;::::0;::::1;::::0;:39:::1;::::0;60536:4:::1;::::0;60503:39:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60465:78;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;37818:1;60111:440:::0;:::o;77463:2530::-;77517:7;77630:19;77652:5;77630:27;;77668:17;77688:22;77668:42;;77731:25;77759:14;77731:42;;77795:14;62126:42;-1:-1:-1;;;;;77812:23:0;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77795:42;-1:-1:-1;77848:19:0;;77896:29;77795:42;77907:17;77896:10;:29::i;:::-;77880:45;;77936:21;77960:18;:16;:18::i;:::-;77936:42;;78039:11;78031:5;:19;78027:444;;;78127:17;78147:22;:11;78163:5;78147:15;:22::i;:::-;78127:42;-1:-1:-1;78220:45:0;78253:11;78220:28;:13;78127:42;78220:17;:28::i;:::-;:32;;:45::i;:::-;78206:59;-1:-1:-1;78314:18:0;78335:21;:9;78349:6;78335:13;:21::i;:::-;78314:42;;78389:10;78375:11;:24;78371:89;;;78434:10;78420:24;;78371:89;78027:444;;;78576:17;78604:42;78576:71;;78658:16;78677:33;78706:3;78677:9;-1:-1:-1;;;;;78677:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:33::-;78658:52;;78742:16;78761:45;78801:4;78761:35;78787:8;67706:42;-1:-1:-1;;;;;78761:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:25;;:35::i;:45::-;78742:64;;78848:16;78867:45;78907:4;78867:35;78893:8;67865:42;-1:-1:-1;;;;;78867:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:45;78848:64;-1:-1:-1;78956:16:0;78975:37;79007:4;78975:27;:8;78988:13;78975:12;:27::i;:37::-;78956:56;-1:-1:-1;79054:16:0;79073:35;79103:4;79073:25;:8;79086:11;79073:12;:25::i;:35::-;79249:10;;79054:54;;-1:-1:-1;79214:20:0;;-1:-1:-1;;;79249:10:0;;;;79245:681;;;79304:16;;;79318:1;79304:16;;;;;;;;;79276:25;;79304:16;;;79276:25;;79304:16;;;-1:-1:-1;;79357:12:0;;79335:11;;;;-1:-1:-1;;;;;;79357:12:0;;79335:11;;-1:-1:-1;79357:12:0;;79335:11;;;;;;;;;:35;-1:-1:-1;;;;;79335:35:0;;;-1:-1:-1;;;;;79335:35:0;;;;;62224:42;79385:8;79394:1;79385:11;;;;;;;;;;;;;:27;-1:-1:-1;;;;;79385:27:0;;;-1:-1:-1;;;;;79385:27:0;;;;;68070:42;79427:8;79436:1;79427:11;;;;;;;;-1:-1:-1;;;;;79427:27:0;;;:11;;;;;;;;;:27;79532:18;;79517:56;;-1:-1:-1;;;79517:56:0;;79471:26;;79532:18;;;;;79517:41;;:56;;79567:4;;79517:56;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79471:102;-1:-1:-1;79592:22:0;;79588:327;;79686:146;;-1:-1:-1;;;79686:146:0;;79635:27;;61884:42;;79686:43;;:146;;79756:18;;79801:8;;79686:146;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;79686:146:0;;;;;;;;;;;;:::i;:::-;79635:197;;79866:10;79897:1;79877:10;:17;:21;79866:33;;;;;;;;;;;;;;79851:48;;79588:327;;79245:681;;;79945:40;79972:12;79945:22;:8;79958;79945:12;:22::i;:::-;:26;;:40::i;:::-;79938:47;;;;;;;;;;;;;;;;77463:2530;;:::o;63119:98::-;63200:9;63193:16;;;;;;;;-1:-1:-1;;63193:16:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63167:13;;63193:16;;63200:9;;63193:16;;63200:9;63193:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63119:98;:::o;66978:183::-;37523:10;;-1:-1:-1;;;;;37523:10:0;37509;:24;;:54;;;37551:12;:10;:12::i;:::-;-1:-1:-1;;;;;37537:26:0;:10;-1:-1:-1;;;;;37537:26:0;;37509:54;37501:78;;;;-1:-1:-1;;;37501:78:0;;;;;;;:::i;:::-;67103:23:::1;:50:::0;;-1:-1:-1;;67103:50:0::1;::::0;::::1;;::::0;;;::::1;::::0;;66978:183::o;42684:175::-;37523:10;;-1:-1:-1;;;;;37523:10:0;37509;:24;;:54;;;37551:12;:10;:12::i;:::-;-1:-1:-1;;;;;37537:26:0;:10;-1:-1:-1;;;;;37537:26:0;;37509:54;37501:78;;;;-1:-1:-1;;;37501:78:0;;;;;;;:::i;:::-;42769:13:::1;:30:::0;;;42815:36:::1;::::0;::::1;::::0;::::1;::::0;42785:14;;42815:36:::1;:::i;:::-;;;;;;;;42684:175:::0;:::o;66352:317::-;37779:12;:10;:12::i;:::-;-1:-1:-1;;;;;37765:26:0;:10;-1:-1:-1;;;;;37765:26:0;;37757:50;;;;-1:-1:-1;;;37757:50:0;;;;;;;:::i;:::-;66523:6:::1;66511:8;:18;;:40;;;;;66545:6;66533:8;:18;;66511:40;66503:49;;;::::0;::::1;;66563:7;:18:::0;;;;66592:7:::1;:18:::0;66621::::1;:40:::0;;-1:-1:-1;;;;;;66621:40:0::1;-1:-1:-1::0;;;;;66621:40:0;;::::1;::::0;;;::::1;::::0;;66352:317::o;38955:115::-;37779:12;:10;:12::i;:::-;-1:-1:-1;;;;;37765:26:0;:10;-1:-1:-1;;;;;37765:26:0;;37757:50;;;;-1:-1:-1;;;37757:50:0;;;;;;;:::i;:::-;39036:11:::1;:26:::0;;-1:-1:-1;;;;;39036:26:0;;::::1;;;-1:-1:-1::0;;;;;;39036:26:0;;::::1;::::0;;;::::1;::::0;;38955:115::o;37329:32::-;;;;:::o;36305:18::-;;;-1:-1:-1;;;;;36305:18:0;;:::o;36214:25::-;;;-1:-1:-1;;;;;36214:25:0;;:::o;61046:37::-;;;;;;-1:-1:-1;;;;;61046:37:0;;:::o;44883:148::-;44948:5;;:31;;-1:-1:-1;;;44948:31:0;;44924:4;;;;-1:-1:-1;;;;;44948:5:0;;;;:16;;:31;;44973:4;;44948:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;:45;:75;;;;45022:1;44997:22;:20;:22::i;:::-;:26;44948:75;44941:82;;44883:148;:::o;34854:91::-;34923:14;;;;;;;;;;;;-1:-1:-1;;;34923:14:0;;;;34854:91;:::o;36935:37::-;;;;:::o;56608:602::-;56723:5;;56667:13;;-1:-1:-1;;;;;56723:5:0;56701:10;:28;56693:47;;;;-1:-1:-1;;;56693:47:0;;;;;;;:::i;:::-;56820:19;56873:32;56891:13;56873:17;:32::i;:::-;56850:55;-1:-1:-1;56850:55:0;-1:-1:-1;56966:22:0;56850:55;;56966:15;:22::i;:::-;56949:13;:39;56941:61;;;;-1:-1:-1;;;56941:61:0;;;;;;;:::i;:::-;57094:4;;:38;;-1:-1:-1;;;57094:38:0;;-1:-1:-1;;;;;57094:4:0;;;;:13;;:38;;57108:10;;57120:11;;57094:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;56608:602;;;;:::o;65544:227::-;37523:10;;-1:-1:-1;;;;;37523:10:0;37509;:24;;:54;;;37551:12;:10;:12::i;:::-;-1:-1:-1;;;;;37537:26:0;:10;-1:-1:-1;;;;;37537:26:0;;37509:54;37501:78;;;;-1:-1:-1;;;37501:78:0;;;;;;;:::i;:::-;65620:18:::1;65641:15;:13;:15::i;:::-;65620:36:::0;-1:-1:-1;65671:14:0;;65667:97:::1;;65702:15;::::0;65739:12:::1;::::0;65702:50:::1;::::0;-1:-1:-1;;;65702:50:0;;:15:::1;::::0;;::::1;-1:-1:-1::0;;;;;65702:15:0::1;::::0;:24:::1;::::0;:50:::1;::::0;65727:10;;65739:12:::1;;::::0;65702:50:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;65667:97;37590:1;65544:227::o:0;62806:24::-;;;;;;:::o;62395:31::-;;;;:::o;50133:170::-;37891:6;;-1:-1:-1;;;;;37891:6:0;37877:10;:20;;:48;;-1:-1:-1;37915:10:0;;-1:-1:-1;;;;;37915:10:0;37901;:24;37877:48;:78;;;;37943:12;:10;:12::i;:::-;-1:-1:-1;;;;;37929:26:0;:10;-1:-1:-1;;;;;37929:26:0;;37877:78;37869:102;;;;-1:-1:-1;;;37869:102:0;;;;;;;:::i;:::-;50271:5:::1;::::0;:23:::1;::::0;;-1:-1:-1;;;50271:23:0;;;;50256:39:::1;::::0;-1:-1:-1;;;;;50271:5:0::1;::::0;:21:::1;::::0;:23:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:5;:23;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50256:14;:39::i;:::-;50133:170::o:0;54349:2015::-;37891:6;;-1:-1:-1;;;;;37891:6:0;37877:10;:20;;:48;;-1:-1:-1;37915:10:0;;-1:-1:-1;;;;;37915:10:0;37901;:24;37877:48;:78;;;;37943:12;:10;:12::i;:::-;-1:-1:-1;;;;;37929:26:0;:10;-1:-1:-1;;;;;37929:26:0;;37877:78;37869:102;;;;-1:-1:-1;;;37869:102:0;;;;;;;:::i;:::-;54400:14:::1;54429:12:::0;54456:23:::1;54482:5;;;;;;;;;-1:-1:-1::0;;;;;54482:5:0::1;-1:-1:-1::0;;;;;54482:21:0::1;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54554:13;::::0;54456:49;;-1:-1:-1;54516:19:0::1;::::0;54554:13:::1;;54550:731;;;54636:19;54658:22;:20;:22::i;:::-;54636:44;;54814:80;54846:15;54832:11;:29;:61;;54878:15;54832:61;;;54864:11;54832:61;54814:17;:80::i;:::-;54792:102:::0;-1:-1:-1;54792:102:0;-1:-1:-1;54972:29:0;;::::1;54968:159;;;55031:32;:11:::0;55047:15;55031::::1;:32::i;:::-;55022:41;;55096:15;55082:29;;54968:159;54550:731;;;;55239:30;55253:15;55239:13;:30::i;:::-;55209:60:::0;;-1:-1:-1;55209:60:0;-1:-1:-1;55209:60:0;-1:-1:-1;54550:731:0::1;55497:5;::::0;:31:::1;::::0;-1:-1:-1;;;55497:31:0;;55477:17:::1;::::0;-1:-1:-1;;;;;55497:5:0::1;::::0;:16:::1;::::0;:31:::1;::::0;55522:4:::1;::::0;55497:31:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;::::0;55567:5:::1;::::0;:39:::1;::::0;-1:-1:-1;;;55567:39:0;;55497:41;;-1:-1:-1;;;;;;55567:5:0::1;::::0;:12:::1;::::0;:39:::1;::::0;55580:6;;55588:4;;55594:11;;55567:39:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55549:57;;55698:19;:17;:19::i;:::-;55793:31;55808:15;55793:14;:31::i;:::-;55879:13;::::0;::::1;;:42:::0;::::1;;;-1:-1:-1::0;55919:1:0::1;55896:11:::0;::::1;::::0;::::1;-1:-1:-1::0;;;;;55896:11:0::1;:25:::0;::::1;55879:42;55875:411;;;55976:11;::::0;55964:209:::1;::::0;-1:-1:-1;;;55964:209:0;;55976:11:::1;::::0;;::::1;-1:-1:-1::0;;;;;55976:11:0::1;::::0;55964:30:::1;::::0;:209:::1;::::0;56017:6;;56046:4;;56073:11;;56107:15;;56145:9;;55964:209:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55938:283;;;;-1:-1:-1::0;;;55938:283:0::1;;;;;;;:::i;:::-;55875:411;;;56254:13;:20:::0;;-1:-1:-1;;56254:20:0::1;56270:4;56254:20;::::0;;55875:411:::1;56303:53;56313:6;56321:4;56327:11;56340:15;56303:53;;;;;;;;;:::i;:::-;;;;;;;;37982:1;;;;;54349:2015::o:0;61381:22::-;;;;:::o;37412:25::-;;;;;;:::o;63281:121::-;63354:15;;:40;;-1:-1:-1;;;63354:40:0;;63327:7;;63354:15;;;-1:-1:-1;;;;;63354:15:0;;:25;;:40;;63388:4;;63354:40;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;62297:31::-;;;;:::o;49518:286::-;49586:4;49518:286;;;;:::o;34511:25::-;;;;;;:::o;67390:21::-;;;;;;-1:-1:-1;;;;;67390:21:0;;:::o;40187:174::-;37523:10;;-1:-1:-1;;;;;37523:10:0;37509;:24;;:54;;;37551:12;:10;:12::i;:::-;-1:-1:-1;;;;;37537:26:0;:10;-1:-1:-1;;;;;37537:26:0;;37509:54;37501:78;;;;-1:-1:-1;;;37501:78:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;40266:21:0;::::1;40258:30;;;::::0;::::1;;40299:6;:16:::0;;-1:-1:-1;;;;;;40299:16:0::1;-1:-1:-1::0;;;;;40299:16:0;::::1;;::::0;;40331:22:::1;::::0;::::1;::::0;::::1;::::0;40299:16;;40331:22:::1;:::i;61288:::-:0;;;;:::o;37145:33::-;;;;:::o;36084:94::-;36142:7;36084:94;:::o;41958:169::-;37523:10;;-1:-1:-1;;;;;37523:10:0;37509;:24;;:54;;;37551:12;:10;:12::i;:::-;-1:-1:-1;;;;;37537:26:0;:10;-1:-1:-1;;;;;37537:26:0;;37509:54;37501:78;;;;-1:-1:-1;;;37501:78:0;;;;;;;:::i;:::-;42041:12:::1;:28:::0;;;42085:34:::1;::::0;::::1;::::0;::::1;::::0;42056:13;;42085:34:::1;:::i;36246:22::-:0;;;-1:-1:-1;;;;;36246:22:0;;:::o;66785:116::-;37523:10;;-1:-1:-1;;;;;37523:10:0;37509;:24;;:54;;;37551:12;:10;:12::i;:::-;-1:-1:-1;;;;;37537:26:0;:10;-1:-1:-1;;;;;37537:26:0;;37509:54;37501:78;;;;-1:-1:-1;;;37501:78:0;;;;;;;:::i;:::-;66865:12:::1;:28:::0;;-1:-1:-1;;66865:28:0::1;::::0;::::1;;::::0;;;::::1;::::0;;66785:116::o;62493:30::-;;;;:::o;39078:120::-;37779:12;:10;:12::i;:::-;-1:-1:-1;;;;;37765:26:0;:10;-1:-1:-1;;;;;37765:26:0;;37757:50;;;;-1:-1:-1;;;37757:50:0;;;;;;;:::i;:::-;39160:13:::1;:30:::0;;-1:-1:-1;;39160:30:0::1;::::0;::::1;;::::0;;;::::1;::::0;;39078:120::o;36275:21::-;;;-1:-1:-1;;;;;36275:21:0;;:::o;34543:26::-;;;;;;-1:-1:-1;;;;;34543:26:0;;:::o;82536:386::-;37523:10;;-1:-1:-1;;;;;37523:10:0;37509;:24;;:54;;;37551:12;:10;:12::i;:::-;-1:-1:-1;;;;;37537:26:0;:10;-1:-1:-1;;;;;37537:26:0;;37509:54;37501:78;;;;-1:-1:-1;;;37501:78:0;;;;;;;:::i;:::-;82747:16:::1;:36:::0;;;;82794:16:::1;:36:::0;;;;82841:15:::1;:34:::0;82886:12:::1;:28:::0;;;::::1;;-1:-1:-1::0;;;82886:28:0::1;-1:-1:-1::0;;;;82886:28:0;;::::1;::::0;;;::::1;::::0;;82536:386::o;61127:33::-;;;-1:-1:-1;;;;;61127:33:0;;:::o;63467:110::-;63540:4;;:29;;-1:-1:-1;;;63540:29:0;;63513:7;;-1:-1:-1;;;;;63540:4:0;;:14;;:29;;63563:4;;63540:29;;;:::i;63654:121::-;63730:15;;:37;;-1:-1:-1;;;63730:37:0;;63703:7;;63730:15;;;-1:-1:-1;;;;;63730:15:0;;:22;;:37;;63761:4;;63730:37;;;:::i;39431:202::-;37523:10;;-1:-1:-1;;;;;37523:10:0;37509;:24;;:54;;;37551:12;:10;:12::i;:::-;-1:-1:-1;;;;;37537:26:0;:10;-1:-1:-1;;;;;37537:26:0;;37509:54;37501:78;;;;-1:-1:-1;;;37501:78:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;39518:25:0;::::1;39510:34;;;::::0;::::1;;39555:10;:24:::0;;-1:-1:-1;;;;;;39555:24:0::1;-1:-1:-1::0;;;;;39555:24:0;::::1;;::::0;;39595:30:::1;::::0;::::1;::::0;::::1;::::0;39555:24;;39595:30:::1;:::i;57801:307::-:0;57890:5;;-1:-1:-1;;;;;57890:5:0;57868:10;:28;;:58;;;57914:12;:10;:12::i;:::-;-1:-1:-1;;;;;57900:26:0;:10;-1:-1:-1;;;;;57900:26:0;;57868:58;57860:67;;;;;;57984:5;;57946:34;;;-1:-1:-1;;;57946:34:0;;;;-1:-1:-1;;;;;57984:5:0;;;;57946:32;;;;;:34;;;;;;;;;;;;;;:32;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;57946:43:0;;57938:52;;;;;;58001:30;58018:12;58001:16;:30::i;:::-;58042:4;;58070:29;;-1:-1:-1;;;58070:29:0;;-1:-1:-1;;;;;58042:4:0;;;;:13;;58056:12;;58042:4;;58070:14;;:29;;58093:4;;58070:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58042:58;;;;;;;;;;;;;;;;:::i;68246:26::-;;;-1:-1:-1;;;;;68246:26:0;;:::o;81204:1059::-;37779:12;:10;:12::i;:::-;-1:-1:-1;;;;;37765:26:0;:10;-1:-1:-1;;;;;37765:26:0;;37757:50;;;;-1:-1:-1;;;37757:50:0;;;;;;;:::i;:::-;81352:12:::1;::::0;-1:-1:-1;;;;;81352:12:0::1;81344:35:::0;;::::1;::::0;:97:::1;;-1:-1:-1::0;81404:12:0::1;::::0;-1:-1:-1;;;;;81404:12:0::1;62126:42;81396:45;;81344:97;81326:197;;;81468:12;::::0;:43:::1;::::0;-1:-1:-1;;;81468:43:0;;-1:-1:-1;;;;;81468:12:0;;::::1;::::0;:20:::1;::::0;:43:::1;::::0;61884:42:::1;::::0;81468:12:::1;::::0;:43:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;81326:197;81537:20:::0;81533:723:::1;;81574:10;:18:::0;;-1:-1:-1;;;;;;81607:33:0;;;81655:18:::1;:31:::0;;-1:-1:-1;;;;;;81655:31:0::1;::::0;;81533:723:::1;;;81819:15;::::0;:43:::1;::::0;-1:-1:-1;;;81819:43:0;;:15:::1;::::0;;::::1;-1:-1:-1::0;;;;;81819:15:0::1;::::0;:28:::1;::::0;:43:::1;::::0;81848:13;;81819:43:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81798:18;:64:::0;;-1:-1:-1;;;;;;81798:64:0::1;-1:-1:-1::0;;;;;81798:64:0;;::::1;;::::0;;;;81918:48:::1;::::0;;-1:-1:-1;;;81918:48:0;;;;-1:-1:-1;;81933:18:0;;;::::1;::::0;81918:46:::1;::::0;:48:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;;81933:18;81918:48;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81981:12;:36:::0;;-1:-1:-1;;;;;;81981:36:0::1;-1:-1:-1::0;;;;;81981:36:0;;::::1;::::0;;;::::1;::::0;;;;82095:50:::1;::::0;-1:-1:-1;;;82095:50:0;;81981:36;;-1:-1:-1;82095:12:0::1;::::0;:20:::1;::::0;:50:::1;::::0;61884:42:::1;::::0;-1:-1:-1;;82127:17:0;82095:50:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;82160:52:0::1;::::0;;;;::::1;::::0;;;82183:12:::1;::::0;-1:-1:-1;;;;;82183:12:0::1;82160:52:::0;;62224:42:::1;82160:52;::::0;::::1;::::0;::::1;::::0;:11:::1;::::0;:52:::1;;:::i;:::-;-1:-1:-1::0;;82227:10:0::1;:17:::0;;-1:-1:-1;;;;82227:17:0::1;-1:-1:-1::0;;;82227:17:0::1;::::0;;81204:1059;;:::o;67475:24::-;;;-1:-1:-1;;;67475:24:0;;;;;:::o;40709:181::-;37666:10;;-1:-1:-1;;;;;37666:10:0;37652;:24;37644:48;;;;-1:-1:-1;;;37644:48:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;40790:22:0;::::1;40782:31;;;::::0;::::1;;40824:7;:18:::0;;-1:-1:-1;;;;;;40824:18:0::1;-1:-1:-1::0;;;;;40824:18:0;::::1;;::::0;;40858:24:::1;::::0;::::1;::::0;::::1;::::0;40824:18;;40858:24:::1;:::i;68279:22::-:0;;;-1:-1:-1;;;68279:22:0;;;;;:::o;75499:1858::-;75612:4;75773:10;:8;:10::i;:::-;75768:56;;-1:-1:-1;75807:5:0;75800:12;;75768:56;75919:12;;-1:-1:-1;;;75919:12:0;;;;75915:184;;;76019:20;:18;:20::i;:::-;76015:73;;;-1:-1:-1;76067:5:0;76060:12;;76015:73;76209:23;76235;:21;:23::i;:::-;76209:49;;76291:16;;76273:15;:34;76269:78;;;76331:4;76324:11;;;;;76269:78;76459:21;:19;:21::i;:::-;76454:67;;76504:5;76497:12;;;;;76454:67;76629:23;;;;76625:67;;;76676:4;76669:11;;;;;76625:67;76827:16;;76809:15;:34;76805:78;;;76867:4;76860:11;;;;;76805:78;76895:28;;:::i;:::-;76926:5;;:31;;-1:-1:-1;;;76926:31:0;;-1:-1:-1;;;;;76926:5:0;;;;:16;;:31;;76951:4;;76926:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;76895:62;;77075:14;;77034:38;77054:6;:17;;;77034:15;:19;;:38;;;;:::i;:::-;:55;77030:99;;;77113:4;77106:11;;;;;;77030:99;77230:15;;77204:5;;;;;;;;;-1:-1:-1;;;;;77204:5:0;-1:-1:-1;;;;;77204:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;77200:85;;;77269:4;77262:11;;;;;;77200:85;-1:-1:-1;77344:5:0;;75499:1858;-1:-1:-1;;;75499:1858:0:o;61480:33::-;;;-1:-1:-1;;;;;61480:33:0;;:::o;63783:133::-;63845:7;63872:36;63892:15;:13;:15::i;:::-;63872;:13;:15::i;41407:151::-;37523:10;;-1:-1:-1;;;;;37523:10:0;37509;:24;;:54;;;37551:12;:10;:12::i;:::-;-1:-1:-1;;;;;37537:26:0;:10;-1:-1:-1;;;;;37537:26:0;;37509:54;37501:78;;;;-1:-1:-1;;;37501:78:0;;;;;;;:::i;:::-;41485:14:::1;:23:::0;;;41524:26:::1;::::0;::::1;::::0;::::1;::::0;41502:6;;41524:26:::1;:::i;80370:539::-:0;80421:17;80508;80528:15;;;;;;;;;-1:-1:-1;;;;;80528:15:0;-1:-1:-1;;;;;80528:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;80508:50;;80585:15;80573:9;:27;80569:333;;;80624:4;80617:11;;;;;80569:333;80650:10;;-1:-1:-1;;;80650:10:0;;;;80646:256;;;80803:18;;80788:49;;;-1:-1:-1;;;80788:49:0;;;;80747:21;;-1:-1:-1;;;;;80803:18:0;;80788:47;;:49;;;;;;;;;;;;;;80803:18;80788:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;80875:15;-1:-1:-1;80859:31:0;-1:-1:-1;80852:38:0;;-1:-1:-1;;80852:38:0;80646:256;80370:539;;:::o;61208:18::-;;;;:::o;36186:21::-;;;-1:-1:-1;;;;;36186:21:0;;:::o;58537:164::-;37523:10;;-1:-1:-1;;;;;37523:10:0;37509;:24;;:54;;;37551:12;:10;:12::i;:::-;-1:-1:-1;;;;;37537:26:0;:10;-1:-1:-1;;;;;37537:26:0;;37509:54;37501:78;;;;-1:-1:-1;;;37501:78:0;;;;;;;:::i;:::-;58600:13:::1;:20:::0;;-1:-1:-1;;58600:20:0::1;58616:4;58600:20:::0;;::::1;::::0;;;58631:5;:22:::1;::::0;;-1:-1:-1;;;58631:22:0;;;;-1:-1:-1;;;;;58631:5:0;;::::1;::::0;:20:::1;::::0;:22:::1;::::0;;::::1;::::0;58600:13:::1;::::0;58631:22;;;;;;;;58600:13;58631:5;:22;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;58671:22:0::1;::::0;::::1;::::0;-1:-1:-1;58671:22:0;;-1:-1:-1;58671:22:0::1;58537:164::o:0;43013:98::-;43085:5;;:18;;;-1:-1:-1;;;43085:18:0;;;;43058:7;;-1:-1:-1;;;;;43085:5:0;;:16;;:18;;;;;;;;;;;;;;:5;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;65946:120::-;66041:16;65946:120;:::o;20187:132::-;20245:7;20272:39;20276:1;20279;20272:39;;;;;;;;;;;;;;;;;:3;:39::i;:::-;20265:46;;20187:132;;;;;:::o;18350:136::-;18408:7;18435:43;18439:1;18442;18435:43;;;;;;;;;;;;;;;;;:3;:43::i;19240:471::-;19298:7;19543:6;19539:47;;-1:-1:-1;19573:1:0;19566:8;;19539:47;19610:5;;;19614:1;19610;:5;:1;19634:5;;;;;:10;19626:56;;;;-1:-1:-1;;;19626:56:0;;;;;;;:::i;17886:181::-;17944:7;17976:5;;;18000:6;;;;17992:46;;;;-1:-1:-1;;;17992:46:0;;;;;;;:::i;64445:853::-;64549:25;64576:13;64607:16;64626:15;:13;:15::i;:::-;64607:34;;64672:8;64656:13;:24;64652:639;;;64697:18;64718:15;:13;:15::i;:::-;64697:36;-1:-1:-1;64752:14:0;;64748:214;;64787:15;;;;;-1:-1:-1;;;;;64787:15:0;:33;64843:49;64852:10;64864:27;:13;64882:8;64864:17;:27::i;:::-;64843:8;:49::i;:::-;64915:12;;64787:159;;-1:-1:-1;;;;;;64787:159:0;;;;;;;;;;64915:12;;;64787:159;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;64748:214;64976:21;65000:15;:13;:15::i;:::-;64976:39;;65050:38;65059:13;65074;65050:8;:38::i;:::-;65030:58;-1:-1:-1;65111:36:0;:13;65030:58;65111:17;:36::i;:::-;65103:44;;64652:639;;;;;65262:13;65277:1;65254:25;;;;;;;64652:639;64445:853;;;;;:::o;63978:459::-;64061:13;;;;64057:52;;;64091:7;;64057:52;64181:17;64201:15;:13;:15::i;:::-;64181:35;-1:-1:-1;64327:13:0;;64323:107;;64397:3;;64357:61;;-1:-1:-1;;;64357:61:0;;60933:42;;64357:39;;:61;;64397:3;64402:9;;64413:4;;64357:61;;;:::i;70562:3152::-;70924:15;;:46;;-1:-1:-1;;;70924:46:0;;70679:15;;;;;;70924;;;-1:-1:-1;;;;;70924:15:0;;:25;;:46;;70958:4;;70924:15;;:46;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;71004:28:0;;-1:-1:-1;;;71004:28:0;;70983:18;;62021:42;;71004:13;;:28;;71026:4;;71004:28;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71067:36;;-1:-1:-1;;;71067:36:0;;70983:49;;-1:-1:-1;71043:21:0;;62126:42;;71067:21;;:36;;71097:4;;71067:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71043:60;;71116:20;71139:44;61748:5;71139:23;71154:7;;71139:10;:14;;:23;;;;:::i;:44::-;71116:67;-1:-1:-1;71198:16:0;;71194:142;;71231:37;62021:42;61603;71255:12;71231:16;:37::i;:::-;71296:28;;-1:-1:-1;;;71296:28:0;;62021:42;;71296:13;;:28;;71318:4;;71296:28;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71283:41;;71194:142;71348:18;71369:47;61748:5;71369:26;71387:7;;71369:13;:17;;:26;;;;:::i;:47::-;71348:68;-1:-1:-1;71431:14:0;;71427:170;;71487:18;;71462:56;;62126:42;;-1:-1:-1;;;;;71487:18:0;71507:10;71462:24;:56::i;:::-;71549:36;;-1:-1:-1;;;71549:36:0;;62126:42;;71549:21;;:36;;71579:4;;71549:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71533:52;;71427:170;71668:10;;-1:-1:-1;;;71668:10:0;;;;71664:234;;;71745:12;;71738:45;;-1:-1:-1;;;71738:45:0;;71695:23;;-1:-1:-1;;;;;71745:12:0;;71738:30;;:45;;71777:4;;71738:45;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71695:88;-1:-1:-1;71802:19:0;;71798:89;;71842:29;71855:15;71842:12;:29::i;:::-;71664:234;;71993:41;72008:10;72020:13;71993:14;:41::i;:::-;72108:21;72144:14;;72140:105;;72175:5;;:58;;;;;;;;;;;-1:-1:-1;72175:58:0;;;;;;;;-1:-1:-1;;;72175:58:0;;:5;;;;-1:-1:-1;;;;;72175:5:0;;:19;;:58;;;;;;-1:-1:-1;72175:58:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72140:105;72401:20;;72397:431;;72438:18;72459:15;:13;:15::i;:::-;72438:36;-1:-1:-1;72493:14:0;;72489:203;;72528:15;;;;;-1:-1:-1;;;;;72528:15:0;:33;72584:38;72593:10;72605:16;72584:8;:38::i;:::-;72645:12;;72528:148;;-1:-1:-1;;;;;;72528:148:0;;;;;;;;;;72645:12;;;72528:148;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;72489:203;72706:21;72730:15;:13;:15::i;:::-;72706:39;;72775:41;72784:16;72802:13;72775:8;:41::i;:::-;72760:56;;72397:431;;;72964:14;72981:22;:20;:22::i;:::-;73029:5;;:31;;-1:-1:-1;;;73029:31:0;;72964:39;;-1:-1:-1;73014:12:0;;-1:-1:-1;;;;;73029:5:0;;;;:16;;:31;;73054:4;;73029:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;73014:56;;73167:4;73158:6;:13;73154:439;;;73198:16;:6;73209:4;73198:10;:16::i;:::-;73188:26;;73229:16;73248:15;:13;:15::i;:::-;73229:34;-1:-1:-1;73229:34:0;73282:25;:7;73294:12;73282:11;:25::i;:::-;:36;73278:178;;;73415:25;73433:6;73415:17;:25::i;:::-;;;73278:178;73154:439;;;;73565:16;:4;73574:6;73565:8;:16::i;:::-;73557:24;;73154:439;-1:-1:-1;;73675:23:0;:31;;-1:-1:-1;;73675:31:0;;;-1:-1:-1;70562:3152:0;;;;-1:-1:-1;70562:3152:0;;-1:-1:-1;;;;70562:3152:0:o;48265:297::-;48438:5;;:30;;-1:-1:-1;;;48438:30:0;;48420:15;;-1:-1:-1;;;;;48438:5:0;;:15;;:30;;48462:4;;48438:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48420:48;-1:-1:-1;48483:11:0;;48479:76;;48511:5;;48526:7;;48511:32;;-1:-1:-1;;;48511:32:0;;-1:-1:-1;;;;;48511:5:0;;;;:14;;:32;;48526:7;;;48535;;48511:32;;;:::i;73918:432::-;73995:18;74016:15;:13;:15::i;:::-;73995:36;-1:-1:-1;74046:14:0;;74042:106;;74077:15;;74123:12;;74077:59;;-1:-1:-1;;;74077:59:0;;:15;;;;-1:-1:-1;;;;;74077:15:0;;:33;;:59;;74111:10;;74123:12;;;74077:59;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;74042:106;74189:28;;-1:-1:-1;;;74189:28:0;;74158:60;;74175:12;;62021:42;;74189:13;;:28;;74211:4;;74189:28;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62021:42;;74158:60;:16;:60::i;:::-;74295:36;;-1:-1:-1;;;74295:36:0;;74229:113;;74268:12;;62126:42;;74295:21;;:36;;74325:4;;74295:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62126:42;;74229:113;:24;:113::i;80067:198::-;80121:4;80167:42;-1:-1:-1;;;;;80158:97:0;;:99;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;20815:278::-;20901:7;20936:12;20929:5;20921:28;;;;-1:-1:-1;;;20921:28:0;;;;;;;;:::i;:::-;;20960:9;20976:1;20972;:5;;;;;;;20815:278;-1:-1:-1;;;;;20815:278:0:o;18789:192::-;18875:7;18911:12;18903:6;;;;18895:29;;;;-1:-1:-1;;;18895:29:0;;;;;;;;:::i;:::-;-1:-1:-1;;;18947:5:0;;;18789:192::o;16558:106::-;16616:7;16647:1;16643;:5;:13;;16655:1;16643:13;;;-1:-1:-1;16651:1:0;;16558:106;-1:-1:-1;16558:106:0:o;27869:177::-;27952:86;27972:5;28002:23;;;28027:2;28031:5;27979:58;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;27979:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;27979:58:0;-1:-1:-1;;;;;;27979:58:0;;;;;;;;;;27952:19;:86::i;75141:263::-;75200:196;;-1:-1:-1;;;75200:196:0;;61884:42;;75200:54;;:196;;75269:7;;75299:1;;75316:11;;75350:4;;75370:15;;75200:196;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;75200:196:0;;;;;;;;;;;;:::i;74472:594::-;74593:4;74577:13;:20;74573:158;;;74673:46;;-1:-1:-1;;;74673:46:0;;67865:42;;74673:15;;:46;;74689:1;;74692;;74695:13;;74692:1;;;;74673:46;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74573:158;74760:4;74747:10;:17;74743:152;;;74840:43;;-1:-1:-1;;;74840:43:0;;67706:42;;74840:15;;:43;;74856:1;;74859;;74862:10;;74859:1;;;;74840:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74743:152;74929:29;;-1:-1:-1;;;74929:29:0;;74907:19;;62224:42;;74929:14;;:29;;74952:4;;74929:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74907:51;-1:-1:-1;74973:15:0;;74969:90;;75005:42;;-1:-1:-1;;;75005:42:0;;62224;;75005:29;;:42;;75035:11;;75005:42;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74472:594;;;:::o;30174:761::-;30598:23;30624:69;30652:4;30624:69;;;;;;;;;;;;;;;;;30632:5;-1:-1:-1;;;;;30624:27:0;;;:69;;;;;:::i;:::-;30708:17;;30598:95;;-1:-1:-1;30708:21:0;30704:224;;30850:10;30839:30;;;;;;;;;;;;:::i;:::-;30831:85;;;;-1:-1:-1;;;30831:85:0;;;;;;;:::i;11015:196::-;11118:12;11150:53;11173:6;11181:4;11187:1;11190:12;11150:22;:53::i;:::-;11143:60;11015:196;-1:-1:-1;;;;11015:196:0:o;12392:979::-;12522:12;12555:18;12566:6;12555:10;:18::i;:::-;12547:60;;;;-1:-1:-1;;;12547:60:0;;;;;;;:::i;:::-;12681:12;12695:23;12722:6;-1:-1:-1;;;;;12722:11:0;12742:8;12753:4;12722:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12680:78;;;;12773:7;12769:595;;;12804:10;-1:-1:-1;12797:17:0;;-1:-1:-1;12797:17:0;12769:595;12918:17;;:21;12914:439;;13181:10;13175:17;13242:15;13229:10;13225:2;13221:19;13214:44;13129:148;13324:12;13317:20;;-1:-1:-1;;;13317:20:0;;;;;;;;:::i;7900:619::-;7960:4;8428:20;;8271:66;8468:23;;;;;;:42;;-1:-1:-1;;8495:15:0;;;8460:51;-1:-1:-1;;7900:619:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;3275:241;;3379:2;3367:9;3358:7;3354:23;3350:32;3347:2;;;-1:-1;;3385:12;3347:2;85:6;72:20;97:33;124:5;97:33;:::i;3523:263::-;;3638:2;3626:9;3617:7;3613:23;3609:32;3606:2;;;-1:-1;;3644:12;3606:2;226:6;220:13;238:33;265:5;238:33;:::i;3793:392::-;;3933:2;;3921:9;3912:7;3908:23;3904:32;3901:2;;;-1:-1;;3939:12;3901:2;3990:17;3984:24;4028:18;4020:6;4017:30;4014:2;;;-1:-1;;4050:12;4014:2;4137:22;;422:4;410:17;;406:27;-1:-1;396:2;;-1:-1;;437:12;396:2;477:6;471:13;499:80;514:64;571:6;514:64;:::i;:::-;499:80;:::i;:::-;607:21;;;664:14;;;;639:17;;;753;;;744:27;;;;741:36;-1:-1;738:2;;;-1:-1;;780:12;738:2;-1:-1;806:10;;800:217;825:6;822:1;819:13;800:217;;;3212:13;;893:61;;847:1;840:9;;;;;968:14;;;;996;;800:217;;;-1:-1;4070:99;3895:290;-1:-1;;;;;;;3895:290::o;4192:235::-;;4293:2;4281:9;4272:7;4268:23;4264:32;4261:2;;;-1:-1;;4299:12;4261:2;1108:6;1095:20;1120:30;1144:5;1120:30;:::i;4434:257::-;;4546:2;4534:9;4525:7;4521:23;4517:32;4514:2;;;-1:-1;;4552:12;4514:2;1243:6;1237:13;1255:30;1279:5;1255:30;:::i;4698:360::-;;;4816:2;4804:9;4795:7;4791:23;4787:32;4784:2;;;-1:-1;;4822:12;4784:2;1108:6;1095:20;1120:30;1144:5;1120:30;:::i;:::-;4874:60;4971:2;5010:22;;;;3064:20;;-1:-1;;;4778:280::o;5369:324::-;;5514:3;;5502:9;5493:7;5489:23;5485:33;5482:2;;;-1:-1;;5521:12;5482:2;1668:22;5514:3;1668:22;:::i;:::-;1659:31;;1814:22;3212:13;1764:16;1757:86;1910:2;1979:9;1975:22;3212:13;1910:2;1929:5;1925:16;1918:86;2070:2;2139:9;2135:22;3212:13;2070:2;2089:5;2085:16;2078:86;2230:2;2299:9;2295:22;3212:13;2230:2;2249:5;2245:16;2238:86;2391:3;2461:9;2457:22;3212:13;2391:3;2411:5;2407:16;2400:86;2552:3;2622:9;2618:22;3212:13;2552:3;2572:5;2568:16;2561:86;2713:3;2783:9;2779:22;3212:13;2713:3;2733:5;2729:16;2722:86;2874:3;2944:9;2940:22;3212:13;2874:3;2894:5;2890:16;2883:86;5573:104;;;;5476:217;;;;:::o;5700:241::-;;5804:2;5792:9;5783:7;5779:23;5775:32;5772:2;;;-1:-1;;5810:12;5772:2;-1:-1;3064:20;;5766:175;-1:-1;5766:175::o;5948:263::-;;6063:2;6051:9;6042:7;6038:23;6034:32;6031:2;;;-1:-1;;6069:12;6031:2;-1:-1;3212:13;;6025:186;-1:-1;6025:186::o;6218:491::-;;;;6356:2;6344:9;6335:7;6331:23;6327:32;6324:2;;;-1:-1;;6362:12;6324:2;3077:6;3064:20;6414:63;;6514:2;6557:9;6553:22;3064:20;6522:63;;6622:2;6665:9;6661:22;72:20;97:33;124:5;97:33;:::i;:::-;6630:63;;;;6318:391;;;;;:::o;6716:611::-;;;;;6868:3;6856:9;6847:7;6843:23;6839:33;6836:2;;;-1:-1;;6875:12;6836:2;3077:6;3064:20;6927:63;;7027:2;7070:9;7066:22;3064:20;7035:63;;7135:2;7178:9;7174:22;3064:20;7143:63;;7243:2;7283:9;7279:22;1095:20;1120:30;1144:5;1120:30;:::i;:::-;6830:497;;;;-1:-1;6830:497;;-1:-1;;6830:497::o;16263:271::-;;10526:5;31005:12;10637:52;10682:6;10677:3;10670:4;10663:5;10659:16;10637:52;:::i;:::-;10701:16;;;;;16397:137;-1:-1;;16397:137::o;16541:222::-;-1:-1;;;;;32642:54;;;;7908:37;;16668:2;16653:18;;16639:124::o;17015:337::-;-1:-1;;;;;32642:54;;;;7777:58;;32872:13;32865:21;17338:2;17323:18;;10320:34;17172:2;17157:18;;17143:209::o;17359:349::-;-1:-1;;;;;32642:54;;;;7777:58;;17694:2;17679:18;;16094:37;17522:2;17507:18;;17493:215::o;18055:441::-;18264:2;18249:18;;18253:9;9950:21;18055:441;9977:258;31288:4;9999:1;9996:13;9977:258;;;10063:13;;16094:37;;7679:4;7670:14;;;;31655;;;;10024:1;10017:9;9977:258;;;9981:14;;;11531:5;18482:2;18471:9;18467:18;11480:58;18235:261;;;;;:::o;18503:210::-;32872:13;;32865:21;10320:34;;18624:2;18609:18;;18595:118::o;19776:704::-;11480:58;;;20214:2;20199:18;;11480:58;;;;20297:2;20282:18;;16094:37;;;;20388:2;20373:18;;11480:58;32872:13;32865:21;20465:3;20450:19;;10320:34;20033:3;20018:19;;20004:476::o;20487:310::-;;20634:2;20655:17;20648:47;11844:5;31005:12;32037:6;20634:2;20623:9;20619:18;32025:19;11938:52;11983:6;32065:14;20623:9;32065:14;20634:2;11964:5;11960:16;11938:52;:::i;:::-;35701:7;35685:14;-1:-1;;35681:28;12002:39;;;;32065:14;12002:39;;20605:192;-1:-1;;20605:192::o;20804:416::-;21004:2;21018:47;;;12278:2;20989:18;;;32025:19;-1:-1;;;32065:14;;;12294:34;12347:12;;;20975:245::o;21227:416::-;21427:2;21441:47;;;12598:1;21412:18;;;32025:19;-1:-1;;;32065:14;;;12613:28;12660:12;;;21398:245::o;21650:416::-;21850:2;21864:47;;;12911:2;21835:18;;;32025:19;12947:29;32065:14;;;12927:50;12996:12;;;21821:245::o;22073:416::-;22273:2;22287:47;;;13247:2;22258:18;;;32025:19;-1:-1;;;32065:14;;;13263:35;13317:12;;;22244:245::o;22496:416::-;22696:2;22710:47;;;13568:1;22681:18;;;32025:19;-1:-1;;;32065:14;;;13583:32;13634:12;;;22667:245::o;22919:416::-;23119:2;23133:47;;;13885:2;23104:18;;;32025:19;13921:34;32065:14;;;13901:55;-1:-1;;;13976:12;;;13969:25;14013:12;;;23090:245::o;23342:416::-;23542:2;23556:47;;;14264:1;23527:18;;;32025:19;-1:-1;;;32065:14;;;14279:29;14327:12;;;23513:245::o;23765:416::-;23965:2;23979:47;;;14578:1;23950:18;;;32025:19;-1:-1;;;32065:14;;;14593:30;14642:12;;;23936:245::o;24188:416::-;24388:2;24402:47;;;14893:2;24373:18;;;32025:19;14929:31;32065:14;;;14909:52;14980:12;;;24359:245::o;24611:416::-;24811:2;24825:47;;;15231:2;24796:18;;;32025:19;-1:-1;;;32065:14;;;15247:34;15300:12;;;24782:245::o;25034:416::-;25234:2;25248:47;;;15551:2;25219:18;;;32025:19;15587:34;32065:14;;;15567:55;-1:-1;;;15642:12;;;15635:34;15688:12;;;25205:245::o;25457:416::-;25657:2;25671:47;;;15939:2;25642:18;;;32025:19;-1:-1;;;32065:14;;;15955:33;16007:12;;;25628:245::o;25880:222::-;16094:37;;;26007:2;25992:18;;25978:124::o;26109:481::-;;26314:2;26303:9;26299:18;16124:5;16101:3;16094:37;26432:2;26314;26432;26421:9;26417:18;26410:48;26472:108;8301:5;31005:12;32037:6;32032:3;32025:19;32065:14;26303:9;32065:14;8313:93;;26432:2;8477:5;30575:14;8489:21;;-1:-1;8516:260;8541:6;8538:1;8535:13;8516:260;;;8602:13;;-1:-1;;;;;32642:54;7908:37;;31655:14;;;;7488;;;;4028:18;8556:9;8516:260;;;-1:-1;26464:116;;26285:305;-1:-1;;;;;;;26285:305::o;26597:321::-;16094:37;;;32872:13;32865:21;26904:2;26889:18;;10320:34;26746:2;26731:18;;26717:201::o;26925:826::-;;27219:3;27208:9;27204:19;16124:5;16101:3;16094:37;27384:2;16124:5;27384:2;27373:9;27369:18;16094:37;27219:3;27421:2;27410:9;27406:18;27399:48;27461:105;9024:5;31152:12;32037:6;32032:3;32025:19;32065:14;27208:9;32065:14;9036:93;;30738:3;-1:-1;30728:14;27384:2;-1:-1;30757:18;9209:21;;-1:-1;9236:288;9261:6;9258:1;9255:13;9236:288;;;35593:11;;-1:-1;;;;;32642:54;7908:37;;4028:18;31767:14;;;;7488;;;;9276:9;9236:288;;;-1:-1;;;;;;;32642:54;;;;27653:2;27638:18;;7777:58;-1:-1;;;27736:3;27721:19;16094:37;27453:113;27190:561;-1:-1;;;27190:561::o;27758:432::-;16094:37;;;28099:2;28084:18;;16094:37;;;;32872:13;32865:21;28176:2;28161:18;;10320:34;27935:2;27920:18;;27906:284::o;28197:444::-;16094:37;;;28544:2;28529:18;;16094:37;;;;28627:2;28612:18;;16094:37;28380:2;28365:18;;28351:290::o;28648:556::-;16094:37;;;29024:2;29009:18;;16094:37;;;;29107:2;29092:18;;16094:37;29190:2;29175:18;;16094:37;28859:3;28844:19;;28830:374::o;29211:668::-;16094:37;;;29615:2;29600:18;;16094:37;;;;29698:2;29683:18;;16094:37;;;;29781:2;29766:18;;16094:37;29864:3;29849:19;;16094:37;29450:3;29435:19;;29421:458::o;29886:256::-;29948:2;29942:9;29974:17;;;30049:18;30034:34;;30070:22;;;30031:62;30028:2;;;30106:1;;30096:12;30028:2;29948;30115:22;29926:216;;-1:-1;29926:216::o;30149:304::-;;30308:18;30300:6;30297:30;30294:2;;;-1:-1;;30330:12;30294:2;-1:-1;30375:4;30363:17;;;30428:15;;30231:222::o;35028:268::-;35093:1;35100:101;35114:6;35111:1;35108:13;35100:101;;;35181:11;;;35175:18;35162:11;;;35155:39;35136:2;35129:10;35100:101;;;35216:6;35213:1;35210:13;35207:2;;;35093:1;35272:6;35267:3;35263:16;35256:27;35207:2;;35077:219;;;:::o;35832:117::-;-1:-1;;;;;32642:54;;35891:35;;35881:2;;35940:1;;35930:12;35956:111;36037:5;32872:13;32865:21;36015:5;36012:32;36002:2;;36058:1;;36048:12
Swarm Source
ipfs://38d8aa59fccb902e8d93aa5239e24e4aab5c3f1e7b0e6a65a8802b9c01e3e6fd
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.