Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| - | 13025721 | 1656 days ago | 0.13393538 ETH | ||||
| - | 13025721 | 1656 days ago | 0.13393538 ETH | ||||
| - | 13012792 | 1658 days ago | 0.14174262 ETH | ||||
| - | 13012792 | 1658 days ago | 0.14174262 ETH | ||||
| - | 12999868 | 1660 days ago | 0.03789079 ETH | ||||
| - | 12999868 | 1660 days ago | 0.03789079 ETH | ||||
| - | 12996111 | 1660 days ago | 0.13157484 ETH | ||||
| - | 12996111 | 1660 days ago | 0.13157484 ETH | ||||
| - | 12983084 | 1662 days ago | 0.01177303 ETH | ||||
| - | 12983084 | 1662 days ago | 0.01177303 ETH | ||||
| - | 12981500 | 1662 days ago | 0.08604875 ETH | ||||
| - | 12981500 | 1662 days ago | 0.08604875 ETH | ||||
| - | 12968510 | 1664 days ago | 0.33611653 ETH | ||||
| - | 12968510 | 1664 days ago | 0.33611653 ETH | ||||
| - | 12955838 | 1666 days ago | 0.59439277 ETH | ||||
| - | 12955838 | 1666 days ago | 0.59439277 ETH | ||||
| - | 12943125 | 1668 days ago | 0.30364133 ETH | ||||
| - | 12943125 | 1668 days ago | 0.30364133 ETH | ||||
| - | 12936718 | 1669 days ago | 0.67038049 ETH | ||||
| - | 12936718 | 1669 days ago | 0.67038049 ETH | ||||
| - | 12924120 | 1671 days ago | 0.40899321 ETH | ||||
| - | 12924120 | 1671 days ago | 0.40899321 ETH | ||||
| - | 12916461 | 1673 days ago | 0.44975528 ETH | ||||
| - | 12916461 | 1673 days ago | 0.44975528 ETH | ||||
| - | 12907793 | 1674 days ago | 0.71217798 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Strategy
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2021-05-21
*/
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.6.12;
pragma experimental ABIEncoderV2;
// Global Enums and Structs
struct StrategyParams {
uint256 performanceFee;
uint256 activation;
uint256 debtRatio;
uint256 minDebtPerHarvest;
uint256 maxDebtPerHarvest;
uint256 lastReport;
uint256 totalDebt;
uint256 totalGain;
uint256 totalLoss;
}
// Part: ICurveFi
interface ICurveFi {
function add_liquidity(
uint256[2] calldata amounts,
uint256 min_mint_amount,
bool _use_underlying
) external payable returns (uint256);
function add_liquidity(
uint256[3] calldata amounts,
uint256 min_mint_amount,
bool _use_underlying
) external payable returns (uint256);
function add_liquidity(
uint256[4] calldata amounts,
uint256 min_mint_amount,
bool _use_underlying
) external payable returns (uint256);
function add_liquidity(
uint256[2] calldata amounts,
uint256 min_mint_amount
) external payable;
function add_liquidity(
uint256[3] calldata amounts,
uint256 min_mint_amount
) external payable;
function add_liquidity(
uint256[4] calldata amounts,
uint256 min_mint_amount
) external payable;
// crv.finance: Curve.fi Factory USD Metapool v2
function add_liquidity(
address pool,
uint256[4] calldata amounts,
uint256 min_mint_amount
) external;
function exchange(
int128 i,
int128 j,
uint256 dx,
uint256 min_dy
) external;
function exchange_underlying(
int128 i,
int128 j,
uint256 dx,
uint256 min_dy
) external;
function get_dy(
int128 i,
int128 j,
uint256 dx
) external view returns (uint256);
function balances(int128) external view returns (uint256);
function get_virtual_price() external view returns (uint256);
}
// Part: IERC20Metadata
interface IERC20Metadata {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
// Part: IVoterProxy
interface IVoterProxy {
function proxy() external returns (address);
function balanceOf(address _gauge) external view returns (uint256);
function deposit(address _gauge, address _token) external;
function withdraw(
address _gauge,
address _token,
uint256 _amount
) external returns (uint256);
function withdrawAll(address _gauge, address _token) external returns (uint256);
function harvest(address _gauge) external;
function lock() external;
function approveStrategy(address) external;
function revokeStrategy(address) external;
function claimRewards(address _gauge, address _token) external;
}
// Part: 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/openzeppelin-contracts@3.1.0/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/openzeppelin-contracts@3.1.0/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/openzeppelin-contracts@3.1.0/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: Uni
interface Uni {
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint[] memory amounts);
function swapExactTokensForETH(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint[] memory amounts);
}
// Part: WETH
interface WETH {
function deposit() external payable;
function withdraw(uint256 wad) external;
}
// Part: OpenZeppelin/openzeppelin-contracts@3.1.0/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/yearn-vaults@0.3.3/VaultAPI
interface VaultAPI is IERC20 {
function name() external view returns (string calldata);
function symbol() external view returns (string calldata);
function decimals() external view returns (uint256);
function apiVersion() external pure returns (string memory);
function permit(
address owner,
address spender,
uint256 amount,
uint256 expiry,
bytes calldata signature
) external returns (bool);
// NOTE: Vyper produces multiple signatures for a given function with "default" args
function deposit() external returns (uint256);
function deposit(uint256 amount) external returns (uint256);
function deposit(uint256 amount, address recipient) external returns (uint256);
// NOTE: Vyper produces multiple signatures for a given function with "default" args
function withdraw() external returns (uint256);
function withdraw(uint256 maxShares) external returns (uint256);
function withdraw(uint256 maxShares, address recipient) external returns (uint256);
function token() external view returns (address);
function strategies(address _strategy) external view returns (StrategyParams memory);
function pricePerShare() external view returns (uint256);
function totalAssets() external view returns (uint256);
function depositLimit() external view returns (uint256);
function maxAvailableShares() external view returns (uint256);
/**
* View how much the Vault would increase this Strategy's borrow limit,
* based on its present performance (since its last report). Can be used to
* determine expectedReturn in your Strategy.
*/
function creditAvailable() external view returns (uint256);
/**
* View how much the Vault would like to pull back from the Strategy,
* based on its present performance (since its last report). Can be used to
* determine expectedReturn in your Strategy.
*/
function debtOutstanding() external view returns (uint256);
/**
* View how much the Vault expect this Strategy to return at the current
* block, based on its present performance (since its last report). Can be
* used to determine expectedReturn in your Strategy.
*/
function expectedReturn() external view returns (uint256);
/**
* This is the main contact point where the Strategy interacts with the
* Vault. It is critical that this call is handled as intended by the
* Strategy. Therefore, this function will be called by BaseStrategy to
* make sure the integration is correct.
*/
function report(
uint256 _gain,
uint256 _loss,
uint256 _debtPayment
) external returns (uint256);
/**
* This function should only be used in the scenario where the Strategy is
* being retired but no migration of the positions are possible, or in the
* extreme scenario that the Strategy needs to be put into "Emergency Exit"
* mode in order for it to exit as quickly as possible. The latter scenario
* could be for any reason that is considered "critical" that the Strategy
* exits its position as fast as possible, such as a sudden change in
* market conditions leading to losses, or an imminent failure in an
* external dependency.
*/
function revokeStrategy() external;
/**
* View the governance address of the Vault to assert privileged functions
* can only be called by governance. The Strategy serves the Vault, so it
* is subject to governance defined by the Vault.
*/
function governance() external view returns (address);
/**
* View the management address of the Vault to assert privileged functions
* can only be called by management. The Strategy serves the Vault, so it
* is subject to management defined by the Vault.
*/
function management() external view returns (address);
/**
* View the guardian address of the Vault to assert privileged functions
* can only be called by guardian. The Strategy serves the Vault, so it
* is subject to guardian defined by the Vault.
*/
function guardian() external view returns (address);
}
// Part: iearn-finance/yearn-vaults@0.3.3/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.3";
}
/**
* @notice This Strategy's name.
* @dev
* You can use this field to manage the "version" of this Strategy, e.g.
* `StrategySomethingOrOtherV1`. However, "API Version" is managed by
* `apiVersion()` function above.
* @return This Strategy's name.
*/
function name() external 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;
// The maximum number of seconds between harvest calls. See
// `setMaxReportDelay()` for more details.
uint256 public maxReportDelay;
// The minimum multiple that `callCost` must be above the credit/profit to
// be "justifiable". See `setProfitFactor()` for more details.
uint256 public profitFactor;
// Use this to adjust the threshold at which running a debt causes a
// harvest trigger. See `setDebtThreshold()` for more details.
uint256 public debtThreshold;
// See note on `setEmergencyExit()`.
bool public emergencyExit;
// modifiers
modifier onlyAuthorized() {
require(msg.sender == strategist || msg.sender == governance(), "!authorized");
_;
}
modifier 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;
// initialize variables
minReportDelay = 0;
maxReportDelay = 86400;
profitFactor = 100;
debtThreshold = 0;
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: CurveVoterProxy
abstract contract CurveVoterProxy is BaseStrategy {
using SafeERC20 for IERC20;
using Address for address;
using SafeMath for uint256;
address public constant voter = address(0xF147b8125d2ef93FB6965Db97D6746952a133934);
address public constant crv = address(0xD533a949740bb3306d119CC777fa900bA034cd52);
address public constant dai = address(0x6B175474E89094C44Da98b954EedeAC495271d0F);
address public constant usdc = address(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48);
address public constant usdt = address(0xdAC17F958D2ee523a2206206994597C13D831ec7);
address public constant weth = address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
address public constant wbtc = address(0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599);
address public constant uniswap = address(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
address public constant sushiswap = address(0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F);
uint256 public constant DENOMINATOR = 10000;
address public proxy;
address public dex;
address public curve;
address public gauge;
uint256 public keepCRV;
constructor(address _vault) public BaseStrategy(_vault) {
minReportDelay = 6 hours;
maxReportDelay = 2 days;
profitFactor = 1;
debtThreshold = 1e24;
proxy = address(0xA420A63BbEFfbda3B147d0585F1852C358e2C152);
}
function setProxy(address _proxy) external onlyGovernance {
proxy = _proxy;
}
function setKeepCRV(uint256 _keepCRV) external onlyAuthorized {
keepCRV = _keepCRV;
}
function switchDex(bool isUniswap) external onlyAuthorized {
if (isUniswap) dex = uniswap;
else dex = sushiswap;
}
function name() external view override returns (string memory) {
return string(abi.encodePacked("Curve", IERC20Metadata(address(want)).symbol(), "VoterProxy"));
}
function balanceOfWant() public view returns (uint256) {
return want.balanceOf(address(this));
}
function balanceOfPool() public view returns (uint256) {
return IVoterProxy(proxy).balanceOf(gauge);
}
function estimatedTotalAssets() public view override returns (uint256) {
return balanceOfWant().add(balanceOfPool());
}
function adjustPosition(uint256 _debtOutstanding) internal override {
uint256 _want = want.balanceOf(address(this));
if (_want > 0) {
want.safeTransfer(proxy, _want);
IVoterProxy(proxy).deposit(gauge, address(want));
}
}
function _withdrawSome(uint256 _amount) internal returns (uint256) {
_amount = Math.min(_amount, balanceOfPool());
return IVoterProxy(proxy).withdraw(gauge, address(want), _amount);
}
function liquidatePosition(uint256 _amountNeeded)
internal
override
returns (uint256 _liquidatedAmount, uint256 _loss)
{
uint256 _balance = want.balanceOf(address(this));
if (_balance < _amountNeeded) {
_liquidatedAmount = _withdrawSome(_amountNeeded.sub(_balance));
_liquidatedAmount = _liquidatedAmount.add(_balance);
_loss = _amountNeeded.sub(_liquidatedAmount); // this should be 0. o/w there must be an error
}
else {
_liquidatedAmount = _amountNeeded;
}
}
function prepareMigration(address _newStrategy) internal override {
IVoterProxy(proxy).withdrawAll(gauge, address(want));
}
function _adjustCRV(uint256 _crv) internal returns (uint256) {
uint256 _keepCRV = _crv.mul(keepCRV).div(DENOMINATOR);
IERC20(crv).safeTransfer(voter, _keepCRV);
return _crv.sub(_keepCRV);
}
}
// File: ankr.sol
contract Strategy is CurveVoterProxy {
using SafeERC20 for IERC20;
using Address for address;
using SafeMath for uint256;
address public constant onx = address(0xE0aD1806Fd3E7edF6FF52Fdb822432e847411033);
address public constant ankr = address(0x8290333ceF9e6D528dD5618Fb97a76f268f3EDD4);
address[] public path;
constructor(address _vault) public CurveVoterProxy(_vault) {
dex = sushiswap;
curve = address(0xA96A65c051bF88B4095Ee1f2451C2A9d43F53Ae2);
gauge = address(0x6d10ed2cF043E6fcf51A0e7b4C2Af3Fa06695707);
keepCRV = 1000;
path = new address[](2);
path[1] = weth;
}
receive() external payable {}
function prepareReturn(uint256 _debtOutstanding)
internal
override
returns (
uint256 _profit,
uint256 _loss,
uint256 _debtPayment
)
{
uint before = want.balanceOf(address(this));
IVoterProxy(proxy).harvest(gauge);
uint256 _crv = IERC20(crv).balanceOf(address(this));
if (_crv > 0) {
_crv = _adjustCRV(_crv);
IERC20(crv).safeApprove(dex, 0);
IERC20(crv).safeApprove(dex, _crv);
path[0] = crv;
Uni(dex).swapExactTokensForTokens(_crv, uint256(0), path, address(this), now);
}
IVoterProxy(proxy).claimRewards(gauge, onx);
uint256 _onx = IERC20(onx).balanceOf(address(this));
if (_onx > 0) {
IERC20(onx).safeApprove(uniswap, 0);
IERC20(onx).safeApprove(uniswap, _onx);
path[0] = onx;
Uni(uniswap).swapExactTokensForTokens(_onx, uint256(0), path, address(this), now);
}
IVoterProxy(proxy).claimRewards(gauge, ankr);
uint256 _ankr = IERC20(ankr).balanceOf(address(this));
if (_ankr > 0) {
IERC20(ankr).safeApprove(uniswap, 0);
IERC20(ankr).safeApprove(uniswap, _ankr);
path[0] = ankr;
Uni(uniswap).swapExactTokensForTokens(_ankr, uint256(0), path, address(this), now);
}
uint256 _weth = IERC20(weth).balanceOf(address(this));
if (_weth > 0) {
WETH(weth).withdraw(_weth);
_weth = address(this).balance;
ICurveFi(curve).add_liquidity{value: _weth}([_weth, 0], 0);
}
_profit = want.balanceOf(address(this)).sub(before);
uint _total = estimatedTotalAssets();
uint _debt = vault.strategies(address(this)).totalDebt;
if(_total < _debt) {
_loss = _debt - _total;
_profit = 0;
}
if (_debtOutstanding > 0) {
_withdrawSome(_debtOutstanding);
_debtPayment = Math.min(_debtOutstanding, balanceOfWant().sub(_profit));
}
}
// NOTE: Can override `tendTrigger` and `harvestTrigger` if necessary
function protectedTokens()
internal
view
override
returns (address[] memory)
{
address[] memory protected = new address[](3);
protected[0] = crv;
protected[1] = onx;
protected[2] = ankr;
return protected;
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[],"name":"EmergencyExitEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"profit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"loss","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"debtPayment","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"debtOutstanding","type":"uint256"}],"name":"Harvested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"debtThreshold","type":"uint256"}],"name":"UpdatedDebtThreshold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newKeeper","type":"address"}],"name":"UpdatedKeeper","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"delay","type":"uint256"}],"name":"UpdatedMaxReportDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"metadataURI","type":"string"}],"name":"UpdatedMetadataURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"delay","type":"uint256"}],"name":"UpdatedMinReportDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"profitFactor","type":"uint256"}],"name":"UpdatedProfitFactor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"rewards","type":"address"}],"name":"UpdatedRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newStrategist","type":"address"}],"name":"UpdatedStrategist","type":"event"},{"inputs":[],"name":"DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ankr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"apiVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"balanceOfPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balanceOfWant","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crv","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dai","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"debtThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"delegatedAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dex","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emergencyExit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"estimatedTotalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":[],"name":"isActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"keepCRV","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"keeper","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxReportDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"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":"onx","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"path","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"profitFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewards","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"uint256","name":"_keepCRV","type":"uint256"}],"name":"setKeepCRV","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_keeper","type":"address"}],"name":"setKeeper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_delay","type":"uint256"}],"name":"setMaxReportDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_metadataURI","type":"string"}],"name":"setMetadataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_delay","type":"uint256"}],"name":"setMinReportDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_profitFactor","type":"uint256"}],"name":"setProfitFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_proxy","type":"address"}],"name":"setProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewards","type":"address"}],"name":"setRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategist","type":"address"}],"name":"setStrategist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sushiswap","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":[{"internalType":"bool","name":"isUniswap","type":"bool"}],"name":"switchDex","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":"uniswap","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdc","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdt","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":"voter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"want","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wbtc","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"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60806040523480156200001157600080fd5b50604051620045f4380380620045f48339810160408190526200003491620006c6565b8080620000448133808062000187565b50506154606006556202a300600755600160085569d3c21bcecceda1000000600955600a805474a420a63bbeffbda3b147d0585f1852c358e2c15200610100600160a81b0319909116179055600b80546001600160a01b031990811673d9e1ce17f2641f24ae83637ab66a2cca9c378b9f17909155600c8054821673a96a65c051bf88b4095ee1f2451c2a9d43f53ae2179055600d8054909116736d10ed2cf043e6fcf51a0e7b4c2af3fa066957071790556103e8600e556040805160028082526060820183529091602083019080368337505081516200012d92600f9250602001906200063b565b5073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2600f6001815481106200015257fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555050620008ff565b6005546001600160a01b031615620001bc5760405162461bcd60e51b8152600401620001b390620007b7565b60405180910390fd5b600180546001600160a01b0319166001600160a01b03868116919091179182905560408051637e062a3560e11b81529051929091169163fc0c546a91600480820192602092909190829003018186803b1580156200021957600080fd5b505afa1580156200022e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002549190620006c6565b600580546001600160a01b0319166001600160a01b0392831617908190556200028e9116856000196200036c602090811b620020eb17901c565b600280546001600160a01b038086166001600160a01b0319928316179092556003805485841690831617908190556004805485851693169290921782556000600681905562015180600755606460085560095560015460405163095ea7b360e01b81529084169363095ea7b3936200030f9390911691600019910162000769565b602060405180830381600087803b1580156200032a57600080fd5b505af11580156200033f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003659190620006f6565b5050505050565b801580620003fb5750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e90620003a590309086906004016200074f565b60206040518083038186803b158015620003be57600080fd5b505afa158015620003d3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003f9919062000718565b155b6200041a5760405162461bcd60e51b8152600401620001b3906200086f565b620004758363095ea7b360e01b84846040516024016200043c92919062000769565b60408051808303601f190181529190526020810180516001600160e01b0319939093166001600160e01b03938416179052906200047a16565b505050565b6060620004d6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200051660201b620021ea179092919060201c565b805190915015620004755780806020019051810190620004f79190620006f6565b620004755760405162461bcd60e51b8152600401620001b39062000825565b60606200052784846000856200052f565b949350505050565b60606200053c8562000601565b6200055b5760405162461bcd60e51b8152600401620001b390620007ee565b60006060866001600160a01b031685876040516200057a919062000731565b60006040518083038185875af1925050503d8060008114620005b9576040519150601f19603f3d011682016040523d82523d6000602084013e620005be565b606091505b50915091508115620005d4579150620005279050565b805115620005e55780518082602001fd5b8360405162461bcd60e51b8152600401620001b3919062000782565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159062000527575050151592915050565b82805482825590600052602060002090810192821562000693579160200282015b828111156200069357825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200065c565b50620006a1929150620006a5565b5090565b5b80821115620006a15780546001600160a01b0319168155600101620006a6565b600060208284031215620006d8578081fd5b81516001600160a01b0381168114620006ef578182fd5b9392505050565b60006020828403121562000708578081fd5b81518015158114620006ef578182fd5b6000602082840312156200072a578081fd5b5051919050565b6000825162000745818460208701620008cc565b9190910192915050565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b6000602082528251806020840152620007a3816040850160208701620008cc565b601f01601f19169190910160400192915050565b6020808252601c908201527f537472617465677920616c726561647920696e697469616c697a656400000000604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000606082015260800190565b60005b83811015620008e9578181015183820152602001620008cf565b83811115620008f9576000848401525b50505050565b613ce5806200090f6000396000f3fe6080604052600436106103545760003560e01c80637165485d116101c6578063aced1661116100f7578063ec55688911610095578063f017c92f1161006f578063f017c92f1461087e578063f4b9fa751461089e578063fbfa77cf146108b3578063fcf2d0ad146108c85761035b565b8063ec55688914610834578063ed882c2b14610849578063efbb5cb0146108695761035b565b8063c7b9d530116100d1578063c7b9d530146107bf578063ce5494bb146107df578063dd9e73da146107ff578063ec38a862146108145761035b565b8063aced166114610775578063af6d1fe41461078a578063c1a3d44c146107aa5761035b565b8063918f86741161016457806397107d6d1161013e57806397107d6d146107165780639be28785146107365780639ec5a8941461074b578063a6f19c84146107605761035b565b8063918f8674146106cc578063955383bd146106e157806395e80c50146107015761035b565b80637fef901a116101a05780637fef901a1461066d5780638cdfe166146106825780638e6350e21461069757806391397ab4146106ac5761035b565b80637165485d14610618578063748747e61461062d578063750521f51461064d5761035b565b80632f48ab7d116102a057806346c96aac1161023e578063650d188011610218578063650d1880146105ae578063692058c2146105ce5780636a4874a1146105e35780636bc55876146105f85761035b565b806346c96aac1461056f5780635641ec031461058457806356e6456f146105995761035b565b80633e413bee1161027a5780633e413bee1461051b5780633fc8cef314610530578063440368a3146105455780634641257d1461055a5761035b565b80632f48ab7d146104d157806339a172a8146104e65780633cdc5389146105065761035b565b80631f1fcd511161030d57806325829410116102e757806325829410146104725780632681f7e41461048757806328b7ccf71461049c5780632e1a7d4d146104b15761035b565b80631f1fcd51146104195780631fe4a6861461043b57806322f3e2d4146104505761035b565b806301681a621461036057806303ee438c1461038257806306fdde03146103ad5780630f969b87146103c257806311588086146103e25780631d12f28b146104045761035b565b3661035b57005b600080fd5b34801561036c57600080fd5b5061038061037b366004613532565b6108dd565b005b34801561038e57600080fd5b50610397610a7c565b6040516103a49190613918565b60405180910390f35b3480156103b957600080fd5b50610397610b0a565b3480156103ce57600080fd5b506103806103dd3660046137ae565b610baf565b3480156103ee57600080fd5b506103f7610c3c565b6040516103a49190613b68565b34801561041057600080fd5b506103f7610cce565b34801561042557600080fd5b5061042e610cd4565b6040516103a4919061383b565b34801561044757600080fd5b5061042e610ce3565b34801561045c57600080fd5b50610465610cf2565b6040516103a491906138de565b34801561047e57600080fd5b50610397610d93565b34801561049357600080fd5b5061042e610db2565b3480156104a857600080fd5b506103f7610dca565b3480156104bd57600080fd5b506103f76104cc3660046137ae565b610dd0565b3480156104dd57600080fd5b5061042e610e2b565b3480156104f257600080fd5b506103806105013660046137ae565b610e43565b34801561051257600080fd5b5061042e610ec5565b34801561052757600080fd5b5061042e610edd565b34801561053c57600080fd5b5061042e610ef5565b34801561055157600080fd5b50610380610f0d565b34801561056657600080fd5b50610380611136565b34801561057b57600080fd5b5061042e6114a0565b34801561059057600080fd5b506104656114b8565b3480156105a557600080fd5b5061042e6114c1565b3480156105ba57600080fd5b506104656105c93660046137ae565b6114d9565b3480156105da57600080fd5b5061042e6114e1565b3480156105ef57600080fd5b5061042e6114f0565b34801561060457600080fd5b506103806106133660046135ff565b611508565b34801561062457600080fd5b5061042e6115b0565b34801561063957600080fd5b50610380610648366004613532565b6115bf565b34801561065957600080fd5b50610380610668366004613637565b61166a565b34801561067957600080fd5b506103f7611701565b34801561068e57600080fd5b506103f7611707565b3480156106a357600080fd5b506103f761170d565b3480156106b857600080fd5b506103806106c73660046137ae565b611712565b3480156106d857600080fd5b506103f7611794565b3480156106ed57600080fd5b506103806106fc3660046137ae565b61179a565b34801561070d57600080fd5b506103f76117ec565b34801561072257600080fd5b50610380610731366004613532565b6117f2565b34801561074257600080fd5b5061042e611852565b34801561075757600080fd5b5061042e61186a565b34801561076c57600080fd5b5061042e611879565b34801561078157600080fd5b5061042e611888565b34801561079657600080fd5b5061042e6107a53660046137ae565b611897565b3480156107b657600080fd5b506103f76118be565b3480156107cb57600080fd5b506103806107da366004613532565b6118ef565b3480156107eb57600080fd5b506103806107fa366004613532565b61199a565b34801561080b57600080fd5b5061042e611b08565b34801561082057600080fd5b5061038061082f366004613532565b611b20565b34801561084057600080fd5b5061042e611cb7565b34801561085557600080fd5b506104656108643660046137ae565b611ccb565b34801561087557600080fd5b506103f7611f43565b34801561088a57600080fd5b506103806108993660046137ae565b611f5e565b3480156108aa57600080fd5b5061042e611fe0565b3480156108bf57600080fd5b5061042e611ff8565b3480156108d457600080fd5b50610380612007565b6108e5612201565b6001600160a01b0316336001600160a01b03161461091e5760405162461bcd60e51b815260040161091590613a7f565b60405180910390fd5b6005546001600160a01b038281169116141561094c5760405162461bcd60e51b815260040161091590613970565b6001546001600160a01b038281169116141561097a5760405162461bcd60e51b815260040161091590613a27565b606061098461227e565b905060005b81518110156109df5781818151811061099e57fe5b60200260200101516001600160a01b0316836001600160a01b031614156109d75760405162461bcd60e51b815260040161091590613aee565b600101610989565b50610a786109eb612201565b6040516370a0823160e01b81526001600160a01b038516906370a0823190610a1790309060040161383b565b60206040518083038186803b158015610a2f57600080fd5b505afa158015610a43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6791906137c6565b6001600160a01b0385169190612366565b5050565b6000805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610b025780601f10610ad757610100808354040283529160200191610b02565b820191906000526020600020905b815481529060010190602001808311610ae557829003601f168201915b505050505081565b600554604080516395d89b4160e01b815290516060926001600160a01b0316916395d89b41916004808301926000929190829003018186803b158015610b4f57600080fd5b505afa158015610b63573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b8b91908101906136a4565b604051602001610b9b91906137fa565b604051602081830303815290604052905090565b6002546001600160a01b0316331480610be05750610bcb612201565b6001600160a01b0316336001600160a01b0316145b610bfc5760405162461bcd60e51b815260040161091590613a7f565b60098190556040517fa68ba126373d04c004c5748c300c9fca12bd444b3d4332e261f3bd2bac4a860090610c31908390613b68565b60405180910390a150565b600a54600d546040516370a0823160e01b815260009261010090046001600160a01b03908116926370a0823192610c79929091169060040161383b565b60206040518083038186803b158015610c9157600080fd5b505afa158015610ca5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc991906137c6565b905090565b60095481565b6005546001600160a01b031681565b6002546001600160a01b031681565b6001546040516339ebf82360e01b815260009182916001600160a01b03909116906339ebf82390610d2790309060040161383b565b6101206040518083038186803b158015610d4057600080fd5b505afa158015610d54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d789190613730565b604001511180610cc957506000610d8d611f43565b11905090565b604080518082019091526005815264302e332e3360d81b602082015290565b737a250d5630b4cf539739df2c5dacb4c659f2488d81565b60075481565b6001546000906001600160a01b03163314610dfd5760405162461bcd60e51b815260040161091590613a07565b6000610e0883612385565b600554909350909150610e25906001600160a01b03163383612366565b50919050565b73dac17f958d2ee523a2206206994597c13d831ec781565b6002546001600160a01b0316331480610e745750610e5f612201565b6001600160a01b0316336001600160a01b0316145b610e905760405162461bcd60e51b815260040161091590613a7f565b60068190556040517fbb2c369a0355a34b02ab5fce0643150c87e1c8dfe7c918d465591879f57948b190610c31908390613b68565b732260fac5e5542a773aa44fbcfedf7c193bc2c59981565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6004546001600160a01b0316331480610f3057506002546001600160a01b031633145b80610f535750610f3e612201565b6001600160a01b0316336001600160a01b0316145b80610ff45750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b158015610fa757600080fd5b505afa158015610fbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fdf919061354e565b6001600160a01b0316336001600160a01b0316145b806110955750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b15801561104857600080fd5b505afa15801561105c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611080919061354e565b6001600160a01b0316336001600160a01b0316145b6110b15760405162461bcd60e51b815260040161091590613a7f565b6001546040805163bf3759b560e01b81529051611134926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b1580156110f757600080fd5b505afa15801561110b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112f91906137c6565b61244f565b565b6004546001600160a01b031633148061115957506002546001600160a01b031633145b8061117c5750611167612201565b6001600160a01b0316336001600160a01b0316145b8061121d5750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b1580156111d057600080fd5b505afa1580156111e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611208919061354e565b6001600160a01b0316336001600160a01b0316145b806112be5750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b15801561127157600080fd5b505afa158015611285573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a9919061354e565b6001600160a01b0316336001600160a01b0316145b6112da5760405162461bcd60e51b815260040161091590613a7f565b6000806000600160009054906101000a90046001600160a01b03166001600160a01b031663bf3759b56040518163ffffffff1660e01b815260040160206040518083038186803b15801561132d57600080fd5b505afa158015611341573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136591906137c6565b600a5490915060009060ff16156113bb576000611380611f43565b90506113998382116113925783611394565b815b612385565b94509150828211156113b5576113af8284612571565b94508291505b506113cc565b6113c4826125bc565b919550935090505b6001546040516328766ebf60e21b81526001600160a01b039091169063a1d9bafc9061140090879087908690600401613be4565b602060405180830381600087803b15801561141a57600080fd5b505af115801561142e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145291906137c6565b915061145d8261244f565b7f4c0f499ffe6befa0ca7c826b0916cf87bea98de658013e76938489368d60d509848483856040516114929493929190613bfa565b60405180910390a150505050565b73f147b8125d2ef93fb6965db97d6746952a13393481565b600a5460ff1681565b73e0ad1806fd3e7edf6ff52fdb822432e84741103381565b60005b919050565b600b546001600160a01b031681565b73d533a949740bb3306d119cc777fa900ba034cd5281565b6002546001600160a01b03163314806115395750611524612201565b6001600160a01b0316336001600160a01b0316145b6115555760405162461bcd60e51b815260040161091590613a7f565b801561158657600b80546001600160a01b031916737a250d5630b4cf539739df2c5dacb4c659f2488d1790556115ad565b600b80546001600160a01b03191673d9e1ce17f2641f24ae83637ab66a2cca9c378b9f1790555b50565b600c546001600160a01b031681565b6002546001600160a01b03163314806115f057506115db612201565b6001600160a01b0316336001600160a01b0316145b61160c5760405162461bcd60e51b815260040161091590613a7f565b6001600160a01b03811661161f57600080fd5b600480546001600160a01b0319166001600160a01b0383161790556040517f2f202ddb4a2e345f6323ed90f8fc8559d770a7abbbeee84dde8aca3351fe715490610c3190839061383b565b6002546001600160a01b031633148061169b5750611686612201565b6001600160a01b0316336001600160a01b0316145b6116b75760405162461bcd60e51b815260040161091590613a7f565b6116c360008383613453565b507f300e67d5a415b6d015a471d9c7b95dd58f3e8290af965e84e0f845de2996dda682826040516116f59291906138e9565b60405180910390a15050565b600e5481565b60085481565b600090565b6002546001600160a01b0316331480611743575061172e612201565b6001600160a01b0316336001600160a01b0316145b61175f5760405162461bcd60e51b815260040161091590613a7f565b60088190556040517fd94596337df4c2f0f44d30a7fc5db1c7bb60d9aca4185ed77c6fd96eb45ec29890610c31908390613b68565b61271081565b6002546001600160a01b03163314806117cb57506117b6612201565b6001600160a01b0316336001600160a01b0316145b6117e75760405162461bcd60e51b815260040161091590613a7f565b600e55565b60065481565b6117fa612201565b6001600160a01b0316336001600160a01b03161461182a5760405162461bcd60e51b815260040161091590613a7f565b600a80546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b73d9e1ce17f2641f24ae83637ab66a2cca9c378b9f81565b6003546001600160a01b031681565b600d546001600160a01b031681565b6004546001600160a01b031681565b600f81815481106118a457fe5b6000918252602090912001546001600160a01b0316905081565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a0823190610c7990309060040161383b565b6002546001600160a01b0316331480611920575061190b612201565b6001600160a01b0316336001600160a01b0316145b61193c5760405162461bcd60e51b815260040161091590613a7f565b6001600160a01b03811661194f57600080fd5b600280546001600160a01b0319166001600160a01b0383161790556040517f352ececae6d7d1e6d26bcf2c549dfd55be1637e9b22dc0cf3b71ddb36097a6b490610c3190839061383b565b6001546001600160a01b03163314806119cb57506119b6612201565b6001600160a01b0316336001600160a01b0316145b6119d457600080fd5b6001546040805163fbfa77cf60e01b815290516001600160a01b039283169284169163fbfa77cf916004808301926020929190829003018186803b158015611a1b57600080fd5b505afa158015611a2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a53919061354e565b6001600160a01b031614611a6657600080fd5b611a6f81613013565b6005546040516370a0823160e01b81526115ad9183916001600160a01b03909116906370a0823190611aa590309060040161383b565b60206040518083038186803b158015611abd57600080fd5b505afa158015611ad1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af591906137c6565b6005546001600160a01b03169190612366565b738290333cef9e6d528dd5618fb97a76f268f3edd481565b6002546001600160a01b03163314611b4a5760405162461bcd60e51b81526004016109159061394b565b6001600160a01b038116611b5d57600080fd5b60015460035460405163095ea7b360e01b81526001600160a01b039283169263095ea7b392611b949291169060009060040161388d565b602060405180830381600087803b158015611bae57600080fd5b505af1158015611bc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611be6919061361b565b50600380546001600160a01b0319166001600160a01b03838116919091179182905560015460405163095ea7b360e01b81529082169263095ea7b392611c35929116906000199060040161388d565b602060405180830381600087803b158015611c4f57600080fd5b505af1158015611c63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c87919061361b565b507fafbb66abf8f3b719799940473a4052a3717cdd8e40fb6c8a3faadab316b1a06981604051610c31919061383b565b600a5461010090046001600160a01b031681565b6000611cd56134d1565b6001546040516339ebf82360e01b81526001600160a01b03909116906339ebf82390611d0590309060040161383b565b6101206040518083038186803b158015611d1e57600080fd5b505afa158015611d32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d569190613730565b9050806020015160001415611d6f5760009150506114dc565b60065460a0820151611d82904290612571565b1015611d925760009150506114dc565b60075460a0820151611da5904290612571565b10611db45760019150506114dc565b6001546040805163bf3759b560e01b815290516000926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b158015611df957600080fd5b505afa158015611e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e3191906137c6565b9050600954811115611e48576001925050506114dc565b6000611e52611f43565b90508260c00151611e6e600954836130a590919063ffffffff16565b1015611e8057600193505050506114dc565b60008360c00151821115611ea15760c0840151611e9e908390612571565b90505b6001546040805163112c1f9b60e01b815290516000926001600160a01b03169163112c1f9b916004808301926020929190829003018186803b158015611ee657600080fd5b505afa158015611efa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f1e91906137c6565b9050611f2a81836130a5565b600854611f3790896130ca565b10979650505050505050565b6000610cc9611f50610c3c565b611f586118be565b906130a5565b6002546001600160a01b0316331480611f8f5750611f7a612201565b6001600160a01b0316336001600160a01b0316145b611fab5760405162461bcd60e51b815260040161091590613a7f565b60078190556040517f5430e11864ad7aa9775b07d12657fe52df9aa2ba734355bd8ef8747be2c800c590610c31908390613b68565b736b175474e89094c44da98b954eedeac495271d0f81565b6001546001600160a01b031681565b6002546001600160a01b03163314806120385750612023612201565b6001600160a01b0316336001600160a01b0316145b6120545760405162461bcd60e51b815260040161091590613a7f565b600a805460ff19166001908117909155546040805163507257cd60e11b815290516001600160a01b039092169163a0e4af9a9160048082019260009290919082900301818387803b1580156120a857600080fd5b505af11580156120bc573d6000803e3d6000fd5b50506040517f97e963041e952738788b9d4871d854d282065b8f90a464928d6528f2e9a4fd0b925060009150a1565b8015806121735750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e90612121903090869060040161384f565b60206040518083038186803b15801561213957600080fd5b505afa15801561214d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217191906137c6565b155b61218f5760405162461bcd60e51b815260040161091590613b12565b6121e58363095ea7b360e01b84846040516024016121ae92919061388d565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613104565b505050565b60606121f98484600085613193565b949350505050565b60015460408051635aa6e67560e01b815290516000926001600160a01b031691635aa6e675916004808301926020929190829003018186803b15801561224657600080fd5b505afa15801561225a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc9919061354e565b6040805160038082526080820190925260609182919060208201838036833701905050905073d533a949740bb3306d119cc777fa900ba034cd52816000815181106122c557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073e0ad1806fd3e7edf6ff52fdb822432e8474110338160018151811061230757fe5b60200260200101906001600160a01b031690816001600160a01b031681525050738290333cef9e6d528dd5618fb97a76f268f3edd48160028151811061234957fe5b6001600160a01b0390921660209283029190910190910152905090565b6121e58363a9059cbb60e01b84846040516024016121ae92919061388d565b6005546040516370a0823160e01b8152600091829182916001600160a01b0316906370a08231906123ba90309060040161383b565b60206040518083038186803b1580156123d257600080fd5b505afa1580156123e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240a91906137c6565b905083811015612445576124266124218583612571565b613257565b925061243283826130a5565b925061243e8484612571565b9150612449565b8392505b50915091565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a082319061248090309060040161383b565b60206040518083038186803b15801561249857600080fd5b505afa1580156124ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124d091906137c6565b90508015610a7857600a546005546124fb916001600160a01b03918216916101009091041683612366565b600a54600d54600554604051631f2c13e160e31b81526001600160a01b0361010090940484169363f9609f089361253b939082169291169060040161384f565b600060405180830381600087803b15801561255557600080fd5b505af1158015612569573d6000803e3d6000fd5b505050505050565b60006125b383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506132fa565b90505b92915050565b6005546040516370a0823160e01b81526000918291829182916001600160a01b03909116906370a08231906125f590309060040161383b565b60206040518083038186803b15801561260d57600080fd5b505afa158015612621573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264591906137c6565b600a54600d5460405163072e008f60e11b81529293506001600160a01b03610100909204821692630e5c011e9261268092169060040161383b565b600060405180830381600087803b15801561269a57600080fd5b505af11580156126ae573d6000803e3d6000fd5b50506040516370a0823160e01b81526000925073d533a949740bb3306d119cc777fa900ba034cd5291506370a08231906126ec90309060040161383b565b60206040518083038186803b15801561270457600080fd5b505afa158015612718573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061273c91906137c6565b905080156128775761274d81613326565b600b5490915061277d9073d533a949740bb3306d119cc777fa900ba034cd52906001600160a01b031660006120eb565b600b546127a99073d533a949740bb3306d119cc777fa900ba034cd52906001600160a01b0316836120eb565b73d533a949740bb3306d119cc777fa900ba034cd52600f6000815481106127cc57fe5b6000918252602082200180546001600160a01b0319166001600160a01b03938416179055600b546040516338ed173960e01b81529216916338ed17399161281f91859190600f9030904290600401613b71565b600060405180830381600087803b15801561283957600080fd5b505af115801561284d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612875919081019061356a565b505b600a54600d5460405163f1e42ccd60e01b81526001600160a01b0361010090930483169263f1e42ccd926128c69291169073e0ad1806fd3e7edf6ff52fdb822432e8474110339060040161384f565b600060405180830381600087803b1580156128e057600080fd5b505af11580156128f4573d6000803e3d6000fd5b50506040516370a0823160e01b81526000925073e0ad1806fd3e7edf6ff52fdb822432e84741103391506370a082319061293290309060040161383b565b60206040518083038186803b15801561294a57600080fd5b505afa15801561295e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061298291906137c6565b90508015612ad3576129be73e0ad1806fd3e7edf6ff52fdb822432e847411033737a250d5630b4cf539739df2c5dacb4c659f2488d60006120eb565b6129f173e0ad1806fd3e7edf6ff52fdb822432e847411033737a250d5630b4cf539739df2c5dacb4c659f2488d836120eb565b73e0ad1806fd3e7edf6ff52fdb822432e847411033600f600081548110612a1457fe5b6000918252602082200180546001600160a01b0319166001600160a01b0393909316929092179091556040516338ed173960e01b8152737a250d5630b4cf539739df2c5dacb4c659f2488d916338ed173991612a7b918591600f9030904290600401613b71565b600060405180830381600087803b158015612a9557600080fd5b505af1158015612aa9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612ad1919081019061356a565b505b600a54600d5460405163f1e42ccd60e01b81526001600160a01b0361010090930483169263f1e42ccd92612b2292911690738290333cef9e6d528dd5618fb97a76f268f3edd49060040161384f565b600060405180830381600087803b158015612b3c57600080fd5b505af1158015612b50573d6000803e3d6000fd5b50506040516370a0823160e01b815260009250738290333cef9e6d528dd5618fb97a76f268f3edd491506370a0823190612b8e90309060040161383b565b60206040518083038186803b158015612ba657600080fd5b505afa158015612bba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bde91906137c6565b90508015612d2f57612c1a738290333cef9e6d528dd5618fb97a76f268f3edd4737a250d5630b4cf539739df2c5dacb4c659f2488d60006120eb565b612c4d738290333cef9e6d528dd5618fb97a76f268f3edd4737a250d5630b4cf539739df2c5dacb4c659f2488d836120eb565b738290333cef9e6d528dd5618fb97a76f268f3edd4600f600081548110612c7057fe5b6000918252602082200180546001600160a01b0319166001600160a01b0393909316929092179091556040516338ed173960e01b8152737a250d5630b4cf539739df2c5dacb4c659f2488d916338ed173991612cd7918591600f9030904290600401613b71565b600060405180830381600087803b158015612cf157600080fd5b505af1158015612d05573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612d2d919081019061356a565b505b6040516370a0823160e01b815260009073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2906370a0823190612d6990309060040161383b565b60206040518083038186803b158015612d8157600080fd5b505afa158015612d95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612db991906137c6565b90508015612ea657604051632e1a7d4d60e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d90612df8908490600401613b68565b600060405180830381600087803b158015612e1257600080fd5b505af1158015612e26573d6000803e3d6000fd5b5050600c54604080518082018252478082526000602083018190529251630b4c7e4d60e01b81529096506001600160a01b039093169450630b4c7e4d93508592612e7392906004016138a6565b6000604051808303818588803b158015612e8c57600080fd5b505af1158015612ea0573d6000803e3d6000fd5b50505050505b6005546040516370a0823160e01b8152612f329187916001600160a01b03909116906370a0823190612edc90309060040161383b565b60206040518083038186803b158015612ef457600080fd5b505afa158015612f08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f2c91906137c6565b90612571565b97506000612f3e611f43565b6001546040516339ebf82360e01b81529192506000916001600160a01b03909116906339ebf82390612f7490309060040161383b565b6101206040518083038186803b158015612f8d57600080fd5b505afa158015612fa1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fc59190613730565b60c00151905080821015612fdd578181039850600099505b8a1561300557612fec8b613257565b506130028b612ffd8c612f2c6118be565b613390565b97505b505050505050509193909250565b600a54600d546005546040516301395c5960e31b81526001600160a01b036101009094048416936309cae2c893613053939082169291169060040161384f565b602060405180830381600087803b15801561306d57600080fd5b505af1158015613081573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7891906137c6565b6000828201838110156125b35760405162461bcd60e51b81526004016109159061398f565b6000826130d9575060006125b6565b828202828482816130e657fe5b04146125b35760405162461bcd60e51b8152600401610915906139c6565b6060613159826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166121ea9092919063ffffffff16565b8051909150156121e55780806020019051810190613177919061361b565b6121e55760405162461bcd60e51b815260040161091590613aa4565b606061319e856133a6565b6131ba5760405162461bcd60e51b815260040161091590613a48565b60006060866001600160a01b031685876040516131d791906137de565b60006040518083038185875af1925050503d8060008114613214576040519150601f19603f3d011682016040523d82523d6000602084013e613219565b606091505b5091509150811561322d5791506121f99050565b80511561323d5780518082602001fd5b8360405162461bcd60e51b81526004016109159190613918565b600061326582612ffd610c3c565b600a54600d54600554604051636ce5768960e11b81529395506001600160a01b0361010090930483169363d9caed12936132a89381169216908790600401613869565b602060405180830381600087803b1580156132c257600080fd5b505af11580156132d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b691906137c6565b6000818484111561331e5760405162461bcd60e51b81526004016109159190613918565b505050900390565b60008061334a612710613344600e54866130ca90919063ffffffff16565b906133df565b905061337f73d533a949740bb3306d119cc777fa900ba034cd5273f147b8125d2ef93fb6965db97d6746952a13393483612366565b6133898382612571565b9392505050565b600081831061339f57816125b3565b5090919050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906121f9575050151592915050565b60006125b383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506000818361343d5760405162461bcd60e51b81526004016109159190613918565b50600083858161344957fe5b0495945050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106134945782800160ff198235161785556134c1565b828001600101855582156134c1579182015b828111156134c15782358255916020019190600101906134a6565b506134cd92915061351d565b5090565b6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b808211156134cd576000815560010161351e565b600060208284031215613543578081fd5b81356125b381613c8c565b60006020828403121561355f578081fd5b81516125b381613c8c565b6000602080838503121561357c578182fd5b825167ffffffffffffffff811115613592578283fd5b8301601f810185136135a2578283fd5b80516135b56135b082613c3c565b613c15565b81815283810190838501858402850186018910156135d1578687fd5b8694505b838510156135f35780518352600194909401939185019185016135d5565b50979650505050505050565b600060208284031215613610578081fd5b81356125b381613ca1565b60006020828403121561362c578081fd5b81516125b381613ca1565b60008060208385031215613649578081fd5b823567ffffffffffffffff80821115613660578283fd5b818501915085601f830112613673578283fd5b813581811115613681578384fd5b866020828501011115613692578384fd5b60209290920196919550909350505050565b6000602082840312156136b5578081fd5b815167ffffffffffffffff808211156136cc578283fd5b818401915084601f8301126136df578283fd5b8151818111156136ed578384fd5b613700601f8201601f1916602001613c15565b9150808252856020828501011115613716578384fd5b613727816020840160208601613c5c565b50949350505050565b6000610120808385031215613743578182fd5b61374c81613c15565b9050825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152508091505092915050565b6000602082840312156137bf578081fd5b5035919050565b6000602082840312156137d7578081fd5b5051919050565b600082516137f0818460208701613c5c565b9190910192915050565b600064437572766560d81b8252825161381a816005850160208701613c5c565b69566f74657250726f787960b01b6005939091019283015250600f01919050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b60608101818460005b60028110156138ce5781518352602092830192909101906001016138af565b5050508260408301529392505050565b901515815260200190565b60006020825282602083015282846040840137818301604090810191909152601f909201601f19160101919050565b6000602082528251806020840152613937816040850160208701613c5c565b601f01601f19169190910160400192915050565b6020808252600b908201526a085cdd1c985d1959da5cdd60aa1b604082015260600190565b602080825260059082015264085dd85b9d60da1b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b602080825260069082015265085d985d5b1d60d21b604082015260600190565b6020808252600790820152662173686172657360c81b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252600b908201526a08585d5d1a1bdc9a5e995960aa1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600a9082015269085c1c9bdd1958dd195960b21b604082015260600190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b90815260200190565b600060a082018783526020878185015260a0604085015281875480845260c0860191508885528285209350845b81811015613bc35784546001600160a01b031683526001948501949284019201613b9e565b50506001600160a01b03969096166060850152505050608001529392505050565b9283526020830191909152604082015260600190565b93845260208401929092526040830152606082015260800190565b60405181810167ffffffffffffffff81118282101715613c3457600080fd5b604052919050565b600067ffffffffffffffff821115613c52578081fd5b5060209081020190565b60005b83811015613c77578181015183820152602001613c5f565b83811115613c86576000848401525b50505050565b6001600160a01b03811681146115ad57600080fd5b80151581146115ad57600080fdfea2646970667358221220d04de687f5702ae56c61bb96e2f4589ebce0bcd736a52d191b78c82435c83de864736f6c634300060c0033000000000000000000000000132d8d2c76db3812403431facb00f3453fc42125
Deployed Bytecode
0x6080604052600436106103545760003560e01c80637165485d116101c6578063aced1661116100f7578063ec55688911610095578063f017c92f1161006f578063f017c92f1461087e578063f4b9fa751461089e578063fbfa77cf146108b3578063fcf2d0ad146108c85761035b565b8063ec55688914610834578063ed882c2b14610849578063efbb5cb0146108695761035b565b8063c7b9d530116100d1578063c7b9d530146107bf578063ce5494bb146107df578063dd9e73da146107ff578063ec38a862146108145761035b565b8063aced166114610775578063af6d1fe41461078a578063c1a3d44c146107aa5761035b565b8063918f86741161016457806397107d6d1161013e57806397107d6d146107165780639be28785146107365780639ec5a8941461074b578063a6f19c84146107605761035b565b8063918f8674146106cc578063955383bd146106e157806395e80c50146107015761035b565b80637fef901a116101a05780637fef901a1461066d5780638cdfe166146106825780638e6350e21461069757806391397ab4146106ac5761035b565b80637165485d14610618578063748747e61461062d578063750521f51461064d5761035b565b80632f48ab7d116102a057806346c96aac1161023e578063650d188011610218578063650d1880146105ae578063692058c2146105ce5780636a4874a1146105e35780636bc55876146105f85761035b565b806346c96aac1461056f5780635641ec031461058457806356e6456f146105995761035b565b80633e413bee1161027a5780633e413bee1461051b5780633fc8cef314610530578063440368a3146105455780634641257d1461055a5761035b565b80632f48ab7d146104d157806339a172a8146104e65780633cdc5389146105065761035b565b80631f1fcd511161030d57806325829410116102e757806325829410146104725780632681f7e41461048757806328b7ccf71461049c5780632e1a7d4d146104b15761035b565b80631f1fcd51146104195780631fe4a6861461043b57806322f3e2d4146104505761035b565b806301681a621461036057806303ee438c1461038257806306fdde03146103ad5780630f969b87146103c257806311588086146103e25780631d12f28b146104045761035b565b3661035b57005b600080fd5b34801561036c57600080fd5b5061038061037b366004613532565b6108dd565b005b34801561038e57600080fd5b50610397610a7c565b6040516103a49190613918565b60405180910390f35b3480156103b957600080fd5b50610397610b0a565b3480156103ce57600080fd5b506103806103dd3660046137ae565b610baf565b3480156103ee57600080fd5b506103f7610c3c565b6040516103a49190613b68565b34801561041057600080fd5b506103f7610cce565b34801561042557600080fd5b5061042e610cd4565b6040516103a4919061383b565b34801561044757600080fd5b5061042e610ce3565b34801561045c57600080fd5b50610465610cf2565b6040516103a491906138de565b34801561047e57600080fd5b50610397610d93565b34801561049357600080fd5b5061042e610db2565b3480156104a857600080fd5b506103f7610dca565b3480156104bd57600080fd5b506103f76104cc3660046137ae565b610dd0565b3480156104dd57600080fd5b5061042e610e2b565b3480156104f257600080fd5b506103806105013660046137ae565b610e43565b34801561051257600080fd5b5061042e610ec5565b34801561052757600080fd5b5061042e610edd565b34801561053c57600080fd5b5061042e610ef5565b34801561055157600080fd5b50610380610f0d565b34801561056657600080fd5b50610380611136565b34801561057b57600080fd5b5061042e6114a0565b34801561059057600080fd5b506104656114b8565b3480156105a557600080fd5b5061042e6114c1565b3480156105ba57600080fd5b506104656105c93660046137ae565b6114d9565b3480156105da57600080fd5b5061042e6114e1565b3480156105ef57600080fd5b5061042e6114f0565b34801561060457600080fd5b506103806106133660046135ff565b611508565b34801561062457600080fd5b5061042e6115b0565b34801561063957600080fd5b50610380610648366004613532565b6115bf565b34801561065957600080fd5b50610380610668366004613637565b61166a565b34801561067957600080fd5b506103f7611701565b34801561068e57600080fd5b506103f7611707565b3480156106a357600080fd5b506103f761170d565b3480156106b857600080fd5b506103806106c73660046137ae565b611712565b3480156106d857600080fd5b506103f7611794565b3480156106ed57600080fd5b506103806106fc3660046137ae565b61179a565b34801561070d57600080fd5b506103f76117ec565b34801561072257600080fd5b50610380610731366004613532565b6117f2565b34801561074257600080fd5b5061042e611852565b34801561075757600080fd5b5061042e61186a565b34801561076c57600080fd5b5061042e611879565b34801561078157600080fd5b5061042e611888565b34801561079657600080fd5b5061042e6107a53660046137ae565b611897565b3480156107b657600080fd5b506103f76118be565b3480156107cb57600080fd5b506103806107da366004613532565b6118ef565b3480156107eb57600080fd5b506103806107fa366004613532565b61199a565b34801561080b57600080fd5b5061042e611b08565b34801561082057600080fd5b5061038061082f366004613532565b611b20565b34801561084057600080fd5b5061042e611cb7565b34801561085557600080fd5b506104656108643660046137ae565b611ccb565b34801561087557600080fd5b506103f7611f43565b34801561088a57600080fd5b506103806108993660046137ae565b611f5e565b3480156108aa57600080fd5b5061042e611fe0565b3480156108bf57600080fd5b5061042e611ff8565b3480156108d457600080fd5b50610380612007565b6108e5612201565b6001600160a01b0316336001600160a01b03161461091e5760405162461bcd60e51b815260040161091590613a7f565b60405180910390fd5b6005546001600160a01b038281169116141561094c5760405162461bcd60e51b815260040161091590613970565b6001546001600160a01b038281169116141561097a5760405162461bcd60e51b815260040161091590613a27565b606061098461227e565b905060005b81518110156109df5781818151811061099e57fe5b60200260200101516001600160a01b0316836001600160a01b031614156109d75760405162461bcd60e51b815260040161091590613aee565b600101610989565b50610a786109eb612201565b6040516370a0823160e01b81526001600160a01b038516906370a0823190610a1790309060040161383b565b60206040518083038186803b158015610a2f57600080fd5b505afa158015610a43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6791906137c6565b6001600160a01b0385169190612366565b5050565b6000805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610b025780601f10610ad757610100808354040283529160200191610b02565b820191906000526020600020905b815481529060010190602001808311610ae557829003601f168201915b505050505081565b600554604080516395d89b4160e01b815290516060926001600160a01b0316916395d89b41916004808301926000929190829003018186803b158015610b4f57600080fd5b505afa158015610b63573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b8b91908101906136a4565b604051602001610b9b91906137fa565b604051602081830303815290604052905090565b6002546001600160a01b0316331480610be05750610bcb612201565b6001600160a01b0316336001600160a01b0316145b610bfc5760405162461bcd60e51b815260040161091590613a7f565b60098190556040517fa68ba126373d04c004c5748c300c9fca12bd444b3d4332e261f3bd2bac4a860090610c31908390613b68565b60405180910390a150565b600a54600d546040516370a0823160e01b815260009261010090046001600160a01b03908116926370a0823192610c79929091169060040161383b565b60206040518083038186803b158015610c9157600080fd5b505afa158015610ca5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc991906137c6565b905090565b60095481565b6005546001600160a01b031681565b6002546001600160a01b031681565b6001546040516339ebf82360e01b815260009182916001600160a01b03909116906339ebf82390610d2790309060040161383b565b6101206040518083038186803b158015610d4057600080fd5b505afa158015610d54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d789190613730565b604001511180610cc957506000610d8d611f43565b11905090565b604080518082019091526005815264302e332e3360d81b602082015290565b737a250d5630b4cf539739df2c5dacb4c659f2488d81565b60075481565b6001546000906001600160a01b03163314610dfd5760405162461bcd60e51b815260040161091590613a07565b6000610e0883612385565b600554909350909150610e25906001600160a01b03163383612366565b50919050565b73dac17f958d2ee523a2206206994597c13d831ec781565b6002546001600160a01b0316331480610e745750610e5f612201565b6001600160a01b0316336001600160a01b0316145b610e905760405162461bcd60e51b815260040161091590613a7f565b60068190556040517fbb2c369a0355a34b02ab5fce0643150c87e1c8dfe7c918d465591879f57948b190610c31908390613b68565b732260fac5e5542a773aa44fbcfedf7c193bc2c59981565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6004546001600160a01b0316331480610f3057506002546001600160a01b031633145b80610f535750610f3e612201565b6001600160a01b0316336001600160a01b0316145b80610ff45750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b158015610fa757600080fd5b505afa158015610fbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fdf919061354e565b6001600160a01b0316336001600160a01b0316145b806110955750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b15801561104857600080fd5b505afa15801561105c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611080919061354e565b6001600160a01b0316336001600160a01b0316145b6110b15760405162461bcd60e51b815260040161091590613a7f565b6001546040805163bf3759b560e01b81529051611134926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b1580156110f757600080fd5b505afa15801561110b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112f91906137c6565b61244f565b565b6004546001600160a01b031633148061115957506002546001600160a01b031633145b8061117c5750611167612201565b6001600160a01b0316336001600160a01b0316145b8061121d5750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b1580156111d057600080fd5b505afa1580156111e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611208919061354e565b6001600160a01b0316336001600160a01b0316145b806112be5750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b15801561127157600080fd5b505afa158015611285573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a9919061354e565b6001600160a01b0316336001600160a01b0316145b6112da5760405162461bcd60e51b815260040161091590613a7f565b6000806000600160009054906101000a90046001600160a01b03166001600160a01b031663bf3759b56040518163ffffffff1660e01b815260040160206040518083038186803b15801561132d57600080fd5b505afa158015611341573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136591906137c6565b600a5490915060009060ff16156113bb576000611380611f43565b90506113998382116113925783611394565b815b612385565b94509150828211156113b5576113af8284612571565b94508291505b506113cc565b6113c4826125bc565b919550935090505b6001546040516328766ebf60e21b81526001600160a01b039091169063a1d9bafc9061140090879087908690600401613be4565b602060405180830381600087803b15801561141a57600080fd5b505af115801561142e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145291906137c6565b915061145d8261244f565b7f4c0f499ffe6befa0ca7c826b0916cf87bea98de658013e76938489368d60d509848483856040516114929493929190613bfa565b60405180910390a150505050565b73f147b8125d2ef93fb6965db97d6746952a13393481565b600a5460ff1681565b73e0ad1806fd3e7edf6ff52fdb822432e84741103381565b60005b919050565b600b546001600160a01b031681565b73d533a949740bb3306d119cc777fa900ba034cd5281565b6002546001600160a01b03163314806115395750611524612201565b6001600160a01b0316336001600160a01b0316145b6115555760405162461bcd60e51b815260040161091590613a7f565b801561158657600b80546001600160a01b031916737a250d5630b4cf539739df2c5dacb4c659f2488d1790556115ad565b600b80546001600160a01b03191673d9e1ce17f2641f24ae83637ab66a2cca9c378b9f1790555b50565b600c546001600160a01b031681565b6002546001600160a01b03163314806115f057506115db612201565b6001600160a01b0316336001600160a01b0316145b61160c5760405162461bcd60e51b815260040161091590613a7f565b6001600160a01b03811661161f57600080fd5b600480546001600160a01b0319166001600160a01b0383161790556040517f2f202ddb4a2e345f6323ed90f8fc8559d770a7abbbeee84dde8aca3351fe715490610c3190839061383b565b6002546001600160a01b031633148061169b5750611686612201565b6001600160a01b0316336001600160a01b0316145b6116b75760405162461bcd60e51b815260040161091590613a7f565b6116c360008383613453565b507f300e67d5a415b6d015a471d9c7b95dd58f3e8290af965e84e0f845de2996dda682826040516116f59291906138e9565b60405180910390a15050565b600e5481565b60085481565b600090565b6002546001600160a01b0316331480611743575061172e612201565b6001600160a01b0316336001600160a01b0316145b61175f5760405162461bcd60e51b815260040161091590613a7f565b60088190556040517fd94596337df4c2f0f44d30a7fc5db1c7bb60d9aca4185ed77c6fd96eb45ec29890610c31908390613b68565b61271081565b6002546001600160a01b03163314806117cb57506117b6612201565b6001600160a01b0316336001600160a01b0316145b6117e75760405162461bcd60e51b815260040161091590613a7f565b600e55565b60065481565b6117fa612201565b6001600160a01b0316336001600160a01b03161461182a5760405162461bcd60e51b815260040161091590613a7f565b600a80546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b73d9e1ce17f2641f24ae83637ab66a2cca9c378b9f81565b6003546001600160a01b031681565b600d546001600160a01b031681565b6004546001600160a01b031681565b600f81815481106118a457fe5b6000918252602090912001546001600160a01b0316905081565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a0823190610c7990309060040161383b565b6002546001600160a01b0316331480611920575061190b612201565b6001600160a01b0316336001600160a01b0316145b61193c5760405162461bcd60e51b815260040161091590613a7f565b6001600160a01b03811661194f57600080fd5b600280546001600160a01b0319166001600160a01b0383161790556040517f352ececae6d7d1e6d26bcf2c549dfd55be1637e9b22dc0cf3b71ddb36097a6b490610c3190839061383b565b6001546001600160a01b03163314806119cb57506119b6612201565b6001600160a01b0316336001600160a01b0316145b6119d457600080fd5b6001546040805163fbfa77cf60e01b815290516001600160a01b039283169284169163fbfa77cf916004808301926020929190829003018186803b158015611a1b57600080fd5b505afa158015611a2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a53919061354e565b6001600160a01b031614611a6657600080fd5b611a6f81613013565b6005546040516370a0823160e01b81526115ad9183916001600160a01b03909116906370a0823190611aa590309060040161383b565b60206040518083038186803b158015611abd57600080fd5b505afa158015611ad1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af591906137c6565b6005546001600160a01b03169190612366565b738290333cef9e6d528dd5618fb97a76f268f3edd481565b6002546001600160a01b03163314611b4a5760405162461bcd60e51b81526004016109159061394b565b6001600160a01b038116611b5d57600080fd5b60015460035460405163095ea7b360e01b81526001600160a01b039283169263095ea7b392611b949291169060009060040161388d565b602060405180830381600087803b158015611bae57600080fd5b505af1158015611bc2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611be6919061361b565b50600380546001600160a01b0319166001600160a01b03838116919091179182905560015460405163095ea7b360e01b81529082169263095ea7b392611c35929116906000199060040161388d565b602060405180830381600087803b158015611c4f57600080fd5b505af1158015611c63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c87919061361b565b507fafbb66abf8f3b719799940473a4052a3717cdd8e40fb6c8a3faadab316b1a06981604051610c31919061383b565b600a5461010090046001600160a01b031681565b6000611cd56134d1565b6001546040516339ebf82360e01b81526001600160a01b03909116906339ebf82390611d0590309060040161383b565b6101206040518083038186803b158015611d1e57600080fd5b505afa158015611d32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d569190613730565b9050806020015160001415611d6f5760009150506114dc565b60065460a0820151611d82904290612571565b1015611d925760009150506114dc565b60075460a0820151611da5904290612571565b10611db45760019150506114dc565b6001546040805163bf3759b560e01b815290516000926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b158015611df957600080fd5b505afa158015611e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e3191906137c6565b9050600954811115611e48576001925050506114dc565b6000611e52611f43565b90508260c00151611e6e600954836130a590919063ffffffff16565b1015611e8057600193505050506114dc565b60008360c00151821115611ea15760c0840151611e9e908390612571565b90505b6001546040805163112c1f9b60e01b815290516000926001600160a01b03169163112c1f9b916004808301926020929190829003018186803b158015611ee657600080fd5b505afa158015611efa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f1e91906137c6565b9050611f2a81836130a5565b600854611f3790896130ca565b10979650505050505050565b6000610cc9611f50610c3c565b611f586118be565b906130a5565b6002546001600160a01b0316331480611f8f5750611f7a612201565b6001600160a01b0316336001600160a01b0316145b611fab5760405162461bcd60e51b815260040161091590613a7f565b60078190556040517f5430e11864ad7aa9775b07d12657fe52df9aa2ba734355bd8ef8747be2c800c590610c31908390613b68565b736b175474e89094c44da98b954eedeac495271d0f81565b6001546001600160a01b031681565b6002546001600160a01b03163314806120385750612023612201565b6001600160a01b0316336001600160a01b0316145b6120545760405162461bcd60e51b815260040161091590613a7f565b600a805460ff19166001908117909155546040805163507257cd60e11b815290516001600160a01b039092169163a0e4af9a9160048082019260009290919082900301818387803b1580156120a857600080fd5b505af11580156120bc573d6000803e3d6000fd5b50506040517f97e963041e952738788b9d4871d854d282065b8f90a464928d6528f2e9a4fd0b925060009150a1565b8015806121735750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e90612121903090869060040161384f565b60206040518083038186803b15801561213957600080fd5b505afa15801561214d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217191906137c6565b155b61218f5760405162461bcd60e51b815260040161091590613b12565b6121e58363095ea7b360e01b84846040516024016121ae92919061388d565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613104565b505050565b60606121f98484600085613193565b949350505050565b60015460408051635aa6e67560e01b815290516000926001600160a01b031691635aa6e675916004808301926020929190829003018186803b15801561224657600080fd5b505afa15801561225a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc9919061354e565b6040805160038082526080820190925260609182919060208201838036833701905050905073d533a949740bb3306d119cc777fa900ba034cd52816000815181106122c557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073e0ad1806fd3e7edf6ff52fdb822432e8474110338160018151811061230757fe5b60200260200101906001600160a01b031690816001600160a01b031681525050738290333cef9e6d528dd5618fb97a76f268f3edd48160028151811061234957fe5b6001600160a01b0390921660209283029190910190910152905090565b6121e58363a9059cbb60e01b84846040516024016121ae92919061388d565b6005546040516370a0823160e01b8152600091829182916001600160a01b0316906370a08231906123ba90309060040161383b565b60206040518083038186803b1580156123d257600080fd5b505afa1580156123e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061240a91906137c6565b905083811015612445576124266124218583612571565b613257565b925061243283826130a5565b925061243e8484612571565b9150612449565b8392505b50915091565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a082319061248090309060040161383b565b60206040518083038186803b15801561249857600080fd5b505afa1580156124ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124d091906137c6565b90508015610a7857600a546005546124fb916001600160a01b03918216916101009091041683612366565b600a54600d54600554604051631f2c13e160e31b81526001600160a01b0361010090940484169363f9609f089361253b939082169291169060040161384f565b600060405180830381600087803b15801561255557600080fd5b505af1158015612569573d6000803e3d6000fd5b505050505050565b60006125b383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506132fa565b90505b92915050565b6005546040516370a0823160e01b81526000918291829182916001600160a01b03909116906370a08231906125f590309060040161383b565b60206040518083038186803b15801561260d57600080fd5b505afa158015612621573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264591906137c6565b600a54600d5460405163072e008f60e11b81529293506001600160a01b03610100909204821692630e5c011e9261268092169060040161383b565b600060405180830381600087803b15801561269a57600080fd5b505af11580156126ae573d6000803e3d6000fd5b50506040516370a0823160e01b81526000925073d533a949740bb3306d119cc777fa900ba034cd5291506370a08231906126ec90309060040161383b565b60206040518083038186803b15801561270457600080fd5b505afa158015612718573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061273c91906137c6565b905080156128775761274d81613326565b600b5490915061277d9073d533a949740bb3306d119cc777fa900ba034cd52906001600160a01b031660006120eb565b600b546127a99073d533a949740bb3306d119cc777fa900ba034cd52906001600160a01b0316836120eb565b73d533a949740bb3306d119cc777fa900ba034cd52600f6000815481106127cc57fe5b6000918252602082200180546001600160a01b0319166001600160a01b03938416179055600b546040516338ed173960e01b81529216916338ed17399161281f91859190600f9030904290600401613b71565b600060405180830381600087803b15801561283957600080fd5b505af115801561284d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612875919081019061356a565b505b600a54600d5460405163f1e42ccd60e01b81526001600160a01b0361010090930483169263f1e42ccd926128c69291169073e0ad1806fd3e7edf6ff52fdb822432e8474110339060040161384f565b600060405180830381600087803b1580156128e057600080fd5b505af11580156128f4573d6000803e3d6000fd5b50506040516370a0823160e01b81526000925073e0ad1806fd3e7edf6ff52fdb822432e84741103391506370a082319061293290309060040161383b565b60206040518083038186803b15801561294a57600080fd5b505afa15801561295e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061298291906137c6565b90508015612ad3576129be73e0ad1806fd3e7edf6ff52fdb822432e847411033737a250d5630b4cf539739df2c5dacb4c659f2488d60006120eb565b6129f173e0ad1806fd3e7edf6ff52fdb822432e847411033737a250d5630b4cf539739df2c5dacb4c659f2488d836120eb565b73e0ad1806fd3e7edf6ff52fdb822432e847411033600f600081548110612a1457fe5b6000918252602082200180546001600160a01b0319166001600160a01b0393909316929092179091556040516338ed173960e01b8152737a250d5630b4cf539739df2c5dacb4c659f2488d916338ed173991612a7b918591600f9030904290600401613b71565b600060405180830381600087803b158015612a9557600080fd5b505af1158015612aa9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612ad1919081019061356a565b505b600a54600d5460405163f1e42ccd60e01b81526001600160a01b0361010090930483169263f1e42ccd92612b2292911690738290333cef9e6d528dd5618fb97a76f268f3edd49060040161384f565b600060405180830381600087803b158015612b3c57600080fd5b505af1158015612b50573d6000803e3d6000fd5b50506040516370a0823160e01b815260009250738290333cef9e6d528dd5618fb97a76f268f3edd491506370a0823190612b8e90309060040161383b565b60206040518083038186803b158015612ba657600080fd5b505afa158015612bba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bde91906137c6565b90508015612d2f57612c1a738290333cef9e6d528dd5618fb97a76f268f3edd4737a250d5630b4cf539739df2c5dacb4c659f2488d60006120eb565b612c4d738290333cef9e6d528dd5618fb97a76f268f3edd4737a250d5630b4cf539739df2c5dacb4c659f2488d836120eb565b738290333cef9e6d528dd5618fb97a76f268f3edd4600f600081548110612c7057fe5b6000918252602082200180546001600160a01b0319166001600160a01b0393909316929092179091556040516338ed173960e01b8152737a250d5630b4cf539739df2c5dacb4c659f2488d916338ed173991612cd7918591600f9030904290600401613b71565b600060405180830381600087803b158015612cf157600080fd5b505af1158015612d05573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612d2d919081019061356a565b505b6040516370a0823160e01b815260009073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2906370a0823190612d6990309060040161383b565b60206040518083038186803b158015612d8157600080fd5b505afa158015612d95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612db991906137c6565b90508015612ea657604051632e1a7d4d60e01b815273c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290632e1a7d4d90612df8908490600401613b68565b600060405180830381600087803b158015612e1257600080fd5b505af1158015612e26573d6000803e3d6000fd5b5050600c54604080518082018252478082526000602083018190529251630b4c7e4d60e01b81529096506001600160a01b039093169450630b4c7e4d93508592612e7392906004016138a6565b6000604051808303818588803b158015612e8c57600080fd5b505af1158015612ea0573d6000803e3d6000fd5b50505050505b6005546040516370a0823160e01b8152612f329187916001600160a01b03909116906370a0823190612edc90309060040161383b565b60206040518083038186803b158015612ef457600080fd5b505afa158015612f08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f2c91906137c6565b90612571565b97506000612f3e611f43565b6001546040516339ebf82360e01b81529192506000916001600160a01b03909116906339ebf82390612f7490309060040161383b565b6101206040518083038186803b158015612f8d57600080fd5b505afa158015612fa1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fc59190613730565b60c00151905080821015612fdd578181039850600099505b8a1561300557612fec8b613257565b506130028b612ffd8c612f2c6118be565b613390565b97505b505050505050509193909250565b600a54600d546005546040516301395c5960e31b81526001600160a01b036101009094048416936309cae2c893613053939082169291169060040161384f565b602060405180830381600087803b15801561306d57600080fd5b505af1158015613081573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7891906137c6565b6000828201838110156125b35760405162461bcd60e51b81526004016109159061398f565b6000826130d9575060006125b6565b828202828482816130e657fe5b04146125b35760405162461bcd60e51b8152600401610915906139c6565b6060613159826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166121ea9092919063ffffffff16565b8051909150156121e55780806020019051810190613177919061361b565b6121e55760405162461bcd60e51b815260040161091590613aa4565b606061319e856133a6565b6131ba5760405162461bcd60e51b815260040161091590613a48565b60006060866001600160a01b031685876040516131d791906137de565b60006040518083038185875af1925050503d8060008114613214576040519150601f19603f3d011682016040523d82523d6000602084013e613219565b606091505b5091509150811561322d5791506121f99050565b80511561323d5780518082602001fd5b8360405162461bcd60e51b81526004016109159190613918565b600061326582612ffd610c3c565b600a54600d54600554604051636ce5768960e11b81529395506001600160a01b0361010090930483169363d9caed12936132a89381169216908790600401613869565b602060405180830381600087803b1580156132c257600080fd5b505af11580156132d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b691906137c6565b6000818484111561331e5760405162461bcd60e51b81526004016109159190613918565b505050900390565b60008061334a612710613344600e54866130ca90919063ffffffff16565b906133df565b905061337f73d533a949740bb3306d119cc777fa900ba034cd5273f147b8125d2ef93fb6965db97d6746952a13393483612366565b6133898382612571565b9392505050565b600081831061339f57816125b3565b5090919050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906121f9575050151592915050565b60006125b383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506000818361343d5760405162461bcd60e51b81526004016109159190613918565b50600083858161344957fe5b0495945050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106134945782800160ff198235161785556134c1565b828001600101855582156134c1579182015b828111156134c15782358255916020019190600101906134a6565b506134cd92915061351d565b5090565b6040518061012001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5b808211156134cd576000815560010161351e565b600060208284031215613543578081fd5b81356125b381613c8c565b60006020828403121561355f578081fd5b81516125b381613c8c565b6000602080838503121561357c578182fd5b825167ffffffffffffffff811115613592578283fd5b8301601f810185136135a2578283fd5b80516135b56135b082613c3c565b613c15565b81815283810190838501858402850186018910156135d1578687fd5b8694505b838510156135f35780518352600194909401939185019185016135d5565b50979650505050505050565b600060208284031215613610578081fd5b81356125b381613ca1565b60006020828403121561362c578081fd5b81516125b381613ca1565b60008060208385031215613649578081fd5b823567ffffffffffffffff80821115613660578283fd5b818501915085601f830112613673578283fd5b813581811115613681578384fd5b866020828501011115613692578384fd5b60209290920196919550909350505050565b6000602082840312156136b5578081fd5b815167ffffffffffffffff808211156136cc578283fd5b818401915084601f8301126136df578283fd5b8151818111156136ed578384fd5b613700601f8201601f1916602001613c15565b9150808252856020828501011115613716578384fd5b613727816020840160208601613c5c565b50949350505050565b6000610120808385031215613743578182fd5b61374c81613c15565b9050825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152508091505092915050565b6000602082840312156137bf578081fd5b5035919050565b6000602082840312156137d7578081fd5b5051919050565b600082516137f0818460208701613c5c565b9190910192915050565b600064437572766560d81b8252825161381a816005850160208701613c5c565b69566f74657250726f787960b01b6005939091019283015250600f01919050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b60608101818460005b60028110156138ce5781518352602092830192909101906001016138af565b5050508260408301529392505050565b901515815260200190565b60006020825282602083015282846040840137818301604090810191909152601f909201601f19160101919050565b6000602082528251806020840152613937816040850160208701613c5c565b601f01601f19169190910160400192915050565b6020808252600b908201526a085cdd1c985d1959da5cdd60aa1b604082015260600190565b602080825260059082015264085dd85b9d60da1b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b602080825260069082015265085d985d5b1d60d21b604082015260600190565b6020808252600790820152662173686172657360c81b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252600b908201526a08585d5d1a1bdc9a5e995960aa1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600a9082015269085c1c9bdd1958dd195960b21b604082015260600190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b90815260200190565b600060a082018783526020878185015260a0604085015281875480845260c0860191508885528285209350845b81811015613bc35784546001600160a01b031683526001948501949284019201613b9e565b50506001600160a01b03969096166060850152505050608001529392505050565b9283526020830191909152604082015260600190565b93845260208401929092526040830152606082015260800190565b60405181810167ffffffffffffffff81118282101715613c3457600080fd5b604052919050565b600067ffffffffffffffff821115613c52578081fd5b5060209081020190565b60005b83811015613c77578181015183820152602001613c5f565b83811115613c86576000848401525b50505050565b6001600160a01b03811681146115ad57600080fd5b80151581146115ad57600080fdfea2646970667358221220d04de687f5702ae56c61bb96e2f4589ebce0bcd736a52d191b78c82435c83de864736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000132d8d2c76db3812403431facb00f3453fc42125
-----Decoded View---------------
Arg [0] : _vault (address): 0x132d8D2C76Db3812403431fAcB00F3453Fc42125
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000132d8d2c76db3812403431facb00f3453fc42125
Deployed Bytecode Sourcemap
58359:3265:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54036:444;;;;;;;;;;-1:-1:-1;54036:444:0;;;;;:::i;:::-;;:::i;:::-;;28037:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56295:176;;;;;;;;;;;;;:::i;37182:175::-;;;;;;;;;;-1:-1:-1;37182:175:0;;;;;:::i;:::-;;:::i;56597:116::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;31050:28::-;;;;;;;;;;;;;:::i;29798:18::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;29707:25::-;;;;;;;;;;;;;:::i;39855:148::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;28347:91::-;;;;;;;;;;;;;:::i;55298:85::-;;;;;;;;;;;;;:::i;30686:29::-;;;;;;;;;;;;;:::i;50616:515::-;;;;;;;;;;-1:-1:-1;50616:515:0;;;;;:::i;:::-;;:::i;55029:82::-;;;;;;;;;;;;;:::i;35231:154::-;;;;;;;;;;-1:-1:-1;35231:154:0;;;;;:::i;:::-;;:::i;55207:82::-;;;;;;;;;;;;;:::i;54940:::-;;;;;;;;;;;;;:::i;55118:::-;;;;;;;;;;;;;:::i;44608:170::-;;;;;;;;;;;;;:::i;49001:1371::-;;;;;;;;;;;;;:::i;54672:83::-;;;;;;;;;;;;;:::i;31129:25::-;;;;;;;;;;;;;:::i;58503:81::-;;;;;;;;;;;;;:::i;43993:286::-;;;;;;;;;;-1:-1:-1;43993:286:0;;;;;:::i;:::-;;:::i;55565:18::-;;;;;;;;;;;;;:::i;54764:81::-;;;;;;;;;;;;;:::i;56150:137::-;;;;;;;;;;-1:-1:-1;56150:137:0;;;;;:::i;:::-;;:::i;55590:20::-;;;;;;;;;;;;;:::i;33988:174::-;;;;;;;;;;-1:-1:-1;33988:174:0;;;;;:::i;:::-;;:::i;37660:171::-;;;;;;;;;;-1:-1:-1;37660:171:0;;;;;:::i;:::-;;:::i;55644:22::-;;;;;;;;;;;;;:::i;30872:27::-;;;;;;;;;;;;;:::i;29577:94::-;;;;;;;;;;;;;:::i;36456:169::-;;;;;;;;;;-1:-1:-1;36456:169:0;;;;;:::i;:::-;;:::i;55486:43::-;;;;;;;;;;;;;:::i;56043:99::-;;;;;;;;;;-1:-1:-1;56043:99:0;;;;;:::i;:::-;;:::i;30535:29::-;;;;;;;;;;;;;:::i;55944:91::-;;;;;;;;;;-1:-1:-1;55944:91:0;;;;;:::i;:::-;;:::i;55390:87::-;;;;;;;;;;;;;:::i;29739:22::-;;;;;;;;;;;;;:::i;55617:20::-;;;;;;;;;;;;;:::i;29768:21::-;;;;;;;;;;;;;:::i;58680:::-;;;;;;;;;;-1:-1:-1;58680:21:0;;;;;:::i;:::-;;:::i;56479:110::-;;;;;;;;;;;;;:::i;33232:202::-;;;;;;;;;;-1:-1:-1;33232:202:0;;;;;:::i;:::-;;:::i;51722:311::-;;;;;;;;;;-1:-1:-1;51722:311:0;;;;;:::i;:::-;;:::i;58591:82::-;;;;;;;;;;;;;:::i;34451:263::-;;;;;;;;;;-1:-1:-1;34451:263:0;;;;;:::i;:::-;;:::i;55538:20::-;;;;;;;;;;;;;:::i;46518:1677::-;;;;;;;;;;-1:-1:-1;46518:1677:0;;;;;:::i;:::-;;:::i;56721:133::-;;;;;;;;;;;;;:::i;35902:154::-;;;;;;;;;;-1:-1:-1;35902:154:0;;;;;:::i;:::-;;:::i;54852:81::-;;;;;;;;;;;;;:::i;29679:21::-;;;;;;;;;;;;;:::i;52462:164::-;;;;;;;;;;;;;:::i;54036:444::-;31496:12;:10;:12::i;:::-;-1:-1:-1;;;;;31482:26:0;:10;-1:-1:-1;;;;;31482:26:0;;31474:50;;;;-1:-1:-1;;;31474:50:0;;;;;;;:::i;:::-;;;;;;;;;54128:4:::1;::::0;-1:-1:-1;;;;;54110:23:0;;::::1;54128:4:::0;::::1;54110:23;;54102:41;;;;-1:-1:-1::0;;;54102:41:0::1;;;;;;;:::i;:::-;54180:5;::::0;-1:-1:-1;;;;;54162:24:0;;::::1;54180:5:::0;::::1;54162:24;;54154:44;;;;-1:-1:-1::0;;;54154:44:0::1;;;;;;;:::i;:::-;54211:33;54247:17;:15;:17::i;:::-;54211:53;;54280:9;54275:102;54295:16;:23;54291:1;:27;54275:102;;;54343:16;54360:1;54343:19;;;;;;;;;;;;;;-1:-1:-1::0;;;;;54333:29:0::1;:6;-1:-1:-1::0;;;;;54333:29:0::1;;;54325:52;;;;-1:-1:-1::0;;;54325:52:0::1;;;;;;;:::i;:::-;54320:3;;54275:102;;;;54390:82;54418:12;:10;:12::i;:::-;54432:39;::::0;-1:-1:-1;;;54432:39:0;;-1:-1:-1;;;;;54432:24:0;::::1;::::0;::::1;::::0;:39:::1;::::0;54465:4:::1;::::0;54432:39:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;54390:27:0;::::1;::::0;:82;:27:::1;:82::i;:::-;31535:1;54036:444:::0;:::o;28037:25::-;;;;;;;;;;;;;;;-1:-1:-1;;28037:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;56295:176::-;56432:4;;56409:38;;;-1:-1:-1;;;56409:38:0;;;;56343:13;;-1:-1:-1;;;;;56432:4:0;;56409:36;;:38;;;;;56432:4;;56409:38;;;;;;;56432:4;56409:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;56409:38:0;;;;;;;;;;;;:::i;:::-;56383:79;;;;;;;;:::i;:::-;;;;;;;;;;;;;56369:94;;56295:176;:::o;37182:175::-;31240:10;;-1:-1:-1;;;;;31240:10:0;31226;:24;;:54;;;31268:12;:10;:12::i;:::-;-1:-1:-1;;;;;31254:26:0;:10;-1:-1:-1;;;;;31254:26:0;;31226:54;31218:78;;;;-1:-1:-1;;;31218:78:0;;;;;;;:::i;:::-;37267:13:::1;:30:::0;;;37313:36:::1;::::0;::::1;::::0;::::1;::::0;37283:14;;37313:36:::1;:::i;:::-;;;;;;;;37182:175:::0;:::o;56597:116::-;56682:5;;56699;;56670:35;;-1:-1:-1;;;56670:35:0;;56643:7;;56682:5;;;-1:-1:-1;;;;;56682:5:0;;;;56670:28;;:35;;56699:5;;;;56670:35;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56663:42;;56597:116;:::o;31050:28::-;;;;:::o;29798:18::-;;;-1:-1:-1;;;;;29798:18:0;;:::o;29707:25::-;;;-1:-1:-1;;;;;29707:25:0;;:::o;39855:148::-;39920:5;;:31;;-1:-1:-1;;;39920:31:0;;39896:4;;;;-1:-1:-1;;;;;39920:5:0;;;;:16;;:31;;39945:4;;39920:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;:45;:75;;;;39994:1;39969:22;:20;:22::i;:::-;:26;39913:82;;39855:148;:::o;28347:91::-;28416:14;;;;;;;;;;;;-1:-1:-1;;;28416:14:0;;;;28347:91;:::o;55298:85::-;55340:42;55298:85;:::o;30686:29::-;;;;:::o;50616:515::-;50731:5;;50675:13;;-1:-1:-1;;;;;50731:5:0;50709:10;:28;50701:47;;;;-1:-1:-1;;;50701:47:0;;;;;;;:::i;:::-;50834:19;50887:32;50905:13;50887:17;:32::i;:::-;51011:4;;50864:55;;-1:-1:-1;50864:55:0;;-1:-1:-1;51011:42:0;;-1:-1:-1;;;;;51011:4:0;51029:10;50864:55;51011:17;:42::i;:::-;50616:515;;;;:::o;55029:82::-;55068:42;55029:82;:::o;35231:154::-;31240:10;;-1:-1:-1;;;;;31240:10:0;31226;:24;;:54;;;31268:12;:10;:12::i;:::-;-1:-1:-1;;;;;31254:26:0;:10;-1:-1:-1;;;;;31254:26:0;;31226:54;31218:78;;;;-1:-1:-1;;;31218:78:0;;;;;;;:::i;:::-;35309:14:::1;:23:::0;;;35348:29:::1;::::0;::::1;::::0;::::1;::::0;35326:6;;35348:29:::1;:::i;55207:82::-:0;55246:42;55207:82;:::o;54940:::-;54979:42;54940:82;:::o;55118:::-;55157:42;55118:82;:::o;44608:170::-;31622:6;;-1:-1:-1;;;;;31622:6:0;31608:10;:20;;:65;;-1:-1:-1;31663:10:0;;-1:-1:-1;;;;;31663:10:0;31649;:24;31608:65;:112;;;;31708:12;:10;:12::i;:::-;-1:-1:-1;;;;;31694:26:0;:10;-1:-1:-1;;;;;31694:26:0;;31608:112;:163;;;;31755:5;;;;;;;;;-1:-1:-1;;;;;31755:5:0;-1:-1:-1;;;;;31755:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;31741:30:0;:10;-1:-1:-1;;;;;31741:30:0;;31608:163;:216;;;;31806:5;;;;;;;;;-1:-1:-1;;;;;31806:5:0;-1:-1:-1;;;;;31806:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;31792:32:0;:10;-1:-1:-1;;;;;31792:32:0;;31608:216;31586:277;;;;-1:-1:-1;;;31586:277:0;;;;;;;:::i;:::-;44746:5:::1;::::0;:23:::1;::::0;;-1:-1:-1;;;44746:23:0;;;;44731:39:::1;::::0;-1:-1:-1;;;;;44746:5:0::1;::::0;:21:::1;::::0;:23:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:5;:23;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44731:14;:39::i;:::-;44608:170::o:0;49001:1371::-;31622:6;;-1:-1:-1;;;;;31622:6:0;31608:10;:20;;:65;;-1:-1:-1;31663:10:0;;-1:-1:-1;;;;;31663:10:0;31649;:24;31608:65;:112;;;;31708:12;:10;:12::i;:::-;-1:-1:-1;;;;;31694:26:0;:10;-1:-1:-1;;;;;31694:26:0;;31608:112;:163;;;;31755:5;;;;;;;;;-1:-1:-1;;;;;31755:5:0;-1:-1:-1;;;;;31755:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;31741:30:0;:10;-1:-1:-1;;;;;31741:30:0;;31608:163;:216;;;;31806:5;;;;;;;;;-1:-1:-1;;;;;31806:5:0;-1:-1:-1;;;;;31806:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;31792:32:0;:10;-1:-1:-1;;;;;31792:32:0;;31608:216;31586:277;;;;-1:-1:-1;;;31586:277:0;;;;;;;:::i;:::-;49052:14:::1;49081:12:::0;49108:23:::1;49134:5;;;;;;;;;-1:-1:-1::0;;;;;49134:5:0::1;-1:-1:-1::0;;;;;49134:21:0::1;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49206:13;::::0;49108:49;;-1:-1:-1;49168:19:0::1;::::0;49206:13:::1;;49202:731;;;49288:19;49310:22;:20;:22::i;:::-;49288:44;;49466:80;49498:15;49484:11;:29;:61;;49530:15;49484:61;;;49516:11;49484:61;49466:17;:80::i;:::-;49444:102:::0;-1:-1:-1;49444:102:0;-1:-1:-1;49624:29:0;;::::1;49620:159;;;49683:32;:11:::0;49699:15;49683::::1;:32::i;:::-;49674:41;;49748:15;49734:29;;49620:159;49202:731;;;;49891:30;49905:15;49891:13;:30::i;:::-;49861:60:::0;;-1:-1:-1;49861:60:0;-1:-1:-1;49861:60:0;-1:-1:-1;49202:731:0::1;50147:5;::::0;:39:::1;::::0;-1:-1:-1;;;50147:39:0;;-1:-1:-1;;;;;50147:5:0;;::::1;::::0;:12:::1;::::0;:39:::1;::::0;50160:6;;50168:4;;50174:11;;50147:39:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50129:57;;50262:31;50277:15;50262:14;:31::i;:::-;50311:53;50321:6;50329:4;50335:11;50348:15;50311:53;;;;;;;;;:::i;:::-;;;;;;;;31874:1;;;;49001:1371::o:0;54672:83::-;54712:42;54672:83;:::o;31129:25::-;;;;;;:::o;58503:81::-;58541:42;58503:81;:::o;43993:286::-;44061:4;43993:286;;;;:::o;55565:18::-;;;-1:-1:-1;;;;;55565:18:0;;:::o;54764:81::-;54802:42;54764:81;:::o;56150:137::-;31240:10;;-1:-1:-1;;;;;31240:10:0;31226;:24;;:54;;;31268:12;:10;:12::i;:::-;-1:-1:-1;;;;;31254:26:0;:10;-1:-1:-1;;;;;31254:26:0;;31226:54;31218:78;;;;-1:-1:-1;;;31218:78:0;;;;;;;:::i;:::-;56224:9:::1;56220:59;;;56235:3;:13:::0;;-1:-1:-1;;;;;;56235:13:0::1;55340:42;56235:13;::::0;;56220:59:::1;;;56264:3;:15:::0;;-1:-1:-1;;;;;;56264:15:0::1;55434:42;56264:15;::::0;;56220:59:::1;56150:137:::0;:::o;55590:20::-;;;-1:-1:-1;;;;;55590:20:0;;:::o;33988:174::-;31240:10;;-1:-1:-1;;;;;31240:10:0;31226;:24;;:54;;;31268:12;:10;:12::i;:::-;-1:-1:-1;;;;;31254:26:0;:10;-1:-1:-1;;;;;31254:26:0;;31226:54;31218:78;;;;-1:-1:-1;;;31218:78:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;34067:21:0;::::1;34059:30;;;::::0;::::1;;34100:6;:16:::0;;-1:-1:-1;;;;;;34100:16:0::1;-1:-1:-1::0;;;;;34100:16:0;::::1;;::::0;;34132:22:::1;::::0;::::1;::::0;::::1;::::0;34100:16;;34132:22:::1;:::i;37660:171::-:0;31240:10;;-1:-1:-1;;;;;31240:10:0;31226;:24;;:54;;;31268:12;:10;:12::i;:::-;-1:-1:-1;;;;;31254:26:0;:10;-1:-1:-1;;;;;31254:26:0;;31226:54;31218:78;;;;-1:-1:-1;;;31218:78:0;;;;;;;:::i;:::-;37749:26:::1;:11;37763:12:::0;;37749:26:::1;:::i;:::-;;37791:32;37810:12;;37791:32;;;;;;;:::i;:::-;;;;;;;;37660:171:::0;;:::o;55644:22::-;;;;:::o;30872:27::-;;;;:::o;29577:94::-;29635:7;29577:94;:::o;36456:169::-;31240:10;;-1:-1:-1;;;;;31240:10:0;31226;:24;;:54;;;31268:12;:10;:12::i;:::-;-1:-1:-1;;;;;31254:26:0;:10;-1:-1:-1;;;;;31254:26:0;;31226:54;31218:78;;;;-1:-1:-1;;;31218:78:0;;;;;;;:::i;:::-;36539:12:::1;:28:::0;;;36583:34:::1;::::0;::::1;::::0;::::1;::::0;36554:13;;36583:34:::1;:::i;55486:43::-:0;55524:5;55486:43;:::o;56043:99::-;31240:10;;-1:-1:-1;;;;;31240:10:0;31226;:24;;:54;;;31268:12;:10;:12::i;:::-;-1:-1:-1;;;;;31254:26:0;:10;-1:-1:-1;;;;;31254:26:0;;31226:54;31218:78;;;;-1:-1:-1;;;31218:78:0;;;;;;;:::i;:::-;56116:7:::1;:18:::0;56043:99::o;30535:29::-;;;;:::o;55944:91::-;31496:12;:10;:12::i;:::-;-1:-1:-1;;;;;31482:26:0;:10;-1:-1:-1;;;;;31482:26:0;;31474:50;;;;-1:-1:-1;;;31474:50:0;;;;;;;:::i;:::-;56013:5:::1;:14:::0;;-1:-1:-1;;;;;56013:14:0;;::::1;;;-1:-1:-1::0;;;;;;56013:14:0;;::::1;::::0;;;::::1;::::0;;55944:91::o;55390:87::-;55434:42;55390:87;:::o;29739:22::-;;;-1:-1:-1;;;;;29739:22:0;;:::o;55617:20::-;;;-1:-1:-1;;;;;55617:20:0;;:::o;29768:21::-;;;-1:-1:-1;;;;;29768:21:0;;:::o;58680:::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;58680:21:0;;-1:-1:-1;58680:21:0;:::o;56479:110::-;56552:4;;:29;;-1:-1:-1;;;56552:29:0;;56525:7;;-1:-1:-1;;;;;56552:4:0;;:14;;:29;;56575:4;;56552:29;;;:::i;33232:202::-;31240:10;;-1:-1:-1;;;;;31240:10:0;31226;:24;;:54;;;31268:12;:10;:12::i;:::-;-1:-1:-1;;;;;31254:26:0;:10;-1:-1:-1;;;;;31254:26:0;;31226:54;31218:78;;;;-1:-1:-1;;;31218:78:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;33319:25:0;::::1;33311:34;;;::::0;::::1;;33356:10;:24:::0;;-1:-1:-1;;;;;;33356:24:0::1;-1:-1:-1::0;;;;;33356:24:0;::::1;;::::0;;33396:30:::1;::::0;::::1;::::0;::::1;::::0;33356:24;;33396:30:::1;:::i;51722:311::-:0;51811:5;;-1:-1:-1;;;;;51811:5:0;51789:10;:28;;:58;;;51835:12;:10;:12::i;:::-;-1:-1:-1;;;;;51821:26:0;:10;-1:-1:-1;;;;;51821:26:0;;51789:58;51781:67;;;;;;51905:5;;51867:34;;;-1:-1:-1;;;51867:34:0;;;;-1:-1:-1;;;;;51905:5:0;;;;51867:32;;;;;:34;;;;;;;;;;;;;;:32;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;51867:43:0;;51859:52;;;;;;51922:30;51939:12;51922:16;:30::i;:::-;51995:4;;:29;;-1:-1:-1;;;51995:29:0;;51963:62;;51981:12;;-1:-1:-1;;;;;51995:4:0;;;;:14;;:29;;52018:4;;51995:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51963:4;;-1:-1:-1;;;;;51963:4:0;;:62;:17;:62::i;58591:82::-;58630:42;58591:82;:::o;34451:263::-;31383:10;;-1:-1:-1;;;;;31383:10:0;31369;:24;31361:48;;;;-1:-1:-1;;;31361:48:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;34532:22:0;::::1;34524:31;;;::::0;::::1;;34566:5;::::0;34580:7:::1;::::0;34566:25:::1;::::0;-1:-1:-1;;;34566:25:0;;-1:-1:-1;;;;;34566:5:0;;::::1;::::0;:13:::1;::::0;:25:::1;::::0;34580:7;::::1;::::0;34566:5:::1;::::0;:25:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;34602:7:0::1;:18:::0;;-1:-1:-1;;;;;;34602:18:0::1;-1:-1:-1::0;;;;;34602:18:0;;::::1;::::0;;;::::1;::::0;;;;-1:-1:-1;34631:5:0;:35:::1;::::0;-1:-1:-1;;;34631:35:0;;:5;;::::1;::::0;:13:::1;::::0;:35:::1;::::0;34645:7;::::1;::::0;-1:-1:-1;;34662:2:0;34631:35:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;34682:24;34697:8;34682:24;;;;;;:::i;55538:20::-:0;;;;;;-1:-1:-1;;;;;55538:20:0;;:::o;46518:1677::-;46589:4;46606:28;;:::i;:::-;46637:5;;:31;;-1:-1:-1;;;46637:31:0;;-1:-1:-1;;;;;46637:5:0;;;;:16;;:31;;46662:4;;46637:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46606:62;;46745:6;:17;;;46766:1;46745:22;46741:40;;;46776:5;46769:12;;;;;46741:40;46926:14;;46905:17;;;;46885:38;;:15;;:19;:38::i;:::-;:55;46881:73;;;46949:5;46942:12;;;;;46881:73;47073:14;;47051:17;;;;47031:38;;:15;;:19;:38::i;:::-;:56;47027:73;;47096:4;47089:11;;;;;47027:73;47530:5;;:23;;;-1:-1:-1;;;47530:23:0;;;;47508:19;;-1:-1:-1;;;;;47530:5:0;;:21;;:23;;;;;;;;;;;;;;:5;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47508:45;;47582:13;;47568:11;:27;47564:44;;;47604:4;47597:11;;;;;;47564:44;47662:13;47678:22;:20;:22::i;:::-;47662:38;;47790:6;:16;;;47763:24;47773:13;;47763:5;:9;;:24;;;;:::i;:::-;:43;47759:60;;;47815:4;47808:11;;;;;;;47759:60;47832:14;47873:6;:16;;;47865:5;:24;47861:66;;;47910:16;;;;47900:27;;:5;;:9;:27::i;:::-;47891:36;;47861:66;48097:5;;:23;;;-1:-1:-1;;;48097:23:0;;;;48080:14;;-1:-1:-1;;;;;48097:5:0;;:21;;:23;;;;;;;;;;;;;;:5;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48080:40;-1:-1:-1;48168:18:0;48080:40;48179:6;48168:10;:18::i;:::-;48139:12;;:26;;48156:8;48139:16;:26::i;:::-;:47;;46518:1677;-1:-1:-1;;;;;;;46518:1677:0:o;56721:133::-;56783:7;56810:36;56830:15;:13;:15::i;:::-;56810;:13;:15::i;:::-;:19;;:36::i;35902:154::-;31240:10;;-1:-1:-1;;;;;31240:10:0;31226;:24;;:54;;;31268:12;:10;:12::i;:::-;-1:-1:-1;;;;;31254:26:0;:10;-1:-1:-1;;;;;31254:26:0;;31226:54;31218:78;;;;-1:-1:-1;;;31218:78:0;;;;;;;:::i;:::-;35980:14:::1;:23:::0;;;36019:29:::1;::::0;::::1;::::0;::::1;::::0;35997:6;;36019:29:::1;:::i;54852:81::-:0;54890:42;54852:81;:::o;29679:21::-;;;-1:-1:-1;;;;;29679:21:0;;:::o;52462:164::-;31240:10;;-1:-1:-1;;;;;31240:10:0;31226;:24;;:54;;;31268:12;:10;:12::i;:::-;-1:-1:-1;;;;;31254:26:0;:10;-1:-1:-1;;;;;31254:26:0;;31226:54;31218:78;;;;-1:-1:-1;;;31218:78:0;;;;;;;:::i;:::-;52525:13:::1;:20:::0;;-1:-1:-1;;52525:20:0::1;52541:4;52525:20:::0;;::::1;::::0;;;52556:5;:22:::1;::::0;;-1:-1:-1;;;52556:22:0;;;;-1:-1:-1;;;;;52556:5:0;;::::1;::::0;:20:::1;::::0;:22:::1;::::0;;::::1;::::0;52525:13:::1;::::0;52556:22;;;;;;;;52525:13;52556:5;:22;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;52596:22:0::1;::::0;::::1;::::0;-1:-1:-1;52596:22:0;;-1:-1:-1;52596:22:0::1;52462:164::o:0;20274:622::-;20644:10;;;20643:62;;-1:-1:-1;20660:39:0;;-1:-1:-1;;;20660:39:0;;-1:-1:-1;;;;;20660:15:0;;;;;:39;;20684:4;;20691:7;;20660:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;20643:62;20635:152;;;;-1:-1:-1;;;20635:152:0;;;;;;;:::i;:::-;20798:90;20818:5;20848:22;;;20872:7;20881:5;20825:62;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;20825:62:0;;;;;;;;;;;;;;-1:-1:-1;;;;;20825:62:0;-1:-1:-1;;;;;;20825:62:0;;;;;;;;;;20798:19;:90::i;:::-;20274:622;;;:::o;7871:196::-;7974:12;8006:53;8029:6;8037:4;8043:1;8046:12;8006:22;:53::i;:::-;7999:60;7871:196;-1:-1:-1;;;;7871:196:0:o;37985:98::-;38057:5;;:18;;;-1:-1:-1;;;38057:18:0;;;;38030:7;;-1:-1:-1;;;;;38057:5:0;;:16;;:18;;;;;;;;;;;;;;:5;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;61324:297::-;61482:16;;;61496:1;61482:16;;;;;;;;;61419;;;;61482;;;;61419;;61482;;;;;-1:-1:-1;61482:16:0;61453:45;;54802:42;61509:9;61519:1;61509:12;;;;;;;;;;;;;:18;-1:-1:-1;;;;;61509:18:0;;;-1:-1:-1;;;;;61509:18:0;;;;;58541:42;61538:9;61548:1;61538:12;;;;;;;;;;;;;:18;-1:-1:-1;;;;;61538:18:0;;;-1:-1:-1;;;;;61538:18:0;;;;;58630:42;61567:9;61577:1;61567:12;;;;;;;;-1:-1:-1;;;;;61567:19:0;;;:12;;;;;;;;;;;:19;61604:9;-1:-1:-1;61324:297:0;:::o;19615:177::-;19698:86;19718:5;19748:23;;;19773:2;19777:5;19725:58;;;;;;;;;:::i;57362:595::-;57543:4;;:29;;-1:-1:-1;;;57543:29:0;;57466:25;;;;;;-1:-1:-1;;;;;57543:4:0;;:14;;:29;;57566:4;;57543:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57524:48;;57598:13;57587:8;:24;57583:367;;;57648:42;57662:27;:13;57680:8;57662:17;:27::i;:::-;57648:13;:42::i;:::-;57628:62;-1:-1:-1;57725:31:0;57628:62;57747:8;57725:21;:31::i;:::-;57705:51;-1:-1:-1;57779:36:0;:13;57705:51;57779:17;:36::i;:::-;57771:44;;57583:367;;;57925:13;57905:33;;57583:367;57362:595;;;;:::o;56862:278::-;56957:4;;:29;;-1:-1:-1;;;56957:29:0;;56941:13;;-1:-1:-1;;;;;56957:4:0;;:14;;:29;;56980:4;;56957:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56941:45;-1:-1:-1;57001:9:0;;56997:136;;57045:5;;57027:4;;:31;;-1:-1:-1;;;;;57027:4:0;;;;57045:5;;;;;57052;57027:17;:31::i;:::-;57085:5;;57100;;57115:4;;57073:48;;-1:-1:-1;;;57073:48:0;;-1:-1:-1;;;;;57085:5:0;;;;;;;57073:26;;:48;;57100:5;;;;57115:4;;;57073:48;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56862:278;;:::o;14375:136::-;14433:7;14460:43;14464:1;14467;14460:43;;;;;;;;;;;;;;;;;:3;:43::i;:::-;14453:50;;14375:136;;;;;:::o;59074:2165::-;59311:4;;:29;;-1:-1:-1;;;59311:29:0;;59191:15;;;;;;;;-1:-1:-1;;;;;59311:4:0;;;;:14;;:29;;59334:4;;59311:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59363:5;;59378;;59351:33;;-1:-1:-1;;;59351:33:0;;59297:43;;-1:-1:-1;;;;;;59363:5:0;;;;;;;59351:26;;:33;;59378:5;;59351:33;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;59410:36:0;;-1:-1:-1;;;59410:36:0;;59395:12;;-1:-1:-1;54802:42:0;;-1:-1:-1;59410:21:0;;:36;;59440:4;;59410:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59395:51;-1:-1:-1;59461:8:0;;59457:283;;59493:16;59504:4;59493:10;:16::i;:::-;59550:3;;59486:23;;-1:-1:-1;59526:31:0;;54802:42;;-1:-1:-1;;;;;59550:3:0;;59526:23;:31::i;:::-;59596:3;;59572:34;;54802:42;;-1:-1:-1;;;;;59596:3:0;59601:4;59572:23;:34::i;:::-;54802:42;59623:4;59628:1;59623:7;;;;;;;;;;;;;;;;:13;;-1:-1:-1;;;;;;59623:13:0;-1:-1:-1;;;;;59623:13:0;;;;;;59655:3;;59651:77;;-1:-1:-1;;;59651:77:0;;59655:3;;;59651:33;;:77;;59685:4;;59623:7;59703:4;;59717;;59724:3;;59651:77;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;59651:77:0;;;;;;;;;;;;:::i;:::-;;59457:283;59762:5;;59782;;59750:43;;-1:-1:-1;;;59750:43:0;;-1:-1:-1;;;;;59762:5:0;;;;;;;59750:31;;:43;;59782:5;;;58541:42;;59750:43;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;59819:36:0;;-1:-1:-1;;;59819:36:0;;59804:12;;-1:-1:-1;58541:42:0;;-1:-1:-1;59819:21:0;;:36;;59849:4;;59819:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59804:51;-1:-1:-1;59870:8:0;;59866:255;;59895:35;58541:42;55340;59928:1;59895:23;:35::i;:::-;59945:38;58541:42;55340;59978:4;59945:23;:38::i;:::-;58541:42;60000:4;60005:1;60000:7;;;;;;;;;;;;;;;;:13;;-1:-1:-1;;;;;;60000:13:0;-1:-1:-1;;;;;60000:13:0;;;;;;;;;;;60028:81;;-1:-1:-1;;;60028:81:0;;55340:42;;60028:37;;:81;;60066:4;;60084;;60098;;60105:3;;60028:81;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;60028:81:0;;;;;;;;;;;;:::i;:::-;;59866:255;60143:5;;60163;;60131:44;;-1:-1:-1;;;60131:44:0;;-1:-1:-1;;;;;60143:5:0;;;;;;;60131:31;;:44;;60163:5;;;58630:42;;60131:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;60202:37:0;;-1:-1:-1;;;60202:37:0;;60186:13;;-1:-1:-1;58630:42:0;;-1:-1:-1;60202:22:0;;:37;;60233:4;;60202:37;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60186:53;-1:-1:-1;60254:9:0;;60250:261;;60280:36;58630:42;55340;60314:1;60280:24;:36::i;:::-;60331:40;58630:42;55340;60365:5;60331:24;:40::i;:::-;58630:42;60388:4;60393:1;60388:7;;;;;;;;;;;;;;;;:14;;-1:-1:-1;;;;;;60388:14:0;-1:-1:-1;;;;;60388:14:0;;;;;;;;;;;60417:82;;-1:-1:-1;;;60417:82:0;;55340:42;;60417:37;;:82;;60455:5;;60474:4;;60488;;60495:3;;60417:82;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;60417:82:0;;;;;;;;;;;;:::i;:::-;;60250:261;60537:37;;-1:-1:-1;;;60537:37:0;;60521:13;;55157:42;;60537:22;;:37;;60568:4;;60537:37;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60521:53;-1:-1:-1;60589:9:0;;60585:185;;60615:26;;-1:-1:-1;;;60615:26:0;;55157:42;;60615:19;;:26;;60635:5;;60615:26;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;60709:5:0;;60700:58;;;;;;;;60664:21;60700:58;;;60709:5;60700:58;;;;;;;;-1:-1:-1;;;60700:58:0;;60664:21;;-1:-1:-1;;;;;;60709:5:0;;;;-1:-1:-1;60700:29:0;;-1:-1:-1;60664:21:0;;60700:58;;60709:5;60700:58;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60585:185;60790:4;;:29;;-1:-1:-1;;;60790:29:0;;:41;;60824:6;;-1:-1:-1;;;;;60790:4:0;;;;:14;;:29;;60813:4;;60790:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:33;;:41::i;:::-;60780:51;;60844:11;60858:22;:20;:22::i;:::-;60904:5;;:31;;-1:-1:-1;;;60904:31:0;;60844:36;;-1:-1:-1;60891:10:0;;-1:-1:-1;;;;;60904:5:0;;;;:16;;:31;;60929:4;;60904:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;60891:54;;60968:5;60959:6;:14;60956:94;;;61006:6;60998:5;:14;60990:22;;61037:1;61027:11;;60956:94;61066:20;;61062:170;;61103:31;61117:16;61103:13;:31::i;:::-;;61164:56;61173:16;61191:28;61211:7;61191:15;:13;:15::i;:28::-;61164:8;:56::i;:::-;61149:71;;61062:170;59074:2165;;;;;;;;;;;;:::o;57965:137::-;58054:5;;58073;;58088:4;;58042:52;;-1:-1:-1;;;58042:52:0;;-1:-1:-1;;;;;58054:5:0;;;;;;;58042:30;;:52;;58073:5;;;;58088:4;;;58042:52;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;13911:181::-;13969:7;14001:5;;;14025:6;;;;14017:46;;;;-1:-1:-1;;;14017:46:0;;;;;;;:::i;15265:471::-;15323:7;15568:6;15564:47;;-1:-1:-1;15598:1:0;15591:8;;15564:47;15635:5;;;15639:1;15635;:5;:1;15659:5;;;;;:10;15651:56;;;;-1:-1:-1;;;15651:56:0;;;;;;;:::i;21920:761::-;22344:23;22370:69;22398:4;22370:69;;;;;;;;;;;;;;;;;22378:5;-1:-1:-1;;;;;22370:27:0;;;:69;;;;;:::i;:::-;22454:17;;22344:95;;-1:-1:-1;22454:21:0;22450:224;;22596:10;22585:30;;;;;;;;;;;;:::i;:::-;22577:85;;;;-1:-1:-1;;;22577:85:0;;;;;;;:::i;9248:979::-;9378:12;9411:18;9422:6;9411:10;:18::i;:::-;9403:60;;;;-1:-1:-1;;;9403:60:0;;;;;;;:::i;:::-;9537:12;9551:23;9578:6;-1:-1:-1;;;;;9578:11:0;9598:8;9609:4;9578:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9536:78;;;;9629:7;9625:595;;;9660:10;-1:-1:-1;9653:17:0;;-1:-1:-1;9653:17:0;9625:595;9774:17;;:21;9770:439;;10037:10;10031:17;10098:15;10085:10;10081:2;10077:19;10070:44;9985:148;10180:12;10173:20;;-1:-1:-1;;;10173:20:0;;;;;;;;:::i;57148:206::-;57206:7;57236:34;57245:7;57254:15;:13;:15::i;57236:34::-;57300:5;;57316;;57331:4;;57288:58;;-1:-1:-1;;;57288:58:0;;57226:44;;-1:-1:-1;;;;;;57300:5:0;;;;;;;57288:27;;:58;;57316:5;;;57331:4;;57226:44;;57288:58;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;14814:192::-;14900:7;14936:12;14928:6;;;;14920:29;;;;-1:-1:-1;;;14920:29:0;;;;;;;;:::i;:::-;-1:-1:-1;;;14972:5:0;;;14814:192::o;58110:221::-;58162:7;58182:16;58201:34;55524:5;58201:17;58210:7;;58201:4;:8;;:17;;;;:::i;:::-;:21;;:34::i;:::-;58182:53;-1:-1:-1;58246:41:0;54802:42;54712;58182:53;58246:24;:41::i;:::-;58305:18;:4;58314:8;58305;:18::i;:::-;58298:25;58110:221;-1:-1:-1;;;58110:221:0:o;3588:106::-;3646:7;3677:1;3673;:5;:13;;3685:1;3673:13;;;-1:-1:-1;3681:1:0;;3588:106;-1:-1:-1;3588:106:0:o;4756:619::-;4816:4;5284:20;;5127:66;5324:23;;;;;;:42;;-1:-1:-1;;5351:15:0;;;5316:51;-1:-1:-1;;4756:619:0:o;16212:132::-;16270:7;16297:39;16301:1;16304;16297:39;;;;;;;;;;;;;;;;;16926:7;16961:12;16954:5;16946:28;;;;-1:-1:-1;;;16946:28:0;;;;;;;;:::i;:::-;;16985:9;17001:1;16997;:5;;;;;;;16840:278;-1:-1:-1;;;;;16840:278:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;4267:241;;4371:2;4359:9;4350:7;4346:23;4342:32;4339:2;;;-1:-1;;4377:12;4339:2;85:6;72:20;97:33;124:5;97:33;:::i;4515:263::-;;4630:2;4618:9;4609:7;4605:23;4601:32;4598:2;;;-1:-1;;4636:12;4598:2;226:6;220:13;238:33;265:5;238:33;:::i;4785:392::-;;4925:2;;4913:9;4904:7;4900:23;4896:32;4893:2;;;-1:-1;;4931:12;4893:2;4982:17;4976:24;5020:18;5012:6;5009:30;5006:2;;;-1:-1;;5042:12;5006:2;5129:22;;422:4;410:17;;406:27;-1:-1;396:2;;-1:-1;;437:12;396:2;477:6;471:13;499:80;514:64;571:6;514:64;:::i;:::-;499:80;:::i;:::-;607:21;;;664:14;;;;639:17;;;753;;;744:27;;;;741:36;-1:-1;738:2;;;-1:-1;;780:12;738:2;-1:-1;806:10;;800:217;825:6;822:1;819:13;800:217;;;4204:13;;893:61;;847:1;840:9;;;;;968:14;;;;996;;800:217;;;-1:-1;5062:99;4887:290;-1:-1;;;;;;;4887:290::o;5184:235::-;;5285:2;5273:9;5264:7;5260:23;5256:32;5253:2;;;-1:-1;;5291:12;5253:2;1108:6;1095:20;1120:30;1144:5;1120:30;:::i;5426:257::-;;5538:2;5526:9;5517:7;5513:23;5509:32;5506:2;;;-1:-1;;5544:12;5506:2;1243:6;1237:13;1255:30;1279:5;1255:30;:::i;5994:367::-;;;6118:2;6106:9;6097:7;6093:23;6089:32;6086:2;;;-1:-1;;6124:12;6086:2;6182:17;6169:31;6220:18;;6212:6;6209:30;6206:2;;;-1:-1;;6242:12;6206:2;6328:6;6317:9;6313:22;;;1602:3;1595:4;1587:6;1583:17;1579:27;1569:2;;-1:-1;;1610:12;1569:2;1653:6;1640:20;6220:18;1672:6;1669:30;1666:2;;;-1:-1;;1702:12;1666:2;1797:3;6118:2;1777:17;1738:6;1763:32;;1760:41;1757:2;;;-1:-1;;1804:12;1757:2;6118;1734:17;;;;;6262:83;;-1:-1;6080:281;;-1:-1;;;;6080:281::o;6368:362::-;;6493:2;6481:9;6472:7;6468:23;6464:32;6461:2;;;-1:-1;;6499:12;6461:2;6550:17;6544:24;6588:18;;6580:6;6577:30;6574:2;;;-1:-1;;6610:12;6574:2;6697:6;6686:9;6682:22;;;1946:3;1939:4;1931:6;1927:17;1923:27;1913:2;;-1:-1;;1954:12;1913:2;1994:6;1988:13;6588:18;28791:6;28788:30;28785:2;;;-1:-1;;28821:12;28785:2;2016:65;28894:9;28875:17;;-1:-1;;28871:33;6493:2;28952:15;2016:65;:::i;:::-;2007:74;;2101:6;2094:5;2087:21;2205:3;6493:2;2196:6;2129;2187:16;;2184:25;2181:2;;;-1:-1;;2212:12;2181:2;2232:39;2264:6;6493:2;2163:5;2159:16;6493:2;2129:6;2125:17;2232:39;:::i;:::-;-1:-1;6630:84;6455:275;-1:-1;;;;6455:275::o;6737:324::-;;6882:3;;6870:9;6861:7;6857:23;6853:33;6850:2;;;-1:-1;;6889:12;6850:2;2481:22;6882:3;2481:22;:::i;:::-;2472:31;;2627:22;4204:13;2577:16;2570:86;2723:2;2792:9;2788:22;4204:13;2723:2;2742:5;2738:16;2731:86;2883:2;2952:9;2948:22;4204:13;2883:2;2902:5;2898:16;2891:86;3051:2;3120:9;3116:22;4204:13;3051:2;3070:5;3066:16;3059:86;3219:3;3289:9;3285:22;4204:13;3219:3;3239:5;3235:16;3228:86;3381:3;3451:9;3447:22;4204:13;3381:3;3401:5;3397:16;3390:86;3542:3;3612:9;3608:22;4204:13;3542:3;3562:5;3558:16;3551:86;3703:3;3773:9;3769:22;4204:13;3703:3;3723:5;3719:16;3712:86;3864:3;;3936:9;3932:22;4204:13;3864:3;3884:5;3880:18;3873:88;;6941:104;;;;6844:217;;;;:::o;7068:241::-;;7172:2;7160:9;7151:7;7147:23;7143:32;7140:2;;;-1:-1;;7178:12;7140:2;-1:-1;4056:20;;7134:175;-1:-1;7134:175::o;7316:263::-;;7431:2;7419:9;7410:7;7406:23;7402:32;7399:2;;;-1:-1;;7437:12;7399:2;-1:-1;4204:13;;7393:186;-1:-1;7393:186::o;16458:271::-;;10049:5;29618:12;10160:52;10205:6;10200:3;10193:4;10186:5;10182:16;10160:52;:::i;:::-;10224:16;;;;;16592:137;-1:-1;;16592:137::o;16736:809::-;;-1:-1;;;13035:11;13028:28;10049:5;29618:12;10160:52;10205:6;13013:1;13079:3;13075:11;10193:4;10186:5;10182:16;10160:52;:::i;:::-;-1:-1;;;13013:1;10224:16;;;;;;;14385:33;-1:-1;14437:12;;;17074:471;-1:-1;17074:471::o;17552:222::-;-1:-1;;;;;30903:54;;;;8160:37;;17679:2;17664:18;;17650:124::o;18026:333::-;-1:-1;;;;;30903:54;;;8160:37;;30903:54;;18345:2;18330:18;;8160:37;18181:2;18166:18;;18152:207::o;18366:444::-;-1:-1;;;;;30903:54;;;8160:37;;30903:54;;;;18713:2;18698:18;;8160:37;18796:2;18781:18;;16289:37;;;;18549:2;18534:18;;18520:290::o;18817:349::-;-1:-1;;;;;30903:54;;;;8160:37;;19152:2;19137:18;;10659:58;18980:2;18965:18;;18951:215::o;19513:441::-;19722:2;19707:18;;19711:9;9473:21;19513:441;9500:258;29510:4;9522:1;9519:13;9500:258;;;9586:13;;16289:37;;7931:4;7922:14;;;;29987;;;;9547:1;9540:9;9500:258;;;9504:14;;;10710:5;19940:2;19929:9;19925:18;10659:58;19693:261;;;;;:::o;19961:210::-;31133:13;;31126:21;9843:34;;20082:2;20067:18;;20053:118::o;20698:330::-;;20855:2;20876:17;20869:47;30144:6;20855:2;20844:9;20840:18;30132:19;32644:6;32639:3;30172:14;20844:9;30172:14;32621:30;32682:16;;;30172:14;32682:16;;;32675:27;;;;28894:9;33374:14;;;-1:-1;;33370:28;11009:39;;;20826:202;-1:-1;20826:202::o;21035:310::-;;21182:2;21203:17;21196:47;11207:5;29618:12;30144:6;21182:2;21171:9;21167:18;30132:19;11301:52;11346:6;30172:14;21171:9;30172:14;21182:2;11327:5;11323:16;11301:52;:::i;:::-;28894:9;33374:14;-1:-1;;33370:28;11365:39;;;;30172:14;11365:39;;21153:192;-1:-1;;21153:192::o;21352:416::-;21552:2;21566:47;;;12008:2;21537:18;;;30132:19;-1:-1;;;30172:14;;;12024:34;12077:12;;;21523:245::o;21775:416::-;21975:2;21989:47;;;12328:1;21960:18;;;30132:19;-1:-1;;;30172:14;;;12343:28;12390:12;;;21946:245::o;22198:416::-;22398:2;22412:47;;;12641:2;22383:18;;;30132:19;12677:29;30172:14;;;12657:50;12726:12;;;22369:245::o;22621:416::-;22821:2;22835:47;;;13325:2;22806:18;;;30132:19;13361:34;30172:14;;;13341:55;-1:-1;;;13416:12;;;13409:25;13453:12;;;22792:245::o;23044:416::-;23244:2;23258:47;;;13704:1;23229:18;;;30132:19;-1:-1;;;30172:14;;;13719:29;13767:12;;;23215:245::o;23467:416::-;23667:2;23681:47;;;14018:1;23652:18;;;30132:19;-1:-1;;;30172:14;;;14033:30;14082:12;;;23638:245::o;23890:416::-;24090:2;24104:47;;;14688:2;24075:18;;;30132:19;14724:31;30172:14;;;14704:52;14775:12;;;24061:245::o;24313:416::-;24513:2;24527:47;;;15026:2;24498:18;;;30132:19;-1:-1;;;30172:14;;;15042:34;15095:12;;;24484:245::o;24736:416::-;24936:2;24950:47;;;15346:2;24921:18;;;30132:19;15382:34;30172:14;;;15362:55;-1:-1;;;15437:12;;;15430:34;15483:12;;;24907:245::o;25159:416::-;25359:2;25373:47;;;15734:2;25344:18;;;30132:19;-1:-1;;;30172:14;;;15750:33;15802:12;;;25330:245::o;25582:416::-;25782:2;25796:47;;;16053:2;25767:18;;;30132:19;16089:34;30172:14;;;16069:55;-1:-1;;;16144:12;;;16137:46;16202:12;;;25753:245::o;26005:222::-;16289:37;;;26132:2;26117:18;;26103:124::o;26234:826::-;;26528:3;26517:9;26513:19;16319:5;16296:3;16289:37;26693:2;16319:5;26693:2;26682:9;26678:18;16289:37;26528:3;26730:2;26719:9;26715:18;26708:48;26770:105;8547:5;29374:12;30144:6;30139:3;30132:19;30172:14;26517:9;30172:14;8559:93;;29104:3;-1:-1;29094:14;26693:2;-1:-1;29123:18;8732:21;;-1:-1;8759:288;8784:6;8781:1;8778:13;8759:288;;;33282:11;;-1:-1;;;;;30903:54;8160:37;;5020:18;29874:14;;;;7740;;;;8799:9;8759:288;;;-1:-1;;;;;;;30903:54;;;;26962:2;26947:18;;8029:58;-1:-1;;;27045:3;27030:19;16289:37;26762:113;26499:561;-1:-1;;;26499:561::o;27067:444::-;16289:37;;;27414:2;27399:18;;16289:37;;;;27497:2;27482:18;;16289:37;27250:2;27235:18;;27221:290::o;27518:556::-;16289:37;;;27894:2;27879:18;;16289:37;;;;27977:2;27962:18;;16289:37;28060:2;28045:18;;16289:37;27729:3;27714:19;;27700:374::o;28081:256::-;28143:2;28137:9;28169:17;;;28244:18;28229:34;;28265:22;;;28226:62;28223:2;;;28301:1;;28291:12;28223:2;28143;28310:22;28121:216;;-1:-1;28121:216::o;28344:304::-;;28503:18;28495:6;28492:30;28489:2;;;-1:-1;;28525:12;28489:2;-1:-1;28570:4;28558:17;;;28623:15;;28426:222::o;32717:268::-;32782:1;32789:101;32803:6;32800:1;32797:13;32789:101;;;32870:11;;;32864:18;32851:11;;;32844:39;32825:2;32818:10;32789:101;;;32905:6;32902:1;32899:13;32896:2;;;32782:1;32961:6;32956:3;32952:16;32945:27;32896:2;;32766:219;;;:::o;33521:117::-;-1:-1;;;;;30903:54;;33580:35;;33570:2;;33629:1;;33619:12;33645:111;33726:5;31133:13;31126:21;33704:5;33701:32;33691:2;;33747:1;;33737:12
Swarm Source
ipfs://d04de687f5702ae56c61bb96e2f4589ebce0bcd736a52d191b78c82435c83de8
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
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.