Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 38 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Clone | 16535130 | 544 days ago | IN | 0 ETH | 0.00551047 | ||||
Clone | 16502087 | 549 days ago | IN | 0 ETH | 0.00375355 | ||||
Clone | 15484442 | 693 days ago | IN | 0 ETH | 0.00285392 | ||||
Clone | 15274433 | 726 days ago | IN | 0 ETH | 0.00498903 | ||||
Harvest | 12612622 | 1145 days ago | IN | 0 ETH | 0.00750583 | ||||
Clone | 12588978 | 1148 days ago | IN | 0 ETH | 0.01166126 | ||||
Harvest | 12550280 | 1154 days ago | IN | 0 ETH | 0.02314298 | ||||
Harvest | 12478037 | 1166 days ago | IN | 0 ETH | 0.0452266 | ||||
Harvest | 12477691 | 1166 days ago | IN | 0 ETH | 0.02335908 | ||||
Clone | 12376949 | 1181 days ago | IN | 0 ETH | 0.01578642 | ||||
Clone | 12344906 | 1186 days ago | IN | 0 ETH | 0.00954852 | ||||
Clone | 12344899 | 1186 days ago | IN | 0 ETH | 0.01000555 | ||||
Clone | 12344894 | 1186 days ago | IN | 0 ETH | 0.01000195 | ||||
Harvest | 12253136 | 1200 days ago | IN | 0 ETH | 0.10261071 | ||||
Clone | 12136006 | 1218 days ago | IN | 0 ETH | 0.04446897 | ||||
Clone | 12116279 | 1221 days ago | IN | 0 ETH | 0.03939062 | ||||
Clone | 12065396 | 1229 days ago | IN | 0 ETH | 0.03431885 | ||||
Harvest | 12055137 | 1231 days ago | IN | 0 ETH | 0.16596147 | ||||
Harvest | 12025385 | 1235 days ago | IN | 0 ETH | 0.09221072 | ||||
Harvest | 12018349 | 1236 days ago | IN | 0 ETH | 0.21971582 | ||||
Clone | 12018287 | 1237 days ago | IN | 0 ETH | 0.03786564 | ||||
Clone | 12014938 | 1237 days ago | IN | 0 ETH | 0.01932641 | ||||
Set Profit Facto... | 12004889 | 1239 days ago | IN | 0 ETH | 0.00321914 | ||||
Set Profit Facto... | 11999796 | 1239 days ago | IN | 0 ETH | 0.00393134 | ||||
Set Debt Thresho... | 11999794 | 1239 days ago | IN | 0 ETH | 0.00394583 |
Latest 22 internal transactions
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Strategy
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-02-19 */ // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.6.12; pragma experimental ABIEncoderV2; // Global Enums and Structs struct StrategyParams { uint256 performanceFee; uint256 activation; uint256 debtRatio; uint256 minDebtPerHarvest; uint256 maxDebtPerHarvest; uint256 lastReport; uint256 totalDebt; uint256 totalGain; uint256 totalLoss; } // Part: IGenericLender interface IGenericLender { function lenderName() external view returns (string memory); function nav() external view returns (uint256); function strategy() external view returns (address); function apr() external view returns (uint256); function weightedApr() external view returns (uint256); function withdraw(uint256 amount) external returns (uint256); function emergencyWithdraw(uint256 amount) external; function deposit() external; function withdrawAll() external returns (bool); function hasAssets() external view returns (bool); function aprAfterDeposit(uint256 amount) external view returns (uint256); function setDust(uint256 _dust) external; function sweep(address _token) external; } // Part: IUni interface IUni { function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); } // Part: IWantToEth interface IWantToEth { function wantToEth(uint256 input) external view returns (uint256); function ethToWant(uint256 input) external view returns (uint256); } // Part: OpenZeppelin/[email protected]/Address /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // Part: OpenZeppelin/[email protected]/IERC20 /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // Part: OpenZeppelin/[email protected]/Math /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } } // Part: OpenZeppelin/[email protected]/SafeMath /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // Part: OpenZeppelin/[email protected]/SafeERC20 /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // Part: iearn-finance/[email protected]/VaultAPI interface VaultAPI is IERC20 { function apiVersion() external pure returns (string memory); function withdraw(uint256 shares, address recipient) external returns (uint256); function token() external view returns (address); function strategies(address _strategy) external view returns (StrategyParams memory); /** * View how much the Vault would increase this Strategy's borrow limit, * based on its present performance (since its last report). Can be used to * determine expectedReturn in your Strategy. */ function creditAvailable() external view returns (uint256); /** * View how much the Vault would like to pull back from the Strategy, * based on its present performance (since its last report). Can be used to * determine expectedReturn in your Strategy. */ function debtOutstanding() external view returns (uint256); /** * View how much the Vault expect this Strategy to return at the current * block, based on its present performance (since its last report). Can be * used to determine expectedReturn in your Strategy. */ function expectedReturn() external view returns (uint256); /** * This is the main contact point where the Strategy interacts with the * Vault. It is critical that this call is handled as intended by the * Strategy. Therefore, this function will be called by BaseStrategy to * make sure the integration is correct. */ function report( uint256 _gain, uint256 _loss, uint256 _debtPayment ) external returns (uint256); /** * This function should only be used in the scenario where the Strategy is * being retired but no migration of the positions are possible, or in the * extreme scenario that the Strategy needs to be put into "Emergency Exit" * mode in order for it to exit as quickly as possible. The latter scenario * could be for any reason that is considered "critical" that the Strategy * exits its position as fast as possible, such as a sudden change in * market conditions leading to losses, or an imminent failure in an * external dependency. */ function revokeStrategy() external; /** * View the governance address of the Vault to assert privileged functions * can only be called by governance. The Strategy serves the Vault, so it * is subject to governance defined by the Vault. */ function governance() external view returns (address); /** * 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); } // Part: iearn-finance/[email protected]/BaseStrategy /** * @title Yearn Base Strategy * @author yearn.finance * @notice * BaseStrategy implements all of the required functionality to interoperate * closely with the Vault contract. This contract should be inherited and the * abstract methods implemented to adapt the Strategy to the particular needs * it has to create a return. * * Of special interest is the relationship between `harvest()` and * `vault.report()'. `harvest()` may be called simply because enough time has * elapsed since the last report, and not because any funds need to be moved * or positions adjusted. This is critical so that the Vault may maintain an * accurate picture of the Strategy's performance. See `vault.report()`, * `harvest()`, and `harvestTrigger()` for further details. */ abstract contract BaseStrategy { using SafeMath for uint256; using SafeERC20 for IERC20; string public metadataURI; /** * @notice * Used to track which version of `StrategyAPI` this Strategy * implements. * @dev The Strategy's version must match the Vault's `API_VERSION`. * @return A string which holds the current API version of this contract. */ function apiVersion() public pure returns (string memory) { return "0.3.2"; } /** * @notice This Strategy's name. * @dev * You can use this field to manage the "version" of this Strategy, e.g. * `StrategySomethingOrOtherV1`. However, "API Version" is managed by * `apiVersion()` function above. * @return This Strategy's name. */ function name() external virtual view returns (string memory); /** * @notice * The amount (priced in want) of the total assets managed by this strategy should not count * towards Yearn's TVL calculations. * @dev * You can override this field to set it to a non-zero value if some of the assets of this * Strategy is somehow delegated inside another part of of Yearn's ecosystem e.g. another Vault. * Note that this value must be strictly less than or equal to the amount provided by * `estimatedTotalAssets()` below, as the TVL calc will be total assets minus delegated assets. * @return * The amount of assets this strategy manages that should not be included in Yearn's Total Value * Locked (TVL) calculation across it's ecosystem. */ function delegatedAssets() external virtual view returns (uint256) { return 0; } VaultAPI public vault; address public strategist; address public rewards; address public keeper; IERC20 public want; // So indexers can keep track of this event Harvested(uint256 profit, uint256 loss, uint256 debtPayment, uint256 debtOutstanding); event UpdatedStrategist(address newStrategist); event UpdatedKeeper(address newKeeper); event UpdatedRewards(address rewards); event 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 = 0; // The maximum number of seconds between harvest calls. See // `setMaxReportDelay()` for more details. uint256 public maxReportDelay = 86400; // ~ once a day // The minimum multiple that `callCost` must be above the credit/profit to // be "justifiable". See `setProfitFactor()` for more details. uint256 public profitFactor = 100; // Use this to adjust the threshold at which running a debt causes a // harvest trigger. See `setDebtThreshold()` for more details. uint256 public debtThreshold = 0; // See note on `setEmergencyExit()`. bool public emergencyExit; // modifiers modifier onlyAuthorized() { require(msg.sender == strategist || msg.sender == governance(), "!authorized"); _; } modifier onlyStrategist() { require(msg.sender == strategist, "!strategist"); _; } modifier onlyGovernance() { require(msg.sender == governance(), "!authorized"); _; } modifier onlyKeepers() { require( msg.sender == keeper || msg.sender == strategist || msg.sender == governance() || msg.sender == vault.guardian() || msg.sender == vault.management(), "!authorized" ); _; } constructor(address _vault) public { _initialize(_vault, msg.sender, msg.sender, msg.sender); } /** * @notice * Initializes the Strategy, this is called only once, when the * contract is deployed. * @dev `_vault` should implement `VaultAPI`. * @param _vault The address of the Vault responsible for this Strategy. */ function _initialize( address _vault, address _strategist, address _rewards, address _keeper ) internal { require(address(want) == address(0), "Strategy already initialized"); vault = VaultAPI(_vault); want = IERC20(vault.token()); want.safeApprove(_vault, uint256(-1)); // Give Vault unlimited access (might save gas) strategist = _strategist; rewards = _rewards; keeper = _keeper; vault.approve(rewards, uint256(-1)); // Allow rewards to be pulled } /** * @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 estimate for the total amount of assets * (principle + return) that this Strategy is currently managing, * denominated in terms of `want` tokens. * * This total should be "realizable" e.g. the total value that could * *actually* be obtained from this Strategy if it were to divest its * entire position based on current on-chain conditions. * @dev * Care must be taken in using this function, since it relies on external * systems, which could be manipulated by the attacker to give an inflated * (or reduced) value produced by this function, based on current on-chain * conditions (e.g. this function is possible to influence through * flashloan attacks, oracle manipulations, or other DeFi attack * mechanisms). * * It is up to governance to use this function to correctly order this * Strategy relative to its peers in the withdrawal queue to minimize * losses for the Vault based on sudden withdrawals. This value should be * higher than the total debt of the Strategy and higher than its expected * value to be "safe". * @return The estimated total assets in this Strategy. */ function estimatedTotalAssets() public virtual view returns (uint256); /* * @notice * Provide an indication of whether this strategy is currently "active" * in that it is managing an active position, or will manage a position in * the future. This should correlate to `harvest()` activity, so that Harvest * events can be tracked externally by indexing agents. * @return True if the strategy is actively managing a position. */ function isActive() public view returns (bool) { return vault.strategies(address(this)).debtRatio > 0 || estimatedTotalAssets() > 0; } /** * Perform any Strategy unwinding or other calls necessary to capture the * "free return" this Strategy has generated since the last time its core * position(s) were adjusted. Examples include unwrapping extra rewards. * This call is only used during "normal operation" of a Strategy, and * should be optimized to minimize losses as much as possible. * * This method returns any realized profits and/or realized losses * incurred, and should return the total amounts of profits/losses/debt * payments (in `want` tokens) for the Vault's accounting (e.g. * `want.balanceOf(this) >= _debtPayment + _profit - _loss`). * * `_debtOutstanding` will be 0 if the Strategy is not past the configured * debt limit, otherwise its value will be how far past the debt limit * the Strategy is. The Strategy's debt limit is configured in the Vault. * * NOTE: `_debtPayment` should be less than or equal to `_debtOutstanding`. * It is okay for it to be less than `_debtOutstanding`, as that * should only used as a guide for how much is left to pay back. * Payments should be made to minimize loss from slippage, debt, * withdrawal fees, etc. * * See `vault.debtOutstanding()`. */ function prepareReturn(uint256 _debtOutstanding) internal virtual returns ( uint256 _profit, uint256 _loss, uint256 _debtPayment ); /** * Perform any adjustments to the core position(s) of this Strategy given * what change the Vault made in the "investable capital" available to the * Strategy. Note that all "free capital" in the Strategy after the report * was made is available for reinvestment. Also note that this number * could be 0, and you should handle that scenario accordingly. * * See comments regarding `_debtOutstanding` on `prepareReturn()`. */ function adjustPosition(uint256 _debtOutstanding) internal virtual; /** * Liquidate up to `_amountNeeded` of `want` of this strategy's positions, * irregardless of slippage. Any excess will be re-invested with `adjustPosition()`. * This function should return the amount of `want` tokens made available by the * liquidation. If there is a difference between them, `_loss` indicates whether the * difference is due to a realized loss, or if there is some other sitution at play * (e.g. locked funds) where the amount made available is less than what is needed. * This function is used during emergency exit instead of `prepareReturn()` to * liquidate all of the Strategy's positions back to the Vault. * * NOTE: The invariant `_liquidatedAmount + _loss <= _amountNeeded` should always be maintained */ function liquidatePosition(uint256 _amountNeeded) internal virtual returns (uint256 _liquidatedAmount, uint256 _loss); /** * @notice * Provide a signal to the keeper that `tend()` should be called. The * keeper will provide the estimated gas cost that they would pay to call * `tend()`, and this function should use that estimate to make a * determination if calling it is "worth it" for the keeper. This is not * the only consideration into issuing this trigger, for example if the * position would be negatively affected if `tend()` is not called * shortly, then this can return `true` even if the keeper might be * "at a loss" (keepers are always reimbursed by Yearn). * @dev * `callCost` must be priced in terms of `want`. * * This call and `harvestTrigger()` should never return `true` at the same * time. * @param callCost The keeper's estimated cast cost to call `tend()`. * @return `true` if `tend()` should be called, `false` otherwise. */ function tendTrigger(uint256 callCost) public virtual view returns (bool) { // We usually don't need tend, but if there are positions that need // active maintainence, overriding this function is how you would // signal for that. return false; } /** * @notice * Adjust the Strategy's position. The purpose of tending isn't to * realize gains, but to maximize yield by reinvesting any returns. * * See comments on `adjustPosition()`. * * This may only be called by governance, the strategist, or the keeper. */ function tend() external onlyKeepers { // Don't take profits with this call, but adjust for better gains adjustPosition(vault.debtOutstanding()); } /** * @notice * Provide a signal to the keeper that `harvest()` should be called. The * keeper will provide the estimated gas cost that they would pay to call * `harvest()`, and this function should use that estimate to make a * determination if calling it is "worth it" for the keeper. This is not * the only consideration into issuing this trigger, for example if the * position would be negatively affected if `harvest()` is not called * shortly, then this can return `true` even if the keeper might be "at a * loss" (keepers are always reimbursed by Yearn). * @dev * `callCost` must be priced in terms of `want`. * * This call and `tendTrigger` should never return `true` at the * same time. * * See `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/master/scripts/keep.py), * or via an integration with the Keep3r network (e.g. * https://github.com/Macarse/GenericKeep3rV2/blob/master/contracts/keep3r/GenericKeep3rV2.sol). * @param callCost The keeper's estimated cast cost to call `harvest()`. * @return `true` if `harvest()` should be called, `false` otherwise. */ function harvestTrigger(uint256 callCost) public virtual view returns (bool) { StrategyParams memory params = vault.strategies(address(this)); // Should not trigger if Strategy is not activated if (params.activation == 0) return false; // Should 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 totalAssets = estimatedTotalAssets(); // NOTE: use the larger of total assets or debt outstanding to book losses properly (debtPayment, loss) = liquidatePosition(totalAssets > debtOutstanding ? totalAssets : debtOutstanding); // NOTE: take up any remainder here as profit if (debtPayment > debtOutstanding) { profit = debtPayment.sub(debtOutstanding); debtPayment = debtOutstanding; } } else { // Free up returns for Vault to pull (profit, loss, debtPayment) = prepareReturn(debtOutstanding); } // Allow Vault to take up to the "harvested" balance of this contract, // which is the amount it has earned since the last time it reported to // the Vault. debtOutstanding = vault.report(profit, loss, debtPayment); // Check if free returns are left, and re-invest them adjustPosition(debtOutstanding); 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 governance or the Vault. * @dev * The new Strategy's Vault must be the same as this Strategy's Vault. * @param _newStrategy The Strategy to migrate to. */ function migrate(address _newStrategy) external { require(msg.sender == address(vault) || msg.sender == governance()); require(BaseStrategy(_newStrategy).vault() == vault); prepareMigration(_newStrategy); want.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 onlyAuthorized { emergencyExit = true; vault.revokeStrategy(); emit EmergencyExitEnabled(); } /** * Override this to add all tokens/tokenized positions this contract * manages on a *persistent* basis (e.g. not just for swapping back to * want ephemerally). * * NOTE: Do *not* include `want`, already included in `sweep` below. * * Example: * * function protectedTokens() internal override view returns (address[] memory) { * address[] memory protected = new address[](3); * protected[0] = tokenA; * protected[1] = tokenB; * protected[2] = tokenC; * return protected; * } */ function protectedTokens() internal virtual view returns (address[] memory); /** * @notice * Removes tokens from this Strategy that are not the type of tokens * managed by this Strategy. This may be used in case of accidentally * sending the wrong kind of token to this Strategy. * * Tokens will be sent to `governance()`. * * This will fail if an attempt is made to sweep `want`, or any tokens * that are protected by this Strategy. * * This may only be called by governance. * @dev * Implement `protectedTokens()` to specify any additional tokens that * should be protected from sweeping in addition to `want`. * @param _token The token to transfer out of this vault. */ function sweep(address _token) external onlyGovernance { require(_token != address(want), "!want"); require(_token != address(vault), "!shares"); address[] memory _protectedTokens = protectedTokens(); for (uint256 i; i < _protectedTokens.length; i++) require(_token != _protectedTokens[i], "!protected"); IERC20(_token).safeTransfer(governance(), IERC20(_token).balanceOf(address(this))); } } // Part: iearn-finance/[email protected]/BaseStrategyInitializable abstract contract BaseStrategyInitializable is BaseStrategy { constructor(address _vault) public BaseStrategy(_vault) {} function initialize( address _vault, address _strategist, address _rewards, address _keeper ) external { _initialize(_vault, _strategist, _rewards, _keeper); } } // File: Strategy.sol /******************** * * A lender optimisation strategy for any erc20 asset * https://github.com/Grandthrax/yearnV2-generic-lender-strat * v0.3.1 * * This strategy works by taking plugins designed for standard lending platforms * It automatically chooses the best yield generating platform and adjusts accordingly * The adjustment is sub optimal so there is an additional option to manually set position * ********************* */ contract Strategy is BaseStrategyInitializable { using SafeERC20 for IERC20; using Address for address; using SafeMath for uint256; address public constant uniswapRouter = address(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); address public constant weth = address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); uint256 public withdrawalThreshold = 1e16; uint256 public constant SECONDSPERYEAR = 31556952; IGenericLender[] public lenders; bool public externalOracle = false; address public wantToEthOracle; event Cloned(address indexed clone); constructor(address _vault) public BaseStrategyInitializable(_vault) { debtThreshold = 100 * 1e18; } function clone(address _vault) external returns (address newStrategy) { newStrategy = 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); } function setWithdrawalThreshold(uint256 _threshold) external onlyAuthorized { withdrawalThreshold = _threshold; } function setPriceOracle(address _oracle) external onlyAuthorized { wantToEthOracle = _oracle; } function name() external view override returns (string memory) { return "StrategyLenderYieldOptimiser"; } //management functions //add lenders for the strategy to choose between // only governance to stop strategist adding dodgy lender function addLender(address a) public onlyGovernance { IGenericLender n = IGenericLender(a); require(n.strategy() == address(this), "Undocked Lender"); for (uint256 i = 0; i < lenders.length; i++) { require(a != address(lenders[i]), "Already Added"); } lenders.push(n); } //but strategist can remove for safety function safeRemoveLender(address a) public onlyAuthorized { _removeLender(a, false); } function forceRemoveLender(address a) public onlyAuthorized { _removeLender(a, true); } //force removes the lender even if it still has a balance function _removeLender(address a, bool force) internal { for (uint256 i = 0; i < lenders.length; i++) { if (a == address(lenders[i])) { bool allWithdrawn = lenders[i].withdrawAll(); if (!force) { require(allWithdrawn, "WITHDRAW FAILED"); } //put the last index here //remove last index if (i != lenders.length - 1) { lenders[i] = lenders[lenders.length - 1]; } //pop shortens array by 1 thereby deleting the last index lenders.pop(); //if balance to spend we might as well put it into the best lender if (want.balanceOf(address(this)) > 0) { adjustPosition(0); } return; } } require(false, "NOT LENDER"); } //we could make this more gas efficient but it is only used by a view function struct lendStatus { string name; uint256 assets; uint256 rate; address add; } //Returns the status of all lenders attached the strategy function lendStatuses() public view returns (lendStatus[] memory) { lendStatus[] memory statuses = new lendStatus[](lenders.length); for (uint256 i = 0; i < lenders.length; i++) { lendStatus memory s; s.name = lenders[i].lenderName(); s.add = address(lenders[i]); s.assets = lenders[i].nav(); s.rate = lenders[i].apr(); statuses[i] = s; } return statuses; } // lent assets plus loose assets function estimatedTotalAssets() public view override returns (uint256) { uint256 nav = lentTotalAssets(); nav = nav.add(want.balanceOf(address(this))); return nav; } function numLenders() public view returns (uint256) { return lenders.length; } //the weighted apr of all lenders. sum(nav * apr)/totalNav function estimatedAPR() public view returns (uint256) { uint256 bal = estimatedTotalAssets(); if (bal == 0) { return 0; } uint256 weightedAPR = 0; for (uint256 i = 0; i < lenders.length; i++) { weightedAPR = weightedAPR.add(lenders[i].weightedApr()); } return weightedAPR.div(bal); } //Estimates the impact on APR if we add more money. It does not take into account adjusting position function _estimateDebtLimitIncrease(uint256 change) internal view returns (uint256) { uint256 highestAPR = 0; uint256 aprChoice = 0; uint256 assets = 0; for (uint256 i = 0; i < lenders.length; i++) { uint256 apr = lenders[i].aprAfterDeposit(change); if (apr > highestAPR) { aprChoice = i; highestAPR = apr; assets = lenders[i].nav(); } } uint256 weightedAPR = highestAPR.mul(assets.add(change)); for (uint256 i = 0; i < lenders.length; i++) { if (i != aprChoice) { weightedAPR = weightedAPR.add(lenders[i].weightedApr()); } } uint256 bal = estimatedTotalAssets().add(change); return weightedAPR.div(bal); } //Estimates debt limit decrease. It is not accurate and should only be used for very broad decision making function _estimateDebtLimitDecrease(uint256 change) internal view returns (uint256) { uint256 lowestApr = uint256(-1); uint256 aprChoice = 0; for (uint256 i = 0; i < lenders.length; i++) { uint256 apr = lenders[i].aprAfterDeposit(change); if (apr < lowestApr) { aprChoice = i; lowestApr = apr; } } uint256 weightedAPR = 0; for (uint256 i = 0; i < lenders.length; i++) { if (i != aprChoice) { weightedAPR = weightedAPR.add(lenders[i].weightedApr()); } else { uint256 asset = lenders[i].nav(); if (asset < change) { //simplistic. not accurate change = asset; } weightedAPR = weightedAPR.add(lowestApr.mul(change)); } } uint256 bal = estimatedTotalAssets().add(change); return weightedAPR.div(bal); } //estimates highest and lowest apr lenders. Public for debugging purposes but not much use to general public function estimateAdjustPosition() public view returns ( uint256 _lowest, uint256 _lowestApr, uint256 _highest, uint256 _potential ) { //all loose assets are to be invested uint256 looseAssets = want.balanceOf(address(this)); // our simple algo // get the lowest apr strat // cycle through and see who could take its funds plus want for the highest apr _lowestApr = uint256(-1); _lowest = 0; uint256 lowestNav = 0; for (uint256 i = 0; i < lenders.length; i++) { if (lenders[i].hasAssets()) { uint256 apr = lenders[i].apr(); if (apr < _lowestApr) { _lowestApr = apr; _lowest = i; lowestNav = lenders[i].nav(); } } } uint256 toAdd = lowestNav.add(looseAssets); uint256 highestApr = 0; _highest = 0; for (uint256 i = 0; i < lenders.length; i++) { uint256 apr; apr = lenders[i].aprAfterDeposit(looseAssets); if (apr > highestApr) { highestApr = apr; _highest = i; } } //if we can improve apr by withdrawing we do so _potential = lenders[_highest].aprAfterDeposit(toAdd); } //gives estiomate of future APR with a change of debt limit. Useful for governance to decide debt limits function estimatedFutureAPR(uint256 newDebtLimit) public view returns (uint256) { uint256 oldDebtLimit = vault.strategies(address(this)).totalDebt; uint256 change; if (oldDebtLimit < newDebtLimit) { change = newDebtLimit - oldDebtLimit; return _estimateDebtLimitIncrease(change); } else { change = oldDebtLimit - newDebtLimit; return _estimateDebtLimitDecrease(change); } } //cycle all lenders and collect balances function lentTotalAssets() public view returns (uint256) { uint256 nav = 0; for (uint256 i = 0; i < lenders.length; i++) { nav = nav.add(lenders[i].nav()); } return nav; } //we need to free up profit plus _debtOutstanding. //If _debtOutstanding is more than we can free we get as much as possible // should be no way for there to be a loss. we hope... function prepareReturn(uint256 _debtOutstanding) internal override returns ( uint256 _profit, uint256 _loss, uint256 _debtPayment ) { _profit = 0; _loss = 0; //for clarity _debtPayment = _debtOutstanding; uint256 lentAssets = lentTotalAssets(); uint256 looseAssets = want.balanceOf(address(this)); uint256 total = looseAssets.add(lentAssets); if (lentAssets == 0) { //no position to harvest or profit to report if (_debtPayment > looseAssets) { //we can only return looseAssets _debtPayment = looseAssets; } return (_profit, _loss, _debtPayment); } uint256 debt = vault.strategies(address(this)).totalDebt; if (total > debt) { _profit = total - debt; uint256 amountToFree = _profit.add(_debtPayment); //we need to add outstanding to our profit //dont need to do logic if there is nothiing to free if (amountToFree > 0 && looseAssets < amountToFree) { //withdraw what we can withdraw _withdrawSome(amountToFree.sub(looseAssets)); uint256 newLoose = want.balanceOf(address(this)); //if we dont have enough money adjust _debtOutstanding and only change profit if needed if (newLoose < amountToFree) { if (_profit > newLoose) { _profit = newLoose; _debtPayment = 0; } else { _debtPayment = Math.min(newLoose - _profit, _debtPayment); } } } } else { //serious loss should never happen but if it does lets record it accurately _loss = debt - total; uint256 amountToFree = _loss.add(_debtPayment); if (amountToFree > 0 && looseAssets < amountToFree) { //withdraw what we can withdraw _withdrawSome(amountToFree.sub(looseAssets)); uint256 newLoose = want.balanceOf(address(this)); //if we dont have enough money adjust _debtOutstanding and only change profit if needed if (newLoose < amountToFree) { if (_loss > newLoose) { _loss = newLoose; _debtPayment = 0; } else { _debtPayment = Math.min(newLoose - _loss, _debtPayment); } } } } } /* * Key logic. * The algorithm moves assets from lowest return to highest * like a very slow idiots bubble sort * we ignore debt outstanding for an easy life */ function adjustPosition(uint256 _debtOutstanding) internal override { _debtOutstanding; //ignored. we handle it in prepare return //emergency exit is dealt with at beginning of harvest if (emergencyExit) { return; } //we just keep all money in want if we dont have any lenders if (lenders.length == 0) { return; } (uint256 lowest, uint256 lowestApr, uint256 highest, uint256 potential) = estimateAdjustPosition(); if (potential > lowestApr) { //apr should go down after deposit so wont be withdrawing from self lenders[lowest].withdrawAll(); } uint256 bal = want.balanceOf(address(this)); if (bal > 0) { want.safeTransfer(address(lenders[highest]), bal); lenders[highest].deposit(); } } struct lenderRatio { address lender; //share x 1000 uint16 share; } //share must add up to 1000. 500 means 50% etc function manualAllocation(lenderRatio[] memory _newPositions) public onlyAuthorized { uint256 share = 0; for (uint256 i = 0; i < lenders.length; i++) { lenders[i].withdrawAll(); } uint256 assets = want.balanceOf(address(this)); for (uint256 i = 0; i < _newPositions.length; i++) { bool found = false; //might be annoying and expensive to do this second loop but worth it for safety for (uint256 j = 0; j < lenders.length; j++) { if (address(lenders[j]) == _newPositions[i].lender) { found = true; } } require(found, "NOT LENDER"); share = share.add(_newPositions[i].share); uint256 toSend = assets.mul(_newPositions[i].share).div(1000); want.safeTransfer(_newPositions[i].lender, toSend); IGenericLender(_newPositions[i].lender).deposit(); } require(share == 1000, "SHARE!=1000"); } //cycle through withdrawing from worst rate first function _withdrawSome(uint256 _amount) internal returns (uint256 amountWithdrawn) { if (lenders.length == 0) { return 0; } //dont withdraw dust if (_amount < withdrawalThreshold) { return 0; } amountWithdrawn = 0; //most situations this will only run once. Only big withdrawals will be a gas guzzler uint256 j = 0; while (amountWithdrawn < _amount) { uint256 lowestApr = uint256(-1); uint256 lowest = 0; for (uint256 i = 0; i < lenders.length; i++) { if (lenders[i].hasAssets()) { uint256 apr = lenders[i].apr(); if (apr < lowestApr) { lowestApr = apr; lowest = i; } } } if (!lenders[lowest].hasAssets()) { return amountWithdrawn; } amountWithdrawn = amountWithdrawn.add(lenders[lowest].withdraw(_amount - amountWithdrawn)); j++; //dont want infinite loop if (j >= 6) { return amountWithdrawn; } } } /* * Liquidate as many assets as possible to `want`, irregardless of slippage, * up to `_amountNeeded`. Any excess should be re-invested here as well. */ function liquidatePosition(uint256 _amountNeeded) internal override returns (uint256 _amountFreed, uint256 _loss) { uint256 _balance = want.balanceOf(address(this)); if (_balance >= _amountNeeded) { //if we don't set reserve here withdrawer will be sent our full balance return (_amountNeeded, 0); } else { uint256 received = _withdrawSome(_amountNeeded - _balance).add(_balance); if (received >= _amountNeeded) { return (_amountNeeded, 0); } else { return (received, 0); } } } function harvestTrigger(uint256 callCost) public view override returns (bool) { uint256 wantCallCost = _callCostToWant(callCost); return super.harvestTrigger(wantCallCost); } function ethToWant(uint256 _amount) internal view returns (uint256) { address[] memory path = new address[](2); path = new address[](2); path[0] = weth; path[1] = address(want); uint256[] memory amounts = IUni(uniswapRouter).getAmountsOut(_amount, path); return amounts[amounts.length - 1]; } function _callCostToWant(uint256 callCost) internal view returns (uint256) { uint256 wantCallCost; //three situations //1 currency is eth so no change. //2 we use uniswap swap price //3 we use external oracle if (address(want) == weth) { wantCallCost = callCost; } else if (wantToEthOracle == address(0)) { wantCallCost = ethToWant(callCost); } else { wantCallCost = IWantToEth(wantToEthOracle).ethToWant(callCost); } return wantCallCost; } function tendTrigger(uint256 callCost) public view override returns (bool) { // make sure to call tendtrigger with same callcost as harvestTrigger if (harvestTrigger(callCost)) { return false; } //now let's check if there is better apr somewhere else. //If there is and profit potential is worth changing then lets do it (uint256 lowest, uint256 lowestApr, , uint256 potential) = estimateAdjustPosition(); //if protential > lowestApr it means we are changing horses if (potential > lowestApr) { uint256 nav = lenders[lowest].nav(); //To calculate our potential profit increase we work out how much extra //we would make in a typical harvest interlude. That is maxReportingDelay //then we see if the extra profit is worth more than the gas cost * profitFactor //safe math not needed here //apr is scaled by 1e18 so we downscale here uint256 profitIncrease = (nav.mul(potential) - nav.mul(lowestApr)).div(1e18).mul(maxReportDelay).div(SECONDSPERYEAR); uint256 wantCallCost = _callCostToWant(callCost); return (wantCallCost.mul(profitFactor) < profitIncrease); } } /* * revert if we can't withdraw full balance */ function prepareMigration(address _newStrategy) internal override { uint256 outstanding = vault.strategies(address(this)).totalDebt; (, uint256 loss, uint256 wantBalance) = prepareReturn(outstanding); } function protectedTokens() internal view override returns (address[] memory) { address[] memory protected = new address[](1); protected[0] = address(want); return protected; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"clone","type":"address"}],"name":"Cloned","type":"event"},{"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":"SECONDSPERYEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"a","type":"address"}],"name":"addLender","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"apiVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"clone","outputs":[{"internalType":"address","name":"newStrategy","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_strategist","type":"address"},{"internalType":"address","name":"_rewards","type":"address"},{"internalType":"address","name":"_keeper","type":"address"}],"name":"clone","outputs":[{"internalType":"address","name":"newStrategy","type":"address"}],"stateMutability":"nonpayable","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":"emergencyExit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"estimateAdjustPosition","outputs":[{"internalType":"uint256","name":"_lowest","type":"uint256"},{"internalType":"uint256","name":"_lowestApr","type":"uint256"},{"internalType":"uint256","name":"_highest","type":"uint256"},{"internalType":"uint256","name":"_potential","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"estimatedAPR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newDebtLimit","type":"uint256"}],"name":"estimatedFutureAPR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"estimatedTotalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"externalOracle","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"a","type":"address"}],"name":"forceRemoveLender","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"callCost","type":"uint256"}],"name":"harvestTrigger","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_strategist","type":"address"},{"internalType":"address","name":"_rewards","type":"address"},{"internalType":"address","name":"_keeper","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","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":[],"name":"lendStatuses","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"uint256","name":"rate","type":"uint256"},{"internalType":"address","name":"add","type":"address"}],"internalType":"struct Strategy.lendStatus[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lenders","outputs":[{"internalType":"contract IGenericLender","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lentTotalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"lender","type":"address"},{"internalType":"uint16","name":"share","type":"uint16"}],"internalType":"struct Strategy.lenderRatio[]","name":"_newPositions","type":"tuple[]"}],"name":"manualAllocation","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":"numLenders","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":[{"internalType":"address","name":"a","type":"address"}],"name":"safeRemoveLender","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_debtThreshold","type":"uint256"}],"name":"setDebtThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setEmergencyExit","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":"address","name":"_oracle","type":"address"}],"name":"setPriceOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_profitFactor","type":"uint256"}],"name":"setProfitFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewards","type":"address"}],"name":"setRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategist","type":"address"}],"name":"setStrategist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_threshold","type":"uint256"}],"name":"setWithdrawalThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"callCost","type":"uint256"}],"name":"tendTrigger","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapRouter","outputs":[{"internalType":"address","name":"","type":"address"}],"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":[],"name":"wantToEthOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","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":"withdrawalThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405260006006819055620151806007556064600855600955662386f26fc10000600b55600d805460ff191690553480156200003c57600080fd5b5060405162005797380380620057978339810160408190526200005f9162000523565b80806200006f8133808062000085565b505068056bc75e2d63100000600955506200075c565b6005546001600160a01b031615620000ba5760405162461bcd60e51b8152600401620000b19062000614565b60405180910390fd5b600180546001600160a01b0319166001600160a01b03868116919091179182905560408051637e062a3560e11b81529051929091169163fc0c546a91600480820192602092909190829003018186803b1580156200011757600080fd5b505afa1580156200012c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000152919062000523565b600580546001600160a01b0319166001600160a01b0392831617908190556200018c91168560001962000254602090811b62002a9b17901c565b600280546001600160a01b038086166001600160a01b03199283161790925560038054858416908316179081905560048054858516931692909217825560015460405163095ea7b360e01b81529084169363095ea7b393620001f793909116916000199101620005c6565b602060405180830381600087803b1580156200021257600080fd5b505af115801562000227573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200024d919062000553565b5050505050565b801580620002e35750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e906200028d9030908690600401620005ac565b60206040518083038186803b158015620002a657600080fd5b505afa158015620002bb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002e1919062000575565b155b620003025760405162461bcd60e51b8152600401620000b190620006cc565b6200035d8363095ea7b360e01b848460405160240162000324929190620005c6565b60408051808303601f190181529190526020810180516001600160e01b0319939093166001600160e01b03938416179052906200036216565b505050565b6060620003be826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316620003fe60201b62002b95179092919060201c565b8051909150156200035d5780806020019051810190620003df919062000553565b6200035d5760405162461bcd60e51b8152600401620000b19062000682565b60606200040f848460008562000417565b949350505050565b60606200042485620004e9565b620004435760405162461bcd60e51b8152600401620000b1906200064b565b60006060866001600160a01b031685876040516200046291906200058e565b60006040518083038185875af1925050503d8060008114620004a1576040519150601f19603f3d011682016040523d82523d6000602084013e620004a6565b606091505b50915091508115620004bc5791506200040f9050565b805115620004cd5780518082602001fd5b8360405162461bcd60e51b8152600401620000b19190620005df565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906200040f575050151592915050565b60006020828403121562000535578081fd5b81516001600160a01b03811681146200054c578182fd5b9392505050565b60006020828403121562000565578081fd5b815180151581146200054c578182fd5b60006020828403121562000587578081fd5b5051919050565b60008251620005a281846020870162000729565b9190910192915050565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b60006020825282518060208401526200060081604085016020870162000729565b601f01601f19169190910160400192915050565b6020808252601c908201527f537472617465677920616c726561647920696e697469616c697a656400000000604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000606082015260800190565b60005b83811015620007465781810151838201526020016200072c565b8381111562000756576000848401525b50505050565b61502b806200076c6000396000f3fe608060405234801561001057600080fd5b50600436106103425760003560e01c806376ee75d8116101b8578063af306e1611610104578063ed882c2b116100a2578063f8c8765e1161007c578063f8c8765e14610623578063fbfa77cf14610636578063fcc5f59a1461063e578063fcf2d0ad1461065357610342565b8063ed882c2b146105f5578063efbb5cb014610608578063f017c92f1461061057610342565b8063ce5494bb116100de578063ce5494bb146105a4578063d0511842146105b7578063d6c38271146105ca578063ec38a862146105e257610342565b8063af306e1614610581578063bb927c4614610589578063c7b9d5301461059157610342565b80638e6350e21161017157806393084b341161014b57806393084b341461055657806395e80c50146105695780639ec5a89414610571578063aced16611461057957610342565b80638e6350e21461052857806391397ab414610530578063929eea211461054357610342565b806376ee75d8146104cc5780637985fd51146104df5780637a4b1c14146104e75780638124b78e146104fa5780638baf29571461050d5780638cdfe1661461052057610342565b8063397dc14911610292578063530e784f11610230578063650d18801161020a578063650d18801461048b578063735de9f71461049e578063748747e6146104a6578063750521f5146104b957610342565b8063530e784f146104685780635641ec031461047b5780635a5cd45e1461048357610342565b8063440368a31161026c578063440368a31461043d5780634641257d1461044557806346d8cf3f1461044d5780634786b0cb1461045557610342565b8063397dc1491461040f57806339a172a8146104225780633fc8cef31461043557610342565b80631f1fcd51116102ff57806325829410116102d957806325829410146103e457806328b7ccf7146103ec5780632a5dc8c1146103f45780632e1a7d4d146103fc57610342565b80631f1fcd51146103b25780631fe4a686146103c757806322f3e2d4146103cf57610342565b806301681a621461034757806303ee438c1461035c57806306fdde031461037a5780630e6e15f0146103825780630f969b87146103975780631d12f28b146103aa575b600080fd5b61035a610355366004614675565b61065b565b005b6103646107fa565b6040516103719190614ba4565b60405180910390f35b610364610888565b61038a6108c0565b6040516103719190614ecd565b61035a6103a53660046149fd565b610977565b61038a610a04565b6103ba610a0a565b6040516103719190614a75565b6103ba610a19565b6103d7610a28565b6040516103719190614b6a565b610364610aca565b61038a610ae9565b6103ba610aef565b61038a61040a3660046149fd565b610b03565b61038a61041d3660046149fd565b610b5e565b61035a6104303660046149fd565b610c1c565b6103ba610c9e565b61035a610cb6565b61035a610edf565b6103d7611249565b61035a6104633660046149fd565b611252565b61035a610476366004614675565b6112a4565b6103d7611319565b61038a611322565b6103d76104993660046149fd565b6113c1565b6103ba61150e565b61035a6104b4366004614675565b611526565b61035a6104c7366004614886565b6115d1565b61035a6104da366004614675565b611668565b61038a6116c3565b61035a6104f5366004614708565b6116c9565b6103ba610508366004614675565b611a11565b61035a61051b366004614675565b611a95565b61038a611aed565b61038a611af3565b61035a61053e3660046149fd565b611af8565b6103ba6105513660046149fd565b611b7a565b61035a610564366004614675565b611ba1565b61038a611d2c565b6103ba611d32565b6103ba611d41565b61038a611d50565b61038a611d58565b61035a61059f366004614675565b611d5e565b61035a6105b2366004614675565b611e09565b6103ba6105c53660046146ad565b611f77565b6105d2612064565b6040516103719493929190614f42565b61035a6105f0366004614675565b61244a565b6103d76106033660046149fd565b6125e1565b61038a6125ff565b61035a61061e3660046149fd565b61269e565b61035a6106313660046146ad565b612720565b6103ba612732565b610646612741565b6040516103719190614ae7565b61035a6129b7565b610663612bac565b6001600160a01b0316336001600160a01b03161461069c5760405162461bcd60e51b815260040161069390614dbb565b60405180910390fd5b6005546001600160a01b03828116911614156106ca5760405162461bcd60e51b815260040161069390614c05565b6001546001600160a01b03828116911614156106f85760405162461bcd60e51b815260040161069390614d3c565b6060610702612c29565b905060005b815181101561075d5781818151811061071c57fe5b60200260200101516001600160a01b0316836001600160a01b031614156107555760405162461bcd60e51b815260040161069390614e2a565b600101610707565b506107f6610769612bac565b6040516370a0823160e01b81526001600160a01b038516906370a0823190610795903090600401614a75565b60206040518083038186803b1580156107ad57600080fd5b505afa1580156107c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e59190614a15565b6001600160a01b0385169190612c85565b5050565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156108805780601f1061085557610100808354040283529160200191610880565b820191906000526020600020905b81548152906001019060200180831161086357829003601f168201915b505050505081565b60408051808201909152601c81527f53747261746567794c656e6465725969656c644f7074696d697365720000000060208201525b90565b600080805b600c5481101561097157610967600c82815481106108df57fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b15801561092857600080fd5b505afa15801561093c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109609190614a15565b8390612ca4565b91506001016108c5565b50905090565b6002546001600160a01b03163314806109a85750610993612bac565b6001600160a01b0316336001600160a01b0316145b6109c45760405162461bcd60e51b815260040161069390614dbb565b60098190556040517fa68ba126373d04c004c5748c300c9fca12bd444b3d4332e261f3bd2bac4a8600906109f9908390614ecd565b60405180910390a150565b60095481565b6005546001600160a01b031681565b6002546001600160a01b031681565b6001546040516339ebf82360e01b815260009182916001600160a01b03909116906339ebf82390610a5d903090600401614a75565b6101206040518083038186803b158015610a7657600080fd5b505afa158015610a8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aae919061497f565b604001511180610ac557506000610ac36125ff565b115b905090565b604080518082019091526005815264181719971960d91b602082015290565b60075481565b600d5461010090046001600160a01b031681565b6001546000906001600160a01b03163314610b305760405162461bcd60e51b815260040161069390614d1c565b6000610b3b83612cc9565b600554909350909150610b58906001600160a01b03163383612c85565b50919050565b6001546040516339ebf82360e01b815260009182916001600160a01b03909116906339ebf82390610b93903090600401614a75565b6101206040518083038186803b158015610bac57600080fd5b505afa158015610bc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be4919061497f565b60c001519050600083821015610c0a5750808303610c0181612da4565b92505050610c17565b50828103610c0181612f65565b919050565b6002546001600160a01b0316331480610c4d5750610c38612bac565b6001600160a01b0316336001600160a01b0316145b610c695760405162461bcd60e51b815260040161069390614dbb565b60068190556040517fbb2c369a0355a34b02ab5fce0643150c87e1c8dfe7c918d465591879f57948b1906109f9908390614ecd565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6004546001600160a01b0316331480610cd957506002546001600160a01b031633145b80610cfc5750610ce7612bac565b6001600160a01b0316336001600160a01b0316145b80610d9d5750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b158015610d5057600080fd5b505afa158015610d64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d889190614691565b6001600160a01b0316336001600160a01b0316145b80610e3e5750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b158015610df157600080fd5b505afa158015610e05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e299190614691565b6001600160a01b0316336001600160a01b0316145b610e5a5760405162461bcd60e51b815260040161069390614dbb565b6001546040805163bf3759b560e01b81529051610edd926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b158015610ea057600080fd5b505afa158015610eb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ed89190614a15565b613139565b565b6004546001600160a01b0316331480610f0257506002546001600160a01b031633145b80610f255750610f10612bac565b6001600160a01b0316336001600160a01b0316145b80610fc65750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b158015610f7957600080fd5b505afa158015610f8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb19190614691565b6001600160a01b0316336001600160a01b0316145b806110675750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b15801561101a57600080fd5b505afa15801561102e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110529190614691565b6001600160a01b0316336001600160a01b0316145b6110835760405162461bcd60e51b815260040161069390614dbb565b6000806000600160009054906101000a90046001600160a01b03166001600160a01b031663bf3759b56040518163ffffffff1660e01b815260040160206040518083038186803b1580156110d657600080fd5b505afa1580156110ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110e9190614a15565b600a5490915060009060ff16156111645760006111296125ff565b905061114283821161113b578361113d565b815b612cc9565b945091508282111561115e576111588284613343565b94508291505b50611175565b61116d82613385565b919550935090505b6001546040516328766ebf60e21b81526001600160a01b039091169063a1d9bafc906111a990879087908690600401614f2c565b602060405180830381600087803b1580156111c357600080fd5b505af11580156111d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fb9190614a15565b915061120682613139565b7f4c0f499ffe6befa0ca7c826b0916cf87bea98de658013e76938489368d60d5098484838560405161123b9493929190614f42565b60405180910390a150505050565b600d5460ff1681565b6002546001600160a01b0316331480611283575061126e612bac565b6001600160a01b0316336001600160a01b0316145b61129f5760405162461bcd60e51b815260040161069390614dbb565b600b55565b6002546001600160a01b03163314806112d557506112c0612bac565b6001600160a01b0316336001600160a01b0316145b6112f15760405162461bcd60e51b815260040161069390614dbb565b600d80546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600a5460ff1681565b60008061132d6125ff565b90508061133e5760009150506108bd565b6000805b600c548110156113af576113a5600c828154811061135c57fe5b600091825260209182902001546040805163116ac4a360e01b815290516001600160a01b039092169263116ac4a392600480840193829003018186803b15801561092857600080fd5b9150600101611342565b506113ba81836136b4565b9250505090565b60006113cc826125e1565b156113d957506000610c17565b60008060006113e6612064565b9350509250925081811115611506576000600c848154811061140457fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b15801561144d57600080fd5b505afa158015611461573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114859190614a15565b905060006114d36301e185586114cd6007546114c7670de0b6b3a76400006114b68a896136f690919063ffffffff16565b6114c0898b6136f6565b03906136b4565b906136f6565b906136b4565b905060006114e088613730565b9050816114f8600854836136f690919063ffffffff16565b109650505050505050610c17565b505050919050565b737a250d5630b4cf539739df2c5dacb4c659f2488d81565b6002546001600160a01b03163314806115575750611542612bac565b6001600160a01b0316336001600160a01b0316145b6115735760405162461bcd60e51b815260040161069390614dbb565b6001600160a01b03811661158657600080fd5b600480546001600160a01b0319166001600160a01b0383161790556040517f2f202ddb4a2e345f6323ed90f8fc8559d770a7abbbeee84dde8aca3351fe7154906109f9908390614a75565b6002546001600160a01b031633148061160257506115ed612bac565b6001600160a01b0316336001600160a01b0316145b61161e5760405162461bcd60e51b815260040161069390614dbb565b61162a60008383614565565b507f300e67d5a415b6d015a471d9c7b95dd58f3e8290af965e84e0f845de2996dda6828260405161165c929190614b75565b60405180910390a15050565b6002546001600160a01b03163314806116995750611684612bac565b6001600160a01b0316336001600160a01b0316145b6116b55760405162461bcd60e51b815260040161069390614dbb565b6116c081600161380c565b50565b600b5481565b6002546001600160a01b03163314806116fa57506116e5612bac565b6001600160a01b0316336001600160a01b0316145b6117165760405162461bcd60e51b815260040161069390614dbb565b6000805b600c548110156117ca57600c818154811061173157fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561178957600080fd5b505af115801561179d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c19190614866565b5060010161171a565b506005546040516370a0823160e01b81526000916001600160a01b0316906370a08231906117fc903090600401614a75565b60206040518083038186803b15801561181457600080fd5b505afa158015611828573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184c9190614a15565b905060005b83518110156119ea576000805b600c548110156118be5785838151811061187457fe5b6020026020010151600001516001600160a01b0316600c828154811061189657fe5b6000918252602090912001546001600160a01b031614156118b657600191505b60010161185e565b50806118dc5760405162461bcd60e51b815260040161069390614c80565b61190a8583815181106118eb57fe5b60200260200101516020015161ffff1685612ca490919063ffffffff16565b935060006119426103e86114cd88868151811061192357fe5b60200260200101516020015161ffff16876136f690919063ffffffff16565b905061197286848151811061195357fe5b6020908102919091010151516005546001600160a01b03169083612c85565b85838151811061197e57fe5b6020026020010151600001516001600160a01b031663d0e30db06040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156119c457600080fd5b505af11580156119d8573d6000803e3d6000fd5b50506001909401935061185192505050565b50816103e814611a0c5760405162461bcd60e51b815260040161069390614c24565b505050565b6040516368288c2160e11b8152600090309063d051184290611a3d908590339081908190600401614aa3565b602060405180830381600087803b158015611a5757600080fd5b505af1158015611a6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8f9190614691565b92915050565b6002546001600160a01b0316331480611ac65750611ab1612bac565b6001600160a01b0316336001600160a01b0316145b611ae25760405162461bcd60e51b815260040161069390614dbb565b6116c081600061380c565b60085481565b600090565b6002546001600160a01b0316331480611b295750611b14612bac565b6001600160a01b0316336001600160a01b0316145b611b455760405162461bcd60e51b815260040161069390614dbb565b60088190556040517fd94596337df4c2f0f44d30a7fc5db1c7bb60d9aca4185ed77c6fd96eb45ec298906109f9908390614ecd565b600c8181548110611b8757fe5b6000918252602090912001546001600160a01b0316905081565b611ba9612bac565b6001600160a01b0316336001600160a01b031614611bd95760405162461bcd60e51b815260040161069390614dbb565b6000819050306001600160a01b0316816001600160a01b031663a8c62e766040518163ffffffff1660e01b815260040160206040518083038186803b158015611c2157600080fd5b505afa158015611c35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c599190614691565b6001600160a01b031614611c7f5760405162461bcd60e51b815260040161069390614bdc565b60005b600c54811015611cd857600c8181548110611c9957fe5b6000918252602090912001546001600160a01b0384811691161415611cd05760405162461bcd60e51b815260040161069390614d5d565b600101611c82565b50600c80546001810182556000919091527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180546001600160a01b0319166001600160a01b039290921691909117905550565b60065481565b6003546001600160a01b031681565b6004546001600160a01b031681565b6301e1855881565b600c5490565b6002546001600160a01b0316331480611d8f5750611d7a612bac565b6001600160a01b0316336001600160a01b0316145b611dab5760405162461bcd60e51b815260040161069390614dbb565b6001600160a01b038116611dbe57600080fd5b600280546001600160a01b0319166001600160a01b0383161790556040517f352ececae6d7d1e6d26bcf2c549dfd55be1637e9b22dc0cf3b71ddb36097a6b4906109f9908390614a75565b6001546001600160a01b0316331480611e3a5750611e25612bac565b6001600160a01b0316336001600160a01b0316145b611e4357600080fd5b6001546040805163fbfa77cf60e01b815290516001600160a01b039283169284169163fbfa77cf916004808301926020929190829003018186803b158015611e8a57600080fd5b505afa158015611e9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec29190614691565b6001600160a01b031614611ed557600080fd5b611ede81613a64565b6005546040516370a0823160e01b81526116c09183916001600160a01b03909116906370a0823190611f14903090600401614a75565b60206040518083038186803b158015611f2c57600080fd5b505afa158015611f40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f649190614a15565b6005546001600160a01b03169190612c85565b604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81523060601b601482018190526e5af43d82803e903d91602b57fd5bf360881b602883015260009160378184f0604051637c643b2f60e11b81529093506001600160a01b038416915063f8c8765e90611ff5908990899089908990600401614aa3565b600060405180830381600087803b15801561200f57600080fd5b505af1158015612023573d6000803e3d6000fd5b50506040516001600160a01b03851692507f783540fb4221a3238720dc7038937d0d79982bcf895274aa6ad179f82cf0d53c9150600090a250949350505050565b6005546040516370a0823160e01b815260009182918291829182916001600160a01b0316906370a082319061209d903090600401614a75565b60206040518083038186803b1580156120b557600080fd5b505afa1580156120c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ed9190614a15565b90506000199350600094506000805b600c548110156122d457600c818154811061211357fe5b6000918252602091829020015460408051635be9b2d360e01b815290516001600160a01b0390921692635be9b2d392600480840193829003018186803b15801561215c57600080fd5b505afa158015612170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121949190614866565b156122cc576000600c82815481106121a857fe5b60009182526020918290200154604080516357ded9c960e01b815290516001600160a01b03909216926357ded9c992600480840193829003018186803b1580156121f157600080fd5b505afa158015612205573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122299190614a15565b9050868110156122ca57809650819750600c828154811061224657fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b15801561228f57600080fd5b505afa1580156122a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c79190614a15565b92505b505b6001016120fc565b5060006122e18284612ca4565b9050600080955060005b600c548110156123a7576000600c828154811061230457fe5b60009182526020909120015460405163052692b960e21b81526001600160a01b039091169063149a4ae49061233d908990600401614ecd565b60206040518083038186803b15801561235557600080fd5b505afa158015612369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061238d9190614a15565b90508281111561239e578092508197505b506001016122eb565b50600c86815481106123b557fe5b60009182526020909120015460405163052692b960e21b81526001600160a01b039091169063149a4ae4906123ee908590600401614ecd565b60206040518083038186803b15801561240657600080fd5b505afa15801561241a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243e9190614a15565b94505050505090919293565b6002546001600160a01b031633146124745760405162461bcd60e51b815260040161069390614bb7565b6001600160a01b03811661248757600080fd5b60015460035460405163095ea7b360e01b81526001600160a01b039283169263095ea7b3926124be92911690600090600401614ace565b602060405180830381600087803b1580156124d857600080fd5b505af11580156124ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125109190614866565b50600380546001600160a01b0319166001600160a01b03838116919091179182905560015460405163095ea7b360e01b81529082169263095ea7b39261255f9291169060001990600401614ace565b602060405180830381600087803b15801561257957600080fd5b505af115801561258d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b19190614866565b507fafbb66abf8f3b719799940473a4052a3717cdd8e40fb6c8a3faadab316b1a069816040516109f99190614a75565b6000806125ed83613730565b90506125f881613b01565b9392505050565b60008061260a6108c0565b6005546040516370a0823160e01b8152919250612698916001600160a01b03909116906370a0823190612641903090600401614a75565b60206040518083038186803b15801561265957600080fd5b505afa15801561266d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126919190614a15565b8290612ca4565b91505090565b6002546001600160a01b03163314806126cf57506126ba612bac565b6001600160a01b0316336001600160a01b0316145b6126eb5760405162461bcd60e51b815260040161069390614dbb565b60078190556040517f5430e11864ad7aa9775b07d12657fe52df9aa2ba734355bd8ef8747be2c800c5906109f9908390614ecd565b61272c84848484613d79565b50505050565b6001546001600160a01b031681565b600c54606090819067ffffffffffffffff8111801561275f57600080fd5b5060405190808252806020026020018201604052801561279957816020015b6127866145e3565b81526020019060019003908161277e5790505b50905060005b600c54811015610971576127b16145e3565b600c82815481106127be57fe5b60009182526020822001546040805163459010bb60e11b815290516001600160a01b0390921692638b20217692600480840193829003018186803b15801561280557600080fd5b505afa158015612819573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261284191908101906148f3565b8152600c80548390811061285157fe5b6000918252602090912001546001600160a01b03166060820152600c80548390811061287957fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b1580156128c257600080fd5b505afa1580156128d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128fa9190614a15565b6020820152600c80548390811061290d57fe5b60009182526020918290200154604080516357ded9c960e01b815290516001600160a01b03909216926357ded9c992600480840193829003018186803b15801561295657600080fd5b505afa15801561296a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061298e9190614a15565b6040820152825181908490849081106129a357fe5b60209081029190910101525060010161279f565b6002546001600160a01b03163314806129e857506129d3612bac565b6001600160a01b0316336001600160a01b0316145b612a045760405162461bcd60e51b815260040161069390614dbb565b600a805460ff19166001908117909155546040805163507257cd60e11b815290516001600160a01b039092169163a0e4af9a9160048082019260009290919082900301818387803b158015612a5857600080fd5b505af1158015612a6c573d6000803e3d6000fd5b50506040517f97e963041e952738788b9d4871d854d282065b8f90a464928d6528f2e9a4fd0b925060009150a1565b801580612b235750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e90612ad19030908690600401614a89565b60206040518083038186803b158015612ae957600080fd5b505afa158015612afd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b219190614a15565b155b612b3f5760405162461bcd60e51b815260040161069390614e77565b611a0c8363095ea7b360e01b8484604051602401612b5e929190614ace565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613f24565b6060612ba48484600085613fb3565b949350505050565b60015460408051635aa6e67560e01b815290516000926001600160a01b031691635aa6e675916004808301926020929190829003018186803b158015612bf157600080fd5b505afa158015612c05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac59190614691565b60408051600180825281830190925260609182919060208083019080368337505060055482519293506001600160a01b031691839150600090612c6857fe5b6001600160a01b0390921660209283029190910190910152905090565b611a0c8363a9059cbb60e01b8484604051602401612b5e929190614ace565b6000828201838110156125f85760405162461bcd60e51b815260040161069390614c49565b6005546040516370a0823160e01b8152600091829182916001600160a01b0316906370a0823190612cfe903090600401614a75565b60206040518083038186803b158015612d1657600080fd5b505afa158015612d2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d4e9190614a15565b9050838110612d64578360009250925050612d9f565b6000612d7b82612d75848803614077565b90612ca4565b9050848110612d9257846000935093505050612d9f565b925060009150612d9f9050565b915091565b6000808080805b600c54811015612ef7576000600c8281548110612dc457fe5b60009182526020909120015460405163052692b960e21b81526001600160a01b039091169063149a4ae490612dfd908a90600401614ecd565b60206040518083038186803b158015612e1557600080fd5b505afa158015612e29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4d9190614a15565b905084811115612eee57819350809450600c8281548110612e6a57fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b158015612eb357600080fd5b505afa158015612ec7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eeb9190614a15565b92505b50600101612dab565b506000612f0e612f078388612ca4565b85906136f6565b905060005b600c54811015612f3f57838114612f3757612f34600c828154811061135c57fe5b91505b600101612f13565b506000612f4e87612d756125ff565b9050612f5a82826136b4565b979650505050505050565b600060001981805b600c54811015613029576000600c8281548110612f8657fe5b60009182526020909120015460405163052692b960e21b81526001600160a01b039091169063149a4ae490612fbf908990600401614ecd565b60206040518083038186803b158015612fd757600080fd5b505afa158015612feb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061300f9190614a15565b905083811015613020578192508093505b50600101612f6d565b506000805b600c54811015613114578281146130565761304f600c828154811061135c57fe5b915061310c565b6000600c828154811061306557fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b1580156130ae57600080fd5b505afa1580156130c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130e69190614a15565b9050868110156130f4578096505b61310861310186896136f6565b8490612ca4565b9250505b60010161302e565b50600061312386612d756125ff565b905061312f82826136b4565b9695505050505050565b600a5460ff1615613149576116c0565b600c54613155576116c0565b600080600080613163612064565b93509350935093508281111561321257600c848154811061318057fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156131d857600080fd5b505af11580156131ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132109190614866565b505b6005546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613243903090600401614a75565b60206040518083038186803b15801561325b57600080fd5b505afa15801561326f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132939190614a15565b9050801561333b576132cd600c84815481106132ab57fe5b6000918252602090912001546005546001600160a01b03908116911683612c85565b600c83815481106132da57fe5b600091825260208220015460408051630d0e30db60e41b815290516001600160a01b039092169263d0e30db09260048084019382900301818387803b15801561332257600080fd5b505af1158015613336573d6000803e3d6000fd5b505050505b505050505050565b60006125f883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614355565b60008082816133926108c0565b6005546040516370a0823160e01b81529192506000916001600160a01b03909116906370a08231906133c8903090600401614a75565b60206040518083038186803b1580156133e057600080fd5b505afa1580156133f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134189190614a15565b905060006134268284612ca4565b9050826134415781841115613439578193505b5050506136ad565b6001546040516339ebf82360e01b81526000916001600160a01b0316906339ebf82390613472903090600401614a75565b6101206040518083038186803b15801561348b57600080fd5b505afa15801561349f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134c3919061497f565b60c001519050808211156135c157808203965060006134e28887612ca4565b90506000811180156134f357508084105b156135bb5761350a6135058286613343565b614077565b506005546040516370a0823160e01b81526000916001600160a01b0316906370a082319061353c903090600401614a75565b60206040518083038186803b15801561355457600080fd5b505afa158015613568573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061358c9190614a15565b9050818110156135b957808911156135aa57809850600096506135b9565b6135b689820388614381565b96505b505b506136a8565b818103955060006135d28787612ca4565b90506000811180156135e357508084105b156136a6576135f56135058286613343565b506005546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613627903090600401614a75565b60206040518083038186803b15801561363f57600080fd5b505afa158015613653573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136779190614a15565b9050818110156136a4578088111561369557809750600096506136a4565b6136a188820388614381565b96505b505b505b505050505b9193909250565b60006125f883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614397565b60008261370557506000611a8f565b8282028284828161371257fe5b04146125f85760405162461bcd60e51b815260040161069390614cdb565b60055460009081906001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21415613763575081611a8f565b600d5461010090046001600160a01b031661378857613781836143ce565b9050611a8f565b600d546040516303c0011560e51b81526101009091046001600160a01b03169063780022a0906137bc908690600401614ecd565b60206040518083038186803b1580156137d457600080fd5b505afa1580156137e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125f89190614a15565b60005b600c54811015613a4b57600c818154811061382657fe5b6000918252602090912001546001600160a01b0384811691161415613a43576000600c828154811061385457fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156138ac57600080fd5b505af11580156138c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138e49190614866565b90508261390857806139085760405162461bcd60e51b815260040161069390614e4e565b600c5460001901821461397c57600c8054600019810190811061392757fe5b600091825260209091200154600c80546001600160a01b03909216918490811061394d57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b600c80548061398757fe5b600082815260208120600019908301810180546001600160a01b03191690559091019091556005546040516370a0823160e01b81526001600160a01b03909116906370a08231906139dc903090600401614a75565b60206040518083038186803b1580156139f457600080fd5b505afa158015613a08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a2c9190614a15565b1115613a3c57613a3c6000613139565b50506107f6565b60010161380f565b5060405162461bcd60e51b815260040161069390614c80565b6001546040516339ebf82360e01b81526000916001600160a01b0316906339ebf82390613a95903090600401614a75565b6101206040518083038186803b158015613aae57600080fd5b505afa158015613ac2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ae6919061497f565b60c001519050600080613af883613385565b50505050505050565b6000613b0b614614565b6001546040516339ebf82360e01b81526001600160a01b03909116906339ebf82390613b3b903090600401614a75565b6101206040518083038186803b158015613b5457600080fd5b505afa158015613b68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b8c919061497f565b9050806020015160001415613ba5576000915050610c17565b60065460a0820151613bb8904290613343565b1015613bc8576000915050610c17565b60075460a0820151613bdb904290613343565b10613bea576001915050610c17565b6001546040805163bf3759b560e01b815290516000926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b158015613c2f57600080fd5b505afa158015613c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c679190614a15565b9050600954811115613c7e57600192505050610c17565b6000613c886125ff565b90508260c00151613ca460095483612ca490919063ffffffff16565b1015613cb65760019350505050610c17565b60008360c00151821115613cd75760c0840151613cd4908390613343565b90505b6001546040805163112c1f9b60e01b815290516000926001600160a01b03169163112c1f9b916004808301926020929190829003018186803b158015613d1c57600080fd5b505afa158015613d30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d549190614a15565b9050613d608183612ca4565b600854613d6d90896136f6565b10979650505050505050565b6005546001600160a01b031615613da25760405162461bcd60e51b815260040161069390614ca4565b600180546001600160a01b0319166001600160a01b03868116919091179182905560408051637e062a3560e11b81529051929091169163fc0c546a91600480820192602092909190829003018186803b158015613dfe57600080fd5b505afa158015613e12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e369190614691565b600580546001600160a01b0319166001600160a01b039283161790819055613e62911685600019612a9b565b600280546001600160a01b038086166001600160a01b03199283161790925560038054858416908316179081905560048054858516931692909217825560015460405163095ea7b360e01b81529084169363095ea7b393613ecb93909116916000199101614ace565b602060405180830381600087803b158015613ee557600080fd5b505af1158015613ef9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f1d9190614866565b5050505050565b6060613f79826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612b959092919063ffffffff16565b805190915015611a0c5780806020019051810190613f979190614866565b611a0c5760405162461bcd60e51b815260040161069390614de0565b6060613fbe8561452c565b613fda5760405162461bcd60e51b815260040161069390614d84565b60006060866001600160a01b03168587604051613ff79190614a59565b60006040518083038185875af1925050503d8060008114614034576040519150601f19603f3d011682016040523d82523d6000602084013e614039565b606091505b5091509150811561404d579150612ba49050565b80511561405d5780518082602001fd5b8360405162461bcd60e51b81526004016106939190614ba4565b600c5460009061408957506000610c17565b600b5482101561409b57506000610c17565b506000805b82821015610b58576000196000805b600c548110156141f757600c81815481106140c657fe5b6000918252602091829020015460408051635be9b2d360e01b815290516001600160a01b0390921692635be9b2d392600480840193829003018186803b15801561410f57600080fd5b505afa158015614123573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141479190614866565b156141ef576000600c828154811061415b57fe5b60009182526020918290200154604080516357ded9c960e01b815290516001600160a01b03909216926357ded9c992600480840193829003018186803b1580156141a457600080fd5b505afa1580156141b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141dc9190614a15565b9050838110156141ed578093508192505b505b6001016140af565b50600c818154811061420557fe5b6000918252602091829020015460408051635be9b2d360e01b815290516001600160a01b0390921692635be9b2d392600480840193829003018186803b15801561424e57600080fd5b505afa158015614262573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142869190614866565b61429257505050610c17565b614336600c82815481106142a257fe5b600091825260209091200154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d906142dd90888a0390600401614ecd565b602060405180830381600087803b1580156142f757600080fd5b505af115801561430b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061432f9190614a15565b8590612ca4565b93506001909201916006831061434e57505050610c17565b50506140a0565b600081848411156143795760405162461bcd60e51b81526004016106939190614ba4565b505050900390565b600081831061439057816125f8565b5090919050565b600081836143b85760405162461bcd60e51b81526004016106939190614ba4565b5060008385816143c457fe5b0495945050505050565b6040805160028082526060808301845260009390929190602083019080368337505060408051600280825260608201835293945092915060208301908036833701905050905073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160008151811061443657fe5b6001600160a01b03928316602091820292909201015260055482519116908290600190811061446157fe5b6001600160a01b039092166020928302919091019091015260405163d06ca61f60e01b8152606090737a250d5630b4cf539739df2c5dacb4c659f2488d9063d06ca61f906144b59087908690600401614ed6565b60006040518083038186803b1580156144cd57600080fd5b505afa1580156144e1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261450991908101906147d6565b90508060018251038151811061451b57fe5b602002602001015192505050919050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612ba4575050151592915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106145a65782800160ff198235161785556145d3565b828001600101855582156145d3579182015b828111156145d35782358255916020019190600101906145b8565b506145df929150614660565b5090565b604051806080016040528060608152602001600081526020016000815260200160006001600160a01b031681525090565b6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b808211156145df5760008155600101614661565b600060208284031215614686578081fd5b81356125f881614fd0565b6000602082840312156146a2578081fd5b81516125f881614fd0565b600080600080608085870312156146c2578283fd5b84356146cd81614fd0565b935060208501356146dd81614fd0565b925060408501356146ed81614fd0565b915060608501356146fd81614fd0565b939692955090935050565b6000602080838503121561471a578182fd5b823567ffffffffffffffff811115614730578283fd5b8301601f81018513614740578283fd5b803561475361474e82614f84565b614f5d565b818152838101908385016040808502860187018a1015614771578788fd5b8795505b848610156147c85780828b03121561478b578788fd5b61479481614f5d565b823561479f81614fd0565b8152828801356147ae81614fe5565b818901528452600195909501949286019290810190614775565b509098975050505050505050565b600060208083850312156147e8578182fd5b825167ffffffffffffffff8111156147fe578283fd5b8301601f8101851361480e578283fd5b805161481c61474e82614f84565b8181528381019083850185840285018601891015614838578687fd5b8694505b8385101561485a57805183526001949094019391850191850161483c565b50979650505050505050565b600060208284031215614877578081fd5b815180151581146125f8578182fd5b60008060208385031215614898578182fd5b823567ffffffffffffffff808211156148af578384fd5b818501915085601f8301126148c2578384fd5b8135818111156148d0578485fd5b8660208285010111156148e1578485fd5b60209290920196919550909350505050565b600060208284031215614904578081fd5b815167ffffffffffffffff8082111561491b578283fd5b818401915084601f83011261492e578283fd5b81518181111561493c578384fd5b61494f601f8201601f1916602001614f5d565b9150808252856020828501011115614965578384fd5b614976816020840160208601614fa4565b50949350505050565b6000610120808385031215614992578182fd5b61499b81614f5d565b9050825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152508091505092915050565b600060208284031215614a0e578081fd5b5035919050565b600060208284031215614a26578081fd5b5051919050565b60008151808452614a45816020860160208601614fa4565b601f01601f19169290920160200192915050565b60008251614a6b818460208701614fa4565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03948516815292841660208401529083166040830152909116606082015260800190565b6001600160a01b03929092168252602082015260400190565b60208082528251828201819052600091906040908185019080840286018301878501865b838110156147c857603f19898403018552815160808151818652614b3182870182614a2d565b838b0151878c0152898401518a8801526060938401516001600160a01b0316939096019290925250509386019390860190600101614b0b565b901515815260200190565b60006020825282602083015282846040840137818301604090810191909152601f909201601f19160101919050565b6000602082526125f86020830184614a2d565b6020808252600b908201526a085cdd1c985d1959da5cdd60aa1b604082015260600190565b6020808252600f908201526e2ab73237b1b5b2b2102632b73232b960891b604082015260600190565b602080825260059082015264085dd85b9d60da1b604082015260600190565b6020808252600b908201526a05348415245213d313030360ac1b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252600a90820152692727aa102622a72222a960b11b604082015260600190565b6020808252601c908201527f537472617465677920616c726561647920696e697469616c697a656400000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b602080825260069082015265085d985d5b1d60d21b604082015260600190565b6020808252600790820152662173686172657360c81b604082015260600190565b6020808252600d908201526c105b1c9958591e481059191959609a1b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252600b908201526a08585d5d1a1bdc9a5e995960aa1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600a9082015269085c1c9bdd1958dd195960b21b604082015260600190565b6020808252600f908201526e15d2551211149055c8119052531151608a1b604082015260600190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b90815260200190565b60006040820184835260206040818501528185518084526060860191508287019350845b81811015614f1f5784516001600160a01b031683529383019391830191600101614efa565b5090979650505050505050565b9283526020830191909152604082015260600190565b93845260208401929092526040830152606082015260800190565b60405181810167ffffffffffffffff81118282101715614f7c57600080fd5b604052919050565b600067ffffffffffffffff821115614f9a578081fd5b5060209081020190565b60005b83811015614fbf578181015183820152602001614fa7565b8381111561272c5750506000910152565b6001600160a01b03811681146116c057600080fd5b61ffff811681146116c057600080fdfea26469706673582212207390dc22a40549c877ab13859252daba33bf46f5da299b012be0d06f8db51d7a64736f6c634300060c0033000000000000000000000000a9fe4601811213c340e850ea305481aff02f5b28
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103425760003560e01c806376ee75d8116101b8578063af306e1611610104578063ed882c2b116100a2578063f8c8765e1161007c578063f8c8765e14610623578063fbfa77cf14610636578063fcc5f59a1461063e578063fcf2d0ad1461065357610342565b8063ed882c2b146105f5578063efbb5cb014610608578063f017c92f1461061057610342565b8063ce5494bb116100de578063ce5494bb146105a4578063d0511842146105b7578063d6c38271146105ca578063ec38a862146105e257610342565b8063af306e1614610581578063bb927c4614610589578063c7b9d5301461059157610342565b80638e6350e21161017157806393084b341161014b57806393084b341461055657806395e80c50146105695780639ec5a89414610571578063aced16611461057957610342565b80638e6350e21461052857806391397ab414610530578063929eea211461054357610342565b806376ee75d8146104cc5780637985fd51146104df5780637a4b1c14146104e75780638124b78e146104fa5780638baf29571461050d5780638cdfe1661461052057610342565b8063397dc14911610292578063530e784f11610230578063650d18801161020a578063650d18801461048b578063735de9f71461049e578063748747e6146104a6578063750521f5146104b957610342565b8063530e784f146104685780635641ec031461047b5780635a5cd45e1461048357610342565b8063440368a31161026c578063440368a31461043d5780634641257d1461044557806346d8cf3f1461044d5780634786b0cb1461045557610342565b8063397dc1491461040f57806339a172a8146104225780633fc8cef31461043557610342565b80631f1fcd51116102ff57806325829410116102d957806325829410146103e457806328b7ccf7146103ec5780632a5dc8c1146103f45780632e1a7d4d146103fc57610342565b80631f1fcd51146103b25780631fe4a686146103c757806322f3e2d4146103cf57610342565b806301681a621461034757806303ee438c1461035c57806306fdde031461037a5780630e6e15f0146103825780630f969b87146103975780631d12f28b146103aa575b600080fd5b61035a610355366004614675565b61065b565b005b6103646107fa565b6040516103719190614ba4565b60405180910390f35b610364610888565b61038a6108c0565b6040516103719190614ecd565b61035a6103a53660046149fd565b610977565b61038a610a04565b6103ba610a0a565b6040516103719190614a75565b6103ba610a19565b6103d7610a28565b6040516103719190614b6a565b610364610aca565b61038a610ae9565b6103ba610aef565b61038a61040a3660046149fd565b610b03565b61038a61041d3660046149fd565b610b5e565b61035a6104303660046149fd565b610c1c565b6103ba610c9e565b61035a610cb6565b61035a610edf565b6103d7611249565b61035a6104633660046149fd565b611252565b61035a610476366004614675565b6112a4565b6103d7611319565b61038a611322565b6103d76104993660046149fd565b6113c1565b6103ba61150e565b61035a6104b4366004614675565b611526565b61035a6104c7366004614886565b6115d1565b61035a6104da366004614675565b611668565b61038a6116c3565b61035a6104f5366004614708565b6116c9565b6103ba610508366004614675565b611a11565b61035a61051b366004614675565b611a95565b61038a611aed565b61038a611af3565b61035a61053e3660046149fd565b611af8565b6103ba6105513660046149fd565b611b7a565b61035a610564366004614675565b611ba1565b61038a611d2c565b6103ba611d32565b6103ba611d41565b61038a611d50565b61038a611d58565b61035a61059f366004614675565b611d5e565b61035a6105b2366004614675565b611e09565b6103ba6105c53660046146ad565b611f77565b6105d2612064565b6040516103719493929190614f42565b61035a6105f0366004614675565b61244a565b6103d76106033660046149fd565b6125e1565b61038a6125ff565b61035a61061e3660046149fd565b61269e565b61035a6106313660046146ad565b612720565b6103ba612732565b610646612741565b6040516103719190614ae7565b61035a6129b7565b610663612bac565b6001600160a01b0316336001600160a01b03161461069c5760405162461bcd60e51b815260040161069390614dbb565b60405180910390fd5b6005546001600160a01b03828116911614156106ca5760405162461bcd60e51b815260040161069390614c05565b6001546001600160a01b03828116911614156106f85760405162461bcd60e51b815260040161069390614d3c565b6060610702612c29565b905060005b815181101561075d5781818151811061071c57fe5b60200260200101516001600160a01b0316836001600160a01b031614156107555760405162461bcd60e51b815260040161069390614e2a565b600101610707565b506107f6610769612bac565b6040516370a0823160e01b81526001600160a01b038516906370a0823190610795903090600401614a75565b60206040518083038186803b1580156107ad57600080fd5b505afa1580156107c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e59190614a15565b6001600160a01b0385169190612c85565b5050565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156108805780601f1061085557610100808354040283529160200191610880565b820191906000526020600020905b81548152906001019060200180831161086357829003601f168201915b505050505081565b60408051808201909152601c81527f53747261746567794c656e6465725969656c644f7074696d697365720000000060208201525b90565b600080805b600c5481101561097157610967600c82815481106108df57fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b15801561092857600080fd5b505afa15801561093c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109609190614a15565b8390612ca4565b91506001016108c5565b50905090565b6002546001600160a01b03163314806109a85750610993612bac565b6001600160a01b0316336001600160a01b0316145b6109c45760405162461bcd60e51b815260040161069390614dbb565b60098190556040517fa68ba126373d04c004c5748c300c9fca12bd444b3d4332e261f3bd2bac4a8600906109f9908390614ecd565b60405180910390a150565b60095481565b6005546001600160a01b031681565b6002546001600160a01b031681565b6001546040516339ebf82360e01b815260009182916001600160a01b03909116906339ebf82390610a5d903090600401614a75565b6101206040518083038186803b158015610a7657600080fd5b505afa158015610a8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aae919061497f565b604001511180610ac557506000610ac36125ff565b115b905090565b604080518082019091526005815264181719971960d91b602082015290565b60075481565b600d5461010090046001600160a01b031681565b6001546000906001600160a01b03163314610b305760405162461bcd60e51b815260040161069390614d1c565b6000610b3b83612cc9565b600554909350909150610b58906001600160a01b03163383612c85565b50919050565b6001546040516339ebf82360e01b815260009182916001600160a01b03909116906339ebf82390610b93903090600401614a75565b6101206040518083038186803b158015610bac57600080fd5b505afa158015610bc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be4919061497f565b60c001519050600083821015610c0a5750808303610c0181612da4565b92505050610c17565b50828103610c0181612f65565b919050565b6002546001600160a01b0316331480610c4d5750610c38612bac565b6001600160a01b0316336001600160a01b0316145b610c695760405162461bcd60e51b815260040161069390614dbb565b60068190556040517fbb2c369a0355a34b02ab5fce0643150c87e1c8dfe7c918d465591879f57948b1906109f9908390614ecd565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6004546001600160a01b0316331480610cd957506002546001600160a01b031633145b80610cfc5750610ce7612bac565b6001600160a01b0316336001600160a01b0316145b80610d9d5750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b158015610d5057600080fd5b505afa158015610d64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d889190614691565b6001600160a01b0316336001600160a01b0316145b80610e3e5750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b158015610df157600080fd5b505afa158015610e05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e299190614691565b6001600160a01b0316336001600160a01b0316145b610e5a5760405162461bcd60e51b815260040161069390614dbb565b6001546040805163bf3759b560e01b81529051610edd926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b158015610ea057600080fd5b505afa158015610eb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ed89190614a15565b613139565b565b6004546001600160a01b0316331480610f0257506002546001600160a01b031633145b80610f255750610f10612bac565b6001600160a01b0316336001600160a01b0316145b80610fc65750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b158015610f7957600080fd5b505afa158015610f8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb19190614691565b6001600160a01b0316336001600160a01b0316145b806110675750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b15801561101a57600080fd5b505afa15801561102e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110529190614691565b6001600160a01b0316336001600160a01b0316145b6110835760405162461bcd60e51b815260040161069390614dbb565b6000806000600160009054906101000a90046001600160a01b03166001600160a01b031663bf3759b56040518163ffffffff1660e01b815260040160206040518083038186803b1580156110d657600080fd5b505afa1580156110ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110e9190614a15565b600a5490915060009060ff16156111645760006111296125ff565b905061114283821161113b578361113d565b815b612cc9565b945091508282111561115e576111588284613343565b94508291505b50611175565b61116d82613385565b919550935090505b6001546040516328766ebf60e21b81526001600160a01b039091169063a1d9bafc906111a990879087908690600401614f2c565b602060405180830381600087803b1580156111c357600080fd5b505af11580156111d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fb9190614a15565b915061120682613139565b7f4c0f499ffe6befa0ca7c826b0916cf87bea98de658013e76938489368d60d5098484838560405161123b9493929190614f42565b60405180910390a150505050565b600d5460ff1681565b6002546001600160a01b0316331480611283575061126e612bac565b6001600160a01b0316336001600160a01b0316145b61129f5760405162461bcd60e51b815260040161069390614dbb565b600b55565b6002546001600160a01b03163314806112d557506112c0612bac565b6001600160a01b0316336001600160a01b0316145b6112f15760405162461bcd60e51b815260040161069390614dbb565b600d80546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b600a5460ff1681565b60008061132d6125ff565b90508061133e5760009150506108bd565b6000805b600c548110156113af576113a5600c828154811061135c57fe5b600091825260209182902001546040805163116ac4a360e01b815290516001600160a01b039092169263116ac4a392600480840193829003018186803b15801561092857600080fd5b9150600101611342565b506113ba81836136b4565b9250505090565b60006113cc826125e1565b156113d957506000610c17565b60008060006113e6612064565b9350509250925081811115611506576000600c848154811061140457fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b15801561144d57600080fd5b505afa158015611461573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114859190614a15565b905060006114d36301e185586114cd6007546114c7670de0b6b3a76400006114b68a896136f690919063ffffffff16565b6114c0898b6136f6565b03906136b4565b906136f6565b906136b4565b905060006114e088613730565b9050816114f8600854836136f690919063ffffffff16565b109650505050505050610c17565b505050919050565b737a250d5630b4cf539739df2c5dacb4c659f2488d81565b6002546001600160a01b03163314806115575750611542612bac565b6001600160a01b0316336001600160a01b0316145b6115735760405162461bcd60e51b815260040161069390614dbb565b6001600160a01b03811661158657600080fd5b600480546001600160a01b0319166001600160a01b0383161790556040517f2f202ddb4a2e345f6323ed90f8fc8559d770a7abbbeee84dde8aca3351fe7154906109f9908390614a75565b6002546001600160a01b031633148061160257506115ed612bac565b6001600160a01b0316336001600160a01b0316145b61161e5760405162461bcd60e51b815260040161069390614dbb565b61162a60008383614565565b507f300e67d5a415b6d015a471d9c7b95dd58f3e8290af965e84e0f845de2996dda6828260405161165c929190614b75565b60405180910390a15050565b6002546001600160a01b03163314806116995750611684612bac565b6001600160a01b0316336001600160a01b0316145b6116b55760405162461bcd60e51b815260040161069390614dbb565b6116c081600161380c565b50565b600b5481565b6002546001600160a01b03163314806116fa57506116e5612bac565b6001600160a01b0316336001600160a01b0316145b6117165760405162461bcd60e51b815260040161069390614dbb565b6000805b600c548110156117ca57600c818154811061173157fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561178957600080fd5b505af115801561179d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c19190614866565b5060010161171a565b506005546040516370a0823160e01b81526000916001600160a01b0316906370a08231906117fc903090600401614a75565b60206040518083038186803b15801561181457600080fd5b505afa158015611828573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184c9190614a15565b905060005b83518110156119ea576000805b600c548110156118be5785838151811061187457fe5b6020026020010151600001516001600160a01b0316600c828154811061189657fe5b6000918252602090912001546001600160a01b031614156118b657600191505b60010161185e565b50806118dc5760405162461bcd60e51b815260040161069390614c80565b61190a8583815181106118eb57fe5b60200260200101516020015161ffff1685612ca490919063ffffffff16565b935060006119426103e86114cd88868151811061192357fe5b60200260200101516020015161ffff16876136f690919063ffffffff16565b905061197286848151811061195357fe5b6020908102919091010151516005546001600160a01b03169083612c85565b85838151811061197e57fe5b6020026020010151600001516001600160a01b031663d0e30db06040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156119c457600080fd5b505af11580156119d8573d6000803e3d6000fd5b50506001909401935061185192505050565b50816103e814611a0c5760405162461bcd60e51b815260040161069390614c24565b505050565b6040516368288c2160e11b8152600090309063d051184290611a3d908590339081908190600401614aa3565b602060405180830381600087803b158015611a5757600080fd5b505af1158015611a6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8f9190614691565b92915050565b6002546001600160a01b0316331480611ac65750611ab1612bac565b6001600160a01b0316336001600160a01b0316145b611ae25760405162461bcd60e51b815260040161069390614dbb565b6116c081600061380c565b60085481565b600090565b6002546001600160a01b0316331480611b295750611b14612bac565b6001600160a01b0316336001600160a01b0316145b611b455760405162461bcd60e51b815260040161069390614dbb565b60088190556040517fd94596337df4c2f0f44d30a7fc5db1c7bb60d9aca4185ed77c6fd96eb45ec298906109f9908390614ecd565b600c8181548110611b8757fe5b6000918252602090912001546001600160a01b0316905081565b611ba9612bac565b6001600160a01b0316336001600160a01b031614611bd95760405162461bcd60e51b815260040161069390614dbb565b6000819050306001600160a01b0316816001600160a01b031663a8c62e766040518163ffffffff1660e01b815260040160206040518083038186803b158015611c2157600080fd5b505afa158015611c35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c599190614691565b6001600160a01b031614611c7f5760405162461bcd60e51b815260040161069390614bdc565b60005b600c54811015611cd857600c8181548110611c9957fe5b6000918252602090912001546001600160a01b0384811691161415611cd05760405162461bcd60e51b815260040161069390614d5d565b600101611c82565b50600c80546001810182556000919091527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180546001600160a01b0319166001600160a01b039290921691909117905550565b60065481565b6003546001600160a01b031681565b6004546001600160a01b031681565b6301e1855881565b600c5490565b6002546001600160a01b0316331480611d8f5750611d7a612bac565b6001600160a01b0316336001600160a01b0316145b611dab5760405162461bcd60e51b815260040161069390614dbb565b6001600160a01b038116611dbe57600080fd5b600280546001600160a01b0319166001600160a01b0383161790556040517f352ececae6d7d1e6d26bcf2c549dfd55be1637e9b22dc0cf3b71ddb36097a6b4906109f9908390614a75565b6001546001600160a01b0316331480611e3a5750611e25612bac565b6001600160a01b0316336001600160a01b0316145b611e4357600080fd5b6001546040805163fbfa77cf60e01b815290516001600160a01b039283169284169163fbfa77cf916004808301926020929190829003018186803b158015611e8a57600080fd5b505afa158015611e9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec29190614691565b6001600160a01b031614611ed557600080fd5b611ede81613a64565b6005546040516370a0823160e01b81526116c09183916001600160a01b03909116906370a0823190611f14903090600401614a75565b60206040518083038186803b158015611f2c57600080fd5b505afa158015611f40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f649190614a15565b6005546001600160a01b03169190612c85565b604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81523060601b601482018190526e5af43d82803e903d91602b57fd5bf360881b602883015260009160378184f0604051637c643b2f60e11b81529093506001600160a01b038416915063f8c8765e90611ff5908990899089908990600401614aa3565b600060405180830381600087803b15801561200f57600080fd5b505af1158015612023573d6000803e3d6000fd5b50506040516001600160a01b03851692507f783540fb4221a3238720dc7038937d0d79982bcf895274aa6ad179f82cf0d53c9150600090a250949350505050565b6005546040516370a0823160e01b815260009182918291829182916001600160a01b0316906370a082319061209d903090600401614a75565b60206040518083038186803b1580156120b557600080fd5b505afa1580156120c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ed9190614a15565b90506000199350600094506000805b600c548110156122d457600c818154811061211357fe5b6000918252602091829020015460408051635be9b2d360e01b815290516001600160a01b0390921692635be9b2d392600480840193829003018186803b15801561215c57600080fd5b505afa158015612170573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121949190614866565b156122cc576000600c82815481106121a857fe5b60009182526020918290200154604080516357ded9c960e01b815290516001600160a01b03909216926357ded9c992600480840193829003018186803b1580156121f157600080fd5b505afa158015612205573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122299190614a15565b9050868110156122ca57809650819750600c828154811061224657fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b15801561228f57600080fd5b505afa1580156122a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122c79190614a15565b92505b505b6001016120fc565b5060006122e18284612ca4565b9050600080955060005b600c548110156123a7576000600c828154811061230457fe5b60009182526020909120015460405163052692b960e21b81526001600160a01b039091169063149a4ae49061233d908990600401614ecd565b60206040518083038186803b15801561235557600080fd5b505afa158015612369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061238d9190614a15565b90508281111561239e578092508197505b506001016122eb565b50600c86815481106123b557fe5b60009182526020909120015460405163052692b960e21b81526001600160a01b039091169063149a4ae4906123ee908590600401614ecd565b60206040518083038186803b15801561240657600080fd5b505afa15801561241a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243e9190614a15565b94505050505090919293565b6002546001600160a01b031633146124745760405162461bcd60e51b815260040161069390614bb7565b6001600160a01b03811661248757600080fd5b60015460035460405163095ea7b360e01b81526001600160a01b039283169263095ea7b3926124be92911690600090600401614ace565b602060405180830381600087803b1580156124d857600080fd5b505af11580156124ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125109190614866565b50600380546001600160a01b0319166001600160a01b03838116919091179182905560015460405163095ea7b360e01b81529082169263095ea7b39261255f9291169060001990600401614ace565b602060405180830381600087803b15801561257957600080fd5b505af115801561258d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b19190614866565b507fafbb66abf8f3b719799940473a4052a3717cdd8e40fb6c8a3faadab316b1a069816040516109f99190614a75565b6000806125ed83613730565b90506125f881613b01565b9392505050565b60008061260a6108c0565b6005546040516370a0823160e01b8152919250612698916001600160a01b03909116906370a0823190612641903090600401614a75565b60206040518083038186803b15801561265957600080fd5b505afa15801561266d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126919190614a15565b8290612ca4565b91505090565b6002546001600160a01b03163314806126cf57506126ba612bac565b6001600160a01b0316336001600160a01b0316145b6126eb5760405162461bcd60e51b815260040161069390614dbb565b60078190556040517f5430e11864ad7aa9775b07d12657fe52df9aa2ba734355bd8ef8747be2c800c5906109f9908390614ecd565b61272c84848484613d79565b50505050565b6001546001600160a01b031681565b600c54606090819067ffffffffffffffff8111801561275f57600080fd5b5060405190808252806020026020018201604052801561279957816020015b6127866145e3565b81526020019060019003908161277e5790505b50905060005b600c54811015610971576127b16145e3565b600c82815481106127be57fe5b60009182526020822001546040805163459010bb60e11b815290516001600160a01b0390921692638b20217692600480840193829003018186803b15801561280557600080fd5b505afa158015612819573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261284191908101906148f3565b8152600c80548390811061285157fe5b6000918252602090912001546001600160a01b03166060820152600c80548390811061287957fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b1580156128c257600080fd5b505afa1580156128d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128fa9190614a15565b6020820152600c80548390811061290d57fe5b60009182526020918290200154604080516357ded9c960e01b815290516001600160a01b03909216926357ded9c992600480840193829003018186803b15801561295657600080fd5b505afa15801561296a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061298e9190614a15565b6040820152825181908490849081106129a357fe5b60209081029190910101525060010161279f565b6002546001600160a01b03163314806129e857506129d3612bac565b6001600160a01b0316336001600160a01b0316145b612a045760405162461bcd60e51b815260040161069390614dbb565b600a805460ff19166001908117909155546040805163507257cd60e11b815290516001600160a01b039092169163a0e4af9a9160048082019260009290919082900301818387803b158015612a5857600080fd5b505af1158015612a6c573d6000803e3d6000fd5b50506040517f97e963041e952738788b9d4871d854d282065b8f90a464928d6528f2e9a4fd0b925060009150a1565b801580612b235750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e90612ad19030908690600401614a89565b60206040518083038186803b158015612ae957600080fd5b505afa158015612afd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b219190614a15565b155b612b3f5760405162461bcd60e51b815260040161069390614e77565b611a0c8363095ea7b360e01b8484604051602401612b5e929190614ace565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613f24565b6060612ba48484600085613fb3565b949350505050565b60015460408051635aa6e67560e01b815290516000926001600160a01b031691635aa6e675916004808301926020929190829003018186803b158015612bf157600080fd5b505afa158015612c05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac59190614691565b60408051600180825281830190925260609182919060208083019080368337505060055482519293506001600160a01b031691839150600090612c6857fe5b6001600160a01b0390921660209283029190910190910152905090565b611a0c8363a9059cbb60e01b8484604051602401612b5e929190614ace565b6000828201838110156125f85760405162461bcd60e51b815260040161069390614c49565b6005546040516370a0823160e01b8152600091829182916001600160a01b0316906370a0823190612cfe903090600401614a75565b60206040518083038186803b158015612d1657600080fd5b505afa158015612d2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d4e9190614a15565b9050838110612d64578360009250925050612d9f565b6000612d7b82612d75848803614077565b90612ca4565b9050848110612d9257846000935093505050612d9f565b925060009150612d9f9050565b915091565b6000808080805b600c54811015612ef7576000600c8281548110612dc457fe5b60009182526020909120015460405163052692b960e21b81526001600160a01b039091169063149a4ae490612dfd908a90600401614ecd565b60206040518083038186803b158015612e1557600080fd5b505afa158015612e29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4d9190614a15565b905084811115612eee57819350809450600c8281548110612e6a57fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b158015612eb357600080fd5b505afa158015612ec7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eeb9190614a15565b92505b50600101612dab565b506000612f0e612f078388612ca4565b85906136f6565b905060005b600c54811015612f3f57838114612f3757612f34600c828154811061135c57fe5b91505b600101612f13565b506000612f4e87612d756125ff565b9050612f5a82826136b4565b979650505050505050565b600060001981805b600c54811015613029576000600c8281548110612f8657fe5b60009182526020909120015460405163052692b960e21b81526001600160a01b039091169063149a4ae490612fbf908990600401614ecd565b60206040518083038186803b158015612fd757600080fd5b505afa158015612feb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061300f9190614a15565b905083811015613020578192508093505b50600101612f6d565b506000805b600c54811015613114578281146130565761304f600c828154811061135c57fe5b915061310c565b6000600c828154811061306557fe5b600091825260209182902001546040805163c1590cd760e01b815290516001600160a01b039092169263c1590cd792600480840193829003018186803b1580156130ae57600080fd5b505afa1580156130c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130e69190614a15565b9050868110156130f4578096505b61310861310186896136f6565b8490612ca4565b9250505b60010161302e565b50600061312386612d756125ff565b905061312f82826136b4565b9695505050505050565b600a5460ff1615613149576116c0565b600c54613155576116c0565b600080600080613163612064565b93509350935093508281111561321257600c848154811061318057fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156131d857600080fd5b505af11580156131ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132109190614866565b505b6005546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613243903090600401614a75565b60206040518083038186803b15801561325b57600080fd5b505afa15801561326f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132939190614a15565b9050801561333b576132cd600c84815481106132ab57fe5b6000918252602090912001546005546001600160a01b03908116911683612c85565b600c83815481106132da57fe5b600091825260208220015460408051630d0e30db60e41b815290516001600160a01b039092169263d0e30db09260048084019382900301818387803b15801561332257600080fd5b505af1158015613336573d6000803e3d6000fd5b505050505b505050505050565b60006125f883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614355565b60008082816133926108c0565b6005546040516370a0823160e01b81529192506000916001600160a01b03909116906370a08231906133c8903090600401614a75565b60206040518083038186803b1580156133e057600080fd5b505afa1580156133f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134189190614a15565b905060006134268284612ca4565b9050826134415781841115613439578193505b5050506136ad565b6001546040516339ebf82360e01b81526000916001600160a01b0316906339ebf82390613472903090600401614a75565b6101206040518083038186803b15801561348b57600080fd5b505afa15801561349f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134c3919061497f565b60c001519050808211156135c157808203965060006134e28887612ca4565b90506000811180156134f357508084105b156135bb5761350a6135058286613343565b614077565b506005546040516370a0823160e01b81526000916001600160a01b0316906370a082319061353c903090600401614a75565b60206040518083038186803b15801561355457600080fd5b505afa158015613568573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061358c9190614a15565b9050818110156135b957808911156135aa57809850600096506135b9565b6135b689820388614381565b96505b505b506136a8565b818103955060006135d28787612ca4565b90506000811180156135e357508084105b156136a6576135f56135058286613343565b506005546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613627903090600401614a75565b60206040518083038186803b15801561363f57600080fd5b505afa158015613653573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136779190614a15565b9050818110156136a4578088111561369557809750600096506136a4565b6136a188820388614381565b96505b505b505b505050505b9193909250565b60006125f883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614397565b60008261370557506000611a8f565b8282028284828161371257fe5b04146125f85760405162461bcd60e51b815260040161069390614cdb565b60055460009081906001600160a01b031673c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21415613763575081611a8f565b600d5461010090046001600160a01b031661378857613781836143ce565b9050611a8f565b600d546040516303c0011560e51b81526101009091046001600160a01b03169063780022a0906137bc908690600401614ecd565b60206040518083038186803b1580156137d457600080fd5b505afa1580156137e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125f89190614a15565b60005b600c54811015613a4b57600c818154811061382657fe5b6000918252602090912001546001600160a01b0384811691161415613a43576000600c828154811061385457fe5b9060005260206000200160009054906101000a90046001600160a01b03166001600160a01b031663853828b66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156138ac57600080fd5b505af11580156138c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138e49190614866565b90508261390857806139085760405162461bcd60e51b815260040161069390614e4e565b600c5460001901821461397c57600c8054600019810190811061392757fe5b600091825260209091200154600c80546001600160a01b03909216918490811061394d57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b600c80548061398757fe5b600082815260208120600019908301810180546001600160a01b03191690559091019091556005546040516370a0823160e01b81526001600160a01b03909116906370a08231906139dc903090600401614a75565b60206040518083038186803b1580156139f457600080fd5b505afa158015613a08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a2c9190614a15565b1115613a3c57613a3c6000613139565b50506107f6565b60010161380f565b5060405162461bcd60e51b815260040161069390614c80565b6001546040516339ebf82360e01b81526000916001600160a01b0316906339ebf82390613a95903090600401614a75565b6101206040518083038186803b158015613aae57600080fd5b505afa158015613ac2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ae6919061497f565b60c001519050600080613af883613385565b50505050505050565b6000613b0b614614565b6001546040516339ebf82360e01b81526001600160a01b03909116906339ebf82390613b3b903090600401614a75565b6101206040518083038186803b158015613b5457600080fd5b505afa158015613b68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b8c919061497f565b9050806020015160001415613ba5576000915050610c17565b60065460a0820151613bb8904290613343565b1015613bc8576000915050610c17565b60075460a0820151613bdb904290613343565b10613bea576001915050610c17565b6001546040805163bf3759b560e01b815290516000926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b158015613c2f57600080fd5b505afa158015613c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c679190614a15565b9050600954811115613c7e57600192505050610c17565b6000613c886125ff565b90508260c00151613ca460095483612ca490919063ffffffff16565b1015613cb65760019350505050610c17565b60008360c00151821115613cd75760c0840151613cd4908390613343565b90505b6001546040805163112c1f9b60e01b815290516000926001600160a01b03169163112c1f9b916004808301926020929190829003018186803b158015613d1c57600080fd5b505afa158015613d30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d549190614a15565b9050613d608183612ca4565b600854613d6d90896136f6565b10979650505050505050565b6005546001600160a01b031615613da25760405162461bcd60e51b815260040161069390614ca4565b600180546001600160a01b0319166001600160a01b03868116919091179182905560408051637e062a3560e11b81529051929091169163fc0c546a91600480820192602092909190829003018186803b158015613dfe57600080fd5b505afa158015613e12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e369190614691565b600580546001600160a01b0319166001600160a01b039283161790819055613e62911685600019612a9b565b600280546001600160a01b038086166001600160a01b03199283161790925560038054858416908316179081905560048054858516931692909217825560015460405163095ea7b360e01b81529084169363095ea7b393613ecb93909116916000199101614ace565b602060405180830381600087803b158015613ee557600080fd5b505af1158015613ef9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f1d9190614866565b5050505050565b6060613f79826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612b959092919063ffffffff16565b805190915015611a0c5780806020019051810190613f979190614866565b611a0c5760405162461bcd60e51b815260040161069390614de0565b6060613fbe8561452c565b613fda5760405162461bcd60e51b815260040161069390614d84565b60006060866001600160a01b03168587604051613ff79190614a59565b60006040518083038185875af1925050503d8060008114614034576040519150601f19603f3d011682016040523d82523d6000602084013e614039565b606091505b5091509150811561404d579150612ba49050565b80511561405d5780518082602001fd5b8360405162461bcd60e51b81526004016106939190614ba4565b600c5460009061408957506000610c17565b600b5482101561409b57506000610c17565b506000805b82821015610b58576000196000805b600c548110156141f757600c81815481106140c657fe5b6000918252602091829020015460408051635be9b2d360e01b815290516001600160a01b0390921692635be9b2d392600480840193829003018186803b15801561410f57600080fd5b505afa158015614123573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141479190614866565b156141ef576000600c828154811061415b57fe5b60009182526020918290200154604080516357ded9c960e01b815290516001600160a01b03909216926357ded9c992600480840193829003018186803b1580156141a457600080fd5b505afa1580156141b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141dc9190614a15565b9050838110156141ed578093508192505b505b6001016140af565b50600c818154811061420557fe5b6000918252602091829020015460408051635be9b2d360e01b815290516001600160a01b0390921692635be9b2d392600480840193829003018186803b15801561424e57600080fd5b505afa158015614262573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142869190614866565b61429257505050610c17565b614336600c82815481106142a257fe5b600091825260209091200154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d906142dd90888a0390600401614ecd565b602060405180830381600087803b1580156142f757600080fd5b505af115801561430b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061432f9190614a15565b8590612ca4565b93506001909201916006831061434e57505050610c17565b50506140a0565b600081848411156143795760405162461bcd60e51b81526004016106939190614ba4565b505050900390565b600081831061439057816125f8565b5090919050565b600081836143b85760405162461bcd60e51b81526004016106939190614ba4565b5060008385816143c457fe5b0495945050505050565b6040805160028082526060808301845260009390929190602083019080368337505060408051600280825260608201835293945092915060208301908036833701905050905073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160008151811061443657fe5b6001600160a01b03928316602091820292909201015260055482519116908290600190811061446157fe5b6001600160a01b039092166020928302919091019091015260405163d06ca61f60e01b8152606090737a250d5630b4cf539739df2c5dacb4c659f2488d9063d06ca61f906144b59087908690600401614ed6565b60006040518083038186803b1580156144cd57600080fd5b505afa1580156144e1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261450991908101906147d6565b90508060018251038151811061451b57fe5b602002602001015192505050919050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612ba4575050151592915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106145a65782800160ff198235161785556145d3565b828001600101855582156145d3579182015b828111156145d35782358255916020019190600101906145b8565b506145df929150614660565b5090565b604051806080016040528060608152602001600081526020016000815260200160006001600160a01b031681525090565b6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b808211156145df5760008155600101614661565b600060208284031215614686578081fd5b81356125f881614fd0565b6000602082840312156146a2578081fd5b81516125f881614fd0565b600080600080608085870312156146c2578283fd5b84356146cd81614fd0565b935060208501356146dd81614fd0565b925060408501356146ed81614fd0565b915060608501356146fd81614fd0565b939692955090935050565b6000602080838503121561471a578182fd5b823567ffffffffffffffff811115614730578283fd5b8301601f81018513614740578283fd5b803561475361474e82614f84565b614f5d565b818152838101908385016040808502860187018a1015614771578788fd5b8795505b848610156147c85780828b03121561478b578788fd5b61479481614f5d565b823561479f81614fd0565b8152828801356147ae81614fe5565b818901528452600195909501949286019290810190614775565b509098975050505050505050565b600060208083850312156147e8578182fd5b825167ffffffffffffffff8111156147fe578283fd5b8301601f8101851361480e578283fd5b805161481c61474e82614f84565b8181528381019083850185840285018601891015614838578687fd5b8694505b8385101561485a57805183526001949094019391850191850161483c565b50979650505050505050565b600060208284031215614877578081fd5b815180151581146125f8578182fd5b60008060208385031215614898578182fd5b823567ffffffffffffffff808211156148af578384fd5b818501915085601f8301126148c2578384fd5b8135818111156148d0578485fd5b8660208285010111156148e1578485fd5b60209290920196919550909350505050565b600060208284031215614904578081fd5b815167ffffffffffffffff8082111561491b578283fd5b818401915084601f83011261492e578283fd5b81518181111561493c578384fd5b61494f601f8201601f1916602001614f5d565b9150808252856020828501011115614965578384fd5b614976816020840160208601614fa4565b50949350505050565b6000610120808385031215614992578182fd5b61499b81614f5d565b9050825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152508091505092915050565b600060208284031215614a0e578081fd5b5035919050565b600060208284031215614a26578081fd5b5051919050565b60008151808452614a45816020860160208601614fa4565b601f01601f19169290920160200192915050565b60008251614a6b818460208701614fa4565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03948516815292841660208401529083166040830152909116606082015260800190565b6001600160a01b03929092168252602082015260400190565b60208082528251828201819052600091906040908185019080840286018301878501865b838110156147c857603f19898403018552815160808151818652614b3182870182614a2d565b838b0151878c0152898401518a8801526060938401516001600160a01b0316939096019290925250509386019390860190600101614b0b565b901515815260200190565b60006020825282602083015282846040840137818301604090810191909152601f909201601f19160101919050565b6000602082526125f86020830184614a2d565b6020808252600b908201526a085cdd1c985d1959da5cdd60aa1b604082015260600190565b6020808252600f908201526e2ab73237b1b5b2b2102632b73232b960891b604082015260600190565b602080825260059082015264085dd85b9d60da1b604082015260600190565b6020808252600b908201526a05348415245213d313030360ac1b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252600a90820152692727aa102622a72222a960b11b604082015260600190565b6020808252601c908201527f537472617465677920616c726561647920696e697469616c697a656400000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b602080825260069082015265085d985d5b1d60d21b604082015260600190565b6020808252600790820152662173686172657360c81b604082015260600190565b6020808252600d908201526c105b1c9958591e481059191959609a1b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252600b908201526a08585d5d1a1bdc9a5e995960aa1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600a9082015269085c1c9bdd1958dd195960b21b604082015260600190565b6020808252600f908201526e15d2551211149055c8119052531151608a1b604082015260600190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b90815260200190565b60006040820184835260206040818501528185518084526060860191508287019350845b81811015614f1f5784516001600160a01b031683529383019391830191600101614efa565b5090979650505050505050565b9283526020830191909152604082015260600190565b93845260208401929092526040830152606082015260800190565b60405181810167ffffffffffffffff81118282101715614f7c57600080fd5b604052919050565b600067ffffffffffffffff821115614f9a578081fd5b5060209081020190565b60005b83811015614fbf578181015183820152602001614fa7565b8381111561272c5750506000910152565b6001600160a01b03811681146116c057600080fd5b61ffff811681146116c057600080fdfea26469706673582212207390dc22a40549c877ab13859252daba33bf46f5da299b012be0d06f8db51d7a64736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a9fe4601811213c340e850ea305481aff02f5b28
-----Decoded View---------------
Arg [0] : _vault (address): 0xa9fE4601811213c340e850ea305481afF02f5b28
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000a9fe4601811213c340e850ea305481aff02f5b28
Deployed Bytecode Sourcemap
51901:20455:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50533:444;;;;;;:::i;:::-;;:::i;:::-;;24652:25;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53971:119;;;:::i;61757:225::-;;;:::i;:::-;;;;;;;:::i;33679:175::-;;;;;;:::i;:::-;;:::i;27699:32::-;;;:::i;26413:18::-;;;:::i;:::-;;;;;;;:::i;26322:25::-;;;:::i;36352:148::-;;;:::i;:::-;;;;;;;:::i;24962:91::-;;;:::i;27305:37::-;;;:::i;52427:30::-;;;:::i;47113:515::-;;;;;;:::i;:::-;;:::i;61228:475::-;;;;;;:::i;:::-;;:::i;31728:154::-;;;;;;:::i;:::-;;:::i;52153:82::-;;;:::i;41105:170::-;;;:::i;45498:1371::-;;;:::i;52386:34::-;;;:::i;53719:127::-;;;;;;:::i;:::-;;:::i;53854:109::-;;;;;;:::i;:::-;;:::i;27782:25::-;;;:::i;57043:383::-;;;:::i;70550:1289::-;;;;;;:::i;:::-;;:::i;52055:91::-;;;:::i;30485:174::-;;;;;;:::i;:::-;;:::i;34157:171::-;;;;;;:::i;:::-;;:::i;54739:101::-;;;;;;:::i;:::-;;:::i;52242:41::-;;;:::i;66210:1047::-;;;;;;:::i;:::-;;:::i;52632:157::-;;;;;;:::i;:::-;;:::i;54630:101::-;;;;;;:::i;:::-;;:::i;27515:33::-;;;:::i;26192:94::-;;;:::i;32953:169::-;;;;;;:::i;:::-;;:::i;52348:31::-;;;;;;:::i;:::-;;:::i;54243:335::-;;;;;;:::i;:::-;;:::i;27150:33::-;;;:::i;26354:22::-;;;:::i;26383:21::-;;;:::i;52290:49::-;;;:::i;56879:92::-;;;:::i;29729:202::-;;;;;;:::i;:::-;;:::i;48219:311::-;;;;;;:::i;:::-;;:::i;52797:914::-;;;;;;:::i;:::-;;:::i;59654:1456::-;;;:::i;:::-;;;;;;;;;;:::i;30948:263::-;;;;;;:::i;:::-;;:::i;69394:199::-;;;;;;:::i;:::-;;:::i;56672:::-;;;:::i;32399:154::-;;;;;;:::i;:::-;;:::i;51188:214::-;;;;;;:::i;:::-;;:::i;26294:21::-;;;:::i;56148:478::-;;;:::i;:::-;;;;;;;:::i;48959:164::-;;;:::i;50533:444::-;28149:12;:10;:12::i;:::-;-1:-1:-1;;;;;28135:26:0;:10;-1:-1:-1;;;;;28135:26:0;;28127:50;;;;-1:-1:-1;;;28127:50:0;;;;;;;:::i;:::-;;;;;;;;;50625:4:::1;::::0;-1:-1:-1;;;;;50607:23:0;;::::1;50625:4:::0;::::1;50607:23;;50599:41;;;;-1:-1:-1::0;;;50599:41:0::1;;;;;;;:::i;:::-;50677:5;::::0;-1:-1:-1;;;;;50659:24:0;;::::1;50677:5:::0;::::1;50659:24;;50651:44;;;;-1:-1:-1::0;;;50651:44:0::1;;;;;;;:::i;:::-;50708:33;50744:17;:15;:17::i;:::-;50708:53;;50777:9;50772:102;50792:16;:23;50788:1;:27;50772:102;;;50840:16;50857:1;50840:19;;;;;;;;;;;;;;-1:-1:-1::0;;;;;50830:29:0::1;:6;-1:-1:-1::0;;;;;50830:29:0::1;;;50822:52;;;;-1:-1:-1::0;;;50822:52:0::1;;;;;;;:::i;:::-;50817:3;;50772:102;;;;50887:82;50915:12;:10;:12::i;:::-;50929:39;::::0;-1:-1:-1;;;50929:39:0;;-1:-1:-1;;;;;50929:24:0;::::1;::::0;::::1;::::0;:39:::1;::::0;50962:4:::1;::::0;50929:39:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;50887:27:0;::::1;::::0;:82;:27:::1;:82::i;:::-;28188:1;50533:444:::0;:::o;24652:25::-;;;;;;;;;;;;;;;-1:-1:-1;;24652:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;53971:119::-;54045:37;;;;;;;;;;;;;;;;;53971:119;;:::o;61757:225::-;61805:7;;;61851:103;61875:7;:14;61871:18;;61851:103;;;61917:25;61925:7;61933:1;61925:10;;;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;;;61925:16:0;;;;-1:-1:-1;;;;;61925:10:0;;;;:14;;:16;;;;;;;;;;:10;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61917:3;;:7;:25::i;:::-;61911:31;-1:-1:-1;61891:3:0;;61851:103;;;-1:-1:-1;61971:3:0;-1:-1:-1;61757:225:0;:::o;33679:175::-;27893:10;;-1:-1:-1;;;;;27893:10:0;27879;:24;;:54;;;27921:12;:10;:12::i;:::-;-1:-1:-1;;;;;27907:26:0;:10;-1:-1:-1;;;;;27907:26:0;;27879:54;27871:78;;;;-1:-1:-1;;;27871:78:0;;;;;;;:::i;:::-;33764:13:::1;:30:::0;;;33810:36:::1;::::0;::::1;::::0;::::1;::::0;33780:14;;33810:36:::1;:::i;:::-;;;;;;;;33679:175:::0;:::o;27699:32::-;;;;:::o;26413:18::-;;;-1:-1:-1;;;;;26413:18:0;;:::o;26322:25::-;;;-1:-1:-1;;;;;26322:25:0;;:::o;36352:148::-;36417:5;;:31;;-1:-1:-1;;;36417:31:0;;36393:4;;;;-1:-1:-1;;;;;36417:5:0;;;;:16;;:31;;36442:4;;36417:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;:45;:75;;;;36491:1;36466:22;:20;:22::i;:::-;:26;36417:75;36410:82;;36352:148;:::o;24962:91::-;25031:14;;;;;;;;;;;;-1:-1:-1;;;25031:14:0;;;;24962:91;:::o;27305:37::-;;;;:::o;52427:30::-;;;;;;-1:-1:-1;;;;;52427:30:0;;:::o;47113:515::-;47228:5;;47172:13;;-1:-1:-1;;;;;47228:5:0;47206:10;:28;47198:47;;;;-1:-1:-1;;;47198:47:0;;;;;;;:::i;:::-;47331:19;47384:32;47402:13;47384:17;:32::i;:::-;47508:4;;47361:55;;-1:-1:-1;47361:55:0;;-1:-1:-1;47508:42:0;;-1:-1:-1;;;;;47508:4:0;47526:10;47361:55;47508:17;:42::i;:::-;47113:515;;;;:::o;61228:475::-;61342:5;;:31;;-1:-1:-1;;;61342:31:0;;61299:7;;;;-1:-1:-1;;;;;61342:5:0;;;;:16;;:31;;61367:4;;61342:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;61319:64;;61394:14;61438:12;61423;:27;61419:277;;;-1:-1:-1;61476:27:0;;;61525:34;61476:27;61525:26;:34::i;:::-;61518:41;;;;;;61419:277;-1:-1:-1;61601:27:0;;;61650:34;61601:27;61650:26;:34::i;61228:475::-;;;;:::o;31728:154::-;27893:10;;-1:-1:-1;;;;;27893:10:0;27879;:24;;:54;;;27921:12;:10;:12::i;:::-;-1:-1:-1;;;;;27907:26:0;:10;-1:-1:-1;;;;;27907:26:0;;27879:54;27871:78;;;;-1:-1:-1;;;27871:78:0;;;;;;;:::i;:::-;31806:14:::1;:23:::0;;;31845:29:::1;::::0;::::1;::::0;::::1;::::0;31823:6;;31845:29:::1;:::i;52153:82::-:0;52192:42;52153:82;:::o;41105:170::-;28275:6;;-1:-1:-1;;;;;28275:6:0;28261:10;:20;;:65;;-1:-1:-1;28316:10:0;;-1:-1:-1;;;;;28316:10:0;28302;:24;28261:65;:112;;;;28361:12;:10;:12::i;:::-;-1:-1:-1;;;;;28347:26:0;:10;-1:-1:-1;;;;;28347:26:0;;28261:112;:163;;;;28408:5;;;;;;;;;-1:-1:-1;;;;;28408:5:0;-1:-1:-1;;;;;28408:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;28394:30:0;:10;-1:-1:-1;;;;;28394:30:0;;28261:163;:216;;;;28459:5;;;;;;;;;-1:-1:-1;;;;;28459:5:0;-1:-1:-1;;;;;28459:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;28445:32:0;:10;-1:-1:-1;;;;;28445:32:0;;28261:216;28239:277;;;;-1:-1:-1;;;28239:277:0;;;;;;;:::i;:::-;41243:5:::1;::::0;:23:::1;::::0;;-1:-1:-1;;;41243:23:0;;;;41228:39:::1;::::0;-1:-1:-1;;;;;41243:5:0::1;::::0;:21:::1;::::0;:23:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:5;:23;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41228:14;:39::i;:::-;41105:170::o:0;45498:1371::-;28275:6;;-1:-1:-1;;;;;28275:6:0;28261:10;:20;;:65;;-1:-1:-1;28316:10:0;;-1:-1:-1;;;;;28316:10:0;28302;:24;28261:65;:112;;;;28361:12;:10;:12::i;:::-;-1:-1:-1;;;;;28347:26:0;:10;-1:-1:-1;;;;;28347:26:0;;28261:112;:163;;;;28408:5;;;;;;;;;-1:-1:-1;;;;;28408:5:0;-1:-1:-1;;;;;28408:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;28394:30:0;:10;-1:-1:-1;;;;;28394:30:0;;28261:163;:216;;;;28459:5;;;;;;;;;-1:-1:-1;;;;;28459:5:0;-1:-1:-1;;;;;28459:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;28445:32:0;:10;-1:-1:-1;;;;;28445:32:0;;28261:216;28239:277;;;;-1:-1:-1;;;28239:277:0;;;;;;;:::i;:::-;45549:14:::1;45578:12:::0;45605:23:::1;45631:5;;;;;;;;;-1:-1:-1::0;;;;;45631:5:0::1;-1:-1:-1::0;;;;;45631:21:0::1;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45703:13;::::0;45605:49;;-1:-1:-1;45665:19:0::1;::::0;45703:13:::1;;45699:731;;;45785:19;45807:22;:20;:22::i;:::-;45785:44;;45963:80;45995:15;45981:11;:29;:61;;46027:15;45981:61;;;46013:11;45981:61;45963:17;:80::i;:::-;45941:102:::0;-1:-1:-1;45941:102:0;-1:-1:-1;46121:29:0;;::::1;46117:159;;;46180:32;:11:::0;46196:15;46180::::1;:32::i;:::-;46171:41;;46245:15;46231:29;;46117:159;45699:731;;;;46388:30;46402:15;46388:13;:30::i;:::-;46358:60:::0;;-1:-1:-1;46358:60:0;-1:-1:-1;46358:60:0;-1:-1:-1;45699:731:0::1;46644:5;::::0;:39:::1;::::0;-1:-1:-1;;;46644:39:0;;-1:-1:-1;;;;;46644:5:0;;::::1;::::0;:12:::1;::::0;:39:::1;::::0;46657:6;;46665:4;;46671:11;;46644:39:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46626:57;;46759:31;46774:15;46759:14;:31::i;:::-;46808:53;46818:6;46826:4;46832:11;46845:15;46808:53;;;;;;;;;:::i;:::-;;;;;;;;28527:1;;;;45498:1371::o:0;52386:34::-;;;;;;:::o;53719:127::-;27893:10;;-1:-1:-1;;;;;27893:10:0;27879;:24;;:54;;;27921:12;:10;:12::i;:::-;-1:-1:-1;;;;;27907:26:0;:10;-1:-1:-1;;;;;27907:26:0;;27879:54;27871:78;;;;-1:-1:-1;;;27871:78:0;;;;;;;:::i;:::-;53806:19:::1;:32:::0;53719:127::o;53854:109::-;27893:10;;-1:-1:-1;;;;;27893:10:0;27879;:24;;:54;;;27921:12;:10;:12::i;:::-;-1:-1:-1;;;;;27907:26:0;:10;-1:-1:-1;;;;;27907:26:0;;27879:54;27871:78;;;;-1:-1:-1;;;27871:78:0;;;;;;;:::i;:::-;53930:15:::1;:25:::0;;-1:-1:-1;;;;;53930:25:0;;::::1;;;-1:-1:-1::0;;;;;;53930:25:0;;::::1;::::0;;;::::1;::::0;;53854:109::o;27782:25::-;;;;;;:::o;57043:383::-;57088:7;57108:11;57122:22;:20;:22::i;:::-;57108:36;-1:-1:-1;57159:8:0;57155:49;;57191:1;57184:8;;;;;57155:49;57216:19;57257:9;57252:127;57276:7;:14;57272:18;;57252:127;;;57326:41;57342:7;57350:1;57342:10;;;;;;;;;;;;;;;;;;;:24;;;-1:-1:-1;;;57342:24:0;;;;-1:-1:-1;;;;;57342:10:0;;;;:22;;:24;;;;;;;;;;:10;:24;;;;;;;;;;57326:41;57312:55;-1:-1:-1;57292:3:0;;57252:127;;;-1:-1:-1;57398:20:0;:11;57414:3;57398:15;:20::i;:::-;57391:27;;;;57043:383;:::o;70550:1289::-;70619:4;70719:24;70734:8;70719:14;:24::i;:::-;70715:69;;;-1:-1:-1;70767:5:0;70760:12;;70715:69;70941:14;70957:17;70978;70999:24;:22;:24::i;:::-;70940:83;;;;;;;71121:9;71109;:21;71105:727;;;71147:11;71161:7;71169:6;71161:15;;;;;;;;;;;;;;;;;;;:21;;;-1:-1:-1;;;71161:21:0;;;;-1:-1:-1;;;;;71161:15:0;;;;:19;;:21;;;;;;;;;;:15;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71147:35;;71566:22;71591:91;52331:8;71591:71;71647:14;;71591:51;71637:4;71613:18;71621:9;71613:3;:7;;:18;;;;:::i;:::-;71592;:3;71600:9;71592:7;:18::i;:::-;:39;;71591:45;:51::i;:::-;:55;;:71::i;:::-;:75;;:91::i;:::-;71566:116;;71699:20;71722:25;71738:8;71722:15;:25::i;:::-;71699:48;;71805:14;71772:30;71789:12;;71772;:16;;:30;;;;:::i;:::-;:47;71764:56;;;;;;;;;;71105:727;70550:1289;;;;;;:::o;52055:91::-;52103:42;52055:91;:::o;30485:174::-;27893:10;;-1:-1:-1;;;;;27893:10:0;27879;:24;;:54;;;27921:12;:10;:12::i;:::-;-1:-1:-1;;;;;27907:26:0;:10;-1:-1:-1;;;;;27907:26:0;;27879:54;27871:78;;;;-1:-1:-1;;;27871:78:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;30564:21:0;::::1;30556:30;;;::::0;::::1;;30597:6;:16:::0;;-1:-1:-1;;;;;;30597:16:0::1;-1:-1:-1::0;;;;;30597:16:0;::::1;;::::0;;30629:22:::1;::::0;::::1;::::0;::::1;::::0;30597:16;;30629:22:::1;:::i;34157:171::-:0;27893:10;;-1:-1:-1;;;;;27893:10:0;27879;:24;;:54;;;27921:12;:10;:12::i;:::-;-1:-1:-1;;;;;27907:26:0;:10;-1:-1:-1;;;;;27907:26:0;;27879:54;27871:78;;;;-1:-1:-1;;;27871:78:0;;;;;;;:::i;:::-;34246:26:::1;:11;34260:12:::0;;34246:26:::1;:::i;:::-;;34288:32;34307:12;;34288:32;;;;;;;:::i;:::-;;;;;;;;34157:171:::0;;:::o;54739:101::-;27893:10;;-1:-1:-1;;;;;27893:10:0;27879;:24;;:54;;;27921:12;:10;:12::i;:::-;-1:-1:-1;;;;;27907:26:0;:10;-1:-1:-1;;;;;27907:26:0;;27879:54;27871:78;;;;-1:-1:-1;;;27871:78:0;;;;;;;:::i;:::-;54810:22:::1;54824:1;54827:4;54810:13;:22::i;:::-;54739:101:::0;:::o;52242:41::-;;;;:::o;66210:1047::-;27893:10;;-1:-1:-1;;;;;27893:10:0;27879;:24;;:54;;;27921:12;:10;:12::i;:::-;-1:-1:-1;;;;;27907:26:0;:10;-1:-1:-1;;;;;27907:26:0;;27879:54;27871:78;;;;-1:-1:-1;;;27871:78:0;;;;;;;:::i;:::-;66305:13:::1;66340:9:::0;66335:96:::1;66359:7;:14:::0;66355:18;::::1;66335:96;;;66395:7;66403:1;66395:10;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;66395:10:0::1;-1:-1:-1::0;;;;;66395:22:0::1;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;66375:3:0::1;;66335:96;;;-1:-1:-1::0;66460:4:0::1;::::0;:29:::1;::::0;-1:-1:-1;;;66460:29:0;;66443:14:::1;::::0;-1:-1:-1;;;;;66460:4:0::1;::::0;:14:::1;::::0;:29:::1;::::0;66483:4:::1;::::0;66460:29:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66443:46;;66507:9;66502:698;66526:13;:20;66522:1;:24;66502:698;;;66568:10;66702:9:::0;66697:186:::1;66721:7;:14:::0;66717:18;::::1;66697:186;;;66788:13;66802:1;66788:16;;;;;;;;;;;;;;:23;;;-1:-1:-1::0;;;;;66765:46:0::1;66773:7;66781:1;66773:10;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;66773:10:0::1;66765:46;66761:107;;;66844:4;66836:12;;66761:107;66737:3;;66697:186;;;;66905:5;66897:28;;;;-1:-1:-1::0;;;66897:28:0::1;;;;;;;:::i;:::-;66950:33;66960:13;66974:1;66960:16;;;;;;;;;;;;;;:22;;;66950:33;;:5;:9;;:33;;;;:::i;:::-;66942:41;;66998:14;67015:44;67054:4;67015:34;67026:13;67040:1;67026:16;;;;;;;;;;;;;;:22;;;67015:34;;:6;:10;;:34;;;;:::i;:44::-;66998:61;;67074:50;67092:13;67106:1;67092:16;;;;;;;;;::::0;;::::1;::::0;;;;;;:23;67074:4:::1;::::0;-1:-1:-1;;;;;67074:4:0::1;::::0;67117:6;67074:17:::1;:50::i;:::-;67154:13;67168:1;67154:16;;;;;;;;;;;;;;:23;;;-1:-1:-1::0;;;;;67139:47:0::1;;:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;66548:3:0::1;::::0;;::::1;::::0;-1:-1:-1;66502:698:0::1;::::0;-1:-1:-1;;;66502:698:0::1;;;67220:5;67229:4;67220:13;67212:37;;;;-1:-1:-1::0;;;67212:37:0::1;;;;;;;:::i;:::-;27960:1;;66210:1047:::0;:::o;52632:157::-;52727:54;;-1:-1:-1;;;52727:54:0;;52681:19;;52727:4;;:10;;:54;;52738:6;;52746:10;;;;;;52727:54;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52713:68;52632:157;-1:-1:-1;;52632:157:0:o;54630:101::-;27893:10;;-1:-1:-1;;;;;27893:10:0;27879;:24;;:54;;;27921:12;:10;:12::i;:::-;-1:-1:-1;;;;;27907:26:0;:10;-1:-1:-1;;;;;27907:26:0;;27879:54;27871:78;;;;-1:-1:-1;;;27871:78:0;;;;;;;:::i;:::-;54700:23:::1;54714:1;54717:5;54700:13;:23::i;27515:33::-:0;;;;:::o;26192:94::-;26250:7;26192:94;:::o;32953:169::-;27893:10;;-1:-1:-1;;;;;27893:10:0;27879;:24;;:54;;;27921:12;:10;:12::i;:::-;-1:-1:-1;;;;;27907:26:0;:10;-1:-1:-1;;;;;27907:26:0;;27879:54;27871:78;;;;-1:-1:-1;;;27871:78:0;;;;;;;:::i;:::-;33036:12:::1;:28:::0;;;33080:34:::1;::::0;::::1;::::0;::::1;::::0;33051:13;;33080:34:::1;:::i;52348:31::-:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52348:31:0;;-1:-1:-1;52348:31:0;:::o;54243:335::-;28149:12;:10;:12::i;:::-;-1:-1:-1;;;;;28135:26:0;:10;-1:-1:-1;;;;;28135:26:0;;28127:50;;;;-1:-1:-1;;;28127:50:0;;;;;;;:::i;:::-;54306:16:::1;54340:1;54306:36;;54385:4;-1:-1:-1::0;;;;;54361:29:0::1;:1;-1:-1:-1::0;;;;;54361:10:0::1;;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;54361:29:0::1;;54353:57;;;;-1:-1:-1::0;;;54353:57:0::1;;;;;;;:::i;:::-;54428:9;54423:122;54447:7;:14:::0;54443:18;::::1;54423:122;;;54504:7;54512:1;54504:10;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;54491:24:0;;::::1;54504:10:::0;::::1;54491:24;;54483:50;;;;-1:-1:-1::0;;;54483:50:0::1;;;;;;;:::i;:::-;54463:3;;54423:122;;;-1:-1:-1::0;54555:7:0::1;:15:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;54555:15:0;;;;;::::1;::::0;;-1:-1:-1;;;;;;54555:15:0::1;-1:-1:-1::0;;;;;54555:15:0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;54243:335:0:o;27150:33::-;;;;:::o;26354:22::-;;;-1:-1:-1;;;;;26354:22:0;;:::o;26383:21::-;;;-1:-1:-1;;;;;26383:21:0;;:::o;52290:49::-;52331:8;52290:49;:::o;56879:92::-;56949:7;:14;56879:92;:::o;29729:202::-;27893:10;;-1:-1:-1;;;;;27893:10:0;27879;:24;;:54;;;27921:12;:10;:12::i;:::-;-1:-1:-1;;;;;27907:26:0;:10;-1:-1:-1;;;;;27907:26:0;;27879:54;27871:78;;;;-1:-1:-1;;;27871:78:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;29816:25:0;::::1;29808:34;;;::::0;::::1;;29853:10;:24:::0;;-1:-1:-1;;;;;;29853:24:0::1;-1:-1:-1::0;;;;;29853:24:0;::::1;;::::0;;29893:30:::1;::::0;::::1;::::0;::::1;::::0;29853:24;;29893:30:::1;:::i;48219:311::-:0;48308:5;;-1:-1:-1;;;;;48308:5:0;48286:10;:28;;:58;;;48332:12;:10;:12::i;:::-;-1:-1:-1;;;;;48318:26:0;:10;-1:-1:-1;;;;;48318:26:0;;48286:58;48278:67;;;;;;48402:5;;48364:34;;;-1:-1:-1;;;48364:34:0;;;;-1:-1:-1;;;;;48402:5:0;;;;48364:32;;;;;:34;;;;;;;;;;;;;;:32;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48364:43:0;;48356:52;;;;;;48419:30;48436:12;48419:16;:30::i;:::-;48492:4;;:29;;-1:-1:-1;;;48492:29:0;;48460:62;;48478:12;;-1:-1:-1;;;;;48492:4:0;;;;:14;;:29;;48515:4;;48492:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48460:4;;-1:-1:-1;;;;;48460:4:0;;:62;:17;:62::i;52797:914::-;53225:4;53219:11;-1:-1:-1;;;53244:86:0;;53124:4;53108:22;;53367:4;53351:21;;53344:43;;;-1:-1:-1;;;53424:4:0;53408:21;;53401:97;52945:19;;53549:4;53219:11;52945:19;53527:27;53577:89;;-1:-1:-1;;;53577:89:0;;53512:42;;-1:-1:-1;;;;;;53577:49:0;;;-1:-1:-1;53577:49:0;;:89;;53627:6;;53635:11;;53648:8;;53658:7;;53577:89;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;53684:19:0;;-1:-1:-1;;;;;53684:19:0;;;-1:-1:-1;53684:19:0;;-1:-1:-1;53684:19:0;;;52797:914;;;;;;;:::o;59654:1456::-;59959:4;;:29;;-1:-1:-1;;;59959:29:0;;59750:15;;;;;;;;;;-1:-1:-1;;;;;59959:4:0;;:14;;:29;;59982:4;;59959:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59937:51;;-1:-1:-1;;60155:24:0;;60200:1;60190:11;;60212:17;60249:9;60244:348;60268:7;:14;60264:18;;60244:348;;;60308:7;60316:1;60308:10;;;;;;;;;;;;;;;;;;;:22;;;-1:-1:-1;;;60308:22:0;;;;-1:-1:-1;;;;;60308:10:0;;;;:20;;:22;;;;;;;;;;:10;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60304:277;;;60351:11;60365:7;60373:1;60365:10;;;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;;;60365:16:0;;;;-1:-1:-1;;;;;60365:10:0;;;;:14;;:16;;;;;;;;;;:10;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60351:30;;60410:10;60404:3;:16;60400:166;;;60458:3;60445:16;;60494:1;60484:11;;60530:7;60538:1;60530:10;;;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;;;60530:16:0;;;;-1:-1:-1;;;;;60530:10:0;;;;:14;;:16;;;;;;;;;;:10;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60518:28;;60400:166;60304:277;;60284:3;;60244:348;;;-1:-1:-1;60604:13:0;60620:26;:9;60634:11;60620:13;:26::i;:::-;60604:42;;60659:18;60703:1;60692:12;;60722:9;60717:263;60741:7;:14;60737:18;;60717:263;;;60777:11;60809:7;60817:1;60809:10;;;;;;;;;;;;;;;;;;:39;;-1:-1:-1;;;60809:39:0;;-1:-1:-1;;;;;60809:10:0;;;;:26;;:39;;60836:11;;60809:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60803:45;;60875:10;60869:3;:16;60865:104;;;60919:3;60906:16;;60952:1;60941:12;;60865:104;-1:-1:-1;60757:3:0;;60717:263;;;;61062:7;61070:8;61062:17;;;;;;;;;;;;;;;;;;:40;;-1:-1:-1;;;61062:40:0;;-1:-1:-1;;;;;61062:17:0;;;;:33;;:40;;61096:5;;61062:40;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61049:53;;59654:1456;;;;;;;;:::o;30948:263::-;28036:10;;-1:-1:-1;;;;;28036:10:0;28022;:24;28014:48;;;;-1:-1:-1;;;28014:48:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;31029:22:0;::::1;31021:31;;;::::0;::::1;;31063:5;::::0;31077:7:::1;::::0;31063:25:::1;::::0;-1:-1:-1;;;31063:25:0;;-1:-1:-1;;;;;31063:5:0;;::::1;::::0;:13:::1;::::0;:25:::1;::::0;31077:7;::::1;::::0;31063:5:::1;::::0;:25:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;31099:7:0::1;:18:::0;;-1:-1:-1;;;;;;31099:18:0::1;-1:-1:-1::0;;;;;31099:18:0;;::::1;::::0;;;::::1;::::0;;;;-1:-1:-1;31128:5:0;:35:::1;::::0;-1:-1:-1;;;31128:35:0;;:5;;::::1;::::0;:13:::1;::::0;:35:::1;::::0;31142:7;::::1;::::0;-1:-1:-1;;31159:2:0;31128:35:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;31179:24;31194:8;31179:24;;;;;;:::i;69394:199::-:0;69466:4;69483:20;69506:25;69522:8;69506:15;:25::i;:::-;69483:48;;69551:34;69572:12;69551:20;:34::i;:::-;69544:41;69394:199;-1:-1:-1;;;69394:199:0:o;56672:::-;56734:7;56754:11;56768:17;:15;:17::i;:::-;56810:4;;:29;;-1:-1:-1;;;56810:29:0;;56754:31;;-1:-1:-1;56802:38:0;;-1:-1:-1;;;;;56810:4:0;;;;:14;;:29;;56833:4;;56810:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56802:3;;:7;:38::i;:::-;56796:44;-1:-1:-1;;56672:199:0;:::o;32399:154::-;27893:10;;-1:-1:-1;;;;;27893:10:0;27879;:24;;:54;;;27921:12;:10;:12::i;:::-;-1:-1:-1;;;;;27907:26:0;:10;-1:-1:-1;;;;;27907:26:0;;27879:54;27871:78;;;;-1:-1:-1;;;27871:78:0;;;;;;;:::i;:::-;32477:14:::1;:23:::0;;;32516:29:::1;::::0;::::1;::::0;::::1;::::0;32494:6;;32516:29:::1;:::i;51188:214::-:0;51343:51;51355:6;51363:11;51376:8;51386:7;51343:11;:51::i;:::-;51188:214;;;;:::o;26294:21::-;;;-1:-1:-1;;;;;26294:21:0;;:::o;56148:478::-;56273:7;:14;56193:19;;;;56256:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;56225:63;;56304:9;56299:292;56323:7;:14;56319:18;;56299:292;;;56359:19;;:::i;:::-;56402:7;56410:1;56402:10;;;;;;;;;;;;;;;;;:23;;;-1:-1:-1;;;56402:23:0;;;;-1:-1:-1;;;;;56402:10:0;;;;:21;;:23;;;;;;;;;;:10;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;56402:23:0;;;;;;;;;;;;:::i;:::-;56393:32;;56456:7;:10;;56464:1;;56456:10;;;;;;;;;;;;;;;;-1:-1:-1;;;;;56456:10:0;56440:5;;;:27;56493:7;:10;;56501:1;;56493:10;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;;;56493:16:0;;;;-1:-1:-1;;;;;56493:10:0;;;;:14;;:16;;;;;;;;;;:10;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56482:8;;;:27;56533:7;:10;;56541:1;;56533:10;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;;;56533:16:0;;;;-1:-1:-1;;;;;56533:10:0;;;;:14;;:16;;;;;;;;;;:10;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56524:6;;;:25;56564:11;;56524:1;;56564:8;;56573:1;;56564:11;;;;;;;;;;;;;;;:15;-1:-1:-1;56339:3:0;;56299:292;;48959:164;27893:10;;-1:-1:-1;;;;;27893:10:0;27879;:24;;:54;;;27921:12;:10;:12::i;:::-;-1:-1:-1;;;;;27907:26:0;:10;-1:-1:-1;;;;;27907:26:0;;27879:54;27871:78;;;;-1:-1:-1;;;27871:78:0;;;;;;;:::i;:::-;49022:13:::1;:20:::0;;-1:-1:-1;;49022:20:0::1;49038:4;49022:20:::0;;::::1;::::0;;;49053:5;:22:::1;::::0;;-1:-1:-1;;;49053:22:0;;;;-1:-1:-1;;;;;49053:5:0;;::::1;::::0;:20:::1;::::0;:22:::1;::::0;;::::1;::::0;49022:13:::1;::::0;49053:22;;;;;;;;49022:13;49053:5;:22;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;49093:22:0::1;::::0;::::1;::::0;-1:-1:-1;49093:22:0;;-1:-1:-1;49093:22:0::1;48959:164::o:0;18050:622::-;18420:10;;;18419:62;;-1:-1:-1;18436:39:0;;-1:-1:-1;;;18436:39:0;;-1:-1:-1;;;;;18436:15:0;;;;;:39;;18460:4;;18467:7;;18436:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;18419:62;18411:152;;;;-1:-1:-1;;;18411:152:0;;;;;;;:::i;:::-;18574:90;18594:5;18624:22;;;18648:7;18657:5;18601:62;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;18601:62:0;;;;;;;;;;;;;;-1:-1:-1;;;;;18601:62:0;-1:-1:-1;;;;;;18601:62:0;;;;;;;;;;18574:19;:90::i;5437:196::-;5540:12;5572:53;5595:6;5603:4;5609:1;5612:12;5572:22;:53::i;:::-;5565:60;5437:196;-1:-1:-1;;;;5437:196:0:o;34482:98::-;34554:5;;:18;;;-1:-1:-1;;;34554:18:0;;;;34527:7;;-1:-1:-1;;;;;34554:5:0;;:16;;:18;;;;;;;;;;;;;;:5;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;72146:207::-;72263:16;;;72277:1;72263:16;;;;;;;;;72205;;;;72263;;;;;;;;;;-1:-1:-1;;72313:4:0;;72290:12;;;;-1:-1:-1;;;;;;72313:4:0;;72290:12;;-1:-1:-1;72313:4:0;;72290:12;;;;-1:-1:-1;;;;;72290:28:0;;;:12;;;;;;;;;;;:28;72336:9;-1:-1:-1;72146:207:0;:::o;17391:177::-;17474:86;17494:5;17524:23;;;17549:2;17553:5;17501:58;;;;;;;;;:::i;12308:181::-;12366:7;12398:5;;;12422:6;;;;12414:46;;;;-1:-1:-1;;;12414:46:0;;;;;;;:::i;68754:632::-;68898:4;;:29;;-1:-1:-1;;;68898:29:0;;68831:20;;;;;;-1:-1:-1;;;;;68898:4:0;;:14;;:29;;68921:4;;68898:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68879:48;;68956:13;68944:8;:25;68940:439;;69079:13;69094:1;69071:25;;;;;;;68940:439;69129:16;69148:53;69192:8;69148:39;69178:8;69162:13;:24;69148:13;:39::i;:::-;:43;;:53::i;:::-;69129:72;;69232:13;69220:8;:25;69216:152;;69274:13;69289:1;69266:25;;;;;;;;69216:152;69340:8;-1:-1:-1;69350:1:0;;-1:-1:-1;69332:20:0;;-1:-1:-1;69332:20:0;68754:632;;;;:::o;57540:844::-;57615:7;;;;;57731:283;57755:7;:14;57751:18;;57731:283;;;57791:11;57805:7;57813:1;57805:10;;;;;;;;;;;;;;;;;;:34;;-1:-1:-1;;;57805:34:0;;-1:-1:-1;;;;;57805:10:0;;;;:26;;:34;;57832:6;;57805:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57791:48;;57864:10;57858:3;:16;57854:149;;;57907:1;57895:13;;57940:3;57927:16;;57971:7;57979:1;57971:10;;;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;;;57971:16:0;;;;-1:-1:-1;;;;;57971:10:0;;;;:14;;:16;;;;;;;;;;:10;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57962:25;;57854:149;-1:-1:-1;57771:3:0;;57731:283;;;-1:-1:-1;58026:19:0;58048:34;58063:18;:6;58074;58063:10;:18::i;:::-;58048:10;;:14;:34::i;:::-;58026:56;;58100:9;58095:181;58119:7;:14;58115:18;;58095:181;;;58164:9;58159:1;:14;58155:110;;58208:41;58224:7;58232:1;58224:10;;;;;;;58208:41;58194:55;;58155:110;58135:3;;58095:181;;;;58288:11;58302:34;58329:6;58302:22;:20;:22::i;:34::-;58288:48;-1:-1:-1;58356:20:0;:11;58288:48;58356:15;:20::i;:::-;58349:27;57540:844;-1:-1:-1;;;;;;;57540:844:0:o;58504:1028::-;58579:7;-1:-1:-1;;58579:7:0;;58675:237;58699:7;:14;58695:18;;58675:237;;;58735:11;58749:7;58757:1;58749:10;;;;;;;;;;;;;;;;;;:34;;-1:-1:-1;;;58749:34:0;;-1:-1:-1;;;;;58749:10:0;;;;:26;;:34;;58776:6;;58749:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58735:48;;58808:9;58802:3;:15;58798:103;;;58850:1;58838:13;;58882:3;58870:15;;58798:103;-1:-1:-1;58715:3:0;;58675:237;;;;58924:19;58965:9;58960:468;58984:7;:14;58980:18;;58960:468;;;59029:9;59024:1;:14;59020:397;;59073:41;59089:7;59097:1;59089:10;;;;;;;59073:41;59059:55;;59020:397;;;59155:13;59171:7;59179:1;59171:10;;;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;;;59171:16:0;;;;-1:-1:-1;;;;;59171:10:0;;;;:14;;:16;;;;;;;;;;:10;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59155:32;;59218:6;59210:5;:14;59206:125;;;59306:5;59297:14;;59206:125;59363:38;59379:21;:9;59393:6;59379:13;:21::i;:::-;59363:11;;:15;:38::i;:::-;59349:52;;59020:397;;59000:3;;58960:468;;;;59438:11;59452:34;59479:6;59452:22;:20;:22::i;:34::-;59438:48;-1:-1:-1;59504:20:0;:11;59438:48;59504:15;:20::i;:::-;59497:27;58504:1028;-1:-1:-1;;;;;;58504:1028:0:o;65149:894::-;65365:13;;;;65361:52;;;65395:7;;65361:52;65499:7;:14;65495:58;;65535:7;;65495:58;65566:14;65582:17;65601:15;65618:17;65639:24;:22;:24::i;:::-;65565:98;;;;;;;;65692:9;65680;:21;65676:164;;;65799:7;65807:6;65799:15;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;65799:15:0;-1:-1:-1;;;;;65799:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;65676:164;65866:4;;:29;;-1:-1:-1;;;65866:29:0;;65852:11;;-1:-1:-1;;;;;65866:4:0;;:14;;:29;;65889:4;;65866:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65852:43;-1:-1:-1;65910:7:0;;65906:130;;65934:49;65960:7;65968;65960:16;;;;;;;;;;;;;;;;;;65934:4;;-1:-1:-1;;;;;65934:4:0;;;;65960:16;65979:3;65934:17;:49::i;:::-;65998:7;66006;65998:16;;;;;;;;;;;;;;;;;:26;;;-1:-1:-1;;;65998:26:0;;;;-1:-1:-1;;;;;65998:16:0;;;;:24;;:26;;;;;;;;;;:16;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65906:130;65149:894;;;;;;:::o;12772:136::-;12830:7;12857:43;12861:1;12864;12857:43;;;;;;;;;;;;;;;;;:3;:43::i;62185:2753::-;62302:15;;62479:16;62302:15;62529:17;:15;:17::i;:::-;62581:4;;:29;;-1:-1:-1;;;62581:29:0;;62508:38;;-1:-1:-1;62559:19:0;;-1:-1:-1;;;;;62581:4:0;;;;:14;;:29;;62604:4;;62581:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62559:51;-1:-1:-1;62623:13:0;62639:27;62559:51;62655:10;62639:15;:27::i;:::-;62623:43;-1:-1:-1;62683:15:0;62679:302;;62792:11;62777:12;:26;62773:143;;;62889:11;62874:26;;62773:143;62932:37;;;;;62679:302;63008:5;;:31;;-1:-1:-1;;;63008:31:0;;62993:12;;-1:-1:-1;;;;;63008:5:0;;:16;;:31;;63033:4;;63008:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;62993:56;;63074:4;63066:5;:12;63062:1869;;;63105:12;;;;-1:-1:-1;63132:20:0;63155:25;63105:12;63167;63155:11;:25::i;:::-;63132:48;;63338:1;63323:12;:16;:46;;;;;63357:12;63343:11;:26;63323:46;63319:693;;;63439:44;63453:29;:12;63470:11;63453:16;:29::i;:::-;63439:13;:44::i;:::-;-1:-1:-1;63521:4:0;;:29;;-1:-1:-1;;;63521:29:0;;63502:16;;-1:-1:-1;;;;;63521:4:0;;:14;;:29;;63544:4;;63521:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63502:48;;63691:12;63680:8;:23;63676:321;;;63742:8;63732:7;:18;63728:250;;;63789:8;63779:18;;63839:1;63824:16;;63728:250;;;63912:42;63932:7;63921:8;:18;63941:12;63912:8;:42::i;:::-;63897:57;;63728:250;63319:693;;63062:1869;;;;64141:12;;;;-1:-1:-1;64168:20:0;64191:23;64141:12;64201;64191:9;:23::i;:::-;64168:46;;64250:1;64235:12;:16;:46;;;;;64269:12;64255:11;:26;64235:46;64231:689;;;64353:44;64367:29;:12;64384:11;64367:16;:29::i;64353:44::-;-1:-1:-1;64435:4:0;;:29;;-1:-1:-1;;;64435:29:0;;64416:16;;-1:-1:-1;;;;;64435:4:0;;:14;;:29;;64458:4;;64435:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64416:48;;64605:12;64594:8;:23;64590:315;;;64654:8;64646:5;:16;64642:244;;;64699:8;64691:16;;64749:1;64734:16;;64642:244;;;64822:40;64842:5;64831:8;:16;64849:12;64822:8;:40::i;:::-;64807:55;;64642:244;64231:689;;63062:1869;;62185:2753;;;;;;;;;;:::o;14609:132::-;14667:7;14694:39;14698:1;14701;14694:39;;;;;;;;;;;;;;;;;:3;:39::i;13662:471::-;13720:7;13965:6;13961:47;;-1:-1:-1;13995:1:0;13988:8;;13961:47;14032:5;;;14036:1;14032;:5;:1;14056:5;;;;;:10;14048:56;;;;-1:-1:-1;;;14048:56:0;;;;;;;:::i;69964:578::-;70241:4;;70030:7;;;;-1:-1:-1;;;;;70241:4:0;52192:42;70233:21;70229:274;;;-1:-1:-1;70286:8:0;70229:274;;;70316:15;;;;;-1:-1:-1;;;;;70316:15:0;70312:191;;70377:19;70387:8;70377:9;:19::i;:::-;70362:34;;70312:191;;;70455:15;;70444:47;;-1:-1:-1;;;70444:47:0;;70455:15;;;;-1:-1:-1;;;;;70455:15:0;;70444:37;;:47;;70482:8;;70444:47;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;54911:956::-;54982:9;54977:844;55001:7;:14;54997:18;;54977:844;;;55054:7;55062:1;55054:10;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;55041:24:0;;;55054:10;;55041:24;55037:773;;;55086:17;55106:7;55114:1;55106:10;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;55106:10:0;-1:-1:-1;;;;;55106:22:0;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55086:44;;55156:5;55151:95;;55194:12;55186:40;;;;-1:-1:-1;;;55186:40:0;;;;;;;:::i;:::-;55355:7;:14;-1:-1:-1;;55355:18:0;55350:23;;55346:112;;55411:7;55419:14;;-1:-1:-1;;55419:18:0;;;55411:27;;;;;;;;;;;;;;;;55398:7;:10;;-1:-1:-1;;;;;55411:27:0;;;;55406:1;;55398:10;;;;;;;;;;;;;;:40;;;;;-1:-1:-1;;;;;55398:40:0;;;;;-1:-1:-1;;;;;55398:40:0;;;;;;55346:112;55553:7;:13;;;;;;;;;;;;;;-1:-1:-1;;55553:13:0;;;;;;;-1:-1:-1;;;;;;55553:13:0;;;;;;;;;55675:4;;:29;;-1:-1:-1;;;55675:29:0;;-1:-1:-1;;;;;55675:4:0;;;;:14;;:29;;55698:4;;55675:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:33;55671:99;;;55733:17;55748:1;55733:14;:17::i;:::-;55788:7;;;;55037:773;55017:3;;54977:844;;;-1:-1:-1;55831:28:0;;-1:-1:-1;;;55831:28:0;;;;;;;:::i;71913:225::-;72012:5;;:31;;-1:-1:-1;;;72012:31:0;;71990:19;;-1:-1:-1;;;;;72012:5:0;;:16;;:31;;72037:4;;72012:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;71990:63;;72067:12;72081:19;72104:26;72118:11;72104:13;:26::i;:::-;-1:-1:-1;;;;;;;71913:225:0:o;43015:1677::-;43086:4;43103:28;;:::i;:::-;43134:5;;:31;;-1:-1:-1;;;43134:31:0;;-1:-1:-1;;;;;43134:5:0;;;;:16;;:31;;43159:4;;43134:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43103:62;;43242:6;:17;;;43263:1;43242:22;43238:40;;;43273:5;43266:12;;;;;43238:40;43423:14;;43402:17;;;;43382:38;;:15;;:19;:38::i;:::-;:55;43378:73;;;43446:5;43439:12;;;;;43378:73;43570:14;;43548:17;;;;43528:38;;:15;;:19;:38::i;:::-;:56;43524:73;;43593:4;43586:11;;;;;43524:73;44027:5;;:23;;;-1:-1:-1;;;44027:23:0;;;;44005:19;;-1:-1:-1;;;;;44027:5:0;;:21;;:23;;;;;;;;;;;;;;:5;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44005:45;;44079:13;;44065:11;:27;44061:44;;;44101:4;44094:11;;;;;;44061:44;44159:13;44175:22;:20;:22::i;:::-;44159:38;;44287:6;:16;;;44260:24;44270:13;;44260:5;:9;;:24;;;;:::i;:::-;:43;44256:60;;;44312:4;44305:11;;;;;;;44256:60;44329:14;44370:6;:16;;;44362:5;:24;44358:66;;;44407:16;;;;44397:27;;:5;;:9;:27::i;:::-;44388:36;;44358:66;44594:5;;:23;;;-1:-1:-1;;;44594:23:0;;;;44577:14;;-1:-1:-1;;;;;44594:5:0;;:21;;:23;;;;;;;;;;;;;;:5;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44577:40;-1:-1:-1;44665:18:0;44577:40;44676:6;44665:10;:18::i;:::-;44636:12;;:26;;44653:8;44636:16;:26::i;:::-;:47;;43015:1677;-1:-1:-1;;;;;;;43015:1677:0:o;28925:571::-;29097:4;;-1:-1:-1;;;;;29097:4:0;29089:27;29081:68;;;;-1:-1:-1;;;29081:68:0;;;;;;;:::i;:::-;29162:5;:24;;-1:-1:-1;;;;;;29162:24:0;-1:-1:-1;;;;;29162:24:0;;;;;;;;;;;29211:13;;;-1:-1:-1;;;29211:13:0;;;;:5;;;;;:11;;:13;;;;;;;;;;;;;;;:5;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;29197:4;:28;;-1:-1:-1;;;;;;29197:28:0;-1:-1:-1;;;;;29197:28:0;;;;;;;;29236:37;;:4;29253:6;-1:-1:-1;;29236:16:0;:37::i;:::-;29332:10;:24;;-1:-1:-1;;;;;29332:24:0;;;-1:-1:-1;;;;;;29332:24:0;;;;;;;29367:7;:18;;;;;;;;;;;;;29396:6;:16;;;;;;;;;;;;;29332:24;29423:5;:35;;-1:-1:-1;;;29423:35:0;;:5;;;;:13;;:35;;29437:7;;;;-1:-1:-1;;;29423:35:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;28925:571;;;;:::o;19696:761::-;20120:23;20146:69;20174:4;20146:69;;;;;;;;;;;;;;;;;20154:5;-1:-1:-1;;;;;20146:27:0;;;:69;;;;;:::i;:::-;20230:17;;20120:95;;-1:-1:-1;20230:21:0;20226:224;;20372:10;20361:30;;;;;;;;;;;;:::i;:::-;20353:85;;;;-1:-1:-1;;;20353:85:0;;;;;;;:::i;6814:979::-;6944:12;6977:18;6988:6;6977:10;:18::i;:::-;6969:60;;;;-1:-1:-1;;;6969:60:0;;;;;;;:::i;:::-;7103:12;7117:23;7144:6;-1:-1:-1;;;;;7144:11:0;7164:8;7175:4;7144:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7102:78;;;;7195:7;7191:595;;;7226:10;-1:-1:-1;7219:17:0;;-1:-1:-1;7219:17:0;7191:595;7340:17;;:21;7336:439;;7603:10;7597:17;7664:15;7651:10;7647:2;7643:19;7636:44;7551:148;7746:12;7739:20;;-1:-1:-1;;;7739:20:0;;;;;;;;:::i;67320:1249::-;67418:7;:14;67378:23;;67414:60;;-1:-1:-1;67461:1:0;67454:8;;67414:60;67530:19;;67520:7;:29;67516:70;;;-1:-1:-1;67573:1:0;67566:8;;67516:70;-1:-1:-1;67616:1:0;;67747:815;67772:7;67754:15;:25;67747:815;;;-1:-1:-1;;67796:17:0;;67875:326;67899:7;:14;67895:18;;67875:326;;;67943:7;67951:1;67943:10;;;;;;;;;;;;;;;;;;;:22;;;-1:-1:-1;;;67943:22:0;;;;-1:-1:-1;;;;;67943:10:0;;;;:20;;:22;;;;;;;;;;:10;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;67939:247;;;67990:11;68004:7;68012:1;68004:10;;;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;;;68004:16:0;;;;-1:-1:-1;;;;;68004:10:0;;;;:14;;:16;;;;;;;;;;:10;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;67990:30;;68053:9;68047:3;:15;68043:124;;;68103:3;68091:15;;68142:1;68133:10;;68043:124;67939:247;;67915:3;;67875:326;;;;68220:7;68228:6;68220:15;;;;;;;;;;;;;;;;;;;:27;;;-1:-1:-1;;;68220:27:0;;;;-1:-1:-1;;;;;68220:15:0;;;;:25;;:27;;;;;;;;;;:15;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68215:91;;68268:22;;;;;68215:91;68338:72;68358:7;68366:6;68358:15;;;;;;;;;;;;;;;;;;:51;;-1:-1:-1;;;68358:51:0;;-1:-1:-1;;;;;68358:15:0;;;;:24;;:51;;68383:25;;;;68358:51;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68338:15;;:19;:72::i;:::-;68320:90;-1:-1:-1;68425:3:0;;;;;68491:1;68486:6;;68482:69;;68513:22;;;;;68482:69;67747:815;;;;13211:192;13297:7;13333:12;13325:6;;;;13317:29;;;;-1:-1:-1;;;13317:29:0;;;;;;;;:::i;:::-;-1:-1:-1;;;13369:5:0;;;13211:192::o;10980:106::-;11038:7;11069:1;11065;:5;:13;;11077:1;11065:13;;;-1:-1:-1;11073:1:0;;10980:106;-1:-1:-1;10980:106:0:o;15237:278::-;15323:7;15358:12;15351:5;15343:28;;;;-1:-1:-1;;;15343:28:0;;;;;;;;:::i;:::-;;15382:9;15398:1;15394;:5;;;;;;;15237:278;-1:-1:-1;;;;;15237:278:0:o;69601:355::-;69704:16;;;69718:1;69704:16;;;69680:21;69704:16;;;;;69660:7;;69680:21;;69704:16;69718:1;69704:16;;;;;;;;-1:-1:-1;;69738:16:0;;;69752:1;69738:16;;;;;;;;69680:40;;-1:-1:-1;69738:16:0;69752:1;-1:-1:-1;69738:16:0;;;;;;;;;;-1:-1:-1;69738:16:0;69731:23;;52192:42;69765:4;69770:1;69765:7;;;;;;;;-1:-1:-1;;;;;69765:14:0;;;:7;;;;;;;;;:14;69808:4;;69790:7;;69808:4;;;69790;;69808;;69790:7;;;;;;-1:-1:-1;;;;;69790:23:0;;;:7;;;;;;;;;;;:23;69853:48;;-1:-1:-1;;;69853:48:0;;69826:24;;52103:42;;69853:33;;:48;;69887:7;;69896:4;;69853:48;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;69853:48:0;;;;;;;;;;;;:::i;:::-;69826:75;;69921:7;69946:1;69929:7;:14;:18;69921:27;;;;;;;;;;;;;;69914:34;;;;69601:355;;;:::o;2322:619::-;2382:4;2850:20;;2693:66;2890:23;;;;;;:42;;-1:-1:-1;;2917:15:0;;;2882:51;-1:-1:-1;;2322:619:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;5623:241;;5727:2;5715:9;5706:7;5702:23;5698:32;5695:2;;;-1:-1;;5733:12;5695:2;85:6;72:20;97:33;124:5;97:33;:::i;5871:263::-;;5986:2;5974:9;5965:7;5961:23;5957:32;5954:2;;;-1:-1;;5992:12;5954:2;226:6;220:13;238:33;265:5;238:33;:::i;6141:617::-;;;;;6296:3;6284:9;6275:7;6271:23;6267:33;6264:2;;;-1:-1;;6303:12;6264:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;6355:63;-1:-1;6455:2;6494:22;;72:20;97:33;72:20;97:33;:::i;:::-;6463:63;-1:-1;6563:2;6602:22;;72:20;97:33;72:20;97:33;:::i;:::-;6571:63;-1:-1;6671:2;6710:22;;72:20;97:33;72:20;97:33;:::i;:::-;6258:500;;;;-1:-1;6258:500;;-1:-1;;6258:500::o;6765:435::-;;6923:2;;6911:9;6902:7;6898:23;6894:32;6891:2;;;-1:-1;;6929:12;6891:2;6987:17;6974:31;7025:18;7017:6;7014:30;7011:2;;;-1:-1;;7047:12;7011:2;7152:22;;460:4;448:17;;444:27;-1:-1;434:2;;-1:-1;;475:12;434:2;522:6;509:20;544:109;559:93;645:6;559:93;:::i;:::-;544:109;:::i;:::-;681:21;;;738:14;;;;713:17;;;839:4;827:17;;;818:27;;;;815:36;-1:-1;812:2;;;-1:-1;;854:12;812:2;-1:-1;880:10;;874:235;899:6;896:1;893:13;874:235;;;839:4;4836:9;4831:3;4827:19;4823:30;4820:2;;;-1:-1;;4856:12;4820:2;4884:20;839:4;4884:20;:::i;:::-;85:6;72:20;97:33;124:5;97:33;:::i;:::-;4963:75;;5153:22;;;5276:20;5301:32;5276:20;5301:32;:::i;:::-;5115:16;;;5108:74;967:79;;921:1;914:9;;;;;1060:14;;;;1088;;;;874:235;;;-1:-1;7067:117;;6885:315;-1:-1;;;;;;;;6885:315::o;7207:392::-;;7347:2;;7335:9;7326:7;7322:23;7318:32;7315:2;;;-1:-1;;7353:12;7315:2;7404:17;7398:24;7442:18;7434:6;7431:30;7428:2;;;-1:-1;;7464:12;7428:2;7551:22;;1262:4;1250:17;;1246:27;-1:-1;1236:2;;-1:-1;;1277:12;1236:2;1317:6;1311:13;1339:80;1354:64;1411:6;1354:64;:::i;1339:80::-;1447:21;;;1504:14;;;;1479:17;;;1593;;;1584:27;;;;1581:36;-1:-1;1578:2;;;-1:-1;;1620:12;1578:2;-1:-1;1646:10;;1640:217;1665:6;1662:1;1659:13;1640:217;;;5560:13;;1733:61;;1687:1;1680:9;;;;;1808:14;;;;1836;;1640:217;;;-1:-1;7484:99;7309:290;-1:-1;;;;;;;7309:290::o;7606:257::-;;7718:2;7706:9;7697:7;7693:23;7689:32;7686:2;;;-1:-1;;7724:12;7686:2;1952:6;1946:13;41308:5;38745:13;38738:21;41286:5;41283:32;41273:2;;-1:-1;;41319:12;8172:367;;;8296:2;8284:9;8275:7;8271:23;8267:32;8264:2;;;-1:-1;;8302:12;8264:2;8360:17;8347:31;8398:18;;8390:6;8387:30;8384:2;;;-1:-1;;8420:12;8384:2;8506:6;8495:9;8491:22;;;2309:3;2302:4;2294:6;2290:17;2286:27;2276:2;;-1:-1;;2317:12;2276:2;2360:6;2347:20;8398:18;2379:6;2376:30;2373:2;;;-1:-1;;2409:12;2373:2;2504:3;8296:2;2484:17;2445:6;2470:32;;2467:41;2464:2;;;-1:-1;;2511:12;2464:2;8296;2441:17;;;;;8440:83;;-1:-1;8258:281;;-1:-1;;;;8258:281::o;8546:362::-;;8671:2;8659:9;8650:7;8646:23;8642:32;8639:2;;;-1:-1;;8677:12;8639:2;8728:17;8722:24;8766:18;;8758:6;8755:30;8752:2;;;-1:-1;;8788:12;8752:2;8875:6;8864:9;8860:22;;;2653:3;2646:4;2638:6;2634:17;2630:27;2620:2;;-1:-1;;2661:12;2620:2;2701:6;2695:13;8766:18;36324:6;36321:30;36318:2;;;-1:-1;;36354:12;36318:2;2723:65;36427:9;36408:17;;-1:-1;;36404:33;8671:2;36485:15;2723:65;:::i;:::-;2714:74;;2808:6;2801:5;2794:21;2912:3;8671:2;2903:6;2836;2894:16;;2891:25;2888:2;;;-1:-1;;2919:12;2888:2;2939:39;2971:6;8671:2;2870:5;2866:16;8671:2;2836:6;2832:17;2939:39;:::i;:::-;-1:-1;8808:84;8633:275;-1:-1;;;;8633:275::o;8915:324::-;;9060:3;;9048:9;9039:7;9035:23;9031:33;9028:2;;;-1:-1;;9067:12;9028:2;3188:22;9060:3;3188:22;:::i;:::-;3179:31;;3334:22;5560:13;3284:16;3277:86;3430:2;3499:9;3495:22;5560:13;3430:2;3449:5;3445:16;3438:86;3590:2;3659:9;3655:22;5560:13;3590:2;3609:5;3605:16;3598:86;3758:2;3827:9;3823:22;5560:13;3758:2;3777:5;3773:16;3766:86;3926:3;3996:9;3992:22;5560:13;3926:3;3946:5;3942:16;3935:86;4088:3;4158:9;4154:22;5560:13;4088:3;4108:5;4104:16;4097:86;4249:3;4319:9;4315:22;5560:13;4249:3;4269:5;4265:16;4258:86;4410:3;4480:9;4476:22;5560:13;4410:3;4430:5;4426:16;4419:86;4571:3;;4643:9;4639:22;5560:13;4571:3;4591:5;4587:18;4580:88;;9119:104;;;;9022:217;;;;:::o;9246:241::-;;9350:2;9338:9;9329:7;9325:23;9321:32;9318:2;;;-1:-1;;9356:12;9318:2;-1:-1;5412:20;;9312:175;-1:-1;9312:175::o;9494:263::-;;9609:2;9597:9;9588:7;9584:23;9580:32;9577:2;;;-1:-1;;9615:12;9577:2;-1:-1;5560:13;;9571:186;-1:-1;9571:186::o;13934:327::-;;14069:5;36964:12;37823:6;37818:3;37811:19;14153:52;14198:6;37860:4;37855:3;37851:14;37860:4;14179:5;14175:16;14153:52;:::i;:::-;36427:9;41066:14;-1:-1;;41062:28;14217:39;;;;37860:4;14217:39;;14016:245;-1:-1;;14016:245::o;21486:271::-;;12748:5;36964:12;12859:52;12904:6;12899:3;12892:4;12885:5;12881:16;12859:52;:::i;:::-;12923:16;;;;;21620:137;-1:-1;;21620:137::o;21764:222::-;-1:-1;;;;;39038:54;;;;10430:37;;21891:2;21876:18;;21862:124::o;21993:333::-;-1:-1;;;;;39038:54;;;10430:37;;39038:54;;22312:2;22297:18;;10430:37;22148:2;22133:18;;22119:207::o;22333:604::-;-1:-1;;;;;39038:54;;;10430:37;;39038:54;;;22741:2;22726:18;;10299:58;39038:54;;;22832:2;22817:18;;10299:58;39038:54;;;22923:2;22908:18;;10299:58;22568:3;22553:19;;22539:398::o;23507:349::-;-1:-1;;;;;39038:54;;;;10430:37;;23842:2;23827:18;;13531:58;23670:2;23655:18;;23641:215::o;24203:482::-;24436:2;24450:47;;;36964:12;;24421:18;;;37811:19;;;24203:482;;24436:2;37851:14;;;;;;11860:17;;;11851:27;;;;36632:14;;;24203:482;12016:414;12041:6;12038:1;12035:13;12016:414;;;12093:20;;24425:9;12097:4;12093:20;;12088:3;12081:33;12148:6;12142:13;20520:4;20592:16;20586:23;20520:4;20629:14;20622:38;20675:73;20520:4;20515:3;20511:14;20729:12;20675:73;:::i;:::-;20824:16;;;20818:23;20895:14;;;21317:37;20978:16;;;20972:23;21049:14;;;21317:37;21142:4;21131:16;;;21125:23;-1:-1;;;;;39038:54;21202:14;;;;10430:37;;;;-1:-1;;12409:14;;;;37523;;;;7025:18;12056:9;12016:414;;24692:210;38745:13;;38738:21;12542:34;;24813:2;24798:18;;24784:118::o;25698:330::-;;25855:2;25876:17;25869:47;37823:6;25855:2;25844:9;25840:18;37811:19;40649:6;40644:3;37851:14;25844:9;37851:14;40626:30;40687:16;;;37851:14;40687:16;;;40680:27;;;;36427:9;41066:14;;;-1:-1;;41062:28;13881:39;;;25826:202;-1:-1;25826:202::o;26035:310::-;;26182:2;26203:17;26196:47;26257:78;26182:2;26171:9;26167:18;26321:6;26257:78;:::i;26352:416::-;26552:2;26566:47;;;14847:2;26537:18;;;37811:19;-1:-1;;;37851:14;;;14863:34;14916:12;;;26523:245::o;26775:416::-;26975:2;26989:47;;;15167:2;26960:18;;;37811:19;-1:-1;;;37851:14;;;15183:38;15240:12;;;26946:245::o;27198:416::-;27398:2;27412:47;;;15491:1;27383:18;;;37811:19;-1:-1;;;37851:14;;;15506:28;15553:12;;;27369:245::o;27621:416::-;27821:2;27835:47;;;15804:2;27806:18;;;37811:19;-1:-1;;;37851:14;;;15820:34;15873:12;;;27792:245::o;28044:416::-;28244:2;28258:47;;;16124:2;28229:18;;;37811:19;16160:29;37851:14;;;16140:50;16209:12;;;28215:245::o;28467:416::-;28667:2;28681:47;;;16460:2;28652:18;;;37811:19;-1:-1;;;37851:14;;;16476:33;16528:12;;;28638:245::o;28890:416::-;29090:2;29104:47;;;16779:2;29075:18;;;37811:19;16815:30;37851:14;;;16795:51;16865:12;;;29061:245::o;29313:416::-;29513:2;29527:47;;;17116:2;29498:18;;;37811:19;17152:34;37851:14;;;17132:55;-1:-1;;;17207:12;;;17200:25;17244:12;;;29484:245::o;29736:416::-;29936:2;29950:47;;;17495:1;29921:18;;;37811:19;-1:-1;;;37851:14;;;17510:29;17558:12;;;29907:245::o;30159:416::-;30359:2;30373:47;;;17809:1;30344:18;;;37811:19;-1:-1;;;37851:14;;;17824:30;17873:12;;;30330:245::o;30582:416::-;30782:2;30796:47;;;18124:2;30767:18;;;37811:19;-1:-1;;;37851:14;;;18140:36;18195:12;;;30753:245::o;31005:416::-;31205:2;31219:47;;;18446:2;31190:18;;;37811:19;18482:31;37851:14;;;18462:52;18533:12;;;31176:245::o;31428:416::-;31628:2;31642:47;;;18784:2;31613:18;;;37811:19;-1:-1;;;37851:14;;;18800:34;18853:12;;;31599:245::o;31851:416::-;32051:2;32065:47;;;19104:2;32036:18;;;37811:19;19140:34;37851:14;;;19120:55;-1:-1;;;19195:12;;;19188:34;19241:12;;;32022:245::o;32274:416::-;32474:2;32488:47;;;19492:2;32459:18;;;37811:19;-1:-1;;;37851:14;;;19508:33;19560:12;;;32445:245::o;32697:416::-;32897:2;32911:47;;;19811:2;32882:18;;;37811:19;-1:-1;;;37851:14;;;19827:38;19884:12;;;32868:245::o;33120:416::-;33320:2;33334:47;;;20135:2;33305:18;;;37811:19;20171:34;37851:14;;;20151:55;-1:-1;;;20226:12;;;20219:46;20284:12;;;33291:245::o;33543:222::-;21317:37;;;33670:2;33655:18;;33641:124::o;33772:481::-;;33977:2;33966:9;33962:18;21347:5;21324:3;21317:37;34095:2;33977;34095;34084:9;34080:18;34073:48;34135:108;10823:5;36964:12;37823:6;37818:3;37811:19;37851:14;33966:9;37851:14;10835:93;;34095:2;10999:5;36632:14;11011:21;;-1:-1;11038:260;11063:6;11060:1;11057:13;11038:260;;;11124:13;;-1:-1;;;;;39038:54;10430:37;;37523:14;;;;9918;;;;7025:18;11078:9;11038:260;;;-1:-1;34127:116;;33948:305;-1:-1;;;;;;;33948:305::o;34260:444::-;21317:37;;;34607:2;34592:18;;21317:37;;;;34690:2;34675:18;;21317:37;34443:2;34428:18;;34414:290::o;34711:556::-;21317:37;;;35087:2;35072:18;;21317:37;;;;35170:2;35155:18;;21317:37;35253:2;35238:18;;21317:37;34922:3;34907:19;;34893:374::o;35274:256::-;35336:2;35330:9;35362:17;;;35437:18;35422:34;;35458:22;;;35419:62;35416:2;;;35494:1;;35484:12;35416:2;35336;35503:22;35314:216;;-1:-1;35314:216::o;35537:333::-;;35725:18;35717:6;35714:30;35711:2;;;-1:-1;;35747:12;35711:2;-1:-1;35792:4;35780:17;;;35845:15;;35648:222::o;40722:268::-;40787:1;40794:101;40808:6;40805:1;40802:13;40794:101;;;40875:11;;;40869:18;40856:11;;;40849:39;40830:2;40823:10;40794:101;;;40910:6;40907:1;40904:13;40901:2;;;-1:-1;;40787:1;40957:16;;40950:27;40771:219::o;41103:117::-;-1:-1;;;;;39038:54;;41162:35;;41152:2;;41211:1;;41201:12;41501:115;38957:6;41586:5;38946:18;41562:5;41559:34;41549:2;;41607:1;;41597:12
Swarm Source
ipfs://7390dc22a40549c877ab13859252daba33bf46f5da299b012be0d06f8db51d7a
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.