Contract
0xf1c3047c6310806de1d25535bc50748815066a7b
1
Contract Overview
Balance:
0 ETH
ETH Value:
$0.00
My Name Tag:
Not Available
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
StrategyCurveSpell
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Arbiscan on 2022-04-15 */ pragma experimental ABIEncoderV2; // File: Address.sol /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ 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); } } } } // File: IERC20.sol /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File: Math.sol /** * @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); } } // File: SafeMath.sol /** * @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; } } // File: sorbettiere.sol interface ISorbettiere { struct UserInfo { uint256 amount; // How many LP tokens the user has provided. uint256 rewardDebt; // Reward debt. See explanation below. uint256 remainingIceTokenReward; // ICE Tokens that weren't distributed for user per pool. // // We do some fancy math here. Basically, any point in time, the amount of ICE // entitled to a user but is pending to be distributed is: // // pending reward = (user.amount * pool.accICEPerShare) - user.rewardDebt // // Whenever a user deposits or withdraws Staked tokens to a pool. Here's what happens: // 1. The pool's `accICEPerShare` (and `lastRewardTime`) gets updated. // 2. User receives the pending reward sent to his/her address. // 3. User's `amount` gets updated. // 4. User's `rewardDebt` gets updated. } struct PoolInfo { address stakingToken; // Contract address of staked token uint256 stakingTokenTotalAmount; //Total amount of deposited tokens uint256 accIcePerShare; // Accumulated ICE per share, times 1e12. See below. uint32 lastRewardTime; // Last timestamp number that ICE distribution occurs. uint16 allocPoint; // How many allocation points assigned to this pool. ICE to distribute per second. } function withdraw(uint256 _pid, uint256 _amount) external; function deposit(uint256 _pid, uint256 _amount) external; function pendingIce(uint256 _pid, address _user) external view returns (uint256); function userInfo(uint256 _pid, address _user) external view returns (UserInfo memory); function poolInfo(uint256 _pid) external view returns (PoolInfo memory); function emergencyWithdraw(uint256 _pid) external; } // File: uniswap.sol 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); } 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; } // File: SafeERC20.sol /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using 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"); } } } // File: BaseStrategy.sol struct StrategyParams { uint256 performanceFee; uint256 activation; uint256 debtRatio; uint256 minDebtPerHarvest; uint256 maxDebtPerHarvest; uint256 lastReport; uint256 totalDebt; uint256 totalGain; uint256 totalLoss; } interface VaultAPI is IERC20 { function name() external view returns (string calldata); function symbol() external view returns (string calldata); function decimals() external view returns (uint256); function apiVersion() external pure returns (string memory); function permit( address owner, address spender, uint256 amount, uint256 expiry, bytes calldata signature ) external returns (bool); // NOTE: Vyper produces multiple signatures for a given function with "default" args function deposit() external returns (uint256); function deposit(uint256 amount) external returns (uint256); function deposit(uint256 amount, address recipient) external returns (uint256); // NOTE: Vyper produces multiple signatures for a given function with "default" args function withdraw() external returns (uint256); function withdraw(uint256 maxShares) external returns (uint256); function withdraw(uint256 maxShares, address recipient) external returns (uint256); function token() external view returns (address); function strategies(address _strategy) external view returns (StrategyParams memory); function pricePerShare() external view returns (uint256); function totalAssets() external view returns (uint256); function depositLimit() external view returns (uint256); function maxAvailableShares() external view returns (uint256); /** * 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); /** * View the management address of the Vault to assert privileged functions * can only be called by management. The Strategy serves the Vault, so it * is subject to management defined by the Vault. */ function management() external view returns (address); /** * View the guardian address of the Vault to assert privileged functions * can only be called by guardian. The Strategy serves the Vault, so it * is subject to guardian defined by the Vault. */ function guardian() external view returns (address); } /** * This interface is here for the keeper bot to use. */ interface StrategyAPI { function name() external view returns (string memory); function vault() external view returns (address); function want() external view returns (address); function apiVersion() external pure returns (string memory); function keeper() external view returns (address); function isActive() external view returns (bool); function delegatedAssets() external view returns (uint256); function estimatedTotalAssets() external view returns (uint256); function tendTrigger(uint256 callCost) external view returns (bool); function tend() external; function harvestTrigger(uint256 callCost) external view returns (bool); function harvest() external; event Harvested(uint256 profit, uint256 loss, uint256 debtPayment, uint256 debtOutstanding); } interface HealthCheck { function check( uint256 profit, uint256 loss, uint256 debtPayment, uint256 debtOutstanding, uint256 totalDebt ) external view returns (bool); } /** * @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; using SafeERC20 for IERC20; string public metadataURI; // 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.4.3"; } /** * @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 view virtual 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. * Also note that this value is used to determine the total assets under management by this * strategy, for the purposes of computing the management fee in `Vault` * @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 view virtual 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 UpdatedMinReportDelay(uint256 delay); event UpdatedMaxReportDelay(uint256 delay); event UpdatedProfitFactor(uint256 profitFactor); event UpdatedDebtThreshold(uint256 debtThreshold); event EmergencyExitEnabled(); event UpdatedMetadataURI(string metadataURI); // The minimum number of seconds between harvest calls. See // `setMinReportDelay()` for more details. uint256 public minReportDelay; // The maximum number of seconds between harvest calls. See // `setMaxReportDelay()` for more details. uint256 public maxReportDelay; // The minimum multiple that `callCost` must be above the credit/profit to // be "justifiable". See `setProfitFactor()` for more details. uint256 public profitFactor; // Use this to adjust the threshold at which running a debt causes a // harvest trigger. See `setDebtThreshold()` for more details. uint256 public debtThreshold; // See note on `setEmergencyExit()`. bool public emergencyExit; // modifiers modifier onlyAuthorized() { require(msg.sender == strategist || msg.sender == governance(), "!authorized"); _; } modifier onlyEmergencyAuthorized() { require( msg.sender == strategist || msg.sender == governance() || msg.sender == vault.guardian() || msg.sender == vault.management(), "!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() || msg.sender == vault.guardian() || msg.sender == vault.management(), "!authorized" ); _; } modifier onlyVaultManagers() { require(msg.sender == vault.management() || 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. * @param _strategist The address to assign as `strategist`. * The strategist is able to change the reward address * @param _rewards The address to use for pulling rewards. * @param _keeper The adddress of the _keeper. _keeper * can harvest and tend a 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.safeApprove(_vault, uint256(-1)); // Give Vault unlimited access (might save gas) strategist = _strategist; rewards = _rewards; keeper = _keeper; // initialize variables minReportDelay = 0; maxReportDelay = 86400; profitFactor = 100; debtThreshold = 0; vault.approve(rewards, uint256(-1)); // Allow rewards to be pulled } function setHealthCheck(address _healthCheck) external onlyVaultManagers { healthCheck = _healthCheck; } function setDoHealthCheck(bool _doHealthCheck) external onlyVaultManagers { 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`. EOA or smart contract which has the permission * to pull rewards from the vault. * * This may only be called by the strategist. * @param _rewards The address to use for pulling rewards. */ function setRewards(address _rewards) external onlyStrategist { require(_rewards != address(0)); vault.approve(rewards, 0); rewards = _rewards; vault.approve(rewards, uint256(-1)); emit UpdatedRewards(_rewards); } /** * @notice * Used to change `minReportDelay`. `minReportDelay` is the minimum number * of blocks that should pass for `harvest()` to be called. * * For external keepers (such as the Keep3r network), this is the minimum * time between jobs to wait. (see `harvestTrigger()` * for more details.) * * This may only be called by governance or the strategist. * @param _delay The minimum number of seconds to wait between harvests. */ function setMinReportDelay(uint256 _delay) external onlyAuthorized { minReportDelay = _delay; emit UpdatedMinReportDelay(_delay); } /** * @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 UpdatedMaxReportDelay(_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); } /** * @notice * Used to change `metadataURI`. `metadataURI` is used to store the URI * of the file describing the strategy. * * This may only be called by governance or the strategist. * @param _metadataURI The URI that describe the strategy. */ function setMetadataURI(string calldata _metadataURI) external onlyAuthorized { metadataURI = _metadataURI; emit UpdatedMetadataURI(_metadataURI); } /** * 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 conversion from `_amtInWei` (denominated in wei) * to `want` (using the native decimal characteristics of `want`). * @dev * Care must be taken when working with decimals to assure that the conversion * is compatible. As an example: * * given 1e17 wei (0.1 ETH) as input, and want is USDC (6 decimals), * with USDC/ETH = 1800, this should give back 1800000000 (180 USDC) * * @param _amtInWei The amount (in wei/1e-18 ETH) to convert to `want` * @return The amount in `want` of `_amtInEth` converted to `want` **/ function ethToWant(uint256 _amtInWei) public view virtual returns (uint256); /** * @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 view virtual 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`). * * `_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) where the amount made available is less than what is needed. * * NOTE: The invariant `_liquidatedAmount + _loss <= _amountNeeded` should always be maintained */ function liquidatePosition(uint256 _amountNeeded) internal virtual returns (uint256 _liquidatedAmount, uint256 _loss); /** * Liquidate everything and returns the amount that got freed. * This function is used during emergency exit instead of `prepareReturn()` to * liquidate all of the Strategy's positions back to the Vault. */ function liquidateAllPositions() internal virtual returns (uint256 _amountFreed); /** * @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 * `callCostInWei` must be priced in terms of `wei` (1e-18 ETH). * * This call and `harvestTrigger()` should never return `true` at the same * time. * @param callCostInWei The keeper's estimated gas cost to call `tend()` (in wei). * @return `true` if `tend()` should be called, `false` otherwise. */ function tendTrigger(uint256 callCostInWei) public view virtual 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. // If your implementation uses the cost of the call in want, you can // use uint256 callCost = ethToWant(callCostInWei); 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 * `callCostInWei` must be priced in terms of `wei` (1e-18 ETH). * * This call and `tendTrigger` should never return `true` at the * same time. * * See `min/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/main/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 callCostInWei The keeper's estimated gas cost to call `harvest()` (in wei). * @return `true` if `harvest()` should be called, `false` otherwise. */ function harvestTrigger(uint256 callCostInWei) public view virtual returns (bool) { uint256 callCost = ethToWant(callCostInWei); StrategyParams memory params = vault.strategies(address(this)); // Should not trigger if Strategy is not activated if (params.activation == 0) return false; // Should not trigger if we haven't waited long enough since previous harvest if (block.timestamp.sub(params.lastReport) < minReportDelay) 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 amountFreed = liquidateAllPositions(); if (amountFreed < debtOutstanding) { loss = debtOutstanding.sub(amountFreed); } else if (amountFreed > debtOutstanding) { profit = amountFreed.sub(debtOutstanding); } debtPayment = debtOutstanding.sub(loss); } 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); // 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 `_amountNeeded` uint256 amountFreed; (amountFreed, _loss) = liquidatePosition(_amountNeeded); // Send it directly back (NOTE: Using `msg.sender` saves some gas here) want.safeTransfer(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 the Vault. * @dev * The new Strategy's Vault must be the same as this Strategy's Vault. * The migration process should be carefully performed to make sure all * the assets are migrated to the new address, which should have never * interacted with the vault before. * @param _newStrategy The Strategy to migrate to. */ function migrate(address _newStrategy) external { require(msg.sender == address(vault)); require(BaseStrategy(_newStrategy).vault() == vault); prepareMigration(_newStrategy); want.safeTransfer(_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 onlyEmergencyAuthorized { 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 view virtual 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).safeTransfer(governance(), IERC20(_token).balanceOf(address(this))); } } abstract contract BaseStrategyInitializable is BaseStrategy { bool public isOriginal = true; event Cloned(address indexed clone); constructor(address _vault) public BaseStrategy(_vault) {} function initialize( address _vault, address _strategist, address _rewards, address _keeper ) external virtual { _initialize(_vault, _strategist, _rewards, _keeper); } function clone(address _vault) external returns (address) { require(isOriginal, "!clone"); return this.clone(_vault, msg.sender, msg.sender, msg.sender); } function clone( address _vault, address _strategist, address _rewards, address _keeper ) external returns (address newStrategy) { // Copied from https://github.com/optionality/clone-factory/blob/master/contracts/CloneFactory.sol bytes20 addressBytes = bytes20(address(this)); assembly { // EIP-1167 bytecode let clone_code := mload(0x40) mstore(clone_code, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) mstore(add(clone_code, 0x14), addressBytes) mstore(add(clone_code, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) newStrategy := create(0, clone_code, 0x37) } BaseStrategyInitializable(newStrategy).initialize(_vault, _strategist, _rewards, _keeper); emit Cloned(newStrategy); } } // File: curve.sol interface IGauge { function deposit(uint256) external; function balanceOf(address) external view returns (uint256); function claim_rewards() external; function claimable_tokens(address) external view returns (uint256); function claimable_reward(address _addressToCheck, address _rewardToken) external view returns (uint256); function withdraw(uint256) external; } interface ICurveFi { function get_virtual_price() external view returns (uint256); function decimals() external view returns (uint256); 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( // Compound, sAave uint256[8] calldata _amounts, uint256 min_mint_amount ) 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( int128 from, int128 to, uint256 _from_amount, uint256 _min_to_amount ) external; function balances(uint256) 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); } interface ICrvV3 is IERC20 { function minter() external view returns (address); } interface IMinter { function mint(address) external; } interface ICurveZap { function add_liquidity( address _pool, uint256[3] calldata _deposit_amounts, uint256 _min_mint_amount ) external returns (uint256); } // File: yearn.sol interface ICurveStrategyProxy { function proxy() external returns (address); function balanceOf(address _gauge) external view returns (uint256); function deposit(address _gauge, address _token) external; function withdraw( address _gauge, address _token, uint256 _amount ) external returns (uint256); function withdrawAll(address _gauge, address _token) external returns (uint256); function harvest(address _gauge) external; function lock() external; function approveStrategy(address) external; function revokeStrategy(address) external; function claimRewards(address _gauge, address _token) external; } interface IVoter { function execute( address to, uint256 value, bytes calldata data ) external returns (bool, bytes memory); function increaseAmount(uint256) external; } // File: StrategyCurveSpell.sol contract StrategyCurveSpell is BaseStrategy { using SafeERC20 for IERC20; /* ========== STATE VARIABLES ========== */ // these will likely change across different wants. // the rewards contract we deposit into and harvest SPELL from ISorbettiere internal constant sorbettiere = ISorbettiere(0x839De324a1ab773F76a53900D70Ac1B913d2B387); // used as the intermediary for selling spell into an underlying token of the curve pool IERC20 internal constant weth = IERC20(0x82aF49447D8a07e3bd95BD0d56f35241523fBab1); // we use these to deposit to our curve pool IERC20 internal constant mim = IERC20(0xFEa7a6a0B346362BF88A9e4A88416B77a57D6c2A); IERC20 internal constant usdt = IERC20(0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9); IERC20 internal constant usdc = IERC20(0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8); IERC20 internal constant spell = IERC20(0x3E6648C5a70A150A88bCE65F4aD4d506Fe15d2AF); IUniswapV2Router02 public router = IUniswapV2Router02(0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506); // sushi router ICurveZap public curveZapIn = ICurveZap(0x7544Fe3d184b6B55D6B36c3FCA1157eE0Ba30287); address public targetToken; // this is the token we sell into - MIM, USDC, or usdt bool public forceHarvestTriggerOnce; // only set this to true externally when we want to trigger our keepers to harvest for us bool public withdrawStakedOnMigration = true; // set to true to withdraw the deposited lp tokens before migration bool public shouldSellSpell = true; // set to true to sell any farmed spell uint256 internal poolId; // the pool we are depositing into in the rewards contract string internal stratName; // set our strategy name here /* ========== CONSTRUCTOR ========== */ constructor( address _vault, uint256 _poolId, string memory _name ) public BaseStrategy(_vault) { // You can set these parameters on deployment to whatever you want maxReportDelay = 2 days; // 2 days in seconds healthCheck = 0x32059ccE723b4DD15dD5cb2a5187f814e6c470bC; // these are our standard approvals. want = Curve LP token want.approve(address(sorbettiere), type(uint256).max); spell.approve(address(router), type(uint256).max); // set our strategy's name stratName = _name; // set the pool id that we'll use in the rewards contract to deposit into address stakingToken = sorbettiere.poolInfo(_poolId).stakingToken; require(stakingToken == address(want), "wrong pool"); poolId = _poolId; // these are our approvals and path specific to this contract mim.approve(address(curveZapIn), type(uint256).max); usdc.approve(address(curveZapIn), type(uint256).max); usdt.safeApprove(address(curveZapIn), type(uint256).max); // start off with mim targetToken = address(mim); } function name() external view override returns (string memory) { return stratName; } /* ========== MUTATIVE FUNCTIONS ========== */ // these will likely change across different wants. ///@notice Only do this if absolutely necessary; as assets will be withdrawn but rewards won't be claimed. function emergencyWithdraw() external onlyEmergencyAuthorized { sorbettiere.emergencyWithdraw(poolId); } function prepareMigration(address _newStrategy) internal override { if (withdrawStakedOnMigration) { uint256 _stakedBal = stakedBalance(); if (_stakedBal > 0) { sorbettiere.withdraw(poolId, _stakedBal); } } uint256 _spellBalance = spell.balanceOf(address(this)); if (_spellBalance > 0) { spell.safeTransfer(_newStrategy, _spellBalance); } } function protectedTokens() internal view override returns (address[] memory) {} // This allows us to manually harvest with our keeper as needed function setWithdrawStakedOnMigration(bool _withdrawStakedOnMigration) external onlyEmergencyAuthorized { withdrawStakedOnMigration = _withdrawStakedOnMigration; } function setForceHarvestTriggerOnce(bool _forceHarvestTriggerOnce) external onlyEmergencyAuthorized { forceHarvestTriggerOnce = _forceHarvestTriggerOnce; } function setShouldSellSpell(bool _shouldSellSpell) external onlyEmergencyAuthorized { shouldSellSpell = _shouldSellSpell; } function adjustPosition(uint256 _debtOutstanding) internal override { if (emergencyExit) { return; } // Send all of our LP tokens to deposit to the gauge if we have any uint256 _toInvest = balanceOfWant(); if (_toInvest > 0) { sorbettiere.deposit(poolId, _toInvest); } } function liquidatePosition(uint256 _amountNeeded) internal override returns (uint256 _liquidatedAmount, uint256 _loss) { uint256 _wantBal = balanceOfWant(); if (_amountNeeded > _wantBal) { // check if we have enough free funds to cover the withdrawal uint256 _stakedBal = stakedBalance(); if (_stakedBal > 0) { sorbettiere.withdraw( poolId, Math.min(_stakedBal, _amountNeeded.sub(_wantBal)) ); } 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); } } function prepareReturn(uint256 _debtOutstanding) internal override returns ( uint256 _profit, uint256 _loss, uint256 _debtPayment ) { // harvest our rewards from the staking contract sorbettiere.withdraw(poolId, 0); if (shouldSellSpell) { uint256 spellBalance = spell.balanceOf(address(this)); // sell SPELL if we have any if (spellBalance > 0) { _sellSpell(spellBalance); } } uint256 mimBalance = mim.balanceOf(address(this)); uint256 usdtBalance = usdt.balanceOf(address(this)); uint256 usdcBalance = usdc.balanceOf(address(this)); // deposit our balance to Curve if we have any if (mimBalance > 0 || usdcBalance > 0 || usdtBalance > 0) { curveZapIn.add_liquidity( address(want), [mimBalance, usdcBalance, usdtBalance], 0 ); } // debtOustanding will only be > 0 in the event of revoking or if we need to rebalance from a withdrawal or lowering the debtRatio uint256 stakedBal = stakedBalance(); if (_debtOutstanding > 0) { // don't bother withdrawing if we don't have staked funds if (stakedBal > 0) { sorbettiere.withdraw( poolId, Math.min(stakedBal, _debtOutstanding) ); } 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 uint256 _toLiquidate = _profit.add(_debtPayment); liquidatePosition(_toLiquidate); } } // 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; } function stakedBalance() public view returns (uint256) { return sorbettiere.userInfo(poolId, address(this)).amount; } function pendingRewards() public view returns (uint256) { return sorbettiere.pendingIce(poolId, address(this)); } function balanceOfWant() public view returns (uint256) { return want.balanceOf(address(this)); } function estimatedTotalAssets() public view override returns (uint256) { return balanceOfWant().add(stakedBalance()); } // fire sale, get rid of it all! function liquidateAllPositions() internal override returns (uint256) { uint256 _stakedBal = stakedBalance(); // don't bother withdrawing zero if (_stakedBal > 0) { sorbettiere.withdraw(poolId, _stakedBal); } return balanceOfWant(); } function manualSell(uint256 _amount) external onlyEmergencyAuthorized { _sellSpell(_amount); } // Sells our SPELL for our target token function _sellSpell(uint256 _amount) internal { address[] memory path = new address[](3); path[0] = address(spell); path[1] = address(weth); path[2] = address(targetToken); router.swapExactTokensForTokens( _amount, uint256(0), path, address(this), block.timestamp ); } /* ========== KEEP3RS ========== */ function harvestTrigger(uint256 callCostinEth) public view override returns (bool) { 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; } // trigger if we want to manually harvest if (forceHarvestTriggerOnce) { return true; } // otherwise, we don't harvest return false; } // convert our keeper's eth cost into want, we don't need this anymore since we don't use baseStrategy harvestTrigger function ethToWant(uint256 _ethAmount) public view override returns (uint256) { return _ethAmount; } /* ========== SETTERS ========== */ // These functions are useful for setting parameters of the strategy that may need to be adjusted. // Set optimal token to sell harvested funds for depositing to Curve. // Default is MIM, but can be set to USDC or usdt as needed by strategist or governance. function setOptimal(uint256 _optimal) external onlyEmergencyAuthorized { if (_optimal == 0) { targetToken = address(mim); } else if (_optimal == 1) { targetToken = address(usdc); } else if (_optimal == 2) { targetToken = address(usdt); } else { revert("incorrect token"); } } }
[{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"uint256","name":"_poolId","type":"uint256"},{"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":"delay","type":"uint256"}],"name":"UpdatedMaxReportDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"metadataURI","type":"string"}],"name":"UpdatedMetadataURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"delay","type":"uint256"}],"name":"UpdatedMinReportDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"profitFactor","type":"uint256"}],"name":"UpdatedProfitFactor","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":"curveZapIn","outputs":[{"internalType":"contract ICurveZap","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":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"estimatedTotalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_ethAmount","type":"uint256"}],"name":"ethToWant","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"forceHarvestTriggerOnce","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"callCostinEth","type":"uint256"}],"name":"harvestTrigger","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":"keeper","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"manualSell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxReportDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metadataURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newStrategy","type":"address"}],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minReportDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingRewards","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":"router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","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":"address","name":"_healthCheck","type":"address"}],"name":"setHealthCheck","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":"string","name":"_metadataURI","type":"string"}],"name":"setMetadataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_delay","type":"uint256"}],"name":"setMinReportDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_optimal","type":"uint256"}],"name":"setOptimal","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":"bool","name":"_shouldSellSpell","type":"bool"}],"name":"setShouldSellSpell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategist","type":"address"}],"name":"setStrategist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_withdrawStakedOnMigration","type":"bool"}],"name":"setWithdrawStakedOnMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shouldSellSpell","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"targetToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"callCostInWei","type":"uint256"}],"name":"tendTrigger","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"contract VaultAPI","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":"withdrawStakedOnMigration","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6080604052600b8054741b02da8cb0d097eb8d57a175b88c7d8b4799750600610100600160a81b0319909116179055600c80546001600160a01b031916737544fe3d184b6b55d6b36c3fca1157ee0ba30287179055600d805460ff60b01b1960ff60a81b19909116600160a81b1716600160b01b1790553480156200008357600080fd5b5060405162004dd238038062004dd2833981016040819052620000a69162000a46565b82620000b581338080620004bd565b506202a30060085560018054610100600160a81b0319167432059cce723b4dd15dd5cb2a5187f814e6c470bc0017905560065460405163095ea7b360e01b81526001600160a01b039091169063095ea7b3906200012f9073839de324a1ab773f76a53900d70ac1b913d2b387906000199060040162000bea565b602060405180830381600087803b1580156200014a57600080fd5b505af11580156200015f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000185919062000afa565b50600b5460405163095ea7b360e01b8152733e6648c5a70a150a88bce65f4ad4d506fe15d2af9163095ea7b391620001d39161010090046001600160a01b0316906000199060040162000bea565b602060405180830381600087803b158015620001ee57600080fd5b505af115801562000203573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000229919062000afa565b5080516200023f90600f90602084019062000967565b50604051631526fe2760e01b815260009073839de324a1ab773f76a53900d70ac1b913d2b38790631526fe27906200027c90869060040162000d71565b60a06040518083038186803b1580156200029557600080fd5b505afa158015620002aa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002d0919062000b1c565b516006549091506001600160a01b038083169116146200030d5760405162461bcd60e51b8152600401620003049062000c38565b60405180910390fd5b600e839055600c5460405163095ea7b360e01b815273fea7a6a0b346362bf88a9e4a88416b77a57d6c2a9163095ea7b3916200035a916001600160a01b0316906000199060040162000bea565b602060405180830381600087803b1580156200037557600080fd5b505af11580156200038a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003b0919062000afa565b50600c5460405163095ea7b360e01b815273ff970a61a04b1ca14834a43f5de4533ebddb5cc89163095ea7b391620003f9916001600160a01b0316906000199060040162000bea565b602060405180830381600087803b1580156200041457600080fd5b505af115801562000429573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200044f919062000afa565b50600c546200048c9073fd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9906001600160a01b031660001962000698602090811b620029c817901c565b5050600d80546001600160a01b03191673fea7a6a0b346362bf88a9e4a88416b77a57d6c2a1790555062000dd49050565b6006546001600160a01b031615620004e95760405162461bcd60e51b8152600401620003049062000c5c565b600280546001600160a01b0319166001600160a01b03868116919091179182905560408051637e062a3560e11b81529051929091169163fc0c546a91600480820192602092909190829003018186803b1580156200054657600080fd5b505afa1580156200055b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000581919062000a21565b600680546001600160a01b0319166001600160a01b039283161790819055620005bb91168560001962000698602090811b620029c817901c565b600380546001600160a01b038086166001600160a01b03199283161790925560048054858416908316178082556005805486861694169390931790925560006007819055620151806008556064600955600a5560025460405163095ea7b360e01b81529084169363095ea7b3936200063b93911691600019910162000bea565b602060405180830381600087803b1580156200065657600080fd5b505af11580156200066b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000691919062000afa565b5050505050565b801580620007275750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e90620006d1903090869060040162000bd0565b60206040518083038186803b158015620006ea57600080fd5b505afa158015620006ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000725919062000b99565b155b620007465760405162461bcd60e51b8152600401620003049062000d14565b620007a18363095ea7b360e01b84846040516024016200076892919062000bea565b60408051808303601f190181529190526020810180516001600160e01b0319939093166001600160e01b0393841617905290620007a616565b505050565b606062000802826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200084260201b62002ac7179092919060201c565b805190915015620007a1578080602001905181019062000823919062000afa565b620007a15760405162461bcd60e51b8152600401620003049062000cca565b60606200085384846000856200085b565b949350505050565b606062000868856200092d565b620008875760405162461bcd60e51b8152600401620003049062000c93565b60006060866001600160a01b03168587604051620008a6919062000bb2565b60006040518083038185875af1925050503d8060008114620008e5576040519150601f19603f3d011682016040523d82523d6000602084013e620008ea565b606091505b5091509150811562000900579150620008539050565b805115620009115780518082602001fd5b8360405162461bcd60e51b815260040162000304919062000c03565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159062000853575050151592915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620009aa57805160ff1916838001178555620009da565b82800160010185558215620009da579182015b82811115620009da578251825591602001919060010190620009bd565b50620009e8929150620009ec565b5090565b5b80821115620009e85760008155600101620009ed565b80516001600160a01b038116811462000a1b57600080fd5b92915050565b60006020828403121562000a33578081fd5b62000a3f838362000a03565b9392505050565b60008060006060848603121562000a5b578182fd5b62000a67858562000a03565b6020850151604086015191945092506001600160401b038082111562000a8b578283fd5b818601915086601f83011262000a9f578283fd5b81518181111562000aae578384fd5b62000ac3601f8201601f191660200162000d7a565b915080825287602082850101111562000ada578384fd5b62000aed81602084016020860162000da1565b5080925050509250925092565b60006020828403121562000b0c578081fd5b8151801515811462000a3f578182fd5b600060a0828403121562000b2e578081fd5b62000b3a60a062000d7a565b62000b46848462000a03565b81526020830151602082015260408301516040820152606083015163ffffffff8116811462000b73578283fd5b6060820152608083015161ffff8116811462000b8d578283fd5b60808201529392505050565b60006020828403121562000bab578081fd5b5051919050565b6000825162000bc681846020870162000da1565b9190910192915050565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b600060208252825180602084015262000c2481604085016020870162000da1565b601f01601f19169190910160400192915050565b6020808252600a90820152691ddc9bdb99c81c1bdbdb60b21b604082015260600190565b6020808252601c908201527f537472617465677920616c726561647920696e697469616c697a656400000000604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000606082015260800190565b90815260200190565b6040518181016001600160401b038111828210171562000d9957600080fd5b604052919050565b60005b8381101562000dbe57818101518382015260200162000da4565b8381111562000dce576000848401525b50505050565b613fee8062000de46000396000f3fe608060405234801561001057600080fd5b506004361061030c5760003560e01c8063750521f51161019d578063c1a3d44c116100e9578063ed882c2b116100a2578063f017c92f1161007c578063f017c92f146105ac578063f887ea40146105bf578063fbfa77cf146105c7578063fcf2d0ad146105cf5761030c565b8063ed882c2b14610589578063eded3fda1461059c578063efbb5cb0146105a45761030c565b8063c1a3d44c14610538578063c7383f4614610540578063c7b9d53014610548578063ce5494bb1461055b578063db2e21bc1461056e578063ec38a862146105765761030c565b80639ec5a89411610156578063ac00ff2611610130578063ac00ff261461050d578063aced166114610520578063b252720b14610528578063becfc725146105305761030c565b80639ec5a894146104ea578063a763cf5b146104f2578063a9ee9648146104fa5761030c565b8063750521f514610499578063780022a0146104ac5780638cdfe166146104bf5780638e6350e2146104c757806391397ab4146104cf57806395e80c50146104e25761030c565b80632e1a7d4d1161025c578063520009df116102155780635b9f0016116101ef5780635b9f001614610463578063650d18801461046b5780636718835f1461047e578063748747e6146104865761030c565b8063520009df1461044057806352dcacd0146104535780635641ec031461045b5761030c565b80632e1a7d4d146103ef578063327107f71461040257806339a172a81461040a578063440368a31461041d5780634641257d146104255780634b259e171461042d5761030c565b80631d12f28b116102c957806322f3e2d4116102a357806322f3e2d4146103b757806325829410146103cc57806328b7ccf7146103d45780632d4efa47146103dc5761030c565b80631d12f28b146103855780631f1fcd511461039a5780631fe4a686146103af5761030c565b806301681a621461031157806303ee438c1461032657806306fdde03146103445780630ada4dab1461034c5780630f969b871461035f57806311bc824514610372575b600080fd5b61032461031f366004613890565b6105d7565b005b61032e610776565b60405161033b9190613bd2565b60405180910390f35b61032e610804565b61032461035a36600461395d565b61089a565b61032461036d366004613abd565b610a47565b610324610380366004613890565b610ad4565b61038d610bd5565b60405161033b9190613e30565b6103a2610bdb565b60405161033b9190613b09565b6103a2610bea565b6103bf610bf9565b60405161033b9190613b98565b61032e610c9b565b61038d610cba565b6103246103ea366004613abd565b610cc0565b61038d6103fd366004613abd565b610e5b565b6103a2610eb6565b610324610418366004613abd565b610ec5565b610324610f47565b610324611170565b61032461043b36600461395d565b611649565b61032461044e366004613abd565b6117f6565b6103a2611a35565b6103bf611a44565b61038d611a4d565b6103bf610479366004613abd565b611ae0565b6103bf611ae8565b610324610494366004613890565b611af1565b6103246104a7366004613995565b611b9c565b61038d6104ba366004613abd565b611c33565b61038d611c36565b61038d611c3c565b6103246104dd366004613abd565b611c41565b61038d611cc3565b6103a2611cc9565b6103bf611cd8565b61032461050836600461395d565b611ce8565b61032461051b36600461395d565b611e95565b6103a2611f81565b6103a2611f90565b6103bf611fa4565b61038d611fb4565b6103bf612035565b610324610556366004613890565b612045565b610324610569366004613890565b6120f0565b61032461223b565b610324610584366004613890565b612437565b6103bf610597366004613abd565b6125ca565b61038d6126a6565b61038d6126e3565b6103246105ba366004613abd565b6126fe565b6103a2612780565b6103a2612794565b6103246127a3565b6105df612ade565b6001600160a01b0316336001600160a01b0316146106185760405162461bcd60e51b815260040161060f90613d47565b60405180910390fd5b6006546001600160a01b03828116911614156106465760405162461bcd60e51b815260040161060f90613c2a565b6002546001600160a01b03828116911614156106745760405162461bcd60e51b815260040161060f90613cef565b606061067e612b5b565b905060005b81518110156106d95781818151811061069857fe5b60200260200101516001600160a01b0316836001600160a01b031614156106d15760405162461bcd60e51b815260040161060f90613db6565b600101610683565b506107726106e5612ade565b6040516370a0823160e01b81526001600160a01b038516906370a0823190610711903090600401613b09565b60206040518083038186803b15801561072957600080fd5b505afa15801561073d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107619190613ad5565b6001600160a01b0385169190612b60565b5050565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156107fc5780601f106107d1576101008083540402835291602001916107fc565b820191906000526020600020905b8154815290600101906020018083116107df57829003601f168201915b505050505081565b600f8054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156108905780601f1061086557610100808354040283529160200191610890565b820191906000526020600020905b81548152906001019060200180831161087357829003601f168201915b5050505050905090565b6003546001600160a01b03163314806108cb57506108b6612ade565b6001600160a01b0316336001600160a01b0316145b8061096c5750600260009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b15801561091f57600080fd5b505afa158015610933573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095791906138ac565b6001600160a01b0316336001600160a01b0316145b80610a0d5750600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b1580156109c057600080fd5b505afa1580156109d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f891906138ac565b6001600160a01b0316336001600160a01b0316145b610a295760405162461bcd60e51b815260040161060f90613d47565b600d8054911515600160a01b0260ff60a01b19909216919091179055565b6003546001600160a01b0316331480610a785750610a63612ade565b6001600160a01b0316336001600160a01b0316145b610a945760405162461bcd60e51b815260040161060f90613d47565b600a8190556040517fa68ba126373d04c004c5748c300c9fca12bd444b3d4332e261f3bd2bac4a860090610ac9908390613e30565b60405180910390a150565b600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b158015610b2257600080fd5b505afa158015610b36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b5a91906138ac565b6001600160a01b0316336001600160a01b03161480610b915750610b7c612ade565b6001600160a01b0316336001600160a01b0316145b610bad5760405162461bcd60e51b815260040161060f90613d47565b600180546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600a5481565b6006546001600160a01b031681565b6003546001600160a01b031681565b6002546040516339ebf82360e01b815260009182916001600160a01b03909116906339ebf82390610c2e903090600401613b09565b6101206040518083038186803b158015610c4757600080fd5b505afa158015610c5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7f9190613a02565b604001511180610c9657506000610c946126e3565b115b905090565b604080518082019091526005815264302e342e3360d81b602082015290565b60085481565b6003546001600160a01b0316331480610cf15750610cdc612ade565b6001600160a01b0316336001600160a01b0316145b80610d925750600260009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b158015610d4557600080fd5b505afa158015610d59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7d91906138ac565b6001600160a01b0316336001600160a01b0316145b80610e335750600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b158015610de657600080fd5b505afa158015610dfa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1e91906138ac565b6001600160a01b0316336001600160a01b0316145b610e4f5760405162461bcd60e51b815260040161060f90613d47565b610e5881612b7f565b50565b6002546000906001600160a01b03163314610e885760405162461bcd60e51b815260040161060f90613ccf565b6000610e9383612cd3565b600654909350909150610eb0906001600160a01b03163383612b60565b50919050565b600d546001600160a01b031681565b6003546001600160a01b0316331480610ef65750610ee1612ade565b6001600160a01b0316336001600160a01b0316145b610f125760405162461bcd60e51b815260040161060f90613d47565b60078190556040517fbb2c369a0355a34b02ab5fce0643150c87e1c8dfe7c918d465591879f57948b190610ac9908390613e30565b6005546001600160a01b0316331480610f6a57506003546001600160a01b031633145b80610f8d5750610f78612ade565b6001600160a01b0316336001600160a01b0316145b8061102e5750600260009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b158015610fe157600080fd5b505afa158015610ff5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101991906138ac565b6001600160a01b0316336001600160a01b0316145b806110cf5750600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b15801561108257600080fd5b505afa158015611096573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ba91906138ac565b6001600160a01b0316336001600160a01b0316145b6110eb5760405162461bcd60e51b815260040161060f90613d47565b6002546040805163bf3759b560e01b8152905161116e926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b15801561113157600080fd5b505afa158015611145573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111699190613ad5565b612dbd565b565b6005546001600160a01b031633148061119357506003546001600160a01b031633145b806111b657506111a1612ade565b6001600160a01b0316336001600160a01b0316145b806112575750600260009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b15801561120a57600080fd5b505afa15801561121e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061124291906138ac565b6001600160a01b0316336001600160a01b0316145b806112f85750600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b1580156112ab57600080fd5b505afa1580156112bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e391906138ac565b6001600160a01b0316336001600160a01b0316145b6113145760405162461bcd60e51b815260040161060f90613d47565b6000806000600260009054906101000a90046001600160a01b03166001600160a01b031663bf3759b56040518163ffffffff1660e01b815260040160206040518083038186803b15801561136757600080fd5b505afa15801561137b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139f9190613ad5565b600b5490915060009060ff16156113fc5760006113ba612e50565b9050828110156113d5576113ce8382612edf565b93506113ea565b828111156113ea576113e78184612edf565b94505b6113f48385612edf565b91505061140d565b61140582612f28565b919550935090505b6002546040516339ebf82360e01b81526000916001600160a01b0316906339ebf8239061143e903090600401613b09565b6101206040518083038186803b15801561145757600080fd5b505afa15801561146b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148f9190613a02565b60c001516002546040516328766ebf60e21b81529192506001600160a01b03169063a1d9bafc906114c890889088908790600401613ece565b602060405180830381600087803b1580156114e257600080fd5b505af11580156114f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151a9190613ad5565b925061152583612dbd565b60015460ff168015611546575060015461010090046001600160a01b031615155b156115f85760015460405163c70fa00b60e01b81526101009091046001600160a01b03169063c70fa00b906115879088908890879089908890600401613eff565b60206040518083038186803b15801561159f57600080fd5b505afa1580156115b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d79190613979565b6115f35760405162461bcd60e51b815260040161060f90613c80565b611605565b6001805460ff1916811790555b7f4c0f499ffe6befa0ca7c826b0916cf87bea98de658013e76938489368d60d5098585848660405161163a9493929190613ee4565b60405180910390a15050505050565b6003546001600160a01b031633148061167a5750611665612ade565b6001600160a01b0316336001600160a01b0316145b8061171b5750600260009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b1580156116ce57600080fd5b505afa1580156116e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061170691906138ac565b6001600160a01b0316336001600160a01b0316145b806117bc5750600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b15801561176f57600080fd5b505afa158015611783573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117a791906138ac565b6001600160a01b0316336001600160a01b0316145b6117d85760405162461bcd60e51b815260040161060f90613d47565b600d8054911515600160b01b0260ff60b01b19909216919091179055565b6003546001600160a01b03163314806118275750611812612ade565b6001600160a01b0316336001600160a01b0316145b806118c85750600260009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b15801561187b57600080fd5b505afa15801561188f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b391906138ac565b6001600160a01b0316336001600160a01b0316145b806119695750600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b15801561191c57600080fd5b505afa158015611930573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061195491906138ac565b6001600160a01b0316336001600160a01b0316145b6119855760405162461bcd60e51b815260040161060f90613d47565b806119b557600d80546001600160a01b03191673fea7a6a0b346362bf88a9e4a88416b77a57d6c2a179055610e58565b80600114156119e957600d80546001600160a01b03191673ff970a61a04b1ca14834a43f5de4533ebddb5cc8179055610e58565b8060021415611a1d57600d80546001600160a01b03191673fd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9179055610e58565b60405162461bcd60e51b815260040161060f90613ca6565b600c546001600160a01b031681565b600b5460ff1681565b600e546040516393f1a40b60e01b815260009173839de324a1ab773f76a53900d70ac1b913d2b387916393f1a40b91611a8a913090600401613e39565b60606040518083038186803b158015611aa257600080fd5b505afa158015611ab6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ada9190613a80565b51905090565b60005b919050565b60015460ff1681565b6003546001600160a01b0316331480611b225750611b0d612ade565b6001600160a01b0316336001600160a01b0316145b611b3e5760405162461bcd60e51b815260040161060f90613d47565b6001600160a01b038116611b5157600080fd5b600580546001600160a01b0319166001600160a01b0383161790556040517f2f202ddb4a2e345f6323ed90f8fc8559d770a7abbbeee84dde8aca3351fe715490610ac9908390613b09565b6003546001600160a01b0316331480611bcd5750611bb8612ade565b6001600160a01b0316336001600160a01b0316145b611be95760405162461bcd60e51b815260040161060f90613d47565b611bf5600083836137b1565b507f300e67d5a415b6d015a471d9c7b95dd58f3e8290af965e84e0f845de2996dda68282604051611c27929190613ba3565b60405180910390a15050565b90565b60095481565b600090565b6003546001600160a01b0316331480611c725750611c5d612ade565b6001600160a01b0316336001600160a01b0316145b611c8e5760405162461bcd60e51b815260040161060f90613d47565b60098190556040517fd94596337df4c2f0f44d30a7fc5db1c7bb60d9aca4185ed77c6fd96eb45ec29890610ac9908390613e30565b60075481565b6004546001600160a01b031681565b600d54600160a01b900460ff1681565b6003546001600160a01b0316331480611d195750611d04612ade565b6001600160a01b0316336001600160a01b0316145b80611dba5750600260009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b158015611d6d57600080fd5b505afa158015611d81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da591906138ac565b6001600160a01b0316336001600160a01b0316145b80611e5b5750600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b158015611e0e57600080fd5b505afa158015611e22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4691906138ac565b6001600160a01b0316336001600160a01b0316145b611e775760405162461bcd60e51b815260040161060f90613d47565b600d8054911515600160a81b0260ff60a81b19909216919091179055565b600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b158015611ee357600080fd5b505afa158015611ef7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f1b91906138ac565b6001600160a01b0316336001600160a01b03161480611f525750611f3d612ade565b6001600160a01b0316336001600160a01b0316145b611f6e5760405162461bcd60e51b815260040161060f90613d47565b6001805460ff1916911515919091179055565b6005546001600160a01b031681565b60015461010090046001600160a01b031681565b600d54600160b01b900460ff1681565b6006546040516370a0823160e01b81526000916001600160a01b0316906370a0823190611fe5903090600401613b09565b60206040518083038186803b158015611ffd57600080fd5b505afa158015612011573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c969190613ad5565b600d54600160a81b900460ff1681565b6003546001600160a01b03163314806120765750612061612ade565b6001600160a01b0316336001600160a01b0316145b6120925760405162461bcd60e51b815260040161060f90613d47565b6001600160a01b0381166120a557600080fd5b600380546001600160a01b0319166001600160a01b0383161790556040517f352ececae6d7d1e6d26bcf2c549dfd55be1637e9b22dc0cf3b71ddb36097a6b490610ac9908390613b09565b6002546001600160a01b0316331461210757600080fd5b6002546040805163fbfa77cf60e01b815290516001600160a01b039283169284169163fbfa77cf916004808301926020929190829003018186803b15801561214e57600080fd5b505afa158015612162573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061218691906138ac565b6001600160a01b03161461219957600080fd5b6121a281613479565b6006546040516370a0823160e01b8152610e589183916001600160a01b03909116906370a08231906121d8903090600401613b09565b60206040518083038186803b1580156121f057600080fd5b505afa158015612204573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122289190613ad5565b6006546001600160a01b03169190612b60565b6003546001600160a01b031633148061226c5750612257612ade565b6001600160a01b0316336001600160a01b0316145b8061230d5750600260009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b1580156122c057600080fd5b505afa1580156122d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122f891906138ac565b6001600160a01b0316336001600160a01b0316145b806123ae5750600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b15801561236157600080fd5b505afa158015612375573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239991906138ac565b6001600160a01b0316336001600160a01b0316145b6123ca5760405162461bcd60e51b815260040161060f90613d47565b600e54604051632989754760e11b815273839de324a1ab773f76a53900d70ac1b913d2b38791635312ea8e916124039190600401613e30565b600060405180830381600087803b15801561241d57600080fd5b505af1158015612431573d6000803e3d6000fd5b50505050565b6003546001600160a01b031633146124615760405162461bcd60e51b815260040161060f90613c05565b6001600160a01b03811661247457600080fd5b6002546004805460405163095ea7b360e01b81526001600160a01b039384169363095ea7b3936124ab939091169160009101613b7f565b602060405180830381600087803b1580156124c557600080fd5b505af11580156124d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124fd9190613979565b50600480546001600160a01b0319166001600160a01b038381169190911780835560025460405163095ea7b360e01b81529083169363095ea7b3936125489316916000199101613b7f565b602060405180830381600087803b15801561256257600080fd5b505af1158015612576573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259a9190613979565b507fafbb66abf8f3b719799940473a4052a3717cdd8e40fb6c8a3faadab316b1a06981604051610ac99190613b09565b60006125d461382f565b6002546040516339ebf82360e01b81526001600160a01b03909116906339ebf82390612604903090600401613b09565b6101206040518083038186803b15801561261d57600080fd5b505afa158015612631573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126559190613a02565b90506008546126718260a0015142612edf90919063ffffffff16565b1115612681576001915050611ae3565b600d54600160a01b900460ff161561269d576001915050611ae3565b50600092915050565b600e54604051637a668d8160e11b815260009173839de324a1ab773f76a53900d70ac1b913d2b3879163f4cd1b0291611fe5913090600401613e39565b6000610c966126f0611a4d565b6126f8611fb4565b906135be565b6003546001600160a01b031633148061272f575061271a612ade565b6001600160a01b0316336001600160a01b0316145b61274b5760405162461bcd60e51b815260040161060f90613d47565b60088190556040517f5430e11864ad7aa9775b07d12657fe52df9aa2ba734355bd8ef8747be2c800c590610ac9908390613e30565b600b5461010090046001600160a01b031681565b6002546001600160a01b031681565b6003546001600160a01b03163314806127d457506127bf612ade565b6001600160a01b0316336001600160a01b0316145b806128755750600260009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b15801561282857600080fd5b505afa15801561283c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061286091906138ac565b6001600160a01b0316336001600160a01b0316145b806129165750600260009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b1580156128c957600080fd5b505afa1580156128dd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290191906138ac565b6001600160a01b0316336001600160a01b0316145b6129325760405162461bcd60e51b815260040161060f90613d47565b600b805460ff191660011790556002546040805163507257cd60e11b815290516001600160a01b039092169163a0e4af9a9160048082019260009290919082900301818387803b15801561298557600080fd5b505af1158015612999573d6000803e3d6000fd5b50506040517f97e963041e952738788b9d4871d854d282065b8f90a464928d6528f2e9a4fd0b925060009150a1565b801580612a505750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e906129fe9030908690600401613b1d565b60206040518083038186803b158015612a1657600080fd5b505afa158015612a2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a4e9190613ad5565b155b612a6c5760405162461bcd60e51b815260040161060f90613dda565b612ac28363095ea7b360e01b8484604051602401612a8b929190613b7f565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526135e3565b505050565b6060612ad68484600085613672565b949350505050565b60025460408051635aa6e67560e01b815290516000926001600160a01b031691635aa6e675916004808301926020929190829003018186803b158015612b2357600080fd5b505afa158015612b37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9691906138ac565b606090565b612ac28363a9059cbb60e01b8484604051602401612a8b929190613b7f565b60408051600380825260808201909252606091602082018380368337019050509050733e6648c5a70a150a88bce65f4ad4d506fe15d2af81600081518110612bc357fe5b60200260200101906001600160a01b031690816001600160a01b0316815250507382af49447d8a07e3bd95bd0d56f35241523fbab181600181518110612c0557fe5b6001600160a01b039283166020918202929092010152600d54825191169082906002908110612c3057fe5b6001600160a01b039283166020918202929092010152600b546040516338ed173960e01b8152610100909104909116906338ed173990612c7d908590600090869030904290600401613e5e565b600060405180830381600087803b158015612c9757600080fd5b505af1158015612cab573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612ac291908101906138c8565b6000806000612ce0611fb4565b905080841115612da9576000612cf4611a4d565b90508015612d7e57600e5473839de324a1ab773f76a53900d70ac1b913d2b3879063441a3e7090612d2e84612d298a88612edf565b613736565b6040518363ffffffff1660e01b8152600401612d4b929190613e50565b600060405180830381600087803b158015612d6557600080fd5b505af1158015612d79573d6000803e3d6000fd5b505050505b6000612d88611fb4565b9050612d948682613736565b9450612da08686612edf565b93505050612db6565b8360009250925050612db8565b505b915091565b600b5460ff1615612dcd57610e58565b6000612dd7611fb4565b9050801561077257600e54604051631c57762b60e31b815273839de324a1ab773f76a53900d70ac1b913d2b3879163e2bbb15891612e1a91908590600401613e50565b600060405180830381600087803b158015612e3457600080fd5b505af1158015612e48573d6000803e3d6000fd5b505050505050565b600080612e5b611a4d565b90508015612ed157600e54604051630441a3e760e41b815273839de324a1ab773f76a53900d70ac1b913d2b3879163441a3e7091612e9e91908590600401613e50565b600060405180830381600087803b158015612eb857600080fd5b505af1158015612ecc573d6000803e3d6000fd5b505050505b612ed9611fb4565b91505090565b6000612f2183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061374c565b9392505050565b600e54604051630441a3e760e41b81526000918291829173839de324a1ab773f76a53900d70ac1b913d2b3879163441a3e7091612f69918590600401613e50565b600060405180830381600087803b158015612f8357600080fd5b505af1158015612f97573d6000803e3d6000fd5b5050600d54600160b01b900460ff1615915061304c9050576040516370a0823160e01b8152600090733e6648c5a70a150a88bce65f4ad4d506fe15d2af906370a0823190612fe9903090600401613b09565b60206040518083038186803b15801561300157600080fd5b505afa158015613015573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130399190613ad5565b9050801561304a5761304a81612b7f565b505b6040516370a0823160e01b815260009073fea7a6a0b346362bf88a9e4a88416b77a57d6c2a906370a0823190613086903090600401613b09565b60206040518083038186803b15801561309e57600080fd5b505afa1580156130b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130d69190613ad5565b6040516370a0823160e01b815290915060009073fd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9906370a0823190613113903090600401613b09565b60206040518083038186803b15801561312b57600080fd5b505afa15801561313f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131639190613ad5565b6040516370a0823160e01b815290915060009073ff970a61a04b1ca14834a43f5de4533ebddb5cc8906370a08231906131a0903090600401613b09565b60206040518083038186803b1580156131b857600080fd5b505afa1580156131cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131f09190613ad5565b905060008311806132015750600081115b8061320c5750600082115b156132b557600c546006546040805160608101825286815260208101859052808201869052905163a318517960e01b81526001600160a01b039384169363a31851799361326193911691600090600401613b37565b602060405180830381600087803b15801561327b57600080fd5b505af115801561328f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132b39190613ad5565b505b60006132bf611a4d565b9050871561336757801561334d5773839de324a1ab773f76a53900d70ac1b913d2b3876001600160a01b031663441a3e70600e546132fd848c613736565b6040518363ffffffff1660e01b815260040161331a929190613e50565b600060405180830381600087803b15801561333457600080fd5b505af1158015613348573d6000803e3d6000fd5b505050505b6000613357611fb4565b90506133638982613736565b9550505b60006133716126e3565b6002546040516339ebf82360e01b81529192506000916001600160a01b03909116906339ebf823906133a7903090600401613b09565b6101206040518083038186803b1580156133c057600080fd5b505afa1580156133d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133f89190613a02565b60c00151905080821115613450576134108282612edf565b9850600061341c611fb4565b9050806134298b8a6135be565b111561344a57600061343b8b8a6135be565b905061344681612cd3565b5050505b5061345d565b61345a8183612edf565b97505b5050600d805460ff60a01b191690555094969395509193505050565b600d54600160a81b900460ff161561350d576000613495611a4d565b9050801561350b57600e54604051630441a3e760e41b815273839de324a1ab773f76a53900d70ac1b913d2b3879163441a3e70916134d891908590600401613e50565b600060405180830381600087803b1580156134f257600080fd5b505af1158015613506573d6000803e3d6000fd5b505050505b505b6040516370a0823160e01b8152600090733e6648c5a70a150a88bce65f4ad4d506fe15d2af906370a0823190613547903090600401613b09565b60206040518083038186803b15801561355f57600080fd5b505afa158015613573573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135979190613ad5565b9050801561077257610772733e6648c5a70a150a88bce65f4ad4d506fe15d2af8383612b60565b600082820183811015612f215760405162461bcd60e51b815260040161060f90613c49565b6060613638826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612ac79092919063ffffffff16565b805190915015612ac257808060200190518101906136569190613979565b612ac25760405162461bcd60e51b815260040161060f90613d6c565b606061367d85613778565b6136995760405162461bcd60e51b815260040161060f90613d10565b60006060866001600160a01b031685876040516136b69190613aed565b60006040518083038185875af1925050503d80600081146136f3576040519150601f19603f3d011682016040523d82523d6000602084013e6136f8565b606091505b5091509150811561370c579150612ad69050565b80511561371c5780518082602001fd5b8360405162461bcd60e51b815260040161060f9190613bd2565b60008183106137455781612f21565b5090919050565b600081848411156137705760405162461bcd60e51b815260040161060f9190613bd2565b505050900390565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612ad6575050151592915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106137f25782800160ff1982351617855561381f565b8280016001018555821561381f579182015b8281111561381f578235825591602001919060010190613804565b5061382b92915061387b565b5090565b6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b8082111561382b576000815560010161387c565b6000602082840312156138a1578081fd5b8135612f2181613f95565b6000602082840312156138bd578081fd5b8151612f2181613f95565b600060208083850312156138da578182fd5b825167ffffffffffffffff8111156138f0578283fd5b8301601f81018513613900578283fd5b805161391361390e82613f49565b613f22565b818152838101908385018584028501860189101561392f578687fd5b8694505b83851015613951578051835260019490940193918501918501613933565b50979650505050505050565b60006020828403121561396e578081fd5b8135612f2181613faa565b60006020828403121561398a578081fd5b8151612f2181613faa565b600080602083850312156139a7578081fd5b823567ffffffffffffffff808211156139be578283fd5b818501915085601f8301126139d1578283fd5b8135818111156139df578384fd5b8660208285010111156139f0578384fd5b60209290920196919550909350505050565b6000610120808385031215613a15578182fd5b613a1e81613f22565b9050825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152508091505092915050565b600060608284031215613a91578081fd5b613a9b6060613f22565b8251815260208301516020820152604083015160408201528091505092915050565b600060208284031215613ace578081fd5b5035919050565b600060208284031215613ae6578081fd5b5051919050565b60008251613aff818460208701613f69565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b038416815260a0810160208083018560005b6003811015613b6d57815183529183019190830190600101613b50565b50505050826080830152949350505050565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b60006020825282602083015282846040840137818301604090810191909152601f909201601f19160101919050565b6000602082528251806020840152613bf1816040850160208701613f69565b601f01601f19169190910160400192915050565b6020808252600b908201526a085cdd1c985d1959da5cdd60aa1b604082015260600190565b602080825260059082015264085dd85b9d60da1b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252600c908201526b216865616c7468636865636b60a01b604082015260600190565b6020808252600f908201526e34b731b7b93932b1ba103a37b5b2b760891b604082015260600190565b602080825260069082015265085d985d5b1d60d21b604082015260600190565b6020808252600790820152662173686172657360c81b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252600b908201526a08585d5d1a1bdc9a5e995960aa1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600a9082015269085c1c9bdd1958dd195960b21b604082015260600190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b90815260200190565b9182526001600160a01b0316602082015260400190565b918252602082015260400190565b600060a082018783526020878185015260a0604085015281875180845260c0860191508289019350845b81811015613ead5784516001600160a01b031683529383019391830191600101613e88565b50506001600160a01b03969096166060850152505050608001529392505050565b9283526020830191909152604082015260600190565b93845260208401929092526040830152606082015260800190565b948552602085019390935260408401919091526060830152608082015260a00190565b60405181810167ffffffffffffffff81118282101715613f4157600080fd5b604052919050565b600067ffffffffffffffff821115613f5f578081fd5b5060209081020190565b60005b83811015613f84578181015183820152602001613f6c565b838111156124315750506000910152565b6001600160a01b0381168114610e5857600080fd5b8015158114610e5857600080fdfea2646970667358221220636f5de58e8f0875091cbba80f73036d06eaf64244e692f65f77a3ac57ffedd164736f6c634300060c00330000000000000000000000001dba7641dc69188d6086a73b972ac4bda29ec35d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000018537472617465677943757276655374616b65725370656c6c0000000000000000
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001dba7641dc69188d6086a73b972ac4bda29ec35d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000018537472617465677943757276655374616b65725370656c6c0000000000000000
-----Decoded View---------------
Arg [0] : _vault (address): 0x1dba7641dc69188d6086a73b972ac4bda29ec35d
Arg [1] : _poolId (uint256): 0
Arg [2] : _name (string): StrategyCurveStakerSpell
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000001dba7641dc69188d6086a73b972ac4bda29ec35d
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000018
Arg [4] : 537472617465677943757276655374616b65725370656c6c0000000000000000
Deployed ByteCode Sourcemap
68668:11731:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61792:444;;;;;;:::i;:::-;;:::i;:::-;;33021:25;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71729:98;;;:::i;73058:192::-;;;;;;:::i;:::-;;:::i;43394:175::-;;;;;;:::i;:::-;;:::i;38962:118::-;;;;;;:::i;:::-;;:::i;36300:28::-;;;:::i;:::-;;;;;;;:::i;35048:18::-;;;:::i;:::-;;;;;;;:::i;34957:25::-;;;:::i;46796:148::-;;;:::i;:::-;;;;;;;:::i;33420:91::-;;;:::i;35936:29::-;;;:::i;78232:108::-;;;;;;:::i;:::-;;:::i;58196:515::-;;;;;;:::i;:::-;;:::i;69917:26::-;;;:::i;41443:154::-;;;;;;:::i;:::-;;:::i;51893:170::-;;;:::i;56372:1580::-;;;:::i;73258:160::-;;;;;;:::i;:::-;;:::i;80019:377::-;;;;;;:::i;:::-;;:::i;69816:92::-;;;:::i;36379:25::-;;;:::i;77355:131::-;;;:::i;51132:432::-;;;;;;:::i;:::-;;:::i;33077:25::-;;;:::i;40200:174::-;;;;;;:::i;:::-;;:::i;43872:171::-;;;;;;:::i;:::-;;:::i;79540:155::-;;;;;;:::i;:::-;;:::i;36122:27::-;;;:::i;34827:94::-;;;:::i;42668:169::-;;;;;;:::i;:::-;;:::i;35785:29::-;;;:::i;34989:22::-;;;:::i;70005:35::-;;;:::i;72850:200::-;;;;;;:::i;:::-;;:::i;39088:123::-;;;;;;:::i;:::-;;:::i;35018:21::-;;;:::i;33109:26::-;;;:::i;70256:34::-;;;:::i;77629:110::-;;;:::i;70137:44::-;;;:::i;39444:202::-;;;;;;:::i;:::-;;:::i;59483:281::-;;;;;;:::i;:::-;;:::i;72058:118::-;;;:::i;40663:263::-;;;;;;:::i;:::-;;:::i;78836:573::-;;;;;;:::i;:::-;;:::i;77494:127::-;;;:::i;77747:133::-;;;:::i;42114:154::-;;;;;;:::i;:::-;;:::i;69687:106::-;;;:::i;34929:21::-;;;:::i;60193:173::-;;;:::i;61792:444::-;37005:12;:10;:12::i;:::-;-1:-1:-1;;;;;36991:26:0;:10;-1:-1:-1;;;;;36991:26:0;;36983:50;;;;-1:-1:-1;;;36983:50:0;;;;;;;:::i;:::-;;;;;;;;;61884:4:::1;::::0;-1:-1:-1;;;;;61866:23:0;;::::1;61884:4:::0;::::1;61866:23;;61858:41;;;;-1:-1:-1::0;;;61858:41:0::1;;;;;;;:::i;:::-;61936:5;::::0;-1:-1:-1;;;;;61918:24:0;;::::1;61936:5:::0;::::1;61918:24;;61910:44;;;;-1:-1:-1::0;;;61910:44:0::1;;;;;;;:::i;:::-;61967:33;62003:17;:15;:17::i;:::-;61967:53;;62036:9;62031:102;62051:16;:23;62047:1;:27;62031:102;;;62099:16;62116:1;62099:19;;;;;;;;;;;;;;-1:-1:-1::0;;;;;62089:29:0::1;:6;-1:-1:-1::0;;;;;62089:29:0::1;;;62081:52;;;;-1:-1:-1::0;;;62081:52:0::1;;;;;;;:::i;:::-;62076:3;;62031:102;;;;62146:82;62174:12;:10;:12::i;:::-;62188:39;::::0;-1:-1:-1;;;62188:39:0;;-1:-1:-1;;;;;62188:24:0;::::1;::::0;::::1;::::0;:39:::1;::::0;62221:4:::1;::::0;62188:39:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;62146:27:0;::::1;::::0;:82;:27:::1;:82::i;:::-;37044:1;61792:444:::0;:::o;33021:25::-;;;;;;;;;;;;;;;-1:-1:-1;;33021:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;71729:98::-;71810:9;71803:16;;;;;;;;-1:-1:-1;;71803:16:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71777:13;;71803:16;;71810:9;;71803:16;;71810:9;71803:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71729:98;:::o;73058:192::-;36656:10;;-1:-1:-1;;;;;36656:10:0;36642;:24;;:54;;;36684:12;:10;:12::i;:::-;-1:-1:-1;;;;;36670:26:0;:10;-1:-1:-1;;;;;36670:26:0;;36642:54;:88;;;;36714:5;;;;;;;;;-1:-1:-1;;;;;36714:5:0;-1:-1:-1;;;;;36714:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36700:30:0;:10;-1:-1:-1;;;;;36700:30:0;;36642:88;:124;;;;36748:5;;;;;;;;;-1:-1:-1;;;;;36748:5:0;-1:-1:-1;;;;;36748:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36734:32:0;:10;-1:-1:-1;;;;;36734:32:0;;36642:124;36620:185;;;;-1:-1:-1;;;36620:185:0;;;;;;;:::i;:::-;73192:23:::1;:50:::0;;;::::1;;-1:-1:-1::0;;;73192:50:0::1;-1:-1:-1::0;;;;73192:50:0;;::::1;::::0;;;::::1;::::0;;73058:192::o;43394:175::-;36490:10;;-1:-1:-1;;;;;36490:10:0;36476;:24;;:54;;;36518:12;:10;:12::i;:::-;-1:-1:-1;;;;;36504:26:0;:10;-1:-1:-1;;;;;36504:26:0;;36476:54;36468:78;;;;-1:-1:-1;;;36468:78:0;;;;;;;:::i;:::-;43479:13:::1;:30:::0;;;43525:36:::1;::::0;::::1;::::0;::::1;::::0;43495:14;;43525:36:::1;:::i;:::-;;;;;;;;43394:175:::0;:::o;38962:118::-;37462:5;;;;;;;;;-1:-1:-1;;;;;37462:5:0;-1:-1:-1;;;;;37462:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;37448:32:0;:10;-1:-1:-1;;;;;37448:32:0;;:62;;;;37498:12;:10;:12::i;:::-;-1:-1:-1;;;;;37484:26:0;:10;-1:-1:-1;;;;;37484:26:0;;37448:62;37440:86;;;;-1:-1:-1;;;37440:86:0;;;;;;;:::i;:::-;39046:11:::1;:26:::0;;-1:-1:-1;;;;;39046:26:0;;::::1;;;-1:-1:-1::0;;;;;;39046:26:0;;::::1;::::0;;;::::1;::::0;;38962:118::o;36300:28::-;;;;:::o;35048:18::-;;;-1:-1:-1;;;;;35048:18:0;;:::o;34957:25::-;;;-1:-1:-1;;;;;34957:25:0;;:::o;46796:148::-;46861:5;;:31;;-1:-1:-1;;;46861:31:0;;46837:4;;;;-1:-1:-1;;;;;46861:5:0;;;;:16;;:31;;46886:4;;46861:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;:45;:75;;;;46935:1;46910:22;:20;:22::i;:::-;:26;46861:75;46854:82;;46796:148;:::o;33420:91::-;33489:14;;;;;;;;;;;;-1:-1:-1;;;33489:14:0;;;;33420:91;:::o;35936:29::-;;;;:::o;78232:108::-;36656:10;;-1:-1:-1;;;;;36656:10:0;36642;:24;;:54;;;36684:12;:10;:12::i;:::-;-1:-1:-1;;;;;36670:26:0;:10;-1:-1:-1;;;;;36670:26:0;;36642:54;:88;;;;36714:5;;;;;;;;;-1:-1:-1;;;;;36714:5:0;-1:-1:-1;;;;;36714:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36700:30:0;:10;-1:-1:-1;;;;;36700:30:0;;36642:88;:124;;;;36748:5;;;;;;;;;-1:-1:-1;;;;;36748:5:0;-1:-1:-1;;;;;36748:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36734:32:0;:10;-1:-1:-1;;;;;36734:32:0;;36642:124;36620:185;;;;-1:-1:-1;;;36620:185:0;;;;;;;:::i;:::-;78313:19:::1;78324:7;78313:10;:19::i;:::-;78232:108:::0;:::o;58196:515::-;58311:5;;58255:13;;-1:-1:-1;;;;;58311:5:0;58289:10;:28;58281:47;;;;-1:-1:-1;;;58281:47:0;;;;;;;:::i;:::-;58414:19;58467:32;58485:13;58467:17;:32::i;:::-;58591:4;;58444:55;;-1:-1:-1;58444:55:0;;-1:-1:-1;58591:42:0;;-1:-1:-1;;;;;58591:4:0;58609:10;58444:55;58591:17;:42::i;:::-;58196:515;;;;:::o;69917:26::-;;;-1:-1:-1;;;;;69917:26:0;;:::o;41443:154::-;36490:10;;-1:-1:-1;;;;;36490:10:0;36476;:24;;:54;;;36518:12;:10;:12::i;:::-;-1:-1:-1;;;;;36504:26:0;:10;-1:-1:-1;;;;;36504:26:0;;36476:54;36468:78;;;;-1:-1:-1;;;36468:78:0;;;;;;;:::i;:::-;41521:14:::1;:23:::0;;;41560:29:::1;::::0;::::1;::::0;::::1;::::0;41538:6;;41560:29:::1;:::i;51893:170::-:0;37131:6;;-1:-1:-1;;;;;37131:6:0;37117:10;:20;;:65;;-1:-1:-1;37172:10:0;;-1:-1:-1;;;;;37172:10:0;37158;:24;37117:65;:112;;;;37217:12;:10;:12::i;:::-;-1:-1:-1;;;;;37203:26:0;:10;-1:-1:-1;;;;;37203:26:0;;37117:112;:163;;;;37264:5;;;;;;;;;-1:-1:-1;;;;;37264:5:0;-1:-1:-1;;;;;37264:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;37250:30:0;:10;-1:-1:-1;;;;;37250:30:0;;37117:163;:216;;;;37315:5;;;;;;;;;-1:-1:-1;;;;;37315:5:0;-1:-1:-1;;;;;37315:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;37301:32:0;:10;-1:-1:-1;;;;;37301:32:0;;37117:216;37095:277;;;;-1:-1:-1;;;37095:277:0;;;;;;;:::i;:::-;52031:5:::1;::::0;:23:::1;::::0;;-1:-1:-1;;;52031:23:0;;;;52016:39:::1;::::0;-1:-1:-1;;;;;52031:5:0::1;::::0;:21:::1;::::0;:23:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:5;:23;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52016:14;:39::i;:::-;51893:170::o:0;56372:1580::-;37131:6;;-1:-1:-1;;;;;37131:6:0;37117:10;:20;;:65;;-1:-1:-1;37172:10:0;;-1:-1:-1;;;;;37172:10:0;37158;:24;37117:65;:112;;;;37217:12;:10;:12::i;:::-;-1:-1:-1;;;;;37203:26:0;:10;-1:-1:-1;;;;;37203:26:0;;37117:112;:163;;;;37264:5;;;;;;;;;-1:-1:-1;;;;;37264:5:0;-1:-1:-1;;;;;37264:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;37250:30:0;:10;-1:-1:-1;;;;;37250:30:0;;37117:163;:216;;;;37315:5;;;;;;;;;-1:-1:-1;;;;;37315:5:0;-1:-1:-1;;;;;37315:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;37301:32:0;:10;-1:-1:-1;;;;;37301:32:0;;37117:216;37095:277;;;;-1:-1:-1;;;37095:277:0;;;;;;;:::i;:::-;56423:14:::1;56452:12:::0;56479:23:::1;56505:5;;;;;;;;;-1:-1:-1::0;;;;;56505:5:0::1;-1:-1:-1::0;;;;;56505:21:0::1;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56577:13;::::0;56479:49;;-1:-1:-1;56539:19:0::1;::::0;56577:13:::1;;56573:580;;;56659:19;56681:23;:21;:23::i;:::-;56659:45;;56737:15;56723:11;:29;56719:226;;;56780:32;:15:::0;56800:11;56780:19:::1;:32::i;:::-;56773:39;;56719:226;;;56852:15;56838:11;:29;56834:111;;;56897:32;:11:::0;56913:15;56897::::1;:32::i;:::-;56888:41;;56834:111;56973:25;:15:::0;56993:4;56973:19:::1;:25::i;:::-;56959:39;;56573:580;;;;57111:30;57125:15;57111:13;:30::i;:::-;57081:60:::0;;-1:-1:-1;57081:60:0;-1:-1:-1;57081:60:0;-1:-1:-1;56573:580:0::1;57369:5;::::0;:31:::1;::::0;-1:-1:-1;;;57369:31:0;;57349:17:::1;::::0;-1:-1:-1;;;;;57369:5:0::1;::::0;:16:::1;::::0;:31:::1;::::0;57394:4:::1;::::0;57369:31:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;::::0;57439:5:::1;::::0;:39:::1;::::0;-1:-1:-1;;;57439:39:0;;57369:41;;-1:-1:-1;;;;;;57439:5:0::1;::::0;:12:::1;::::0;:39:::1;::::0;57452:6;;57460:4;;57466:11;;57439:39:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57421:57;;57554:31;57569:15;57554:14;:31::i;:::-;57640:13;::::0;::::1;;:42:::0;::::1;;;-1:-1:-1::0;57657:11:0::1;::::0;::::1;::::0;::::1;-1:-1:-1::0;;;;;57657:11:0::1;:25:::0;::::1;57640:42;57636:238;;;57719:11;::::0;57707:85:::1;::::0;-1:-1:-1;;;57707:85:0;;57719:11:::1;::::0;;::::1;-1:-1:-1::0;;;;;57719:11:0::1;::::0;57707:30:::1;::::0;:85:::1;::::0;57738:6;;57746:4;;57752:11;;57765:15;;57782:9;;57707:85:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57699:110;;;;-1:-1:-1::0;;;57699:110:0::1;;;;;;;:::i;:::-;57636:238;;;57858:4;57842:20:::0;;-1:-1:-1;;57842:20:0::1;::::0;::::1;::::0;;57636:238:::1;57891:53;57901:6;57909:4;57915:11;57928:15;57891:53;;;;;;;;;:::i;:::-;;;;;;;;37383:1;;;;;56372:1580::o:0;73258:160::-;36656:10;;-1:-1:-1;;;;;36656:10:0;36642;:24;;:54;;;36684:12;:10;:12::i;:::-;-1:-1:-1;;;;;36670:26:0;:10;-1:-1:-1;;;;;36670:26:0;;36642:54;:88;;;;36714:5;;;;;;;;;-1:-1:-1;;;;;36714:5:0;-1:-1:-1;;;;;36714:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36700:30:0;:10;-1:-1:-1;;;;;36700:30:0;;36642:88;:124;;;;36748:5;;;;;;;;;-1:-1:-1;;;;;36748:5:0;-1:-1:-1;;;;;36748:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36734:32:0;:10;-1:-1:-1;;;;;36734:32:0;;36642:124;36620:185;;;;-1:-1:-1;;;36620:185:0;;;;;;;:::i;:::-;73376:15:::1;:34:::0;;;::::1;;-1:-1:-1::0;;;73376:34:0::1;-1:-1:-1::0;;;;73376:34:0;;::::1;::::0;;;::::1;::::0;;73258:160::o;80019:377::-;36656:10;;-1:-1:-1;;;;;36656:10:0;36642;:24;;:54;;;36684:12;:10;:12::i;:::-;-1:-1:-1;;;;;36670:26:0;:10;-1:-1:-1;;;;;36670:26:0;;36642:54;:88;;;;36714:5;;;;;;;;;-1:-1:-1;;;;;36714:5:0;-1:-1:-1;;;;;36714:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36700:30:0;:10;-1:-1:-1;;;;;36700:30:0;;36642:88;:124;;;;36748:5;;;;;;;;;-1:-1:-1;;;;;36748:5:0;-1:-1:-1;;;;;36748:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36734:32:0;:10;-1:-1:-1;;;;;36734:32:0;;36642:124;36620:185;;;;-1:-1:-1;;;36620:185:0;;;;;;;:::i;:::-;80105:13;80101:288:::1;;80135:11;:26:::0;;-1:-1:-1;;;;;;80135:26:0::1;69340:42;80135:26;::::0;;80101:288:::1;;;80183:8;80195:1;80183:13;80179:210;;;80213:11;:27:::0;;-1:-1:-1;;;;;;80213:27:0::1;69536:42;80213:27;::::0;;80179:210:::1;;;80262:8;80274:1;80262:13;80258:131;;;80292:11;:27:::0;;-1:-1:-1;;;;;;80292:27:0::1;69438:42;80292:27;::::0;;80258:131:::1;;;80352:25;;-1:-1:-1::0;;;80352:25:0::1;;;;;;;:::i;69816:92::-:0;;;-1:-1:-1;;;;;69816:92:0;;:::o;36379:25::-;;;;;;:::o;77355:131::-;77449:6;;77428:43;;-1:-1:-1;;;77428:43:0;;77401:7;;68997:42;;77428:20;;:43;;77465:4;;77428:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:50;;-1:-1:-1;77355:131:0;:::o;51132:432::-;51205:4;51132:432;;;;:::o;33077:25::-;;;;;;:::o;40200:174::-;36490:10;;-1:-1:-1;;;;;36490:10:0;36476;:24;;:54;;;36518:12;:10;:12::i;:::-;-1:-1:-1;;;;;36504:26:0;:10;-1:-1:-1;;;;;36504:26:0;;36476:54;36468:78;;;;-1:-1:-1;;;36468:78:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;40279:21:0;::::1;40271:30;;;::::0;::::1;;40312:6;:16:::0;;-1:-1:-1;;;;;;40312:16:0::1;-1:-1:-1::0;;;;;40312:16:0;::::1;;::::0;;40344:22:::1;::::0;::::1;::::0;::::1;::::0;40312:16;;40344:22:::1;:::i;43872:171::-:0;36490:10;;-1:-1:-1;;;;;36490:10:0;36476;:24;;:54;;;36518:12;:10;:12::i;:::-;-1:-1:-1;;;;;36504:26:0;:10;-1:-1:-1;;;;;36504:26:0;;36476:54;36468:78;;;;-1:-1:-1;;;36468:78:0;;;;;;;:::i;:::-;43961:26:::1;:11;43975:12:::0;;43961:26:::1;:::i;:::-;;44003:32;44022:12;;44003:32;;;;;;;:::i;:::-;;;;;;;;43872:171:::0;;:::o;79540:155::-;79677:10;79540:155::o;36122:27::-;;;;:::o;34827:94::-;34885:7;34827:94;:::o;42668:169::-;36490:10;;-1:-1:-1;;;;;36490:10:0;36476;:24;;:54;;;36518:12;:10;:12::i;:::-;-1:-1:-1;;;;;36504:26:0;:10;-1:-1:-1;;;;;36504:26:0;;36476:54;36468:78;;;;-1:-1:-1;;;36468:78:0;;;;;;;:::i;:::-;42751:12:::1;:28:::0;;;42795:34:::1;::::0;::::1;::::0;::::1;::::0;42766:13;;42795:34:::1;:::i;35785:29::-:0;;;;:::o;34989:22::-;;;-1:-1:-1;;;;;34989:22:0;;:::o;70005:35::-;;;-1:-1:-1;;;70005:35:0;;;;;:::o;72850:200::-;36656:10;;-1:-1:-1;;;;;36656:10:0;36642;:24;;:54;;;36684:12;:10;:12::i;:::-;-1:-1:-1;;;;;36670:26:0;:10;-1:-1:-1;;;;;36670:26:0;;36642:54;:88;;;;36714:5;;;;;;;;;-1:-1:-1;;;;;36714:5:0;-1:-1:-1;;;;;36714:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36700:30:0;:10;-1:-1:-1;;;;;36700:30:0;;36642:88;:124;;;;36748:5;;;;;;;;;-1:-1:-1;;;;;36748:5:0;-1:-1:-1;;;;;36748:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36734:32:0;:10;-1:-1:-1;;;;;36734:32:0;;36642:124;36620:185;;;;-1:-1:-1;;;36620:185:0;;;;;;;:::i;:::-;72988:25:::1;:54:::0;;;::::1;;-1:-1:-1::0;;;72988:54:0::1;-1:-1:-1::0;;;;72988:54:0;;::::1;::::0;;;::::1;::::0;;72850:200::o;39088:123::-;37462:5;;;;;;;;;-1:-1:-1;;;;;37462:5:0;-1:-1:-1;;;;;37462:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;37448:32:0;:10;-1:-1:-1;;;;;37448:32:0;;:62;;;;37498:12;:10;:12::i;:::-;-1:-1:-1;;;;;37484:26:0;:10;-1:-1:-1;;;;;37484:26:0;;37448:62;37440:86;;;;-1:-1:-1;;;37440:86:0;;;;;;;:::i;:::-;39173:13:::1;:30:::0;;-1:-1:-1;;39173:30:0::1;::::0;::::1;;::::0;;;::::1;::::0;;39088:123::o;35018:21::-;;;-1:-1:-1;;;;;35018:21:0;;:::o;33109:26::-;;;;;;-1:-1:-1;;;;;33109:26:0;;:::o;70256:34::-;;;-1:-1:-1;;;70256:34:0;;;;;:::o;77629:110::-;77702:4;;:29;;-1:-1:-1;;;77702:29:0;;77675:7;;-1:-1:-1;;;;;77702:4:0;;:14;;:29;;77725:4;;77702:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;70137:44::-;;;-1:-1:-1;;;70137:44:0;;;;;:::o;39444:202::-;36490:10;;-1:-1:-1;;;;;36490:10:0;36476;:24;;:54;;;36518:12;:10;:12::i;:::-;-1:-1:-1;;;;;36504:26:0;:10;-1:-1:-1;;;;;36504:26:0;;36476:54;36468:78;;;;-1:-1:-1;;;36468:78:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;39531:25:0;::::1;39523:34;;;::::0;::::1;;39568:10;:24:::0;;-1:-1:-1;;;;;;39568:24:0::1;-1:-1:-1::0;;;;;39568:24:0;::::1;;::::0;;39608:30:::1;::::0;::::1;::::0;::::1;::::0;39568:24;;39608:30:::1;:::i;59483:281::-:0;59572:5;;-1:-1:-1;;;;;59572:5:0;59550:10;:28;59542:37;;;;;;59636:5;;59598:34;;;-1:-1:-1;;;59598:34:0;;;;-1:-1:-1;;;;;59636:5:0;;;;59598:32;;;;;:34;;;;;;;;;;;;;;:32;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;59598:43:0;;59590:52;;;;;;59653:30;59670:12;59653:16;:30::i;:::-;59726:4;;:29;;-1:-1:-1;;;59726:29:0;;59694:62;;59712:12;;-1:-1:-1;;;;;59726:4:0;;;;:14;;:29;;59749:4;;59726:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59694:4;;-1:-1:-1;;;;;59694:4:0;;:62;:17;:62::i;72058:118::-;36656:10;;-1:-1:-1;;;;;36656:10:0;36642;:24;;:54;;;36684:12;:10;:12::i;:::-;-1:-1:-1;;;;;36670:26:0;:10;-1:-1:-1;;;;;36670:26:0;;36642:54;:88;;;;36714:5;;;;;;;;;-1:-1:-1;;;;;36714:5:0;-1:-1:-1;;;;;36714:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36700:30:0;:10;-1:-1:-1;;;;;36700:30:0;;36642:88;:124;;;;36748:5;;;;;;;;;-1:-1:-1;;;;;36748:5:0;-1:-1:-1;;;;;36748:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36734:32:0;:10;-1:-1:-1;;;;;36734:32:0;;36642:124;36620:185;;;;-1:-1:-1;;;36620:185:0;;;;;;;:::i;:::-;72161:6:::1;::::0;72131:37:::1;::::0;-1:-1:-1;;;72131:37:0;;68997:42:::1;::::0;72131:29:::1;::::0;:37:::1;::::0;72161:6;72131:37:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;72058:118::o:0;40663:263::-;36892:10;;-1:-1:-1;;;;;36892:10:0;36878;:24;36870:48;;;;-1:-1:-1;;;36870:48:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;40744:22:0;::::1;40736:31;;;::::0;::::1;;40778:5;::::0;40792:7:::1;::::0;;40778:25:::1;::::0;-1:-1:-1;;;40778:25:0;;-1:-1:-1;;;;;40778:5:0;;::::1;::::0;:13:::1;::::0;:25:::1;::::0;40792:7;;::::1;::::0;40778:5:::1;::::0;:25:::1;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;40814:7:0::1;:18:::0;;-1:-1:-1;;;;;;40814:18:0::1;-1:-1:-1::0;;;;;40814:18:0;;::::1;::::0;;;::::1;::::0;;;40843:5:::1;::::0;:35:::1;::::0;-1:-1:-1;;;40843:35:0;;:5;;::::1;::::0;:13:::1;::::0;:35:::1;::::0;40857:7:::1;::::0;-1:-1:-1;;40874:2:0;40843:35:::1;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;40894:24;40909:8;40894:24;;;;;;:::i;78836:573::-:0;78949:4;78971:28;;:::i;:::-;79002:5;;:31;;-1:-1:-1;;;79002:31:0;;-1:-1:-1;;;;;79002:5:0;;;;:16;;:31;;79027:4;;79002:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;78971:62;;79153:14;;79112:38;79132:6;:17;;;79112:15;:19;;:38;;;;:::i;:::-;:55;79108:99;;;79191:4;79184:11;;;;;79108:99;79274:23;;-1:-1:-1;;;79274:23:0;;;;79270:67;;;79321:4;79314:11;;;;;79270:67;-1:-1:-1;79396:5:0;;78836:573;-1:-1:-1;;78836:573:0:o;77494:127::-;77591:6;;77568:45;;-1:-1:-1;;;77568:45:0;;77541:7;;68997:42;;77568:22;;:45;;77607:4;;77568:45;;;:::i;77747:133::-;77809:7;77836:36;77856:15;:13;:15::i;:::-;77836;:13;:15::i;:::-;:19;;:36::i;42114:154::-;36490:10;;-1:-1:-1;;;;;36490:10:0;36476;:24;;:54;;;36518:12;:10;:12::i;:::-;-1:-1:-1;;;;;36504:26:0;:10;-1:-1:-1;;;;;36504:26:0;;36476:54;36468:78;;;;-1:-1:-1;;;36468:78:0;;;;;;;:::i;:::-;42192:14:::1;:23:::0;;;42231:29:::1;::::0;::::1;::::0;::::1;::::0;42209:6;;42231:29:::1;:::i;69687:106::-:0;;;;;;-1:-1:-1;;;;;69687:106:0;;:::o;34929:21::-;;;-1:-1:-1;;;;;34929:21:0;;:::o;60193:173::-;36656:10;;-1:-1:-1;;;;;36656:10:0;36642;:24;;:54;;;36684:12;:10;:12::i;:::-;-1:-1:-1;;;;;36670:26:0;:10;-1:-1:-1;;;;;36670:26:0;;36642:54;:88;;;;36714:5;;;;;;;;;-1:-1:-1;;;;;36714:5:0;-1:-1:-1;;;;;36714:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36700:30:0;:10;-1:-1:-1;;;;;36700:30:0;;36642:88;:124;;;;36748:5;;;;;;;;;-1:-1:-1;;;;;36748:5:0;-1:-1:-1;;;;;36748:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36734:32:0;:10;-1:-1:-1;;;;;36734:32:0;;36642:124;36620:185;;;;-1:-1:-1;;;36620:185:0;;;;;;;:::i;:::-;60265:13:::1;:20:::0;;-1:-1:-1;;60265:20:0::1;60281:4;60265:20;::::0;;60296:5:::1;::::0;:22:::1;::::0;;-1:-1:-1;;;60296:22:0;;;;-1:-1:-1;;;;;60296:5:0;;::::1;::::0;:20:::1;::::0;:22:::1;::::0;;::::1;::::0;60265:13:::1;::::0;60296:22;;;;;;;;60265:13;60296:5;:22;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;60336:22:0::1;::::0;::::1;::::0;-1:-1:-1;60336:22:0;;-1:-1:-1;60336:22:0::1;60193:173::o:0;23930:622::-;24300:10;;;24299:62;;-1:-1:-1;24316:39:0;;-1:-1:-1;;;24316:39:0;;-1:-1:-1;;;;;24316:15:0;;;;;:39;;24340:4;;24347:7;;24316:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;24299:62;24291:152;;;;-1:-1:-1;;;24291:152:0;;;;;;;:::i;:::-;24454:90;24474:5;24504:22;;;24528:7;24537:5;24481:62;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;24481:62:0;;;;;;;;;;;;;;-1:-1:-1;;;;;24481:62:0;-1:-1:-1;;;;;;24481:62:0;;;;;;;;;;24454:19;:90::i;:::-;23930:622;;;:::o;3857:196::-;3960:12;3992:53;4015:6;4023:4;4029:1;4032:12;3992:22;:53::i;:::-;3985:60;3857:196;-1:-1:-1;;;;3857:196:0:o;44197:98::-;44269:5;;:18;;;-1:-1:-1;;;44269:18:0;;;;44242:7;;-1:-1:-1;;;;;44269:5:0;;:16;;:18;;;;;;;;;;;;;;:5;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;72653:120::-;72748:16;72653:120;:::o;23271:177::-;23354:86;23374:5;23404:23;;;23429:2;23433:5;23381:58;;;;;;;;;:::i;78393:392::-;78474:16;;;78488:1;78474:16;;;;;;;;;78450:21;;78474:16;;;78450:21;;78474:16;;;;;-1:-1:-1;78474:16:0;78450:40;;69637:42;78501:4;78506:1;78501:7;;;;;;;;;;;;;:24;-1:-1:-1;;;;;78501:24:0;;;-1:-1:-1;;;;;78501:24:0;;;;;69191:42;78536:4;78541:1;78536:7;;;;;;;;-1:-1:-1;;;;;78536:23:0;;;:7;;;;;;;;;:23;78588:11;;78570:7;;78588:11;;;78570:4;;78575:1;;78570:7;;;;;;-1:-1:-1;;;;;78570:30:0;;;:7;;;;;;;;;:30;78611:6;;:166;;-1:-1:-1;;;78611:166:0;;:6;;;;;;;;:31;;:166;;78657:7;;78687:1;;78704:4;;78731;;78751:15;;78611:166;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;78611:166:0;;;;;;;;;;;;:::i;73791:911::-;73895:25;73922:13;73953:16;73972:15;:13;:15::i;:::-;73953:34;;74018:8;74002:13;:24;73998:697;;;74118:18;74139:15;:13;:15::i;:::-;74118:36;-1:-1:-1;74173:14:0;;74169:195;;74251:6;;68997:42;;74208:20;;74280:49;74289:10;74301:27;:13;74319:8;74301:17;:27::i;:::-;74280:8;:49::i;:::-;74208:140;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74169:195;74380:21;74404:15;:13;:15::i;:::-;74380:39;;74454:38;74463:13;74478;74454:8;:38::i;:::-;74434:58;-1:-1:-1;74515:36:0;:13;74434:58;74515:17;:36::i;:::-;74507:44;;73998:697;;;;;74666:13;74681:1;74658:25;;;;;;;73998:697;73791:911;;;;;:::o;73426:357::-;73509:13;;;;73505:52;;;73539:7;;73505:52;73646:17;73666:15;:13;:15::i;:::-;73646:35;-1:-1:-1;73696:13:0;;73692:84;;73746:6;;73726:38;;-1:-1:-1;;;73726:38:0;;68997:42;;73726:19;;:38;;73746:6;73754:9;;73726:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73426:357;;:::o;77926:298::-;77986:7;78006:18;78027:15;:13;:15::i;:::-;78006:36;-1:-1:-1;78099:14:0;;78095:87;;78151:6;;78130:40;;-1:-1:-1;;;78130:40:0;;68997:42;;78130:20;;:40;;78151:6;78159:10;;78130:40;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78095:87;78201:15;:13;:15::i;:::-;78194:22;;;77926:298;:::o;11078:136::-;11136:7;11163:43;11167:1;11170;11163:43;;;;;;;;;;;;;;;;;:3;:43::i;:::-;11156:50;11078:136;-1:-1:-1;;;11078:136:0:o;74710:2637::-;75012:6;;74991:31;;-1:-1:-1;;;74991:31:0;;74827:15;;;;;;68997:42;;74991:20;;:31;;74827:15;;74991:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;75039:15:0;;-1:-1:-1;;;75039:15:0;;;;75035:238;;-1:-1:-1;75035:238:0;;-1:-1:-1;75035:238:0;75094:30;;-1:-1:-1;;;75094:30:0;;75071:20;;69637:42;;75094:15;;:30;;75118:4;;75094:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75071:53;-1:-1:-1;75185:16:0;;75181:81;;75222:24;75233:12;75222:10;:24::i;:::-;75035:238;;75306:28;;-1:-1:-1;;;75306:28:0;;75285:18;;69340:42;;75306:13;;:28;;75328:4;;75306:28;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75367:29;;-1:-1:-1;;;75367:29:0;;75285:49;;-1:-1:-1;75345:19:0;;69438:42;;75367:14;;:29;;75390:4;;75367:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75429;;-1:-1:-1;;;75429:29:0;;75345:51;;-1:-1:-1;75407:19:0;;69536:42;;75429:14;;:29;;75452:4;;75429:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75407:51;;75544:1;75531:10;:14;:33;;;;75563:1;75549:11;:15;75531:33;:52;;;;75582:1;75568:11;:15;75531:52;75527:233;;;75600:10;;75651:4;;75600:148;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;75600:148:0;;-1:-1:-1;;;;;75600:10:0;;;;:24;;:148;;75651:4;;;75600:10;;:148;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;75527:233;75912:17;75932:15;:13;:15::i;:::-;75912:35;-1:-1:-1;75962:20:0;;75958:430;;76074:13;;76070:182;;68997:42;-1:-1:-1;;;;;76108:20:0;;76151:6;;76180:37;76189:9;76200:16;76180:8;:37::i;:::-;76108:128;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76070:182;76266:21;76290:15;:13;:15::i;:::-;76266:39;;76335:41;76344:16;76362:13;76335:8;:41::i;:::-;76320:56;;75958:430;;76524:14;76541:22;:20;:22::i;:::-;76589:5;;:31;;-1:-1:-1;;;76589:31:0;;76524:39;;-1:-1:-1;76574:12:0;;-1:-1:-1;;;;;76589:5:0;;;;:16;;:31;;76614:4;;76589:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;76574:56;;76727:4;76718:6;:13;76714:512;;;76758:16;:6;76769:4;76758:10;:16::i;:::-;76748:26;;76789:16;76808:15;:13;:15::i;:::-;76789:34;-1:-1:-1;76789:34:0;76842:25;:7;76854:12;76842:11;:25::i;:::-;:36;76838:251;;;76975:20;76998:25;:7;77010:12;76998:11;:25::i;:::-;76975:48;;77042:31;77060:12;77042:17;:31::i;:::-;;;76838:251;;76714:512;;;;77198:16;:4;77207:6;77198:8;:16::i;:::-;77190:24;;76714:512;-1:-1:-1;;77308:23:0;:31;;-1:-1:-1;;;;77308:31:0;;;-1:-1:-1;74710:2637:0;;;;-1:-1:-1;74710:2637:0;;-1:-1:-1;;;74710:2637:0:o;72184:461::-;72265:25;;-1:-1:-1;;;72265:25:0;;;;72261:203;;;72307:18;72328:15;:13;:15::i;:::-;72307:36;-1:-1:-1;72362:14:0;;72358:95;;72418:6;;72397:40;;-1:-1:-1;;;72397:40:0;;68997:42;;72397:20;;:40;;72418:6;72426:10;;72397:40;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72358:95;72261:203;;72500:30;;-1:-1:-1;;;72500:30:0;;72476:21;;69637:42;;72500:15;;:30;;72524:4;;72500:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72476:54;-1:-1:-1;72545:17:0;;72541:97;;72579:47;69637:42;72598:12;72612:13;72579:18;:47::i;10614:181::-;10672:7;10704:5;;;10728:6;;;;10720:46;;;;-1:-1:-1;;;10720:46:0;;;;;;;:::i;25576:761::-;26000:23;26026:69;26054:4;26026:69;;;;;;;;;;;;;;;;;26034:5;-1:-1:-1;;;;;26026:27:0;;;:69;;;;;:::i;:::-;26110:17;;26000:95;;-1:-1:-1;26110:21:0;26106:224;;26252:10;26241:30;;;;;;;;;;;;:::i;:::-;26233:85;;;;-1:-1:-1;;;26233:85:0;;;;;;;:::i;5234:979::-;5364:12;5397:18;5408:6;5397:10;:18::i;:::-;5389:60;;;;-1:-1:-1;;;5389:60:0;;;;;;;:::i;:::-;5523:12;5537:23;5564:6;-1:-1:-1;;;;;5564:11:0;5584:8;5595:4;5564:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5522:78;;;;5615:7;5611:595;;;5646:10;-1:-1:-1;5639:17:0;;-1:-1:-1;5639:17:0;5611:595;5760:17;;:21;5756:439;;6023:10;6017:17;6084:15;6071:10;6067:2;6063:19;6056:44;5971:148;6166:12;6159:20;;-1:-1:-1;;;6159:20:0;;;;;;;;:::i;9324:106::-;9382:7;9413:1;9409;:5;:13;;9421:1;9409:13;;;-1:-1:-1;9417:1:0;;9324:106;-1:-1:-1;9324:106:0:o;11517:192::-;11603:7;11639:12;11631:6;;;;11623:29;;;;-1:-1:-1;;;11623:29:0;;;;;;;;:::i;:::-;-1:-1:-1;;;11675:5:0;;;11517:192::o;742:619::-;802:4;1270:20;;1113:66;1310:23;;;;;;:42;;-1:-1:-1;;1337:15:0;;;1302:51;-1:-1:-1;;742:619:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;4540:241;;4644:2;4632:9;4623:7;4619:23;4615:32;4612:2;;;-1:-1;;4650:12;4612:2;85:6;72:20;97:33;124:5;97:33;:::i;4788:263::-;;4903:2;4891:9;4882:7;4878:23;4874:32;4871:2;;;-1:-1;;4909:12;4871:2;226:6;220:13;238:33;265:5;238:33;:::i;5058:392::-;;5198:2;;5186:9;5177:7;5173:23;5169:32;5166:2;;;-1:-1;;5204:12;5166:2;5255:17;5249:24;5293:18;5285:6;5282:30;5279:2;;;-1:-1;;5315:12;5279:2;5402: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;;;4477:13;;893:61;;847:1;840:9;;;;;968:14;;;;996;;800:217;;;-1:-1;5335:99;5160:290;-1:-1;;;;;;;5160:290::o;5457:235::-;;5558:2;5546:9;5537:7;5533:23;5529:32;5526:2;;;-1:-1;;5564:12;5526:2;1108:6;1095:20;1120:30;1144:5;1120:30;:::i;5699:257::-;;5811:2;5799:9;5790:7;5786:23;5782:32;5779:2;;;-1:-1;;5817:12;5779:2;1243:6;1237:13;1255:30;1279:5;1255:30;:::i;6267:367::-;;;6391:2;6379:9;6370:7;6366:23;6362:32;6359:2;;;-1:-1;;6397:12;6359:2;6455:17;6442:31;6493:18;;6485:6;6482:30;6479:2;;;-1:-1;;6515:12;6479:2;6601:6;6590:9;6586:22;;;1602:3;1595:4;1587:6;1583:17;1579:27;1569:2;;-1:-1;;1610:12;1569:2;1653:6;1640:20;6493:18;1672:6;1669:30;1666:2;;;-1:-1;;1702:12;1666:2;1797:3;6391:2;1777:17;1738:6;1763:32;;1760:41;1757:2;;;-1:-1;;1804:12;1757:2;6391;1734:17;;;;;6535:83;;-1:-1;6353:281;;-1:-1;;;;6353:281::o;6641:328::-;;6788:3;;6776:9;6767:7;6763:23;6759:33;6756:2;;;-1:-1;;6795:12;6756:2;2030:22;6788:3;2030:22;:::i;:::-;2021:31;;2176:22;4477:13;2126:16;2119:86;2272:2;2341:9;2337:22;4477:13;2272:2;2291:5;2287:16;2280:86;2432:2;2501:9;2497:22;4477:13;2432:2;2451:5;2447:16;2440:86;2600:2;2669:9;2665:22;4477:13;2600:2;2619:5;2615:16;2608:86;2768:3;2838:9;2834:22;4477:13;2768:3;2788:5;2784:16;2777:86;2930:3;3000:9;2996:22;4477:13;2930:3;2950:5;2946:16;2939:86;3091:3;3161:9;3157:22;4477:13;3091:3;3111:5;3107:16;3100:86;3252:3;3322:9;3318:22;4477:13;3252:3;3272:5;3268:16;3261:86;3413:3;;3485:9;3481:22;4477:13;3413:3;3433:5;3429:18;3422:88;;6847:106;;;;6750:219;;;;:::o;6976:313::-;;7116:2;7104:9;7095:7;7091:23;7087:32;7084:2;;;-1:-1;;7122:12;7084:2;3734:20;7116:2;3734:20;:::i;:::-;3870:22;4477:13;3820:16;3813:86;3966:2;4035:9;4031:22;4477:13;3966:2;3985:5;3981:16;3974:86;4140:2;4209:9;4205:22;4477:13;4140:2;4159:5;4155:16;4148:86;7174:99;;;;7078:211;;;;:::o;7296:241::-;;7400:2;7388:9;7379:7;7375:23;7371:32;7368:2;;;-1:-1;;7406:12;7368:2;-1:-1;4329:20;;7362:175;-1:-1;7362:175::o;7544:263::-;;7659:2;7647:9;7638:7;7634:23;7630:32;7627:2;;;-1:-1;;7665:12;7627:2;-1:-1;4477:13;;7621:186;-1:-1;7621:186::o;16068:271::-;;10109:5;29901:12;10220:52;10265:6;10260:3;10253:4;10246:5;10242:16;10220:52;:::i;:::-;10284:16;;;;;16202:137;-1:-1;;16202:137::o;16346:222::-;-1:-1;;;;;31570:54;;;;8239:37;;16473:2;16458:18;;16444:124::o;16575:333::-;-1:-1;;;;;31570:54;;;8239:37;;31570:54;;16894:2;16879:18;;8239:37;16730:2;16715:18;;16701:207::o;16915:554::-;-1:-1;;;;;31570:54;;8239:37;;17152:3;17137:19;;17363:2;17348:18;;;9533:21;16915:554;9560:258;30036:4;9582:1;9579:13;9560:258;;;9646:13;;15899:37;;8150:14;;;;30403;;;;9607:1;9600:9;9560:258;;;9564:14;;;;11124:5;17454:3;17443:9;17439:19;11073:58;17123:346;;;;;;:::o;17476:349::-;-1:-1;;;;;31570:54;;;;8239:37;;17811:2;17796:18;;11073:58;17639:2;17624:18;;17610:215::o;18172:210::-;31367:13;;31360:21;9903:34;;18293:2;18278:18;;18264:118::o;19455:330::-;;19612:2;19633:17;19626:47;30673:6;19612:2;19601:9;19597:18;30661:19;33117:6;33112:3;30701:14;19601:9;30701:14;33094:30;33155:16;;;30701:14;33155:16;;;33148:27;;;;33550:7;33534:14;;;-1:-1;;33530:28;11423:39;;;19583:202;-1:-1;19583:202::o;19792:310::-;;19939:2;19960:17;19953:47;11621:5;29901:12;30673:6;19939:2;19928:9;19924:18;30661:19;11715:52;11760:6;30701:14;19928:9;30701:14;19939:2;11741:5;11737:16;11715:52;:::i;:::-;33550:7;33534:14;-1:-1;;33530:28;11779:39;;;;30701:14;11779:39;;19910:192;-1:-1;;19910:192::o;20109:416::-;20309:2;20323:47;;;12055:2;20294:18;;;30661:19;-1:-1;;;30701:14;;;12071:34;12124:12;;;20280:245::o;20532:416::-;20732:2;20746:47;;;12375:1;20717:18;;;30661:19;-1:-1;;;30701:14;;;12390:28;12437:12;;;20703:245::o;20955:416::-;21155:2;21169:47;;;12688:2;21140:18;;;30661:19;12724:29;30701:14;;;12704:50;12773:12;;;21126:245::o;21378:416::-;21578:2;21592:47;;;13024:2;21563:18;;;30661:19;-1:-1;;;30701:14;;;13040:35;13094:12;;;21549:245::o;21801:416::-;22001:2;22015:47;;;13345:2;21986:18;;;30661:19;-1:-1;;;30701:14;;;13361:38;13418:12;;;21972:245::o;22224:416::-;22424:2;22438:47;;;13669:1;22409:18;;;30661:19;-1:-1;;;30701:14;;;13684:29;13732:12;;;22395:245::o;22647:416::-;22847:2;22861:47;;;13983:1;22832:18;;;30661:19;-1:-1;;;30701:14;;;13998:30;14047:12;;;22818:245::o;23070:416::-;23270:2;23284:47;;;14298:2;23255:18;;;30661:19;14334:31;30701:14;;;14314:52;14385:12;;;23241:245::o;23493:416::-;23693:2;23707:47;;;14636:2;23678:18;;;30661:19;-1:-1;;;30701:14;;;14652:34;14705:12;;;23664:245::o;23916:416::-;24116:2;24130:47;;;14956:2;24101:18;;;30661:19;14992:34;30701:14;;;14972:55;-1:-1;;;15047:12;;;15040:34;15093:12;;;24087:245::o;24339:416::-;24539:2;24553:47;;;15344:2;24524:18;;;30661:19;-1:-1;;;30701:14;;;15360:33;15412:12;;;24510:245::o;24762:416::-;24962:2;24976:47;;;15663:2;24947:18;;;30661:19;15699:34;30701:14;;;15679:55;-1:-1;;;15754:12;;;15747:46;15812:12;;;24933:245::o;25185:222::-;15899:37;;;25312:2;25297:18;;25283:124::o;25414:333::-;15899:37;;;-1:-1;;;;;31570:54;25733:2;25718:18;;8239:37;25569:2;25554:18;;25540:207::o;25754:349::-;15899:37;;;26089:2;26074:18;;11073:58;25917:2;25902:18;;25888:215::o;26450:816::-;;26739:3;26728:9;26724:19;15929:5;15906:3;15899:37;26904:2;15929:5;26904:2;26893:9;26889:18;15899:37;26739:3;26941:2;26930:9;26926:18;26919:48;26981:108;8632:5;29901:12;30673:6;30668:3;30661:19;30701:14;26728:9;30701:14;8644:93;;26904:2;8808:5;29651:14;8820:21;;-1:-1;8847:260;8872:6;8869:1;8866:13;8847:260;;;8933:13;;-1:-1;;;;;31570:54;8239:37;;30403:14;;;;7968;;;;5293:18;8887:9;8847:260;;;-1:-1;;;;;;;31570:54;;;;27168:2;27153:18;;8239:37;-1:-1;;;27251:3;27236:19;15899:37;26973:116;26710:556;-1:-1;;;26710:556::o;27273:444::-;15899:37;;;27620:2;27605:18;;15899:37;;;;27703:2;27688:18;;15899:37;27456:2;27441:18;;27427:290::o;27724:556::-;15899:37;;;28100:2;28085:18;;15899:37;;;;28183:2;28168:18;;15899:37;28266:2;28251:18;;15899:37;27935:3;27920:19;;27906:374::o;28287:668::-;15899:37;;;28691:2;28676:18;;15899:37;;;;28774:2;28759:18;;15899:37;;;;28857:2;28842:18;;15899:37;28940:3;28925:19;;15899:37;28526:3;28511:19;;28497:458::o;28962:256::-;29024:2;29018:9;29050:17;;;29125:18;29110:34;;29146:22;;;29107:62;29104:2;;;29182:1;;29172:12;29104:2;29024;29191:22;29002:216;;-1:-1;29002:216::o;29225:304::-;;29384:18;29376:6;29373:30;29370:2;;;-1:-1;;29406:12;29370:2;-1:-1;29451:4;29439:17;;;29504:15;;29307:222::o;33190:268::-;33255:1;33262:101;33276:6;33273:1;33270:13;33262:101;;;33343:11;;;33337:18;33324:11;;;33317:39;33298:2;33291:10;33262:101;;;33378:6;33375:1;33372:13;33369:2;;;-1:-1;;33255:1;33425:16;;33418:27;33239:219::o;33571:117::-;-1:-1;;;;;31570:54;;33630:35;;33620:2;;33679:1;;33669:12;33695:111;33776:5;31367:13;31360:21;33754:5;33751:32;33741:2;;33797:1;;33787:12
Metadata Hash
636f5de58e8f0875091cbba80f73036d06eaf64244e692f65f77a3ac57ffedd1
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.