More Info
Private Name Tags
ContractCreator
TokenTracker
Multichain Info
No addresses found
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
Strategy
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-10-13 */ // SPDX-License-Identifier: AGPL-3.0 pragma solidity 0.6.12; pragma experimental ABIEncoderV2; // Global Enums and Structs struct StrategyParams { uint256 performanceFee; uint256 activation; uint256 debtRatio; uint256 rateLimit; uint256 lastReport; uint256 totalDebt; uint256 totalGain; uint256 totalLoss; } // Part: IAsset interface IAsset { // solhint-disable-previous-line no-empty-blocks } // Part: OpenZeppelin/[email protected]/Address /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // Part: OpenZeppelin/[email protected]/Context /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // Part: OpenZeppelin/[email protected]/IERC20 /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // Part: OpenZeppelin/[email protected]/Math /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } } // Part: OpenZeppelin/[email protected]/SafeMath /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // Part: IBalancerPool interface IBalancerPool is IERC20 { enum SwapKind {GIVEN_IN, GIVEN_OUT} struct SwapRequest { SwapKind kind; IERC20 tokenIn; IERC20 tokenOut; uint256 amount; // Misc data bytes32 poolId; uint256 lastChangeBlock; address from; address to; bytes userData; } function getPoolId() external view returns (bytes32 poolId); function symbol() external view returns (string memory s); function onSwap( SwapRequest memory swapRequest, uint256[] memory balances, uint256 indexIn, uint256 indexOut ) external view returns (uint256 amount); } // Part: IBalancerVault interface IBalancerVault { enum PoolSpecialization {GENERAL, MINIMAL_SWAP_INFO, TWO_TOKEN} enum JoinKind {INIT, EXACT_TOKENS_IN_FOR_BPT_OUT, TOKEN_IN_FOR_EXACT_BPT_OUT, ALL_TOKENS_IN_FOR_EXACT_BPT_OUT} enum ExitKind {EXACT_BPT_IN_FOR_ONE_TOKEN_OUT, EXACT_BPT_IN_FOR_TOKENS_OUT, BPT_IN_FOR_EXACT_TOKENS_OUT} enum SwapKind {GIVEN_IN, GIVEN_OUT} /** * @dev Data for each individual swap executed by `batchSwap`. The asset in and out fields are indexes into the * `assets` array passed to that function, and ETH assets are converted to WETH. * * If `amount` is zero, the multihop mechanism is used to determine the actual amount based on the amount in/out * from the previous swap, depending on the swap kind. * * The `userData` field is ignored by the Vault, but forwarded to the Pool in the `onSwap` hook, and may be * used to extend swap behavior. */ struct BatchSwapStep { bytes32 poolId; uint256 assetInIndex; uint256 assetOutIndex; uint256 amount; bytes userData; } /** * @dev All tokens in a swap are either sent from the `sender` account to the Vault, or from the Vault to the * `recipient` account. * * If the caller is not `sender`, it must be an authorized relayer for them. * * If `fromInternalBalance` is true, the `sender`'s Internal Balance will be preferred, performing an ERC20 * transfer for the difference between the requested amount and the User's Internal Balance (if any). The `sender` * must have allowed the Vault to use their tokens via `IERC20.approve()`. This matches the behavior of * `joinPool`. * * If `toInternalBalance` is true, tokens will be deposited to `recipient`'s internal balance instead of * transferred. This matches the behavior of `exitPool`. * * Note that ETH cannot be deposited to or withdrawn from Internal Balance: attempting to do so will trigger a * revert. */ struct FundManagement { address sender; bool fromInternalBalance; address payable recipient; bool toInternalBalance; } /** * @dev Data for a single swap executed by `swap`. `amount` is either `amountIn` or `amountOut` depending on * the `kind` value. * * `assetIn` and `assetOut` are either token addresses, or the IAsset sentinel value for ETH (the zero address). * Note that Pools never interact with ETH directly: it will be wrapped to or unwrapped from WETH by the Vault. * * The `userData` field is ignored by the Vault, but forwarded to the Pool in the `onSwap` hook, and may be * used to extend swap behavior. */ struct SingleSwap { bytes32 poolId; SwapKind kind; IAsset assetIn; IAsset assetOut; uint256 amount; bytes userData; } // enconding formats https://github.com/balancer-labs/balancer-v2-monorepo/blob/master/pkg/balancer-js/src/pool-weighted/encoder.ts struct JoinPoolRequest { IAsset[] assets; uint256[] maxAmountsIn; bytes userData; bool fromInternalBalance; } struct ExitPoolRequest { IAsset[] assets; uint256[] minAmountsOut; bytes userData; bool toInternalBalance; } function joinPool( bytes32 poolId, address sender, address recipient, JoinPoolRequest memory request ) external payable; function exitPool( bytes32 poolId, address sender, address payable recipient, ExitPoolRequest calldata request ) external; function getPool(bytes32 poolId) external view returns (address poolAddress, PoolSpecialization); function getPoolTokenInfo(bytes32 poolId, IERC20 token) external view returns ( uint256 cash, uint256 managed, uint256 lastChangeBlock, address assetManager ); function getPoolTokens(bytes32 poolId) external view returns ( IERC20[] calldata tokens, uint256[] calldata balances, uint256 lastChangeBlock ); /** * @dev Performs a swap with a single Pool. * * If the swap is 'given in' (the number of tokens to send to the Pool is known), it returns the amount of tokens * taken from the Pool, which must be greater than or equal to `limit`. * * If the swap is 'given out' (the number of tokens to take from the Pool is known), it returns the amount of tokens * sent to the Pool, which must be less than or equal to `limit`. * * Internal Balance usage and the recipient are determined by the `funds` struct. * * Emits a `Swap` event. */ function swap( SingleSwap memory singleSwap, FundManagement memory funds, uint256 limit, uint256 deadline ) external returns (uint256 amountCalculated); /** * @dev Performs a series of swaps with one or multiple Pools. In each individual swap, the caller determines either * the amount of tokens sent to or received from the Pool, depending on the `kind` value. * * Returns an array with the net Vault asset balance deltas. Positive amounts represent tokens (or ETH) sent to the * Vault, and negative amounts represent tokens (or ETH) sent by the Vault. Each delta corresponds to the asset at * the same index in the `assets` array. * * Swaps are executed sequentially, in the order specified by the `swaps` array. Each array element describes a * Pool, the token to be sent to this Pool, the token to receive from it, and an amount that is either `amountIn` or * `amountOut` depending on the swap kind. * * Multihop swaps can be executed by passing an `amount` value of zero for a swap. This will cause the amount in/out * of the previous swap to be used as the amount in for the current one. In a 'given in' swap, 'tokenIn' must equal * the previous swap's `tokenOut`. For a 'given out' swap, `tokenOut` must equal the previous swap's `tokenIn`. * * The `assets` array contains the addresses of all assets involved in the swaps. These are either token addresses, * or the IAsset sentinel value for ETH (the zero address). Each entry in the `swaps` array specifies tokens in and * out by referencing an index in `assets`. Note that Pools never interact with ETH directly: it will be wrapped to * or unwrapped from WETH by the Vault. * * Internal Balance usage, sender, and recipient are determined by the `funds` struct. The `limits` array specifies * the minimum or maximum amount of each token the vault is allowed to transfer. * * `batchSwap` can be used to make a single swap, like `swap` does, but doing so requires more gas than the * equivalent `swap` call. * * Emits `Swap` events. */ function batchSwap( SwapKind kind, BatchSwapStep[] memory swaps, IAsset[] memory assets, FundManagement memory funds, int256[] memory limits, uint256 deadline ) external payable returns (int256[] memory); } // Part: OpenZeppelin/[email protected]/ERC20 /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20 { using SafeMath for uint256; using Address for address; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for {name} and {symbol}, initializes {decimals} with * a default value of 18. * * To select a different value for {decimals}, use {_setupDecimals}. * * All three of these values are immutable: they can only be set once during * construction. */ constructor (string memory name, string memory symbol) public { _name = name; _symbol = symbol; _decimals = 18; } /** * @dev Returns the name of the token. */ function name() public view returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is * called. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view returns (uint8) { return _decimals; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}; * * Requirements: * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements * * - `to` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. * * This is internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Sets {decimals} to a value other than the default one of 18. * * WARNING: This function should only be called from the constructor. Most * applications that interact with token contracts will not expect * {decimals} to ever change, and may work incorrectly if it does. */ function _setupDecimals(uint8 decimals_) internal { _decimals = decimals_; } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } } // Part: OpenZeppelin/[email protected]/SafeERC20 /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // Part: 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: BaseStrategyEdited /** * @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 BaseStrategyEdited { 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.0"; } /** * @notice This Strategy's name. * @dev * You can use this field to manage the "version" of this Strategy, e.g. * `StrategySomethingOrOtherV1`. However, "API Version" is managed by * `apiVersion()` function above. * @return This Strategy's name. */ function name() external view virtual returns (string memory); /** * @notice * The amount (priced in want) of the total assets managed by this strategy should not count * towards Yearn's TVL calculations. * @dev * You can override this field to set it to a non-zero value if some of the assets of this * Strategy is somehow delegated inside another part of of Yearn's ecosystem e.g. another Vault. * Note that this value must be strictly less than or equal to the amount provided by * `estimatedTotalAssets()` below, as the TVL calc will be total assets minus delegated assets. * @return * The amount of assets this strategy manages that should not be included in Yearn's Total Value * Locked (TVL) calculation across it's ecosystem. */ function delegatedAssets() external view virtual returns (uint256) { return 0; } VaultAPI public vault; address public strategist; address public rewards; address public keeper; IERC20 public want; // So indexers can keep track of this event Harvested( uint256 profit, uint256 loss, uint256 debtPayment, uint256 debtOutstanding ); event UpdatedStrategist(address newStrategist); event UpdatedKeeper(address newKeeper); event UpdatedRewards(address rewards); event UpdatedMinReportDelay(uint256 delay); event UpdatedMaxReportDelay(uint256 delay); event UpdatedProfitFactor(uint256 profitFactor); event UpdatedDebtThreshold(uint256 debtThreshold); event EmergencyExitEnabled(); event UpdatedMetadataURI(string metadataURI); // The minimum number of seconds between harvest calls. See // `setMinReportDelay()` for more details. uint256 public minReportDelay; // The maximum number of seconds between harvest calls. See // `setMaxReportDelay()` for more details. uint256 public maxReportDelay; // The minimum multiple that `callCost` must be above the credit/profit to // be "justifiable". See `setProfitFactor()` for more details. uint256 public profitFactor; // Use this to adjust the threshold at which running a debt causes a // harvest trigger. See `setDebtThreshold()` for more details. uint256 public debtThreshold; // See note on `setEmergencyExit()`. bool public emergencyExit; // modifiers modifier onlyAuthorized() { require( msg.sender == strategist || msg.sender == governance(), "!authorized" ); _; } modifier 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 view virtual returns (uint256); /* * @notice * Provide an indication of whether this strategy is currently "active" * in that it is managing an active position, or will manage a position in * the future. This should correlate to `harvest()` activity, so that Harvest * events can be tracked externally by indexing agents. * @return True if the strategy is actively managing a position. */ function isActive() public view returns (bool) { return vault.strategies(address(this)).debtRatio > 0 || estimatedTotalAssets() > 0; } /** * Perform any Strategy unwinding or other calls necessary to capture the * "free return" this Strategy has generated since the last time its core * position(s) were adjusted. Examples include unwrapping extra rewards. * This call is only used during "normal operation" of a Strategy, and * should be optimized to minimize losses as much as possible. * * This method returns any realized profits and/or realized losses * incurred, and should return the total amounts of profits/losses/debt * payments (in `want` tokens) for the Vault's accounting (e.g. * `want.balanceOf(this) >= _debtPayment + _profit - _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 view virtual returns (bool) { // We usually don't need tend, but if there are positions that need // active maintainence, overriding this function is how you would // signal for that. 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 view virtual 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(BaseStrategyEdited(_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 view virtual returns (address[] memory); /** * @notice * Removes tokens from this Strategy that are not the type of tokens * managed by this Strategy. This may be used in case of accidentally * sending the wrong kind of token to this Strategy. * * Tokens will be sent to `governance()`. * * This will fail if an attempt is made to sweep `want`, or any tokens * that are protected by this Strategy. * * This may only be called by governance. * @dev * Implement `protectedTokens()` to specify any additional tokens that * should be protected from sweeping in addition to `want`. * @param _token The token to transfer out of this vault. */ function sweep(address _token) external onlyGovernance { require(_token != address(want), "!want"); require(_token != address(vault), "!shares"); address[] memory _protectedTokens = protectedTokens(); for (uint256 i; i < _protectedTokens.length; i++) require(_token != _protectedTokens[i], "!protected"); IERC20(_token).safeTransfer( governance(), IERC20(_token).balanceOf(address(this)) ); } } // File: Strategy.sol contract Strategy is BaseStrategyEdited { using SafeERC20 for IERC20; using Address for address; using SafeMath for uint256; IERC20 internal constant weth = IERC20(address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)); IBalancerVault public balancerVault; IBalancerPool public bpt; IERC20[] public rewardTokens; IAsset[] internal assets; SwapSteps[] internal swapSteps; uint256[] internal minAmountsOut; bytes32 public balancerPoolId; uint8 public numTokens; uint8 public tokenIndex; struct SwapSteps { bytes32[] poolIds; IAsset[] assets; } uint256 internal constant max = type(uint256).max; //1 0.01% //5 0.05% //10 0.1% //50 0.5% //100 1% //1000 10% //10000 100% uint256 public maxSlippageIn; // bips uint256 public maxSlippageOut; // bips uint256 public maxSingleDeposit; uint256 public minDepositPeriod; // seconds uint256 public lastDepositTime; uint256 internal constant basisOne = 10000; bool internal isOriginal = true; constructor( address _vault, address _balancerVault, address _balancerPool, uint256 _maxSlippageIn, uint256 _maxSlippageOut, uint256 _maxSingleDeposit, uint256 _minDepositPeriod) public BaseStrategyEdited(_vault){ require(address(bpt) == address(0x0), "Strategy already initialized!"); bpt = IBalancerPool(_balancerPool); balancerPoolId = bpt.getPoolId(); balancerVault = IBalancerVault(_balancerVault); (IERC20[] memory tokens,,) = balancerVault.getPoolTokens(balancerPoolId); numTokens = uint8(tokens.length); assets = new IAsset[](numTokens); tokenIndex = type(uint8).max; for (uint8 i = 0; i < numTokens; i++) { if (tokens[i] == want) { tokenIndex = i; } assets[i] = IAsset(address(tokens[i])); } require(tokenIndex != type(uint8).max, "token not supported in pool!"); maxSlippageIn = _maxSlippageIn; maxSlippageOut = _maxSlippageOut; maxSingleDeposit = _maxSingleDeposit.mul(10 ** uint256(ERC20(address(want)).decimals())); minAmountsOut = new uint256[](numTokens); minDepositPeriod = _minDepositPeriod; want.safeApprove(address(balancerVault), max); } function name() external view override returns (string memory) { // Add your own name here, suggestion e.g. "StrategyCreamYFI" return string(abi.encodePacked("SingleSidedBalancer ", bpt.symbol(), "Pool ", ERC20(address(want)).symbol())); } function estimatedTotalAssets() public view override returns (uint256) { return balanceOfWant().add(balanceOfPooled()); } function prepareReturn(uint256 _debtOutstanding) internal override returns (uint256 _profit, uint256 _loss, uint256 _debtPayment){ if (_debtOutstanding > 0) { (_debtPayment, _loss) = liquidatePosition(_debtOutstanding); } uint256 beforeWant = balanceOfWant(); // 2 forms of profit. Incentivized rewards (BAL+other) and pool fees (want) collectTradingFees(); sellRewards(); uint256 afterWant = balanceOfWant(); _profit = afterWant.sub(beforeWant); if (_profit > _loss) { _profit = _profit.sub(_loss); _loss = 0; } else { _loss = _loss.sub(_profit); _profit = 0; } } function adjustPosition(uint256 _debtOutstanding) internal override { if (now - lastDepositTime < minDepositPeriod) { return; } uint256 pooledBefore = balanceOfPooled(); uint256[] memory maxAmountsIn = new uint256[](numTokens); uint256 amountIn = Math.min(maxSingleDeposit, balanceOfWant()); maxAmountsIn[tokenIndex] = amountIn; if (maxAmountsIn[tokenIndex] > 0) { uint256[] memory amountsIn = new uint256[](numTokens); amountsIn[tokenIndex] = amountIn; bytes memory userData = abi.encode(IBalancerVault.JoinKind.EXACT_TOKENS_IN_FOR_BPT_OUT, amountsIn, 0); IBalancerVault.JoinPoolRequest memory request = IBalancerVault.JoinPoolRequest(assets, maxAmountsIn, userData, false); balancerVault.joinPool(balancerPoolId, address(this), address(this), request); uint256 pooledDelta = balanceOfPooled().sub(pooledBefore); uint256 joinSlipped = amountIn > pooledDelta ? amountIn.sub(pooledDelta) : 0; uint256 maxLoss = amountIn.mul(maxSlippageIn).div(basisOne); require(joinSlipped <= maxLoss, "Exceeded maxSlippageIn!"); lastDepositTime = now; } } function liquidatePosition(uint256 _amountNeeded) internal override returns (uint256 _liquidatedAmount, uint256 _loss){ if (estimatedTotalAssets() < _amountNeeded) { _liquidatedAmount = _liquidateAllPositions(); return (_liquidatedAmount, _amountNeeded.sub(_liquidatedAmount)); } uint256 looseAmount = balanceOfWant(); if (_amountNeeded > looseAmount) { uint256 toExitAmount = _amountNeeded.sub(looseAmount); _sellBptForExactToken(toExitAmount); _liquidatedAmount = Math.min(balanceOfWant(), _amountNeeded); _loss = _amountNeeded.sub(_liquidatedAmount); _enforceSlippageOut(toExitAmount, _liquidatedAmount.sub(looseAmount)); } else { _liquidatedAmount = _amountNeeded; } } function _liquidateAllPositions() internal returns (uint256 liquidated) { uint eta = estimatedTotalAssets(); uint256 bpts = balanceOfBpt(); if (bpts > 0) { // exit entire position for single token. Could revert due to single exit limit enforced by balancer bytes memory userData = abi.encode(IBalancerVault.ExitKind.EXACT_BPT_IN_FOR_ONE_TOKEN_OUT, bpts, tokenIndex); IBalancerVault.ExitPoolRequest memory request = IBalancerVault.ExitPoolRequest(assets, minAmountsOut, userData, false); balancerVault.exitPool(balancerPoolId, address(this), address(this), request); } liquidated = balanceOfWant(); _enforceSlippageOut(eta, liquidated); return liquidated; } function prepareMigration(address _newStrategy) internal override { bpt.transfer(_newStrategy, balanceOfBpt()); for (uint i = 0; i < rewardTokens.length; i++) { IERC20 token = rewardTokens[i]; uint256 balance = token.balanceOf(address(this)); if (balance > 0) { token.transfer(_newStrategy, balance); } } } function protectedTokens() internal view override returns (address[] memory){} function tendTrigger(uint256 callCostInWei) public view override returns (bool) { return now.sub(lastDepositTime) > minDepositPeriod && balanceOfWant() > 0; } function harvestTrigger(uint256 callCostInWei) public view override returns (bool){ bool hasRewards; for (uint8 i = 0; i < rewardTokens.length; i++) { ERC20 rewardToken = ERC20(address(rewardTokens[i])); uint decReward = rewardToken.decimals(); uint decWant = ERC20(address(want)).decimals(); if (rewardToken.balanceOf(address(this)) > 10 ** (decReward > decWant ? decReward.sub(decWant) : 0)) { hasRewards = true; break; } } return super.harvestTrigger(callCostInWei) && hasRewards; } // HELPERS // function sellRewards() internal { for (uint8 i = 0; i < rewardTokens.length; i++) { ERC20 rewardToken = ERC20(address(rewardTokens[i])); uint256 amount = rewardToken.balanceOf(address(this)); uint decReward = rewardToken.decimals(); uint decWant = ERC20(address(want)).decimals(); if (amount > 10 ** (decReward > decWant ? decReward.sub(decWant) : 0)) { uint length = swapSteps[i].poolIds.length; IBalancerVault.BatchSwapStep[] memory steps = new IBalancerVault.BatchSwapStep[](length); int[] memory limits = new int[](length + 1); limits[0] = int(amount); for (uint j = 0; j < length; j++) { steps[j] = IBalancerVault.BatchSwapStep(swapSteps[i].poolIds[j], j, j + 1, j == 0 ? amount : 0, abi.encode(0) ); } balancerVault.batchSwap(IBalancerVault.SwapKind.GIVEN_IN, steps, swapSteps[i].assets, IBalancerVault.FundManagement(address(this), false, address(this), false), limits, now + 10); } } } function collectTradingFees() internal { uint256 total = estimatedTotalAssets(); uint256 debt = vault.strategies(address(this)).totalDebt; if (total > debt) { uint256 profit = total.sub(debt); _sellBptForExactToken(profit); } } function balanceOfWant() public view returns (uint256 _amount){ return want.balanceOf(address(this)); } function balanceOfBpt() public view returns (uint256 _amount){ return bpt.balanceOf(address(this)); } function balanceOfReward(uint256 index) public view returns (uint256 _amount){ return rewardTokens[index].balanceOf(address(this)); } function balanceOfPooled() public view returns (uint256 _amount){ uint256 totalWantPooled; (IERC20[] memory tokens,uint256[] memory totalBalances,uint256 lastChangeBlock) = balancerVault.getPoolTokens(balancerPoolId); for (uint8 i = 0; i < numTokens; i++) { uint256 tokenPooled = totalBalances[i].mul(balanceOfBpt()).div(bpt.totalSupply()); if (tokenPooled > 0) { IERC20 token = tokens[i]; if (token != want) { IBalancerPool.SwapRequest memory request = _getSwapRequest(token, tokenPooled, lastChangeBlock); // now denomated in want tokenPooled = bpt.onSwap(request, totalBalances, i, tokenIndex); } totalWantPooled += tokenPooled; } } return totalWantPooled; } function _getSwapRequest(IERC20 token, uint256 amount, uint256 lastChangeBlock) internal view returns (IBalancerPool.SwapRequest memory request){ return IBalancerPool.SwapRequest(IBalancerPool.SwapKind.GIVEN_IN, token, want, amount, balancerPoolId, lastChangeBlock, address(this), address(this), abi.encode(0) ); } function _sellBptForExactToken(uint256 _amountTokenOut) internal { uint256[] memory amountsOut = new uint256[](numTokens); amountsOut[tokenIndex] = _amountTokenOut; bytes memory userData = abi.encode(IBalancerVault.ExitKind.BPT_IN_FOR_EXACT_TOKENS_OUT, amountsOut, balanceOfBpt()); IBalancerVault.ExitPoolRequest memory request = IBalancerVault.ExitPoolRequest(assets, minAmountsOut, userData, false); balancerVault.exitPool(balancerPoolId, address(this), address(this), request); } // for partnership rewards like Lido or airdrops function whitelistRewards(address _rewardToken, SwapSteps memory _steps) public onlyKeepers { IERC20 token = IERC20(_rewardToken); token.approve(address(balancerVault), max); rewardTokens.push(token); swapSteps.push(_steps); } function delistAllRewards() public onlyKeepers { for (uint i = 0; i < rewardTokens.length; i++) { rewardTokens[i].approve(address(balancerVault), 0); } IERC20[] memory noRewardTokens; rewardTokens = noRewardTokens; delete swapSteps; } function numRewards() public view returns (uint256 _num){ return rewardTokens.length; } function setParams(uint256 _maxSlippageIn, uint256 _maxSlippageOut, uint256 _maxSingleDeposit, uint256 _minDepositPeriod) public onlyKeepers { require(_maxSlippageIn <= basisOne, "maxSlippageIn too high"); maxSlippageIn = _maxSlippageIn; require(_maxSlippageOut <= basisOne, "maxSlippageOut too high"); maxSlippageOut = _maxSlippageOut; maxSingleDeposit = _maxSingleDeposit; minDepositPeriod = _minDepositPeriod; } function _enforceSlippageOut(uint _intended, uint _actual) internal { // enforce that amount exited didn't slip beyond our tolerance // just in case there's positive slippage uint256 exitSlipped = _intended > _actual ? _intended.sub(_actual) : 0; uint256 maxLoss = _intended.mul(maxSlippageOut).div(basisOne); require(exitSlipped <= maxLoss, "Exceeded maxSlippageOut!"); } function getSwapSteps() public view returns (SwapSteps[] memory){ return swapSteps; } receive() external payable {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_balancerVault","type":"address"},{"internalType":"address","name":"_balancerPool","type":"address"},{"internalType":"uint256","name":"_maxSlippageIn","type":"uint256"},{"internalType":"uint256","name":"_maxSlippageOut","type":"uint256"},{"internalType":"uint256","name":"_maxSingleDeposit","type":"uint256"},{"internalType":"uint256","name":"_minDepositPeriod","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[],"name":"EmergencyExitEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"profit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"loss","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"debtPayment","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"debtOutstanding","type":"uint256"}],"name":"Harvested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"debtThreshold","type":"uint256"}],"name":"UpdatedDebtThreshold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newKeeper","type":"address"}],"name":"UpdatedKeeper","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"delay","type":"uint256"}],"name":"UpdatedMaxReportDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"metadataURI","type":"string"}],"name":"UpdatedMetadataURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"delay","type":"uint256"}],"name":"UpdatedMinReportDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"profitFactor","type":"uint256"}],"name":"UpdatedProfitFactor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"rewards","type":"address"}],"name":"UpdatedRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newStrategist","type":"address"}],"name":"UpdatedStrategist","type":"event"},{"inputs":[],"name":"apiVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"balanceOfBpt","outputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balanceOfPooled","outputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"balanceOfReward","outputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balanceOfWant","outputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balancerPoolId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balancerVault","outputs":[{"internalType":"contract IBalancerVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bpt","outputs":[{"internalType":"contract IBalancerPool","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":"delistAllRewards","outputs":[],"stateMutability":"nonpayable","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":"getSwapSteps","outputs":[{"components":[{"internalType":"bytes32[]","name":"poolIds","type":"bytes32[]"},{"internalType":"contract IAsset[]","name":"assets","type":"address[]"}],"internalType":"struct Strategy.SwapSteps[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"callCostInWei","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":"keeper","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastDepositTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxReportDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSingleDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSlippageIn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSlippageOut","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":"minDepositPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"numRewards","outputs":[{"internalType":"uint256","name":"_num","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numTokens","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"profitFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardTokens","outputs":[{"internalType":"contract IERC20","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":"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":"_maxSlippageIn","type":"uint256"},{"internalType":"uint256","name":"_maxSlippageOut","type":"uint256"},{"internalType":"uint256","name":"_maxSingleDeposit","type":"uint256"},{"internalType":"uint256","name":"_minDepositPeriod","type":"uint256"}],"name":"setParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_profitFactor","type":"uint256"}],"name":"setProfitFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewards","type":"address"}],"name":"setRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategist","type":"address"}],"name":"setStrategist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"callCostInWei","type":"uint256"}],"name":"tendTrigger","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenIndex","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"contract VaultAPI","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"want","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"},{"components":[{"internalType":"bytes32[]","name":"poolIds","type":"bytes32[]"},{"internalType":"contract IAsset[]","name":"assets","type":"address[]"}],"internalType":"struct Strategy.SwapSteps","name":"_steps","type":"tuple"}],"name":"whitelistRewards","outputs":[],"stateMutability":"nonpayable","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
60806040526017805460ff191660011790553480156200001e57600080fd5b506040516200625e3803806200625e833981016040819052620000419162000b11565b8662000050813380806200048d565b50600b546001600160a01b031615620000865760405162461bcd60e51b81526004016200007d9062000d50565b60405180910390fd5b600b80546001600160a01b0319166001600160a01b0387811691909117918290556040805163038fff2d60e41b8152905192909116916338fff2d091600480820192602092909190829003018186803b158015620000e357600080fd5b505afa158015620000f8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200011e919062000c85565b6010819055600a8054610100600160a81b0319166101006001600160a01b038a811682029290921792839055604051631f29a8cd60e31b8152606094919093049091169163f94d466891620001769160040162000d12565b60006040518083038186803b1580156200018f57600080fd5b505afa158015620001a4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620001ce919081019062000b8b565b505080516011805460ff191660ff9283161790819055919250166001600160401b0381118015620001fe57600080fd5b5060405190808252806020026020018201604052801562000229578160200160208202803683370190505b5080516200024091600d9160209091019062000981565b506011805461ff00191661ff0017905560005b60115460ff90811690821610156200030e5760055482516001600160a01b0390911690839060ff84169081106200028657fe5b60200260200101516001600160a01b03161415620002b3576011805461ff00191661010060ff8416021790555b818160ff1681518110620002c357fe5b6020026020010151600d8260ff1681548110620002dc57fe5b600091825260209091200180546001600160a01b0319166001600160a01b039290921691909117905560010162000253565b50601154610100900460ff90811614156200033d5760405162461bcd60e51b81526004016200007d9062000dbe565b601285905560138490556005546040805163313ce56760e01b81529051620003e5926001600160a01b03169163313ce567916004808301926020929190829003018186803b1580156200038f57600080fd5b505afa158015620003a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003ca919062000c9e565b60ff16600a0a846200066960201b620029f01790919060201c565b60145560115460ff166001600160401b03811180156200040457600080fd5b506040519080825280602002602001820160405280156200042f578160200160208202803683370190505b5080516200044691600f91602090910190620009eb565b506015829055600a546005546200047f916001600160a01b039182169161010090910416600019620006b2602090811b62002a3317901c565b505050505050505062000fa7565b6005546001600160a01b031615620004b95760405162461bcd60e51b81526004016200007d9062000d87565b600180546001600160a01b0319166001600160a01b03868116919091179182905560408051637e062a3560e11b81529051929091169163fc0c546a91600480820192602092909190829003018186803b1580156200051657600080fd5b505afa1580156200052b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000551919062000af2565b600580546001600160a01b0319166001600160a01b0392831617908190556200058b911685600019620006b2602090811b62002a3317901c565b600280546001600160a01b038086166001600160a01b0319928316179092556003805485841690831617908190556004805485851693169290921782556000600681905562015180600755606460085560095560015460405163095ea7b360e01b81529084169363095ea7b3936200060c9390911691600019910162000cf9565b602060405180830381600087803b1580156200062757600080fd5b505af11580156200063c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000662919062000c63565b5050505050565b6000826200067a57506000620006ac565b828202828482816200068857fe5b0414620006a95760405162461bcd60e51b81526004016200007d9062000df5565b90505b92915050565b801580620007415750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e90620006eb903090869060040162000cdf565b60206040518083038186803b1580156200070457600080fd5b505afa15801562000719573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200073f919062000c85565b155b620007605760405162461bcd60e51b81526004016200007d9062000eb7565b620007bb8363095ea7b360e01b84846040516024016200078292919062000cf9565b60408051808303601f190181529190526020810180516001600160e01b0319939093166001600160e01b0393841617905290620007c016565b505050565b60606200081c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200085c60201b62002b32179092919060201c565b805190915015620007bb57808060200190518101906200083d919062000c63565b620007bb5760405162461bcd60e51b81526004016200007d9062000e6d565b60606200086d848460008562000875565b949350505050565b6060620008828562000947565b620008a15760405162461bcd60e51b81526004016200007d9062000e36565b60006060866001600160a01b03168587604051620008c0919062000cc1565b60006040518083038185875af1925050503d8060008114620008ff576040519150601f19603f3d011682016040523d82523d6000602084013e62000904565b606091505b509150915081156200091a5791506200086d9050565b8051156200092b5780518082602001fd5b8360405162461bcd60e51b81526004016200007d919062000d1b565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906200086d575050151592915050565b828054828255906000526020600020908101928215620009d9579160200282015b82811115620009d957825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620009a2565b50620009e792915062000a37565b5090565b82805482825590600052602060002090810192821562000a29579160200282015b8281111562000a2957825182559160200191906001019062000a0c565b50620009e792915062000a58565b5b80821115620009e75780546001600160a01b031916815560010162000a38565b5b80821115620009e7576000815560010162000a59565b600082601f83011262000a80578081fd5b815162000a9762000a918262000f3b565b62000f14565b81815291506020808301908481018184028601820187101562000ab957600080fd5b60005b8481101562000ada5781518452928201929082019060010162000abc565b505050505092915050565b8051620006ac8162000f8e565b60006020828403121562000b04578081fd5b8151620006a98162000f8e565b600080600080600080600060e0888a03121562000b2c578283fd5b875162000b398162000f8e565b602089015190975062000b4c8162000f8e565b604089015190965062000b5f8162000f8e565b80955050606088015193506080880151925060a0880151915060c0880151905092959891949750929550565b60008060006060848603121562000ba0578283fd5b83516001600160401b038082111562000bb7578485fd5b818601915086601f83011262000bcb578485fd5b815162000bdc62000a918262000f3b565b80828252602080830192508086018b82838702890101111562000bfd57898afd5b8996505b8487101562000c2b5762000c168c8262000ae5565b84526001969096019592810192810162000c01565b50890151909750935050508082111562000c43578384fd5b5062000c528682870162000a6f565b925050604084015190509250925092565b60006020828403121562000c75578081fd5b81518015158114620006a9578182fd5b60006020828403121562000c97578081fd5b5051919050565b60006020828403121562000cb0578081fd5b815160ff81168114620006a9578182fd5b6000825162000cd581846020870162000f5b565b9190910192915050565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b90815260200190565b600060208252825180602084015262000d3c81604085016020870162000f5b565b601f01601f19169190910160400192915050565b6020808252601d908201527f537472617465677920616c726561647920696e697469616c697a656421000000604082015260600190565b6020808252601c908201527f537472617465677920616c726561647920696e697469616c697a656400000000604082015260600190565b6020808252601c908201527f746f6b656e206e6f7420737570706f7274656420696e20706f6f6c2100000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000606082015260800190565b6040518181016001600160401b038111828210171562000f3357600080fd5b604052919050565b60006001600160401b0382111562000f51578081fd5b5060209081020190565b60005b8381101562000f7857818101518382015260200162000f5e565b8381111562000f88576000848401525b50505050565b6001600160a01b038116811462000fa457600080fd5b50565b6152a78062000fb76000396000f3fe6080604052600436106103035760003560e01c80637bb7bed111610190578063bd28f351116100dc578063dbbb64b911610095578063efbb5cb01161006f578063efbb5cb014610808578063f017c92f1461081d578063fbfa77cf1461083d578063fcf2d0ad146108525761030a565b8063dbbb64b9146107b3578063ec38a862146107c8578063ed882c2b146107e85761030a565b8063bd28f3511461071f578063c1a3d44c14610734578063c7b9d53014610749578063ca72280414610769578063ce5494bb1461077e578063d55f92731461079e5761030a565b80638e6350e21161014957806395e80c501161012357806395e80c50146106be5780639ec5a894146106d3578063aced1661146106e8578063b8fe6b6c146106fd5761030a565b80638e6350e2146106745780638ebff3781461068957806391397ab41461069e5761030a565b80637bb7bed1146105c85780637d0d53ea146105e85780637ece45e8146105fd5780638951e3bb1461061d5780638cdfe1661461063d5780638e499bcf146106525761030a565b806339a172a81161024f5780635641ec03116102085780636c4c2d56116101e25780636c4c2d561461055e5780637349996a14610573578063748747e614610588578063750521f5146105a85761030a565b80635641ec0314610514578063650d1880146105295780636c4a3c2a146105495761030a565b806339a172a81461048b5780633fa60d02146104ab578063440368a3146104c05780634641257d146104d55780635199283c146104ea578063546af3c3146104ff5761030a565b80631f1fcd51116102bc5780632582941011610296578063258294101461042157806328b7ccf7146104365780632c3a87591461044b5780632e1a7d4d1461046b5761030a565b80631f1fcd51146103d55780631fe4a686146103ea57806322f3e2d4146103ff5761030a565b806301681a621461030f57806303ee438c1461033157806306fdde031461035c5780630f969b8714610371578063158274a5146103915780631d12f28b146103b35761030a565b3661030a57005b600080fd5b34801561031b57600080fd5b5061032f61032a36600461441e565b610867565b005b34801561033d57600080fd5b50610346610a06565b6040516103539190614dbd565b60405180910390f35b34801561036857600080fd5b50610346610a94565b34801561037d57600080fd5b5061032f61038c366004614832565b610bc4565b34801561039d57600080fd5b506103a6610c51565b6040516103539190614afd565b3480156103bf57600080fd5b506103c8610c65565b6040516103539190614bfa565b3480156103e157600080fd5b506103a6610c6b565b3480156103f657600080fd5b506103a6610c7a565b34801561040b57600080fd5b50610414610c89565b6040516103539190614bef565b34801561042d57600080fd5b50610346610d2b565b34801561044257600080fd5b506103c8610d4a565b34801561045757600080fd5b506103c8610466366004614832565b610d50565b34801561047757600080fd5b506103c8610486366004614832565b610df0565b34801561049757600080fd5b5061032f6104a6366004614832565b610e4b565b3480156104b757600080fd5b506103c8610ecd565b3480156104cc57600080fd5b5061032f611145565b3480156104e157600080fd5b5061032f61136e565b3480156104f657600080fd5b5061032f6116d8565b34801561050b57600080fd5b506103a6611955565b34801561052057600080fd5b50610414611964565b34801561053557600080fd5b50610414610544366004614832565b61196d565b34801561055557600080fd5b506103c86119a0565b34801561056a57600080fd5b506103c86119a6565b34801561057f57600080fd5b506103c86119ac565b34801561059457600080fd5b5061032f6105a336600461441e565b6119b2565b3480156105b457600080fd5b5061032f6105c33660046146c7565b611a5d565b3480156105d457600080fd5b506103a66105e3366004614832565b611af4565b3480156105f457600080fd5b506103c8611b1b565b34801561060957600080fd5b5061032f610618366004614862565b611b21565b34801561062957600080fd5b5061032f610638366004614456565b611d1d565b34801561064957600080fd5b506103c8612001565b34801561065e57600080fd5b50610667612007565b6040516103539190614d80565b34801561068057600080fd5b506103c8612010565b34801561069557600080fd5b506103c8612015565b3480156106aa57600080fd5b5061032f6106b9366004614832565b61201b565b3480156106ca57600080fd5b506103c861209d565b3480156106df57600080fd5b506103a66120a3565b3480156106f457600080fd5b506103a66120b2565b34801561070957600080fd5b506107126120c1565b6040516103539190614b44565b34801561072b57600080fd5b506103c86121da565b34801561074057600080fd5b506103c86121e0565b34801561075557600080fd5b5061032f61076436600461441e565b612261565b34801561077557600080fd5b506103c861230c565b34801561078a57600080fd5b5061032f61079936600461441e565b61233d565b3480156107aa57600080fd5b506106676124ab565b3480156107bf57600080fd5b506103c86124b9565b3480156107d457600080fd5b5061032f6107e336600461441e565b6124bf565b3480156107f457600080fd5b50610414610803366004614832565b612656565b34801561081457600080fd5b506103c8612860565b34801561082957600080fd5b5061032f610838366004614832565b61287b565b34801561084957600080fd5b506103a66128fd565b34801561085e57600080fd5b5061032f61290c565b61086f612b49565b6001600160a01b0316336001600160a01b0316146108a85760405162461bcd60e51b815260040161089f90614fa2565b60405180910390fd5b6005546001600160a01b03828116911614156108d65760405162461bcd60e51b815260040161089f90614df5565b6001546001600160a01b03828116911614156109045760405162461bcd60e51b815260040161089f90614ee3565b606061090e612bc6565b905060005b81518110156109695781818151811061092857fe5b60200260200101516001600160a01b0316836001600160a01b031614156109615760405162461bcd60e51b815260040161089f90615011565b600101610913565b50610a02610975612b49565b6040516370a0823160e01b81526001600160a01b038516906370a08231906109a1903090600401614afd565b60206040518083038186803b1580156109b957600080fd5b505afa1580156109cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f1919061484a565b6001600160a01b0385169190612bcb565b5050565b6000805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610a8c5780601f10610a6157610100808354040283529160200191610a8c565b820191906000526020600020905b815481529060010190602001808311610a6f57829003601f168201915b505050505081565b600b54604080516395d89b4160e01b815290516060926001600160a01b0316916395d89b41916004808301926000929190829003018186803b158015610ad957600080fd5b505afa158015610aed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b159190810190614734565b600560009054906101000a90046001600160a01b03166001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015610b6357600080fd5b505afa158015610b77573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b9f9190810190614734565b604051602001610bb0929190614a9d565b604051602081830303815290604052905090565b6002546001600160a01b0316331480610bf55750610be0612b49565b6001600160a01b0316336001600160a01b0316145b610c115760405162461bcd60e51b815260040161089f90614fa2565b60098190556040517fa68ba126373d04c004c5748c300c9fca12bd444b3d4332e261f3bd2bac4a860090610c46908390614bfa565b60405180910390a150565b600a5461010090046001600160a01b031681565b60095481565b6005546001600160a01b031681565b6002546001600160a01b031681565b6001546040516339ebf82360e01b815260009182916001600160a01b03909116906339ebf82390610cbe903090600401614afd565b6101006040518083038186803b158015610cd757600080fd5b505afa158015610ceb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0f91906147c0565b604001511180610d2657506000610d24612860565b115b905090565b6040805180820190915260058152640302e332e360dc1b602082015290565b60075481565b6000600c8281548110610d5f57fe5b6000918252602090912001546040516370a0823160e01b81526001600160a01b03909116906370a0823190610d98903090600401614afd565b60206040518083038186803b158015610db057600080fd5b505afa158015610dc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de8919061484a565b90505b919050565b6001546000906001600160a01b03163314610e1d5760405162461bcd60e51b815260040161089f90614ec3565b6000610e2883612bea565b600554909350909150610e45906001600160a01b03163383612bcb565b50919050565b6002546001600160a01b0316331480610e7c5750610e67612b49565b6001600160a01b0316336001600160a01b0316145b610e985760405162461bcd60e51b815260040161089f90614fa2565b60068190556040517fbb2c369a0355a34b02ab5fce0643150c87e1c8dfe7c918d465591879f57948b190610c46908390614bfa565b6000806060806000600a60019054906101000a90046001600160a01b03166001600160a01b031663f94d46686010546040518263ffffffff1660e01b8152600401610f189190614bfa565b60006040518083038186803b158015610f3057600080fd5b505afa158015610f44573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f6c919081019061454c565b92509250925060005b60115460ff908116908216101561113b576000611047600b60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610fd957600080fd5b505afa158015610fed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611011919061484a565b61104161101c61230c565b878660ff168151811061102b57fe5b60200260200101516129f090919063ffffffff16565b90612c88565b90508015611132576000858360ff168151811061106057fe5b60209081029190910101516005549091506001600160a01b0380831691161461112c5761108b614095565b611096828487612cca565b600b5460115460405162f64aa560e11b81529293506001600160a01b03909116916301ec954a916110d89185918b918a91610100900460ff16906004016150c2565b60206040518083038186803b1580156110f057600080fd5b505afa158015611104573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611128919061484a565b9250505b50948501945b50600101610f75565b5092935050505090565b6004546001600160a01b031633148061116857506002546001600160a01b031633145b8061118b5750611176612b49565b6001600160a01b0316336001600160a01b0316145b8061122c5750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b1580156111df57600080fd5b505afa1580156111f3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611217919061443a565b6001600160a01b0316336001600160a01b0316145b806112cd5750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b15801561128057600080fd5b505afa158015611294573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112b8919061443a565b6001600160a01b0316336001600160a01b0316145b6112e95760405162461bcd60e51b815260040161089f90614fa2565b6001546040805163bf3759b560e01b8152905161136c926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b15801561132f57600080fd5b505afa158015611343573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611367919061484a565b612d52565b565b6004546001600160a01b031633148061139157506002546001600160a01b031633145b806113b4575061139f612b49565b6001600160a01b0316336001600160a01b0316145b806114555750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b15801561140857600080fd5b505afa15801561141c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611440919061443a565b6001600160a01b0316336001600160a01b0316145b806114f65750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b1580156114a957600080fd5b505afa1580156114bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e1919061443a565b6001600160a01b0316336001600160a01b0316145b6115125760405162461bcd60e51b815260040161089f90614fa2565b6000806000600160009054906101000a90046001600160a01b03166001600160a01b031663bf3759b56040518163ffffffff1660e01b815260040160206040518083038186803b15801561156557600080fd5b505afa158015611579573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159d919061484a565b600a5490915060009060ff16156115f35760006115b8612860565b90506115d18382116115ca57836115cc565b815b612bea565b94509150828211156115ed576115e7828461303d565b94508291505b50611604565b6115fc8261307f565b919550935090505b6001546040516328766ebf60e21b81526001600160a01b039091169063a1d9bafc90611638908790879086906004016151a3565b602060405180830381600087803b15801561165257600080fd5b505af1158015611666573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168a919061484a565b915061169582612d52565b7f4c0f499ffe6befa0ca7c826b0916cf87bea98de658013e76938489368d60d509848483856040516116ca94939291906151b9565b60405180910390a150505050565b6004546001600160a01b03163314806116fb57506002546001600160a01b031633145b8061171e5750611709612b49565b6001600160a01b0316336001600160a01b0316145b806117bf5750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b15801561177257600080fd5b505afa158015611786573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117aa919061443a565b6001600160a01b0316336001600160a01b0316145b806118605750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b15801561181357600080fd5b505afa158015611827573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184b919061443a565b6001600160a01b0316336001600160a01b0316145b61187c5760405162461bcd60e51b815260040161089f90614fa2565b60005b600c5481101561193157600c818154811061189657fe5b6000918252602082200154600a5460405163095ea7b360e01b81526001600160a01b039283169363095ea7b3936118d69361010090041691600401614b2b565b602060405180830381600087803b1580156118f057600080fd5b505af1158015611904573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192891906146a7565b5060010161187f565b506060805161194590600c906080906140e5565b50611952600e600061414a565b50565b600b546001600160a01b031681565b600a5460ff1681565b60006015546119876016544261303d90919063ffffffff16565b118015610de8575060006119996121e0565b1192915050565b60135481565b60145481565b60155481565b6002546001600160a01b03163314806119e357506119ce612b49565b6001600160a01b0316336001600160a01b0316145b6119ff5760405162461bcd60e51b815260040161089f90614fa2565b6001600160a01b038116611a1257600080fd5b600480546001600160a01b0319166001600160a01b0383161790556040517f2f202ddb4a2e345f6323ed90f8fc8559d770a7abbbeee84dde8aca3351fe715490610c46908390614afd565b6002546001600160a01b0316331480611a8e5750611a79612b49565b6001600160a01b0316336001600160a01b0316145b611aaa5760405162461bcd60e51b815260040161089f90614fa2565b611ab66000838361416b565b507f300e67d5a415b6d015a471d9c7b95dd58f3e8290af965e84e0f845de2996dda68282604051611ae8929190614d8e565b60405180910390a15050565b600c8181548110611b0157fe5b6000918252602090912001546001600160a01b0316905081565b600c5490565b6004546001600160a01b0316331480611b4457506002546001600160a01b031633145b80611b675750611b52612b49565b6001600160a01b0316336001600160a01b0316145b80611c085750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b158015611bbb57600080fd5b505afa158015611bcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf3919061443a565b6001600160a01b0316336001600160a01b0316145b80611ca95750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b158015611c5c57600080fd5b505afa158015611c70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c94919061443a565b6001600160a01b0316336001600160a01b0316145b611cc55760405162461bcd60e51b815260040161089f90614fa2565b612710841115611ce75760405162461bcd60e51b815260040161089f90614f3b565b6012849055612710831115611d0e5760405162461bcd60e51b815260040161089f90615035565b60139290925560145560155550565b6004546001600160a01b0316331480611d4057506002546001600160a01b031633145b80611d635750611d4e612b49565b6001600160a01b0316336001600160a01b0316145b80611e045750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b158015611db757600080fd5b505afa158015611dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611def919061443a565b6001600160a01b0316336001600160a01b0316145b80611ea55750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b158015611e5857600080fd5b505afa158015611e6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e90919061443a565b6001600160a01b0316336001600160a01b0316145b611ec15760405162461bcd60e51b815260040161089f90614fa2565b600a5460405163095ea7b360e01b815283916001600160a01b038084169263095ea7b392611efd92610100909104169060001990600401614b2b565b602060405180830381600087803b158015611f1757600080fd5b505af1158015611f2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f4f91906146a7565b50600c805460018181019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180546001600160a01b0384166001600160a01b0319909116179055600e805491820181556000528251805184926002027fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0191611fe0918391602001906141e5565b506020828101518051611ff992600185019201906140e5565b505050505050565b60085481565b60115460ff1681565b600090565b60125481565b6002546001600160a01b031633148061204c5750612037612b49565b6001600160a01b0316336001600160a01b0316145b6120685760405162461bcd60e51b815260040161089f90614fa2565b60088190556040517fd94596337df4c2f0f44d30a7fc5db1c7bb60d9aca4185ed77c6fd96eb45ec29890610c46908390614bfa565b60065481565b6003546001600160a01b031681565b6004546001600160a01b031681565b6060600e805480602002602001604051908101604052809291908181526020016000905b828210156121d157838290600052602060002090600202016040518060400160405290816000820180548060200260200160405190810160405280929190818152602001828054801561215757602002820191906000526020600020905b815481526020019060010190808311612143575b50505050508152602001600182018054806020026020016040519081016040528092919081815260200182805480156121b957602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161219b575b505050505081525050815260200190600101906120e5565b50505050905090565b60165481565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612211903090600401614afd565b60206040518083038186803b15801561222957600080fd5b505afa15801561223d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d26919061484a565b6002546001600160a01b0316331480612292575061227d612b49565b6001600160a01b0316336001600160a01b0316145b6122ae5760405162461bcd60e51b815260040161089f90614fa2565b6001600160a01b0381166122c157600080fd5b600280546001600160a01b0319166001600160a01b0383161790556040517f352ececae6d7d1e6d26bcf2c549dfd55be1637e9b22dc0cf3b71ddb36097a6b490610c46908390614afd565b600b546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612211903090600401614afd565b6001546001600160a01b031633148061236e5750612359612b49565b6001600160a01b0316336001600160a01b0316145b61237757600080fd5b6001546040805163fbfa77cf60e01b815290516001600160a01b039283169284169163fbfa77cf916004808301926020929190829003018186803b1580156123be57600080fd5b505afa1580156123d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123f6919061443a565b6001600160a01b03161461240957600080fd5b61241281613102565b6005546040516370a0823160e01b81526119529183916001600160a01b03909116906370a0823190612448903090600401614afd565b60206040518083038186803b15801561246057600080fd5b505afa158015612474573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612498919061484a565b6005546001600160a01b03169190612bcb565b601154610100900460ff1681565b60105481565b6002546001600160a01b031633146124e95760405162461bcd60e51b815260040161089f90614dd0565b6001600160a01b0381166124fc57600080fd5b60015460035460405163095ea7b360e01b81526001600160a01b039283169263095ea7b39261253392911690600090600401614b2b565b602060405180830381600087803b15801561254d57600080fd5b505af1158015612561573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258591906146a7565b50600380546001600160a01b0319166001600160a01b03838116919091179182905560015460405163095ea7b360e01b81529082169263095ea7b3926125d49291169060001990600401614b2b565b602060405180830381600087803b1580156125ee57600080fd5b505af1158015612602573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061262691906146a7565b507fafbb66abf8f3b719799940473a4052a3717cdd8e40fb6c8a3faadab316b1a06981604051610c469190614afd565b60008060005b600c5460ff82161015612846576000600c8260ff168154811061267b57fe5b60009182526020808320909101546040805163313ce56760e01b815290516001600160a01b039092169450849263313ce56792600480840193829003018186803b1580156126c857600080fd5b505afa1580156126dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127009190614893565b60ff1690506000600560009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561275557600080fd5b505afa158015612769573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278d9190614893565b60ff1690508082116127a05760006127aa565b6127aa828261303d565b600a0a836001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016127d99190614afd565b60206040518083038186803b1580156127f157600080fd5b505afa158015612805573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612829919061484a565b111561283b5760019450505050612846565b50505060010161265c565b50612850836132c7565b80156128595750805b9392505050565b6000610d2661286d610ecd565b6128756121e0565b9061353f565b6002546001600160a01b03163314806128ac5750612897612b49565b6001600160a01b0316336001600160a01b0316145b6128c85760405162461bcd60e51b815260040161089f90614fa2565b60078190556040517f5430e11864ad7aa9775b07d12657fe52df9aa2ba734355bd8ef8747be2c800c590610c46908390614bfa565b6001546001600160a01b031681565b6002546001600160a01b031633148061293d5750612928612b49565b6001600160a01b0316336001600160a01b0316145b6129595760405162461bcd60e51b815260040161089f90614fa2565b600a805460ff19166001908117909155546040805163507257cd60e11b815290516001600160a01b039092169163a0e4af9a9160048082019260009290919082900301818387803b1580156129ad57600080fd5b505af11580156129c1573d6000803e3d6000fd5b50506040517f97e963041e952738788b9d4871d854d282065b8f90a464928d6528f2e9a4fd0b925060009150a1565b6000826129ff57506000612a2d565b82820282848281612a0c57fe5b0414612a2a5760405162461bcd60e51b815260040161089f90614e82565b90505b92915050565b801580612abb5750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e90612a699030908690600401614b11565b60206040518083038186803b158015612a8157600080fd5b505afa158015612a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ab9919061484a565b155b612ad75760405162461bcd60e51b815260040161089f9061506c565b612b2d8363095ea7b360e01b8484604051602401612af6929190614b2b565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613564565b505050565b6060612b4184846000856135f3565b949350505050565b60015460408051635aa6e67560e01b815290516000926001600160a01b031691635aa6e675916004808301926020929190829003018186803b158015612b8e57600080fd5b505afa158015612ba2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d26919061443a565b606090565b612b2d8363a9059cbb60e01b8484604051602401612af6929190614b2b565b60008082612bf6612860565b1015612c1a57612c046136b7565b915081612c11848261303d565b91509150612c83565b6000612c246121e0565b905080841115612c7d576000612c3a858361303d565b9050612c4581613869565b612c56612c506121e0565b86613a51565b9350612c62858561303d565b9250612c7781612c72868561303d565b613a67565b50612c81565b8392505b505b915091565b6000612a2a83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613ac2565b612cd2614095565b604080516101208101825260008082526001600160a01b038088166020808501919091526005549091168385015260608301879052601054608084015260a083018690523060c0840181905260e084015292519192610100840192612d38929101614d80565b60408051601f198184030181529190529052949350505050565b60155460165442031015612d6557611952565b6000612d6f610ecd565b60115490915060609060ff1667ffffffffffffffff81118015612d9157600080fd5b50604051908082528060200260200182016040528015612dbb578160200160208202803683370190505b5090506000612dd3601454612dce6121e0565b613a51565b601154835191925082918491610100900460ff16908110612df057fe5b602002602001018181525050600082601160019054906101000a900460ff1660ff1681518110612e1c57fe5b602002602001015111156130375760115460609060ff1667ffffffffffffffff81118015612e4957600080fd5b50604051908082528060200260200182016040528015612e73578160200160208202803683370190505b50601154815191925083918391610100900460ff16908110612e9157fe5b60200260200101818152505060606001826000604051602001612eb693929190614c96565b6040516020818303038152906040529050612ecf614220565b60408051600d805460a060208202840181019094526080830181815292938493929190840182828015612f2b57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612f0d575b50505091835250506020810187905260408082018590526000606090920191909152600a54601054915163172b958560e31b815292935061010090046001600160a01b03169163b95cac2891612f8991309081908790600401614c03565b600060405180830381600087803b158015612fa357600080fd5b505af1158015612fb7573d6000803e3d6000fd5b505050506000612fcf87612fc9610ecd565b9061303d565b90506000818611612fe1576000612feb565b612feb868361303d565b9050600061300a6127106110416012548a6129f090919063ffffffff16565b90508082111561302c5760405162461bcd60e51b815260040161089f90614e4b565b505042601655505050505b50505050565b6000612a2a83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613af9565b6000808083156130975761309284612bea565b925090505b60006130a16121e0565b90506130ab613b25565b6130b3613bdb565b60006130bd6121e0565b90506130c9818361303d565b9450838511156130e8576130dd858561303d565b9450600093506130f9565b6130f2848661303d565b9350600094505b50509193909250565b600b546001600160a01b031663a9059cbb8261311c61230c565b6040518363ffffffff1660e01b8152600401613139929190614b2b565b602060405180830381600087803b15801561315357600080fd5b505af1158015613167573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061318b91906146a7565b5060005b600c54811015610a02576000600c82815481106131a857fe5b60009182526020822001546040516370a0823160e01b81526001600160a01b03909116925082906370a08231906131e3903090600401614afd565b60206040518083038186803b1580156131fb57600080fd5b505afa15801561320f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613233919061484a565b905080156132bd5760405163a9059cbb60e01b81526001600160a01b0383169063a9059cbb906132699087908590600401614b2b565b602060405180830381600087803b15801561328357600080fd5b505af1158015613297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132bb91906146a7565b505b505060010161318f565b60006132d161424a565b6001546040516339ebf82360e01b81526001600160a01b03909116906339ebf82390613301903090600401614afd565b6101006040518083038186803b15801561331a57600080fd5b505afa15801561332e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061335291906147c0565b905080602001516000141561336b576000915050610deb565b600654608082015161337e90429061303d565b101561338e576000915050610deb565b60075460808201516133a190429061303d565b106133b0576001915050610deb565b6001546040805163bf3759b560e01b815290516000926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b1580156133f557600080fd5b505afa158015613409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061342d919061484a565b905060095481111561344457600192505050610deb565b600061344e612860565b90508260a0015161346a6009548361353f90919063ffffffff16565b101561347c5760019350505050610deb565b60008360a0015182111561349d5760a084015161349a90839061303d565b90505b6001546040805163112c1f9b60e01b815290516000926001600160a01b03169163112c1f9b916004808301926020929190829003018186803b1580156134e257600080fd5b505afa1580156134f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061351a919061484a565b9050613526818361353f565b60085461353390896129f0565b10979650505050505050565b600082820183811015612a2a5760405162461bcd60e51b815260040161089f90614e14565b60606135b9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612b329092919063ffffffff16565b805190915015612b2d57808060200190518101906135d791906146a7565b612b2d5760405162461bcd60e51b815260040161089f90614fc7565b60606135fe8561405c565b61361a5760405162461bcd60e51b815260040161089f90614f6b565b60006060866001600160a01b031685876040516136379190614a81565b60006040518083038185875af1925050503d8060008114613674576040519150601f19603f3d011682016040523d82523d6000602084013e613679565b606091505b5091509150811561368d579150612b419050565b80511561369d5780518082602001fd5b8360405162461bcd60e51b815260040161089f9190614dbd565b6000806136c2612860565b905060006136ce61230c565b90508015613850576060600082601160019054906101000a900460ff166040516020016136fd93929190614c70565b6040516020818303038152906040529050613716614220565b60408051600d805460a06020820284018101909452608083018181529293849392919084018282801561377257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613754575b50505050508152602001600f8054806020026020016040519081016040528092919081815260200182805480156137c857602002820191906000526020600020905b8154815260200190600101908083116137b4575b5050509183525050602081018490526000604091820152600a546010549151638bdb391360e01b815292935061010090046001600160a01b031691638bdb39139161381b91309081908790600401614c03565b600060405180830381600087803b15801561383557600080fd5b505af1158015613849573d6000803e3d6000fd5b5050505050505b6138586121e0565b92506138648284613a67565b505090565b60115460609060ff1667ffffffffffffffff8111801561388857600080fd5b506040519080825280602002602001820160405280156138b2578160200160208202803683370190505b50601154815191925083918391610100900460ff169081106138d057fe5b60200260200101818152505060606002826138e961230c565b6040516020016138fb93929190614c3f565b6040516020818303038152906040529050613914614220565b60408051600d805460a06020820284018101909452608083018181529293849392919084018282801561397057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613952575b50505050508152602001600f8054806020026020016040519081016040528092919081815260200182805480156139c657602002820191906000526020600020905b8154815260200190600101908083116139b2575b5050509183525050602081018490526000604091820152600a546010549151638bdb391360e01b815292935061010090046001600160a01b031691638bdb391391613a1991309081908790600401614c03565b600060405180830381600087803b158015613a3357600080fd5b505af1158015613a47573d6000803e3d6000fd5b5050505050505050565b6000818310613a605781612a2a565b5090919050565b6000818311613a77576000613a81565b613a81838361303d565b90506000613aa0612710611041601354876129f090919063ffffffff16565b9050808211156130375760405162461bcd60e51b815260040161089f90614f04565b60008183613ae35760405162461bcd60e51b815260040161089f9190614dbd565b506000838581613aef57fe5b0495945050505050565b60008184841115613b1d5760405162461bcd60e51b815260040161089f9190614dbd565b505050900390565b6000613b2f612860565b6001546040516339ebf82360e01b81529192506000916001600160a01b03909116906339ebf82390613b65903090600401614afd565b6101006040518083038186803b158015613b7e57600080fd5b505afa158015613b92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb691906147c0565b60a00151905080821115610a02576000613bd0838361303d565b9050612b2d81613869565b60005b600c5460ff82161015611952576000600c8260ff1681548110613bfd57fe5b60009182526020822001546040516370a0823160e01b81526001600160a01b03909116925082906370a0823190613c38903090600401614afd565b60206040518083038186803b158015613c5057600080fd5b505afa158015613c64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c88919061484a565b90506000826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015613cc557600080fd5b505afa158015613cd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cfd9190614893565b60ff1690506000600560009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015613d5257600080fd5b505afa158015613d66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d8a9190614893565b60ff169050808211613d9d576000613da7565b613da7828261303d565b600a0a83111561404c576000600e8660ff1681548110613dc357fe5b6000918252602090912060029091020154905060608167ffffffffffffffff81118015613def57600080fd5b50604051908082528060200260200182016040528015613e2957816020015b613e1661428f565b815260200190600190039081613e0e5790505b50905060608260010167ffffffffffffffff81118015613e4857600080fd5b50604051908082528060200260200182016040528015613e72578160200160208202803683370190505b5090508581600081518110613e8357fe5b60200260200101818152505060005b83811015613f49576040518060a00160405280600e8b60ff1681548110613eb557fe5b90600052602060002090600202016000018381548110613ed157fe5b9060005260206000200154815260200182815260200182600101815260200182600014613eff576000613f01565b885b81526020016000604051602001613f189190614d80565b604051602081830303815290604052815250838281518110613f3657fe5b6020908102919091010152600101613e92565b50600a60019054906101000a90046001600160a01b03166001600160a01b031663945bcec9600084600e8c60ff1681548110613f8157fe5b90600052602060002090600202016001016040518060800160405280306001600160a01b03168152602001600015158152602001306001600160a01b03168152602001600015158152508642600a016040518763ffffffff1660e01b8152600401613ff196959493929190614ccc565b600060405180830381600087803b15801561400b57600080fd5b505af115801561401f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526140479190810190614617565b505050505b505060019092019150613bde9050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612b41575050151592915050565b60408051610120810190915280600081526000602082018190526040820181905260608083018290526080830182905260a0830182905260c0830182905260e08301919091526101009091015290565b82805482825590600052602060002090810192821561413a579160200282015b8281111561413a57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614105565b506141469291506142c1565b5090565b508054600082556002029060005260206000209081019061195291906142e0565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106141ac5782800160ff198235161785556141d9565b828001600101855582156141d9579182015b828111156141d95782358255916020019190600101906141be565b5061414692915061430b565b8280548282559060005260206000209081019282156141d9579160200282015b828111156141d9578251825591602001919060010190614205565b60405180608001604052806060815260200160608152602001606081526020016000151581525090565b60405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060a0016040528060008019168152602001600081526020016000815260200160008152602001606081525090565b5b808211156141465780546001600160a01b03191681556001016142c2565b808211156141465760006142f48282614320565b614302600183016000614320565b506002016142e0565b5b80821115614146576000815560010161430c565b5080546000825590600052602060002090810190611952919061430b565b600082601f83011261434e578081fd5b813561436161435c826151fb565b6151d4565b81815291506020808301908481018184028601820187101561438257600080fd5b60005b848110156143aa5781356143988161525c565b84529282019290820190600101614385565b505050505092915050565b600082601f8301126143c5578081fd5b81516143d361435c826151fb565b8181529150602080830190848101818402860182018710156143f457600080fd5b60005b848110156143aa578151845292820192908201906001016143f7565b8051612a2d8161525c565b60006020828403121561442f578081fd5b8135612a2a8161525c565b60006020828403121561444b578081fd5b8151612a2a8161525c565b60008060408385031215614468578081fd5b82356144738161525c565b915060208381013567ffffffffffffffff80821115614490578384fd5b90850190604082880312156144a3578384fd5b6144ad60406151d4565b8235828111156144bb578586fd5b8301601f810189136144cb578586fd5b80356144d961435c826151fb565b81815286810190838801888402850189018d10156144f557898afd5b8994505b838510156145175780358352600194909401939188019188016144f9565b508452505050828401358281111561452d578586fd5b6145398982860161433e565b8583015250809450505050509250929050565b600080600060608486031215614560578081fd5b835167ffffffffffffffff80821115614577578283fd5b818601915086601f83011261458a578283fd5b815161459861435c826151fb565b80828252602080830192508086018b8283870289010111156145b8578788fd5b8796505b848710156145e2576145ce8c82614413565b8452600196909601959281019281016145bc565b5089015190975093505050808211156145f9578283fd5b50614606868287016143b5565b925050604084015190509250925092565b60006020808385031215614629578182fd5b825167ffffffffffffffff81111561463f578283fd5b8301601f8101851361464f578283fd5b805161465d61435c826151fb565b8181528381019083850185840285018601891015614679578687fd5b8694505b8385101561469b57805183526001949094019391850191850161467d565b50979650505050505050565b6000602082840312156146b8578081fd5b81518015158114612a2a578182fd5b600080602083850312156146d9578182fd5b823567ffffffffffffffff808211156146f0578384fd5b818501915085601f830112614703578384fd5b813581811115614711578485fd5b866020828501011115614722578485fd5b60209290920196919550909350505050565b600060208284031215614745578081fd5b815167ffffffffffffffff8082111561475c578283fd5b818401915084601f83011261476f578283fd5b81518181111561477d578384fd5b614790601f8201601f19166020016151d4565b91508082528560208285010111156147a6578384fd5b6147b7816020840160208601615226565b50949350505050565b60006101008083850312156147d3578182fd5b6147dc816151d4565b9050825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201528091505092915050565b600060208284031215614843578081fd5b5035919050565b60006020828403121561485b578081fd5b5051919050565b60008060008060808587031215614877578182fd5b5050823594602084013594506040840135936060013592509050565b6000602082840312156148a4578081fd5b815160ff81168114612a2a578182fd5b6001600160a01b03169052565b6000815180845260208085019450808401835b838110156148f95781516001600160a01b0316875295820195908201906001016148d4565b509495945050505050565b6000815480845260208085019450838352808320835b838110156148f95781546001600160a01b03168752958201956001918201910161491a565b6000815180845260208085019450808401835b838110156148f957815187529582019590820190600101614952565b60008151808452614986816020860160208601615226565b601f01601f19169290920160200192915050565b6149a381615252565b9052565b60ff169052565b600081518352602082015160208401526040820151604084015260608201516060840152608082015160a06080850152612b4160a085018261496e565b6000815160808452614a0060808501826148c1565b905060208301518482036020860152614a19828261493f565b91505060408301518482036040860152614a33828261496e565b9150506060830151151560608501528091505092915050565b80516001600160a01b039081168352602080830151151590840152604080830151909116908301526060908101511515910152565b60008251614a93818460208701615226565b9190910192915050565b600073029b4b733b632a9b4b232b22130b630b731b2b9160651b82528351614acc816014850160208801615226565b6402837b7b6160dd1b6014918401918201528351614af1816019840160208801615226565b01601901949350505050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b60208082528251828201819052600091906040908185019080840286018301878501865b83811015614be157888303603f19018552815180518785528051888601819052908901908a9060608701905b80831015614bb45783518252928b019260019290920191908b0190614b94565b50928a0151868403878c015292614bcb81856148c1565b988b019896505050928801925050600101614b68565b509098975050505050505050565b901515815260200190565b90815260200190565b8481526001600160a01b03848116602083015283166040820152608060608201819052600090614c35908301846149eb565b9695505050505050565b6000614c4a8561521b565b825260606020830152614c60606083018561493f565b9050826040830152949350505050565b60608101614c7d8561521b565b825283602083015260ff83166040830152949350505050565b600060048510614ca257fe5b84825260606020830152614cb9606083018561493f565b905060ff83166040830152949350505050565b6000610120808301614cdd8a615252565b898452602080850192909252885190819052610140808501928281028601909101918a8201855b82811015614d335761013f19888603018652614d218583516149ae565b95840195945090830190600101614d04565b505050508381036040850152614d498189614904565b915050614d596060840187614a4c565b82810360e0840152614d6b818661493f565b91505082610100830152979650505050505050565b60ff91909116815260200190565b60006020825282602083015282846040840137818301604090810191909152601f909201601f19160101919050565b600060208252612a2a602083018461496e565b6020808252600b908201526a085cdd1c985d1959da5cdd60aa1b604082015260600190565b602080825260059082015264085dd85b9d60da1b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526017908201527f4578636565646564206d6178536c697070616765496e21000000000000000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b602080825260069082015265085d985d5b1d60d21b604082015260600190565b6020808252600790820152662173686172657360c81b604082015260600190565b60208082526018908201527f4578636565646564206d6178536c6970706167654f7574210000000000000000604082015260600190565b6020808252601690820152750dac2f0a6d8d2e0e0c2ceca92dc40e8dede40d0d2ced60531b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252600b908201526a08585d5d1a1bdc9a5e995960aa1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600a9082015269085c1c9bdd1958dd195960b21b604082015260600190565b60208082526017908201527f6d6178536c6970706167654f757420746f6f2068696768000000000000000000604082015260600190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b6000608082526150d660808301875161499a565b60208601516150e860a08401826148b4565b5060408601516150fb60c08401826148b4565b50606086015160e08301526080860151610100818185015260a08801519150610120828186015260c089015192506151376101408601846148b4565b60e0890151925061514c6101608601846148b4565b8189015192508061018086015250506151696101a084018261496e565b9050828103602084015261517d818761493f565b91505061518d60408301856149a7565b61519a60608301846149a7565b95945050505050565b9283526020830191909152604082015260600190565b93845260208401929092526040830152606082015260800190565b60405181810167ffffffffffffffff811182821017156151f357600080fd5b604052919050565b600067ffffffffffffffff821115615211578081fd5b5060209081020190565b8060038110610deb57fe5b60005b83811015615241578181015183820152602001615229565b838111156130375750506000910152565b6002811061195257fe5b6001600160a01b038116811461195257600080fdfea2646970667358221220b8132eac1c27d87194d17acc03827ffcfe07f7d5eb9cd3eb78d417c4e000138364736f6c634300060c00330000000000000000000000005f18c75abdae578b483e5f43f12a39cf75b973a9000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c800000000000000000000000006df3b2bbb68adc8b0e302443692037ed9f91b420000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000001e84800000000000000000000000000000000000000000000000000000000000000708
Deployed Bytecode
0x6080604052600436106103035760003560e01c80637bb7bed111610190578063bd28f351116100dc578063dbbb64b911610095578063efbb5cb01161006f578063efbb5cb014610808578063f017c92f1461081d578063fbfa77cf1461083d578063fcf2d0ad146108525761030a565b8063dbbb64b9146107b3578063ec38a862146107c8578063ed882c2b146107e85761030a565b8063bd28f3511461071f578063c1a3d44c14610734578063c7b9d53014610749578063ca72280414610769578063ce5494bb1461077e578063d55f92731461079e5761030a565b80638e6350e21161014957806395e80c501161012357806395e80c50146106be5780639ec5a894146106d3578063aced1661146106e8578063b8fe6b6c146106fd5761030a565b80638e6350e2146106745780638ebff3781461068957806391397ab41461069e5761030a565b80637bb7bed1146105c85780637d0d53ea146105e85780637ece45e8146105fd5780638951e3bb1461061d5780638cdfe1661461063d5780638e499bcf146106525761030a565b806339a172a81161024f5780635641ec03116102085780636c4c2d56116101e25780636c4c2d561461055e5780637349996a14610573578063748747e614610588578063750521f5146105a85761030a565b80635641ec0314610514578063650d1880146105295780636c4a3c2a146105495761030a565b806339a172a81461048b5780633fa60d02146104ab578063440368a3146104c05780634641257d146104d55780635199283c146104ea578063546af3c3146104ff5761030a565b80631f1fcd51116102bc5780632582941011610296578063258294101461042157806328b7ccf7146104365780632c3a87591461044b5780632e1a7d4d1461046b5761030a565b80631f1fcd51146103d55780631fe4a686146103ea57806322f3e2d4146103ff5761030a565b806301681a621461030f57806303ee438c1461033157806306fdde031461035c5780630f969b8714610371578063158274a5146103915780631d12f28b146103b35761030a565b3661030a57005b600080fd5b34801561031b57600080fd5b5061032f61032a36600461441e565b610867565b005b34801561033d57600080fd5b50610346610a06565b6040516103539190614dbd565b60405180910390f35b34801561036857600080fd5b50610346610a94565b34801561037d57600080fd5b5061032f61038c366004614832565b610bc4565b34801561039d57600080fd5b506103a6610c51565b6040516103539190614afd565b3480156103bf57600080fd5b506103c8610c65565b6040516103539190614bfa565b3480156103e157600080fd5b506103a6610c6b565b3480156103f657600080fd5b506103a6610c7a565b34801561040b57600080fd5b50610414610c89565b6040516103539190614bef565b34801561042d57600080fd5b50610346610d2b565b34801561044257600080fd5b506103c8610d4a565b34801561045757600080fd5b506103c8610466366004614832565b610d50565b34801561047757600080fd5b506103c8610486366004614832565b610df0565b34801561049757600080fd5b5061032f6104a6366004614832565b610e4b565b3480156104b757600080fd5b506103c8610ecd565b3480156104cc57600080fd5b5061032f611145565b3480156104e157600080fd5b5061032f61136e565b3480156104f657600080fd5b5061032f6116d8565b34801561050b57600080fd5b506103a6611955565b34801561052057600080fd5b50610414611964565b34801561053557600080fd5b50610414610544366004614832565b61196d565b34801561055557600080fd5b506103c86119a0565b34801561056a57600080fd5b506103c86119a6565b34801561057f57600080fd5b506103c86119ac565b34801561059457600080fd5b5061032f6105a336600461441e565b6119b2565b3480156105b457600080fd5b5061032f6105c33660046146c7565b611a5d565b3480156105d457600080fd5b506103a66105e3366004614832565b611af4565b3480156105f457600080fd5b506103c8611b1b565b34801561060957600080fd5b5061032f610618366004614862565b611b21565b34801561062957600080fd5b5061032f610638366004614456565b611d1d565b34801561064957600080fd5b506103c8612001565b34801561065e57600080fd5b50610667612007565b6040516103539190614d80565b34801561068057600080fd5b506103c8612010565b34801561069557600080fd5b506103c8612015565b3480156106aa57600080fd5b5061032f6106b9366004614832565b61201b565b3480156106ca57600080fd5b506103c861209d565b3480156106df57600080fd5b506103a66120a3565b3480156106f457600080fd5b506103a66120b2565b34801561070957600080fd5b506107126120c1565b6040516103539190614b44565b34801561072b57600080fd5b506103c86121da565b34801561074057600080fd5b506103c86121e0565b34801561075557600080fd5b5061032f61076436600461441e565b612261565b34801561077557600080fd5b506103c861230c565b34801561078a57600080fd5b5061032f61079936600461441e565b61233d565b3480156107aa57600080fd5b506106676124ab565b3480156107bf57600080fd5b506103c86124b9565b3480156107d457600080fd5b5061032f6107e336600461441e565b6124bf565b3480156107f457600080fd5b50610414610803366004614832565b612656565b34801561081457600080fd5b506103c8612860565b34801561082957600080fd5b5061032f610838366004614832565b61287b565b34801561084957600080fd5b506103a66128fd565b34801561085e57600080fd5b5061032f61290c565b61086f612b49565b6001600160a01b0316336001600160a01b0316146108a85760405162461bcd60e51b815260040161089f90614fa2565b60405180910390fd5b6005546001600160a01b03828116911614156108d65760405162461bcd60e51b815260040161089f90614df5565b6001546001600160a01b03828116911614156109045760405162461bcd60e51b815260040161089f90614ee3565b606061090e612bc6565b905060005b81518110156109695781818151811061092857fe5b60200260200101516001600160a01b0316836001600160a01b031614156109615760405162461bcd60e51b815260040161089f90615011565b600101610913565b50610a02610975612b49565b6040516370a0823160e01b81526001600160a01b038516906370a08231906109a1903090600401614afd565b60206040518083038186803b1580156109b957600080fd5b505afa1580156109cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f1919061484a565b6001600160a01b0385169190612bcb565b5050565b6000805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610a8c5780601f10610a6157610100808354040283529160200191610a8c565b820191906000526020600020905b815481529060010190602001808311610a6f57829003601f168201915b505050505081565b600b54604080516395d89b4160e01b815290516060926001600160a01b0316916395d89b41916004808301926000929190829003018186803b158015610ad957600080fd5b505afa158015610aed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b159190810190614734565b600560009054906101000a90046001600160a01b03166001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015610b6357600080fd5b505afa158015610b77573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b9f9190810190614734565b604051602001610bb0929190614a9d565b604051602081830303815290604052905090565b6002546001600160a01b0316331480610bf55750610be0612b49565b6001600160a01b0316336001600160a01b0316145b610c115760405162461bcd60e51b815260040161089f90614fa2565b60098190556040517fa68ba126373d04c004c5748c300c9fca12bd444b3d4332e261f3bd2bac4a860090610c46908390614bfa565b60405180910390a150565b600a5461010090046001600160a01b031681565b60095481565b6005546001600160a01b031681565b6002546001600160a01b031681565b6001546040516339ebf82360e01b815260009182916001600160a01b03909116906339ebf82390610cbe903090600401614afd565b6101006040518083038186803b158015610cd757600080fd5b505afa158015610ceb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0f91906147c0565b604001511180610d2657506000610d24612860565b115b905090565b6040805180820190915260058152640302e332e360dc1b602082015290565b60075481565b6000600c8281548110610d5f57fe5b6000918252602090912001546040516370a0823160e01b81526001600160a01b03909116906370a0823190610d98903090600401614afd565b60206040518083038186803b158015610db057600080fd5b505afa158015610dc4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de8919061484a565b90505b919050565b6001546000906001600160a01b03163314610e1d5760405162461bcd60e51b815260040161089f90614ec3565b6000610e2883612bea565b600554909350909150610e45906001600160a01b03163383612bcb565b50919050565b6002546001600160a01b0316331480610e7c5750610e67612b49565b6001600160a01b0316336001600160a01b0316145b610e985760405162461bcd60e51b815260040161089f90614fa2565b60068190556040517fbb2c369a0355a34b02ab5fce0643150c87e1c8dfe7c918d465591879f57948b190610c46908390614bfa565b6000806060806000600a60019054906101000a90046001600160a01b03166001600160a01b031663f94d46686010546040518263ffffffff1660e01b8152600401610f189190614bfa565b60006040518083038186803b158015610f3057600080fd5b505afa158015610f44573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f6c919081019061454c565b92509250925060005b60115460ff908116908216101561113b576000611047600b60009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610fd957600080fd5b505afa158015610fed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611011919061484a565b61104161101c61230c565b878660ff168151811061102b57fe5b60200260200101516129f090919063ffffffff16565b90612c88565b90508015611132576000858360ff168151811061106057fe5b60209081029190910101516005549091506001600160a01b0380831691161461112c5761108b614095565b611096828487612cca565b600b5460115460405162f64aa560e11b81529293506001600160a01b03909116916301ec954a916110d89185918b918a91610100900460ff16906004016150c2565b60206040518083038186803b1580156110f057600080fd5b505afa158015611104573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611128919061484a565b9250505b50948501945b50600101610f75565b5092935050505090565b6004546001600160a01b031633148061116857506002546001600160a01b031633145b8061118b5750611176612b49565b6001600160a01b0316336001600160a01b0316145b8061122c5750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b1580156111df57600080fd5b505afa1580156111f3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611217919061443a565b6001600160a01b0316336001600160a01b0316145b806112cd5750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b15801561128057600080fd5b505afa158015611294573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112b8919061443a565b6001600160a01b0316336001600160a01b0316145b6112e95760405162461bcd60e51b815260040161089f90614fa2565b6001546040805163bf3759b560e01b8152905161136c926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b15801561132f57600080fd5b505afa158015611343573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611367919061484a565b612d52565b565b6004546001600160a01b031633148061139157506002546001600160a01b031633145b806113b4575061139f612b49565b6001600160a01b0316336001600160a01b0316145b806114555750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b15801561140857600080fd5b505afa15801561141c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611440919061443a565b6001600160a01b0316336001600160a01b0316145b806114f65750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b1580156114a957600080fd5b505afa1580156114bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114e1919061443a565b6001600160a01b0316336001600160a01b0316145b6115125760405162461bcd60e51b815260040161089f90614fa2565b6000806000600160009054906101000a90046001600160a01b03166001600160a01b031663bf3759b56040518163ffffffff1660e01b815260040160206040518083038186803b15801561156557600080fd5b505afa158015611579573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159d919061484a565b600a5490915060009060ff16156115f35760006115b8612860565b90506115d18382116115ca57836115cc565b815b612bea565b94509150828211156115ed576115e7828461303d565b94508291505b50611604565b6115fc8261307f565b919550935090505b6001546040516328766ebf60e21b81526001600160a01b039091169063a1d9bafc90611638908790879086906004016151a3565b602060405180830381600087803b15801561165257600080fd5b505af1158015611666573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168a919061484a565b915061169582612d52565b7f4c0f499ffe6befa0ca7c826b0916cf87bea98de658013e76938489368d60d509848483856040516116ca94939291906151b9565b60405180910390a150505050565b6004546001600160a01b03163314806116fb57506002546001600160a01b031633145b8061171e5750611709612b49565b6001600160a01b0316336001600160a01b0316145b806117bf5750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b15801561177257600080fd5b505afa158015611786573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117aa919061443a565b6001600160a01b0316336001600160a01b0316145b806118605750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b15801561181357600080fd5b505afa158015611827573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184b919061443a565b6001600160a01b0316336001600160a01b0316145b61187c5760405162461bcd60e51b815260040161089f90614fa2565b60005b600c5481101561193157600c818154811061189657fe5b6000918252602082200154600a5460405163095ea7b360e01b81526001600160a01b039283169363095ea7b3936118d69361010090041691600401614b2b565b602060405180830381600087803b1580156118f057600080fd5b505af1158015611904573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192891906146a7565b5060010161187f565b506060805161194590600c906080906140e5565b50611952600e600061414a565b50565b600b546001600160a01b031681565b600a5460ff1681565b60006015546119876016544261303d90919063ffffffff16565b118015610de8575060006119996121e0565b1192915050565b60135481565b60145481565b60155481565b6002546001600160a01b03163314806119e357506119ce612b49565b6001600160a01b0316336001600160a01b0316145b6119ff5760405162461bcd60e51b815260040161089f90614fa2565b6001600160a01b038116611a1257600080fd5b600480546001600160a01b0319166001600160a01b0383161790556040517f2f202ddb4a2e345f6323ed90f8fc8559d770a7abbbeee84dde8aca3351fe715490610c46908390614afd565b6002546001600160a01b0316331480611a8e5750611a79612b49565b6001600160a01b0316336001600160a01b0316145b611aaa5760405162461bcd60e51b815260040161089f90614fa2565b611ab66000838361416b565b507f300e67d5a415b6d015a471d9c7b95dd58f3e8290af965e84e0f845de2996dda68282604051611ae8929190614d8e565b60405180910390a15050565b600c8181548110611b0157fe5b6000918252602090912001546001600160a01b0316905081565b600c5490565b6004546001600160a01b0316331480611b4457506002546001600160a01b031633145b80611b675750611b52612b49565b6001600160a01b0316336001600160a01b0316145b80611c085750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b158015611bbb57600080fd5b505afa158015611bcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf3919061443a565b6001600160a01b0316336001600160a01b0316145b80611ca95750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b158015611c5c57600080fd5b505afa158015611c70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c94919061443a565b6001600160a01b0316336001600160a01b0316145b611cc55760405162461bcd60e51b815260040161089f90614fa2565b612710841115611ce75760405162461bcd60e51b815260040161089f90614f3b565b6012849055612710831115611d0e5760405162461bcd60e51b815260040161089f90615035565b60139290925560145560155550565b6004546001600160a01b0316331480611d4057506002546001600160a01b031633145b80611d635750611d4e612b49565b6001600160a01b0316336001600160a01b0316145b80611e045750600160009054906101000a90046001600160a01b03166001600160a01b031663452a93206040518163ffffffff1660e01b815260040160206040518083038186803b158015611db757600080fd5b505afa158015611dcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611def919061443a565b6001600160a01b0316336001600160a01b0316145b80611ea55750600160009054906101000a90046001600160a01b03166001600160a01b03166388a8d6026040518163ffffffff1660e01b815260040160206040518083038186803b158015611e5857600080fd5b505afa158015611e6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e90919061443a565b6001600160a01b0316336001600160a01b0316145b611ec15760405162461bcd60e51b815260040161089f90614fa2565b600a5460405163095ea7b360e01b815283916001600160a01b038084169263095ea7b392611efd92610100909104169060001990600401614b2b565b602060405180830381600087803b158015611f1757600080fd5b505af1158015611f2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f4f91906146a7565b50600c805460018181019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180546001600160a01b0384166001600160a01b0319909116179055600e805491820181556000528251805184926002027fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0191611fe0918391602001906141e5565b506020828101518051611ff992600185019201906140e5565b505050505050565b60085481565b60115460ff1681565b600090565b60125481565b6002546001600160a01b031633148061204c5750612037612b49565b6001600160a01b0316336001600160a01b0316145b6120685760405162461bcd60e51b815260040161089f90614fa2565b60088190556040517fd94596337df4c2f0f44d30a7fc5db1c7bb60d9aca4185ed77c6fd96eb45ec29890610c46908390614bfa565b60065481565b6003546001600160a01b031681565b6004546001600160a01b031681565b6060600e805480602002602001604051908101604052809291908181526020016000905b828210156121d157838290600052602060002090600202016040518060400160405290816000820180548060200260200160405190810160405280929190818152602001828054801561215757602002820191906000526020600020905b815481526020019060010190808311612143575b50505050508152602001600182018054806020026020016040519081016040528092919081815260200182805480156121b957602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161219b575b505050505081525050815260200190600101906120e5565b50505050905090565b60165481565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612211903090600401614afd565b60206040518083038186803b15801561222957600080fd5b505afa15801561223d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d26919061484a565b6002546001600160a01b0316331480612292575061227d612b49565b6001600160a01b0316336001600160a01b0316145b6122ae5760405162461bcd60e51b815260040161089f90614fa2565b6001600160a01b0381166122c157600080fd5b600280546001600160a01b0319166001600160a01b0383161790556040517f352ececae6d7d1e6d26bcf2c549dfd55be1637e9b22dc0cf3b71ddb36097a6b490610c46908390614afd565b600b546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612211903090600401614afd565b6001546001600160a01b031633148061236e5750612359612b49565b6001600160a01b0316336001600160a01b0316145b61237757600080fd5b6001546040805163fbfa77cf60e01b815290516001600160a01b039283169284169163fbfa77cf916004808301926020929190829003018186803b1580156123be57600080fd5b505afa1580156123d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123f6919061443a565b6001600160a01b03161461240957600080fd5b61241281613102565b6005546040516370a0823160e01b81526119529183916001600160a01b03909116906370a0823190612448903090600401614afd565b60206040518083038186803b15801561246057600080fd5b505afa158015612474573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612498919061484a565b6005546001600160a01b03169190612bcb565b601154610100900460ff1681565b60105481565b6002546001600160a01b031633146124e95760405162461bcd60e51b815260040161089f90614dd0565b6001600160a01b0381166124fc57600080fd5b60015460035460405163095ea7b360e01b81526001600160a01b039283169263095ea7b39261253392911690600090600401614b2b565b602060405180830381600087803b15801561254d57600080fd5b505af1158015612561573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061258591906146a7565b50600380546001600160a01b0319166001600160a01b03838116919091179182905560015460405163095ea7b360e01b81529082169263095ea7b3926125d49291169060001990600401614b2b565b602060405180830381600087803b1580156125ee57600080fd5b505af1158015612602573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061262691906146a7565b507fafbb66abf8f3b719799940473a4052a3717cdd8e40fb6c8a3faadab316b1a06981604051610c469190614afd565b60008060005b600c5460ff82161015612846576000600c8260ff168154811061267b57fe5b60009182526020808320909101546040805163313ce56760e01b815290516001600160a01b039092169450849263313ce56792600480840193829003018186803b1580156126c857600080fd5b505afa1580156126dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127009190614893565b60ff1690506000600560009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561275557600080fd5b505afa158015612769573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278d9190614893565b60ff1690508082116127a05760006127aa565b6127aa828261303d565b600a0a836001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016127d99190614afd565b60206040518083038186803b1580156127f157600080fd5b505afa158015612805573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612829919061484a565b111561283b5760019450505050612846565b50505060010161265c565b50612850836132c7565b80156128595750805b9392505050565b6000610d2661286d610ecd565b6128756121e0565b9061353f565b6002546001600160a01b03163314806128ac5750612897612b49565b6001600160a01b0316336001600160a01b0316145b6128c85760405162461bcd60e51b815260040161089f90614fa2565b60078190556040517f5430e11864ad7aa9775b07d12657fe52df9aa2ba734355bd8ef8747be2c800c590610c46908390614bfa565b6001546001600160a01b031681565b6002546001600160a01b031633148061293d5750612928612b49565b6001600160a01b0316336001600160a01b0316145b6129595760405162461bcd60e51b815260040161089f90614fa2565b600a805460ff19166001908117909155546040805163507257cd60e11b815290516001600160a01b039092169163a0e4af9a9160048082019260009290919082900301818387803b1580156129ad57600080fd5b505af11580156129c1573d6000803e3d6000fd5b50506040517f97e963041e952738788b9d4871d854d282065b8f90a464928d6528f2e9a4fd0b925060009150a1565b6000826129ff57506000612a2d565b82820282848281612a0c57fe5b0414612a2a5760405162461bcd60e51b815260040161089f90614e82565b90505b92915050565b801580612abb5750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e90612a699030908690600401614b11565b60206040518083038186803b158015612a8157600080fd5b505afa158015612a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ab9919061484a565b155b612ad75760405162461bcd60e51b815260040161089f9061506c565b612b2d8363095ea7b360e01b8484604051602401612af6929190614b2b565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613564565b505050565b6060612b4184846000856135f3565b949350505050565b60015460408051635aa6e67560e01b815290516000926001600160a01b031691635aa6e675916004808301926020929190829003018186803b158015612b8e57600080fd5b505afa158015612ba2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d26919061443a565b606090565b612b2d8363a9059cbb60e01b8484604051602401612af6929190614b2b565b60008082612bf6612860565b1015612c1a57612c046136b7565b915081612c11848261303d565b91509150612c83565b6000612c246121e0565b905080841115612c7d576000612c3a858361303d565b9050612c4581613869565b612c56612c506121e0565b86613a51565b9350612c62858561303d565b9250612c7781612c72868561303d565b613a67565b50612c81565b8392505b505b915091565b6000612a2a83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613ac2565b612cd2614095565b604080516101208101825260008082526001600160a01b038088166020808501919091526005549091168385015260608301879052601054608084015260a083018690523060c0840181905260e084015292519192610100840192612d38929101614d80565b60408051601f198184030181529190529052949350505050565b60155460165442031015612d6557611952565b6000612d6f610ecd565b60115490915060609060ff1667ffffffffffffffff81118015612d9157600080fd5b50604051908082528060200260200182016040528015612dbb578160200160208202803683370190505b5090506000612dd3601454612dce6121e0565b613a51565b601154835191925082918491610100900460ff16908110612df057fe5b602002602001018181525050600082601160019054906101000a900460ff1660ff1681518110612e1c57fe5b602002602001015111156130375760115460609060ff1667ffffffffffffffff81118015612e4957600080fd5b50604051908082528060200260200182016040528015612e73578160200160208202803683370190505b50601154815191925083918391610100900460ff16908110612e9157fe5b60200260200101818152505060606001826000604051602001612eb693929190614c96565b6040516020818303038152906040529050612ecf614220565b60408051600d805460a060208202840181019094526080830181815292938493929190840182828015612f2b57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612f0d575b50505091835250506020810187905260408082018590526000606090920191909152600a54601054915163172b958560e31b815292935061010090046001600160a01b03169163b95cac2891612f8991309081908790600401614c03565b600060405180830381600087803b158015612fa357600080fd5b505af1158015612fb7573d6000803e3d6000fd5b505050506000612fcf87612fc9610ecd565b9061303d565b90506000818611612fe1576000612feb565b612feb868361303d565b9050600061300a6127106110416012548a6129f090919063ffffffff16565b90508082111561302c5760405162461bcd60e51b815260040161089f90614e4b565b505042601655505050505b50505050565b6000612a2a83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613af9565b6000808083156130975761309284612bea565b925090505b60006130a16121e0565b90506130ab613b25565b6130b3613bdb565b60006130bd6121e0565b90506130c9818361303d565b9450838511156130e8576130dd858561303d565b9450600093506130f9565b6130f2848661303d565b9350600094505b50509193909250565b600b546001600160a01b031663a9059cbb8261311c61230c565b6040518363ffffffff1660e01b8152600401613139929190614b2b565b602060405180830381600087803b15801561315357600080fd5b505af1158015613167573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061318b91906146a7565b5060005b600c54811015610a02576000600c82815481106131a857fe5b60009182526020822001546040516370a0823160e01b81526001600160a01b03909116925082906370a08231906131e3903090600401614afd565b60206040518083038186803b1580156131fb57600080fd5b505afa15801561320f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613233919061484a565b905080156132bd5760405163a9059cbb60e01b81526001600160a01b0383169063a9059cbb906132699087908590600401614b2b565b602060405180830381600087803b15801561328357600080fd5b505af1158015613297573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132bb91906146a7565b505b505060010161318f565b60006132d161424a565b6001546040516339ebf82360e01b81526001600160a01b03909116906339ebf82390613301903090600401614afd565b6101006040518083038186803b15801561331a57600080fd5b505afa15801561332e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061335291906147c0565b905080602001516000141561336b576000915050610deb565b600654608082015161337e90429061303d565b101561338e576000915050610deb565b60075460808201516133a190429061303d565b106133b0576001915050610deb565b6001546040805163bf3759b560e01b815290516000926001600160a01b03169163bf3759b5916004808301926020929190829003018186803b1580156133f557600080fd5b505afa158015613409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061342d919061484a565b905060095481111561344457600192505050610deb565b600061344e612860565b90508260a0015161346a6009548361353f90919063ffffffff16565b101561347c5760019350505050610deb565b60008360a0015182111561349d5760a084015161349a90839061303d565b90505b6001546040805163112c1f9b60e01b815290516000926001600160a01b03169163112c1f9b916004808301926020929190829003018186803b1580156134e257600080fd5b505afa1580156134f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061351a919061484a565b9050613526818361353f565b60085461353390896129f0565b10979650505050505050565b600082820183811015612a2a5760405162461bcd60e51b815260040161089f90614e14565b60606135b9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612b329092919063ffffffff16565b805190915015612b2d57808060200190518101906135d791906146a7565b612b2d5760405162461bcd60e51b815260040161089f90614fc7565b60606135fe8561405c565b61361a5760405162461bcd60e51b815260040161089f90614f6b565b60006060866001600160a01b031685876040516136379190614a81565b60006040518083038185875af1925050503d8060008114613674576040519150601f19603f3d011682016040523d82523d6000602084013e613679565b606091505b5091509150811561368d579150612b419050565b80511561369d5780518082602001fd5b8360405162461bcd60e51b815260040161089f9190614dbd565b6000806136c2612860565b905060006136ce61230c565b90508015613850576060600082601160019054906101000a900460ff166040516020016136fd93929190614c70565b6040516020818303038152906040529050613716614220565b60408051600d805460a06020820284018101909452608083018181529293849392919084018282801561377257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613754575b50505050508152602001600f8054806020026020016040519081016040528092919081815260200182805480156137c857602002820191906000526020600020905b8154815260200190600101908083116137b4575b5050509183525050602081018490526000604091820152600a546010549151638bdb391360e01b815292935061010090046001600160a01b031691638bdb39139161381b91309081908790600401614c03565b600060405180830381600087803b15801561383557600080fd5b505af1158015613849573d6000803e3d6000fd5b5050505050505b6138586121e0565b92506138648284613a67565b505090565b60115460609060ff1667ffffffffffffffff8111801561388857600080fd5b506040519080825280602002602001820160405280156138b2578160200160208202803683370190505b50601154815191925083918391610100900460ff169081106138d057fe5b60200260200101818152505060606002826138e961230c565b6040516020016138fb93929190614c3f565b6040516020818303038152906040529050613914614220565b60408051600d805460a06020820284018101909452608083018181529293849392919084018282801561397057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613952575b50505050508152602001600f8054806020026020016040519081016040528092919081815260200182805480156139c657602002820191906000526020600020905b8154815260200190600101908083116139b2575b5050509183525050602081018490526000604091820152600a546010549151638bdb391360e01b815292935061010090046001600160a01b031691638bdb391391613a1991309081908790600401614c03565b600060405180830381600087803b158015613a3357600080fd5b505af1158015613a47573d6000803e3d6000fd5b5050505050505050565b6000818310613a605781612a2a565b5090919050565b6000818311613a77576000613a81565b613a81838361303d565b90506000613aa0612710611041601354876129f090919063ffffffff16565b9050808211156130375760405162461bcd60e51b815260040161089f90614f04565b60008183613ae35760405162461bcd60e51b815260040161089f9190614dbd565b506000838581613aef57fe5b0495945050505050565b60008184841115613b1d5760405162461bcd60e51b815260040161089f9190614dbd565b505050900390565b6000613b2f612860565b6001546040516339ebf82360e01b81529192506000916001600160a01b03909116906339ebf82390613b65903090600401614afd565b6101006040518083038186803b158015613b7e57600080fd5b505afa158015613b92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bb691906147c0565b60a00151905080821115610a02576000613bd0838361303d565b9050612b2d81613869565b60005b600c5460ff82161015611952576000600c8260ff1681548110613bfd57fe5b60009182526020822001546040516370a0823160e01b81526001600160a01b03909116925082906370a0823190613c38903090600401614afd565b60206040518083038186803b158015613c5057600080fd5b505afa158015613c64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c88919061484a565b90506000826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015613cc557600080fd5b505afa158015613cd9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cfd9190614893565b60ff1690506000600560009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015613d5257600080fd5b505afa158015613d66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d8a9190614893565b60ff169050808211613d9d576000613da7565b613da7828261303d565b600a0a83111561404c576000600e8660ff1681548110613dc357fe5b6000918252602090912060029091020154905060608167ffffffffffffffff81118015613def57600080fd5b50604051908082528060200260200182016040528015613e2957816020015b613e1661428f565b815260200190600190039081613e0e5790505b50905060608260010167ffffffffffffffff81118015613e4857600080fd5b50604051908082528060200260200182016040528015613e72578160200160208202803683370190505b5090508581600081518110613e8357fe5b60200260200101818152505060005b83811015613f49576040518060a00160405280600e8b60ff1681548110613eb557fe5b90600052602060002090600202016000018381548110613ed157fe5b9060005260206000200154815260200182815260200182600101815260200182600014613eff576000613f01565b885b81526020016000604051602001613f189190614d80565b604051602081830303815290604052815250838281518110613f3657fe5b6020908102919091010152600101613e92565b50600a60019054906101000a90046001600160a01b03166001600160a01b031663945bcec9600084600e8c60ff1681548110613f8157fe5b90600052602060002090600202016001016040518060800160405280306001600160a01b03168152602001600015158152602001306001600160a01b03168152602001600015158152508642600a016040518763ffffffff1660e01b8152600401613ff196959493929190614ccc565b600060405180830381600087803b15801561400b57600080fd5b505af115801561401f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526140479190810190614617565b505050505b505060019092019150613bde9050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612b41575050151592915050565b60408051610120810190915280600081526000602082018190526040820181905260608083018290526080830182905260a0830182905260c0830182905260e08301919091526101009091015290565b82805482825590600052602060002090810192821561413a579160200282015b8281111561413a57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614105565b506141469291506142c1565b5090565b508054600082556002029060005260206000209081019061195291906142e0565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106141ac5782800160ff198235161785556141d9565b828001600101855582156141d9579182015b828111156141d95782358255916020019190600101906141be565b5061414692915061430b565b8280548282559060005260206000209081019282156141d9579160200282015b828111156141d9578251825591602001919060010190614205565b60405180608001604052806060815260200160608152602001606081526020016000151581525090565b60405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060a0016040528060008019168152602001600081526020016000815260200160008152602001606081525090565b5b808211156141465780546001600160a01b03191681556001016142c2565b808211156141465760006142f48282614320565b614302600183016000614320565b506002016142e0565b5b80821115614146576000815560010161430c565b5080546000825590600052602060002090810190611952919061430b565b600082601f83011261434e578081fd5b813561436161435c826151fb565b6151d4565b81815291506020808301908481018184028601820187101561438257600080fd5b60005b848110156143aa5781356143988161525c565b84529282019290820190600101614385565b505050505092915050565b600082601f8301126143c5578081fd5b81516143d361435c826151fb565b8181529150602080830190848101818402860182018710156143f457600080fd5b60005b848110156143aa578151845292820192908201906001016143f7565b8051612a2d8161525c565b60006020828403121561442f578081fd5b8135612a2a8161525c565b60006020828403121561444b578081fd5b8151612a2a8161525c565b60008060408385031215614468578081fd5b82356144738161525c565b915060208381013567ffffffffffffffff80821115614490578384fd5b90850190604082880312156144a3578384fd5b6144ad60406151d4565b8235828111156144bb578586fd5b8301601f810189136144cb578586fd5b80356144d961435c826151fb565b81815286810190838801888402850189018d10156144f557898afd5b8994505b838510156145175780358352600194909401939188019188016144f9565b508452505050828401358281111561452d578586fd5b6145398982860161433e565b8583015250809450505050509250929050565b600080600060608486031215614560578081fd5b835167ffffffffffffffff80821115614577578283fd5b818601915086601f83011261458a578283fd5b815161459861435c826151fb565b80828252602080830192508086018b8283870289010111156145b8578788fd5b8796505b848710156145e2576145ce8c82614413565b8452600196909601959281019281016145bc565b5089015190975093505050808211156145f9578283fd5b50614606868287016143b5565b925050604084015190509250925092565b60006020808385031215614629578182fd5b825167ffffffffffffffff81111561463f578283fd5b8301601f8101851361464f578283fd5b805161465d61435c826151fb565b8181528381019083850185840285018601891015614679578687fd5b8694505b8385101561469b57805183526001949094019391850191850161467d565b50979650505050505050565b6000602082840312156146b8578081fd5b81518015158114612a2a578182fd5b600080602083850312156146d9578182fd5b823567ffffffffffffffff808211156146f0578384fd5b818501915085601f830112614703578384fd5b813581811115614711578485fd5b866020828501011115614722578485fd5b60209290920196919550909350505050565b600060208284031215614745578081fd5b815167ffffffffffffffff8082111561475c578283fd5b818401915084601f83011261476f578283fd5b81518181111561477d578384fd5b614790601f8201601f19166020016151d4565b91508082528560208285010111156147a6578384fd5b6147b7816020840160208601615226565b50949350505050565b60006101008083850312156147d3578182fd5b6147dc816151d4565b9050825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201528091505092915050565b600060208284031215614843578081fd5b5035919050565b60006020828403121561485b578081fd5b5051919050565b60008060008060808587031215614877578182fd5b5050823594602084013594506040840135936060013592509050565b6000602082840312156148a4578081fd5b815160ff81168114612a2a578182fd5b6001600160a01b03169052565b6000815180845260208085019450808401835b838110156148f95781516001600160a01b0316875295820195908201906001016148d4565b509495945050505050565b6000815480845260208085019450838352808320835b838110156148f95781546001600160a01b03168752958201956001918201910161491a565b6000815180845260208085019450808401835b838110156148f957815187529582019590820190600101614952565b60008151808452614986816020860160208601615226565b601f01601f19169290920160200192915050565b6149a381615252565b9052565b60ff169052565b600081518352602082015160208401526040820151604084015260608201516060840152608082015160a06080850152612b4160a085018261496e565b6000815160808452614a0060808501826148c1565b905060208301518482036020860152614a19828261493f565b91505060408301518482036040860152614a33828261496e565b9150506060830151151560608501528091505092915050565b80516001600160a01b039081168352602080830151151590840152604080830151909116908301526060908101511515910152565b60008251614a93818460208701615226565b9190910192915050565b600073029b4b733b632a9b4b232b22130b630b731b2b9160651b82528351614acc816014850160208801615226565b6402837b7b6160dd1b6014918401918201528351614af1816019840160208801615226565b01601901949350505050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03929092168252602082015260400190565b60208082528251828201819052600091906040908185019080840286018301878501865b83811015614be157888303603f19018552815180518785528051888601819052908901908a9060608701905b80831015614bb45783518252928b019260019290920191908b0190614b94565b50928a0151868403878c015292614bcb81856148c1565b988b019896505050928801925050600101614b68565b509098975050505050505050565b901515815260200190565b90815260200190565b8481526001600160a01b03848116602083015283166040820152608060608201819052600090614c35908301846149eb565b9695505050505050565b6000614c4a8561521b565b825260606020830152614c60606083018561493f565b9050826040830152949350505050565b60608101614c7d8561521b565b825283602083015260ff83166040830152949350505050565b600060048510614ca257fe5b84825260606020830152614cb9606083018561493f565b905060ff83166040830152949350505050565b6000610120808301614cdd8a615252565b898452602080850192909252885190819052610140808501928281028601909101918a8201855b82811015614d335761013f19888603018652614d218583516149ae565b95840195945090830190600101614d04565b505050508381036040850152614d498189614904565b915050614d596060840187614a4c565b82810360e0840152614d6b818661493f565b91505082610100830152979650505050505050565b60ff91909116815260200190565b60006020825282602083015282846040840137818301604090810191909152601f909201601f19160101919050565b600060208252612a2a602083018461496e565b6020808252600b908201526a085cdd1c985d1959da5cdd60aa1b604082015260600190565b602080825260059082015264085dd85b9d60da1b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526017908201527f4578636565646564206d6178536c697070616765496e21000000000000000000604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b602080825260069082015265085d985d5b1d60d21b604082015260600190565b6020808252600790820152662173686172657360c81b604082015260600190565b60208082526018908201527f4578636565646564206d6178536c6970706167654f7574210000000000000000604082015260600190565b6020808252601690820152750dac2f0a6d8d2e0e0c2ceca92dc40e8dede40d0d2ced60531b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252600b908201526a08585d5d1a1bdc9a5e995960aa1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252600a9082015269085c1c9bdd1958dd195960b21b604082015260600190565b60208082526017908201527f6d6178536c6970706167654f757420746f6f2068696768000000000000000000604082015260600190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b6000608082526150d660808301875161499a565b60208601516150e860a08401826148b4565b5060408601516150fb60c08401826148b4565b50606086015160e08301526080860151610100818185015260a08801519150610120828186015260c089015192506151376101408601846148b4565b60e0890151925061514c6101608601846148b4565b8189015192508061018086015250506151696101a084018261496e565b9050828103602084015261517d818761493f565b91505061518d60408301856149a7565b61519a60608301846149a7565b95945050505050565b9283526020830191909152604082015260600190565b93845260208401929092526040830152606082015260800190565b60405181810167ffffffffffffffff811182821017156151f357600080fd5b604052919050565b600067ffffffffffffffff821115615211578081fd5b5060209081020190565b8060038110610deb57fe5b60005b83811015615241578181015183820152602001615229565b838111156130375750506000910152565b6002811061195257fe5b6001600160a01b038116811461195257600080fdfea2646970667358221220b8132eac1c27d87194d17acc03827ffcfe07f7d5eb9cd3eb78d417c4e000138364736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005f18c75abdae578b483e5f43f12a39cf75b973a9000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c800000000000000000000000006df3b2bbb68adc8b0e302443692037ed9f91b420000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000001e84800000000000000000000000000000000000000000000000000000000000000708
-----Decoded View---------------
Arg [0] : _vault (address): 0x5f18C75AbDAe578b483E5F43f12a39cF75b973a9
Arg [1] : _balancerVault (address): 0xBA12222222228d8Ba445958a75a0704d566BF2C8
Arg [2] : _balancerPool (address): 0x06Df3b2bbB68adc8B0e302443692037ED9f91b42
Arg [3] : _maxSlippageIn (uint256): 5
Arg [4] : _maxSlippageOut (uint256): 5
Arg [5] : _maxSingleDeposit (uint256): 2000000
Arg [6] : _minDepositPeriod (uint256): 1800
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000005f18c75abdae578b483e5f43f12a39cf75b973a9
Arg [1] : 000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8
Arg [2] : 00000000000000000000000006df3b2bbb68adc8b0e302443692037ed9f91b42
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [5] : 00000000000000000000000000000000000000000000000000000000001e8480
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000708
Deployed Bytecode Sourcemap
71516:13634:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70990:494;;;;;;;;;;-1:-1:-1;70990:494:0;;;;;:::i;:::-;;:::i;:::-;;44730:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73987:262;;;;;;;;;;;;;:::i;53955:175::-;;;;;;;;;;-1:-1:-1;53955:175:0;;;;;:::i;:::-;;:::i;71761:35::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;47786:28::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;46491:18::-;;;;;;;;;;;;;:::i;46400:25::-;;;;;;;;;;;;;:::i;56651:174::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;45040:91::-;;;;;;;;;;;;;:::i;47422:29::-;;;;;;;;;;;;;:::i;81320:147::-;;;;;;;;;;-1:-1:-1;81320:147:0;;;;;:::i;:::-;;:::i;67564:515::-;;;;;;;;;;-1:-1:-1;67564:515:0;;;;;:::i;:::-;;:::i;52004:154::-;;;;;;;;;;-1:-1:-1;52004:154:0;;;;;:::i;:::-;;:::i;81475:881::-;;;;;;;;;;;;;:::i;61457:170::-;;;;;;;;;;;;;:::i;65917:1403::-;;;;;;;;;;;;;:::i;83682:297::-;;;;;;;;;;;;;:::i;71803:24::-;;;;;;;;;;;;;:::i;47865:25::-;;;;;;;;;;;;;:::i;78562:172::-;;;;;;;;;;-1:-1:-1;78562:172:0;;;;;:::i;:::-;;:::i;72377:29::-;;;;;;;;;;;;;:::i;72421:31::-;;;;;;;;;;;;;:::i;72459:::-;;;;;;;;;;;;;:::i;50761:174::-;;;;;;;;;;-1:-1:-1;50761:174:0;;;;;:::i;:::-;;:::i;54433:194::-;;;;;;;;;;-1:-1:-1;54433:194:0;;;;;:::i;:::-;;:::i;71834:28::-;;;;;;;;;;-1:-1:-1;71834:28:0;;;;;:::i;:::-;;:::i;83987:101::-;;;;;;;;;;;;;:::i;84096:477::-;;;;;;;;;;-1:-1:-1;84096:477:0;;;;;:::i;:::-;;:::i;83407:267::-;;;;;;;;;;-1:-1:-1;83407:267:0;;;;;:::i;:::-;;:::i;47608:27::-;;;;;;;;;;;;;:::i;72012:22::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;46270:94::-;;;;;;;;;;;;;:::i;72334:28::-;;;;;;;;;;;;;:::i;53229:169::-;;;;;;;;;;-1:-1:-1;53229:169:0;;;;;:::i;:::-;;:::i;47271:29::-;;;;;;;;;;;;;:::i;46432:22::-;;;;;;;;;;;;;:::i;46461:21::-;;;;;;;;;;;;;:::i;85011:99::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;72508:30::-;;;;;;;;;;;;;:::i;81072:117::-;;;;;;;;;;;;;:::i;50005:202::-;;;;;;;;;;-1:-1:-1;50005:202:0;;;;;:::i;:::-;;:::i;81197:115::-;;;;;;;;;;;;;:::i;68670:317::-;;;;;;;;;;-1:-1:-1;68670:317:0;;;;;:::i;:::-;;:::i;72041:23::-;;;;;;;;;;;;;:::i;71976:29::-;;;;;;;;;;;;;:::i;51224:263::-;;;;;;;;;;-1:-1:-1;51224:263:0;;;;;:::i;:::-;;:::i;78742:627::-;;;;;;;;;;-1:-1:-1;78742:627:0;;;;;:::i;:::-;;:::i;74257:135::-;;;;;;;;;;;;;:::i;52675:154::-;;;;;;;;;;-1:-1:-1;52675:154:0;;;;;:::i;:::-;;:::i;46372:21::-;;;;;;;;;;;;;:::i;69416:164::-;;;;;;;;;;;;;:::i;70990:494::-;48269:12;:10;:12::i;:::-;-1:-1:-1;;;;;48255:26:0;:10;-1:-1:-1;;;;;48255:26:0;;48247:50;;;;-1:-1:-1;;;48247:50:0;;;;;;;:::i;:::-;;;;;;;;;71082:4:::1;::::0;-1:-1:-1;;;;;71064:23:0;;::::1;71082:4:::0;::::1;71064:23;;71056:41;;;;-1:-1:-1::0;;;71056:41:0::1;;;;;;;:::i;:::-;71134:5;::::0;-1:-1:-1;;;;;71116:24:0;;::::1;71134:5:::0;::::1;71116:24;;71108:44;;;;-1:-1:-1::0;;;71108:44:0::1;;;;;;;:::i;:::-;71165:33;71201:17;:15;:17::i;:::-;71165:53;;71234:9;71229:115;71249:16;:23;71245:1;:27;71229:115;;;71310:16;71327:1;71310:19;;;;;;;;;;;;;;-1:-1:-1::0;;;;;71300:29:0::1;:6;-1:-1:-1::0;;;;;71300:29:0::1;;;71292:52;;;;-1:-1:-1::0;;;71292:52:0::1;;;;;;;:::i;:::-;71274:3;;71229:115;;;;71357:119;71399:12;:10;:12::i;:::-;71426:39;::::0;-1:-1:-1;;;71426:39:0;;-1:-1:-1;;;;;71426:24:0;::::1;::::0;::::1;::::0;:39:::1;::::0;71459:4:::1;::::0;71426:39:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;71357:27:0;::::1;::::0;:119;:27:::1;:119::i;:::-;48308:1;70990:494:::0;:::o;44730:25::-;;;;;;;;;;;;;;;-1:-1:-1;;44730:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;73987:262::-;74187:3;;:12;;;-1:-1:-1;;;74187:12:0;;;;74035:13;;-1:-1:-1;;;;;74187:3:0;;:10;;:12;;;;;:3;;:12;;;;;;;:3;:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;74187:12:0;;;;;;;;;;;;:::i;:::-;74224:4;;;;;;;;;-1:-1:-1;;;;;74224:4:0;-1:-1:-1;;;;;74210:27:0;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;74210:29:0;;;;;;;;;;;;:::i;:::-;74146:94;;;;;;;;;:::i;:::-;;;;;;;;;;;;;74132:109;;73987:262;:::o;53955:175::-;47990:10;;-1:-1:-1;;;;;47990:10:0;47976;:24;;:54;;;48018:12;:10;:12::i;:::-;-1:-1:-1;;;;;48004:26:0;:10;-1:-1:-1;;;;;48004:26:0;;47976:54;47954:115;;;;-1:-1:-1;;;47954:115:0;;;;;;;:::i;:::-;54040:13:::1;:30:::0;;;54086:36:::1;::::0;::::1;::::0;::::1;::::0;54056:14;;54086:36:::1;:::i;:::-;;;;;;;;53955:175:::0;:::o;71761:35::-;;;;;;-1:-1:-1;;;;;71761:35:0;;:::o;47786:28::-;;;;:::o;46491:18::-;;;-1:-1:-1;;;;;46491:18:0;;:::o;46400:25::-;;;-1:-1:-1;;;;;46400:25:0;;:::o;56651:174::-;56729:5;;:31;;-1:-1:-1;;;56729:31:0;;56692:4;;;;-1:-1:-1;;;;;56729:5:0;;;;:16;;:31;;56754:4;;56729:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;:45;:88;;;;56816:1;56791:22;:20;:22::i;:::-;:26;56729:88;56709:108;;56651:174;:::o;45040:91::-;45109:14;;;;;;;;;;;;-1:-1:-1;;;45109:14:0;;;;45040:91;:::o;47422:29::-;;;;:::o;81320:147::-;81381:15;81415:12;81428:5;81415:19;;;;;;;;;;;;;;;;;;:44;;-1:-1:-1;;;81415:44:0;;-1:-1:-1;;;;;81415:19:0;;;;:29;;:44;;81453:4;;81415:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81408:51;;81320:147;;;;:::o;67564:515::-;67679:5;;67623:13;;-1:-1:-1;;;;;67679:5:0;67657:10;:28;67649:47;;;;-1:-1:-1;;;67649:47:0;;;;;;;:::i;:::-;67782:19;67835:32;67853:13;67835:17;:32::i;:::-;67959:4;;67812:55;;-1:-1:-1;67812:55:0;;-1:-1:-1;67959:42:0;;-1:-1:-1;;;;;67959:4:0;67977:10;67812:55;67959:17;:42::i;:::-;67564:515;;;;:::o;52004:154::-;47990:10;;-1:-1:-1;;;;;47990:10:0;47976;:24;;:54;;;48018:12;:10;:12::i;:::-;-1:-1:-1;;;;;48004:26:0;:10;-1:-1:-1;;;;;48004:26:0;;47976:54;47954:115;;;;-1:-1:-1;;;47954:115:0;;;;;;;:::i;:::-;52082:14:::1;:23:::0;;;52121:29:::1;::::0;::::1;::::0;::::1;::::0;52099:6;;52121:29:::1;:::i;81475:881::-:0;81523:15;81550:23;81585:22;81608:30;81639:23;81666:13;;;;;;;;;-1:-1:-1;;;;;81666:13:0;-1:-1:-1;;;;;81666:27:0;;81694:14;;81666:43;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;81666:43:0;;;;;;;;;;;;:::i;:::-;81584:125;;;;;;81725:7;81720:596;81742:9;;;;;;81738:13;;;;81720:596;;;81773:19;81795:59;81836:3;;;;;;;;;-1:-1:-1;;;;;81836:3:0;-1:-1:-1;;;;;81836:15:0;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81795:36;81816:14;:12;:14::i;:::-;81795:13;81809:1;81795:16;;;;;;;;;;;;;;;;:20;;:36;;;;:::i;:::-;:40;;:59::i;:::-;81773:81;-1:-1:-1;81873:15:0;;81869:436;;81909:12;81924:6;81931:1;81924:9;;;;;;;;;;;;;;;;;;;;81965:4;;81924:9;;-1:-1:-1;;;;;;81956:13:0;;;81965:4;;81956:13;81952:289;;81994:40;;:::i;:::-;82037:52;82053:5;82060:11;82073:15;82037;:52::i;:::-;82172:3;;82210:10;;82172:49;;-1:-1:-1;;;82172:49:0;;81994:95;;-1:-1:-1;;;;;;82172:3:0;;;;:10;;:49;;81994:95;;82192:13;;82207:1;;82172:3;82210:10;;;;;82172:49;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;82158:63;;81952:289;;-1:-1:-1;82259:30:0;;;;81869:436;-1:-1:-1;81753:3:0;;81720:596;;;-1:-1:-1;82333:15:0;;-1:-1:-1;;;;81475:881:0;:::o;61457:170::-;48395:6;;-1:-1:-1;;;;;48395:6:0;48381:10;:20;;:65;;-1:-1:-1;48436:10:0;;-1:-1:-1;;;;;48436:10:0;48422;:24;48381:65;:112;;;;48481:12;:10;:12::i;:::-;-1:-1:-1;;;;;48467:26:0;:10;-1:-1:-1;;;;;48467:26:0;;48381:112;:163;;;;48528:5;;;;;;;;;-1:-1:-1;;;;;48528:5:0;-1:-1:-1;;;;;48528:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48514:30:0;:10;-1:-1:-1;;;;;48514:30:0;;48381:163;:216;;;;48579:5;;;;;;;;;-1:-1:-1;;;;;48579:5:0;-1:-1:-1;;;;;48579:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48565:32:0;:10;-1:-1:-1;;;;;48565:32:0;;48381:216;48359:277;;;;-1:-1:-1;;;48359:277:0;;;;;;;:::i;:::-;61595:5:::1;::::0;:23:::1;::::0;;-1:-1:-1;;;61595:23:0;;;;61580:39:::1;::::0;-1:-1:-1;;;;;61595:5:0::1;::::0;:21:::1;::::0;:23:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:5;:23;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61580:14;:39::i;:::-;61457:170::o:0;65917:1403::-;48395:6;;-1:-1:-1;;;;;48395:6:0;48381:10;:20;;:65;;-1:-1:-1;48436:10:0;;-1:-1:-1;;;;;48436:10:0;48422;:24;48381:65;:112;;;;48481:12;:10;:12::i;:::-;-1:-1:-1;;;;;48467:26:0;:10;-1:-1:-1;;;;;48467:26:0;;48381:112;:163;;;;48528:5;;;;;;;;;-1:-1:-1;;;;;48528:5:0;-1:-1:-1;;;;;48528:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48514:30:0;:10;-1:-1:-1;;;;;48514:30:0;;48381:163;:216;;;;48579:5;;;;;;;;;-1:-1:-1;;;;;48579:5:0;-1:-1:-1;;;;;48579:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48565:32:0;:10;-1:-1:-1;;;;;48565:32:0;;48381:216;48359:277;;;;-1:-1:-1;;;48359:277:0;;;;;;;:::i;:::-;65968:14:::1;65997:12:::0;66024:23:::1;66050:5;;;;;;;;;-1:-1:-1::0;;;;;66050:5:0::1;-1:-1:-1::0;;;;;66050:21:0::1;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66122:13;::::0;66024:49;;-1:-1:-1;66084:19:0::1;::::0;66122:13:::1;;66118:763;;;66204:19;66226:22;:20;:22::i;:::-;66204:44;;66382:112;66432:15;66418:11;:29;:61;;66464:15;66418:61;;;66450:11;66418:61;66382:17;:112::i;:::-;66360:134:::0;-1:-1:-1;66360:134:0;-1:-1:-1;66572:29:0;;::::1;66568:159;;;66631:32;:11:::0;66647:15;66631::::1;:32::i;:::-;66622:41;;66696:15;66682:29;;66568:159;66118:763;;;;66839:30;66853:15;66839:13;:30::i;:::-;66809:60:::0;;-1:-1:-1;66809:60:0;-1:-1:-1;66809:60:0;-1:-1:-1;66118:763:0::1;67095:5;::::0;:39:::1;::::0;-1:-1:-1;;;67095:39:0;;-1:-1:-1;;;;;67095:5:0;;::::1;::::0;:12:::1;::::0;:39:::1;::::0;67108:6;;67116:4;;67122:11;;67095:39:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;67077:57;;67210:31;67225:15;67210:14;:31::i;:::-;67259:53;67269:6;67277:4;67283:11;67296:15;67259:53;;;;;;;;;:::i;:::-;;;;;;;;48647:1;;;;65917:1403::o:0;83682:297::-;48395:6;;-1:-1:-1;;;;;48395:6:0;48381:10;:20;;:65;;-1:-1:-1;48436:10:0;;-1:-1:-1;;;;;48436:10:0;48422;:24;48381:65;:112;;;;48481:12;:10;:12::i;:::-;-1:-1:-1;;;;;48467:26:0;:10;-1:-1:-1;;;;;48467:26:0;;48381:112;:163;;;;48528:5;;;;;;;;;-1:-1:-1;;;;;48528:5:0;-1:-1:-1;;;;;48528:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48514:30:0;:10;-1:-1:-1;;;;;48514:30:0;;48381:163;:216;;;;48579:5;;;;;;;;;-1:-1:-1;;;;;48579:5:0;-1:-1:-1;;;;;48579:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48565:32:0;:10;-1:-1:-1;;;;;48565:32:0;;48381:216;48359:277;;;;-1:-1:-1;;;48359:277:0;;;;;;;:::i;:::-;83745:6:::1;83740:124;83761:12;:19:::0;83757:23;::::1;83740:124;;;83802:12;83815:1;83802:15;;;;;;;;;::::0;;;::::1;::::0;;::::1;::::0;83834:13:::1;::::0;83802:50:::1;::::0;-1:-1:-1;;;83802:50:0;;-1:-1:-1;;;;;83802:15:0;;::::1;::::0;:23:::1;::::0;:50:::1;::::0;:15:::1;83834:13:::0;::::1;;::::0;83802:50:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;83782:3:0::1;;83740:124;;;-1:-1:-1::0;83874:30:0::1;83915:29:::0;;::::1;::::0;:12:::1;::::0;:29;;::::1;:::i;:::-;-1:-1:-1::0;83955:16:0::1;83962:9;;83955:16;:::i;:::-;48647:1;83682:297::o:0;71803:24::-;;;-1:-1:-1;;;;;71803:24:0;;:::o;47865:25::-;;;;;;:::o;78562:172::-;78636:4;78687:16;;78660:24;78668:15;;78660:3;:7;;:24;;;;:::i;:::-;:43;:66;;;;;78725:1;78707:15;:13;:15::i;:::-;:19;;78562:172;-1:-1:-1;;78562:172:0:o;72377:29::-;;;;:::o;72421:31::-;;;;:::o;72459:::-;;;;:::o;50761:174::-;47990:10;;-1:-1:-1;;;;;47990:10:0;47976;:24;;:54;;;48018:12;:10;:12::i;:::-;-1:-1:-1;;;;;48004:26:0;:10;-1:-1:-1;;;;;48004:26:0;;47976:54;47954:115;;;;-1:-1:-1;;;47954:115:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;50840:21:0;::::1;50832:30;;;::::0;::::1;;50873:6;:16:::0;;-1:-1:-1;;;;;;50873:16:0::1;-1:-1:-1::0;;;;;50873:16:0;::::1;;::::0;;50905:22:::1;::::0;::::1;::::0;::::1;::::0;50873:16;;50905:22:::1;:::i;54433:194::-:0;47990:10;;-1:-1:-1;;;;;47990:10:0;47976;:24;;:54;;;48018:12;:10;:12::i;:::-;-1:-1:-1;;;;;48004:26:0;:10;-1:-1:-1;;;;;48004:26:0;;47976:54;47954:115;;;;-1:-1:-1;;;47954:115:0;;;;;;;:::i;:::-;54545:26:::1;:11;54559:12:::0;;54545:26:::1;:::i;:::-;;54587:32;54606:12;;54587:32;;;;;;;:::i;:::-;;;;;;;;54433:194:::0;;:::o;71834:28::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;71834:28:0;;-1:-1:-1;71834:28:0;:::o;83987:101::-;84061:12;:19;83987:101;:::o;84096:477::-;48395:6;;-1:-1:-1;;;;;48395:6:0;48381:10;:20;;:65;;-1:-1:-1;48436:10:0;;-1:-1:-1;;;;;48436:10:0;48422;:24;48381:65;:112;;;;48481:12;:10;:12::i;:::-;-1:-1:-1;;;;;48467:26:0;:10;-1:-1:-1;;;;;48467:26:0;;48381:112;:163;;;;48528:5;;;;;;;;;-1:-1:-1;;;;;48528:5:0;-1:-1:-1;;;;;48528:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48514:30:0;:10;-1:-1:-1;;;;;48514:30:0;;48381:163;:216;;;;48579:5;;;;;;;;;-1:-1:-1;;;;;48579:5:0;-1:-1:-1;;;;;48579:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48565:32:0;:10;-1:-1:-1;;;;;48565:32:0;;48381:216;48359:277;;;;-1:-1:-1;;;48359:277:0;;;;;;;:::i;:::-;72582:5:::1;84256:14;:26;;84248:61;;;;-1:-1:-1::0;;;84248:61:0::1;;;;;;;:::i;:::-;84320:13;:30:::0;;;72582:5:::1;84371:27:::0;::::1;;84363:63;;;;-1:-1:-1::0;;;84363:63:0::1;;;;;;;:::i;:::-;84437:14;:32:::0;;;;84482:16:::1;:36:::0;84529:16:::1;:36:::0;-1:-1:-1;84096:477:0:o;83407:267::-;48395:6;;-1:-1:-1;;;;;48395:6:0;48381:10;:20;;:65;;-1:-1:-1;48436:10:0;;-1:-1:-1;;;;;48436:10:0;48422;:24;48381:65;:112;;;;48481:12;:10;:12::i;:::-;-1:-1:-1;;;;;48467:26:0;:10;-1:-1:-1;;;;;48467:26:0;;48381:112;:163;;;;48528:5;;;;;;;;;-1:-1:-1;;;;;48528:5:0;-1:-1:-1;;;;;48528:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48514:30:0;:10;-1:-1:-1;;;;;48514:30:0;;48381:163;:216;;;;48579:5;;;;;;;;;-1:-1:-1;;;;;48579:5:0;-1:-1:-1;;;;;48579:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48565:32:0;:10;-1:-1:-1;;;;;48565:32:0;;48381:216;48359:277;;;;-1:-1:-1;;;48359:277:0;;;;;;;:::i;:::-;83578:13:::1;::::0;83556:42:::1;::::0;-1:-1:-1;;;83556:42:0;;83532:12;;-1:-1:-1;;;;;83556:13:0;;::::1;::::0;::::1;::::0;:42:::1;::::0;83578:13:::1;::::0;;::::1;;::::0;-1:-1:-1;;72192:17:0;83556:42:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;83609:12:0::1;:24:::0;;::::1;::::0;;::::1;::::0;;;;::::1;::::0;;-1:-1:-1;;;;;83609:24:0;::::1;-1:-1:-1::0;;;;;;83609:24:0;;::::1;;::::0;;83644:9:::1;:22:::0;;;;::::1;::::0;;-1:-1:-1;83644:22:0;;;;;83659:6;;83644:22:::1;;::::0;::::1;::::0;::::1;::::0;;;83609:24:::1;83644:22;::::0;::::1;:::i;:::-;-1:-1:-1::0;83644:22:0::1;::::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;;;;48647:1;83407:267:::0;;:::o;47608:27::-;;;;:::o;72012:22::-;;;;;;:::o;46270:94::-;46328:7;46270:94;:::o;72334:28::-;;;;:::o;53229:169::-;47990:10;;-1:-1:-1;;;;;47990:10:0;47976;:24;;:54;;;48018:12;:10;:12::i;:::-;-1:-1:-1;;;;;48004:26:0;:10;-1:-1:-1;;;;;48004:26:0;;47976:54;47954:115;;;;-1:-1:-1;;;47954:115:0;;;;;;;:::i;:::-;53312:12:::1;:28:::0;;;53356:34:::1;::::0;::::1;::::0;::::1;::::0;53327:13;;53356:34:::1;:::i;47271:29::-:0;;;;:::o;46432:22::-;;;-1:-1:-1;;;;;46432:22:0;;:::o;46461:21::-;;;-1:-1:-1;;;;;46461:21:0;;:::o;85011:99::-;85056:18;85093:9;85086:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;85086:16:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85011:99;:::o;72508:30::-;;;;:::o;81072:117::-;81152:4;;:29;;-1:-1:-1;;;81152:29:0;;81118:15;;-1:-1:-1;;;;;81152:4:0;;:14;;:29;;81175:4;;81152:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;50005:202::-;47990:10;;-1:-1:-1;;;;;47990:10:0;47976;:24;;:54;;;48018:12;:10;:12::i;:::-;-1:-1:-1;;;;;48004:26:0;:10;-1:-1:-1;;;;;48004:26:0;;47976:54;47954:115;;;;-1:-1:-1;;;47954:115:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;50092:25:0;::::1;50084:34;;;::::0;::::1;;50129:10;:24:::0;;-1:-1:-1;;;;;;50129:24:0::1;-1:-1:-1::0;;;;;50129:24:0;::::1;;::::0;;50169:30:::1;::::0;::::1;::::0;::::1;::::0;50129:24;;50169:30:::1;:::i;81197:115::-:0;81276:3;;:28;;-1:-1:-1;;;81276:28:0;;81242:15;;-1:-1:-1;;;;;81276:3:0;;:13;;:28;;81298:4;;81276:28;;;:::i;68670:317::-;68759:5;;-1:-1:-1;;;;;68759:5:0;68737:10;:28;;:58;;;68783:12;:10;:12::i;:::-;-1:-1:-1;;;;;68769:26:0;:10;-1:-1:-1;;;;;68769:26:0;;68737:58;68729:67;;;;;;68859:5;;68815:40;;;-1:-1:-1;;;68815:40:0;;;;-1:-1:-1;;;;;68859:5:0;;;;68815:38;;;;;:40;;;;;;;;;;;;;;:38;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;68815:49:0;;68807:58;;;;;;68876:30;68893:12;68876:16;:30::i;:::-;68949:4;;:29;;-1:-1:-1;;;68949:29:0;;68917:62;;68935:12;;-1:-1:-1;;;;;68949:4:0;;;;:14;;:29;;68972:4;;68949:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68917:4;;-1:-1:-1;;;;;68917:4:0;;:62;:17;:62::i;72041:23::-;;;;;;;;;:::o;71976:29::-;;;;:::o;51224:263::-;48156:10;;-1:-1:-1;;;;;48156:10:0;48142;:24;48134:48;;;;-1:-1:-1;;;48134:48:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;51305:22:0;::::1;51297:31;;;::::0;::::1;;51339:5;::::0;51353:7:::1;::::0;51339:25:::1;::::0;-1:-1:-1;;;51339:25:0;;-1:-1:-1;;;;;51339:5:0;;::::1;::::0;:13:::1;::::0;:25:::1;::::0;51353:7;::::1;::::0;51339:5:::1;::::0;:25:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;51375:7:0::1;:18:::0;;-1:-1:-1;;;;;;51375:18:0::1;-1:-1:-1::0;;;;;51375:18:0;;::::1;::::0;;;::::1;::::0;;;;-1:-1:-1;51404:5:0;:35:::1;::::0;-1:-1:-1;;;51404:35:0;;:5;;::::1;::::0;:13:::1;::::0;:35:::1;::::0;51418:7;::::1;::::0;-1:-1:-1;;51435:2:0;51404:35:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;51455:24;51470:8;51455:24;;;;;;:::i;78742:627::-:0;78819:4;78835:15;78866:7;78861:434;78883:12;:19;78879:23;;;;78861:434;;;78924:17;78958:12;78971:1;78958:15;;;;;;;;;;;;;;;;;;;;;;79009:22;;;-1:-1:-1;;;79009:22:0;;;;-1:-1:-1;;;;;78958:15:0;;;;-1:-1:-1;78958:15:0;;79009:20;;:22;;;;;;;;;;78958:15;79009:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;78992:39;;;;79046:12;79075:4;;;;;;;;;-1:-1:-1;;;;;79075:4:0;-1:-1:-1;;;;;79061:29:0;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79046:46;;;;79169:7;79157:9;:19;:48;;79204:1;79157:48;;;79179:22;:9;79193:7;79179:13;:22::i;:::-;79150:2;:56;79111:11;-1:-1:-1;;;;;79111:21:0;;79141:4;79111:36;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:95;79107:177;;;79240:4;79227:17;;79263:5;;;;;79107:177;-1:-1:-1;;;78904:3:0;;78861:434;;;;79312:35;79333:13;79312:20;:35::i;:::-;:49;;;;;79351:10;79312:49;79305:56;78742:627;-1:-1:-1;;;78742:627:0:o;74257:135::-;74319:7;74346:38;74366:17;:15;:17::i;:::-;74346:15;:13;:15::i;:::-;:19;;:38::i;52675:154::-;47990:10;;-1:-1:-1;;;;;47990:10:0;47976;:24;;:54;;;48018:12;:10;:12::i;:::-;-1:-1:-1;;;;;48004:26:0;:10;-1:-1:-1;;;;;48004:26:0;;47976:54;47954:115;;;;-1:-1:-1;;;47954:115:0;;;;;;;:::i;:::-;52753:14:::1;:23:::0;;;52792:29:::1;::::0;::::1;::::0;::::1;::::0;52770:6;;52792:29:::1;:::i;46372:21::-:0;;;-1:-1:-1;;;;;46372:21:0;;:::o;69416:164::-;47990:10;;-1:-1:-1;;;;;47990:10:0;47976;:24;;:54;;;48018:12;:10;:12::i;:::-;-1:-1:-1;;;;;48004:26:0;:10;-1:-1:-1;;;;;48004:26:0;;47976:54;47954:115;;;;-1:-1:-1;;;47954:115:0;;;;;;;:::i;:::-;69479:13:::1;:20:::0;;-1:-1:-1;;69479:20:0::1;69495:4;69479:20:::0;;::::1;::::0;;;69510:5;:22:::1;::::0;;-1:-1:-1;;;69510:22:0;;;;-1:-1:-1;;;;;69510:5:0;;::::1;::::0;:20:::1;::::0;:22:::1;::::0;;::::1;::::0;69479:13:::1;::::0;69510:22;;;;;;;;69479:13;69510:5;:22;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;69550:22:0::1;::::0;::::1;::::0;-1:-1:-1;69550:22:0;;-1:-1:-1;69550:22:0::1;69416:164::o:0;13506:471::-;13564:7;13809:6;13805:47;;-1:-1:-1;13839:1:0;13832:8;;13805:47;13876:5;;;13880:1;13876;:5;:1;13900:5;;;;;:10;13892:56;;;;-1:-1:-1;;;13892:56:0;;;;;;;:::i;:::-;13968:1;-1:-1:-1;13506:471:0;;;;;:::o;36958:622::-;37328:10;;;37327:62;;-1:-1:-1;37344:39:0;;-1:-1:-1;;;37344:39:0;;-1:-1:-1;;;;;37344:15:0;;;;;:39;;37368:4;;37375:7;;37344:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;37327:62;37319:152;;;;-1:-1:-1;;;37319:152:0;;;;;;;:::i;:::-;37482:90;37502:5;37532:22;;;37556:7;37565:5;37509:62;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;37509:62:0;;;;;;;;;;;;;;-1:-1:-1;;;;;37509:62:0;-1:-1:-1;;;;;;37509:62:0;;;;;;;;;;37482:19;:90::i;:::-;36958:622;;;:::o;4322:196::-;4425:12;4457:53;4480:6;4488:4;4494:1;4497:12;4457:22;:53::i;:::-;4450:60;4322:196;-1:-1:-1;;;;4322:196:0:o;54781:98::-;54853:5;;:18;;;-1:-1:-1;;;54853:18:0;;;;54826:7;;-1:-1:-1;;;;;54853:5:0;;:16;;:18;;;;;;;;;;;;;;:5;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;78476:78::-;78535:16;78476:78;:::o;36299:177::-;36382:86;36402:5;36432:23;;;36457:2;36461:5;36409:58;;;;;;;;;:::i;76424:843::-;76501:25;76528:13;76582;76557:22;:20;:22::i;:::-;:38;76553:194;;;76632:24;:22;:24::i;:::-;76612:44;-1:-1:-1;76612:44:0;76698:36;:13;76612:44;76698:17;:36::i;:::-;76671:64;;;;;;76553:194;76759:19;76781:15;:13;:15::i;:::-;76759:37;;76827:11;76811:13;:27;76807:453;;;76855:20;76878:30;:13;76896:11;76878:17;:30::i;:::-;76855:53;;76925:35;76947:12;76925:21;:35::i;:::-;76997:40;77006:15;:13;:15::i;:::-;77023:13;76997:8;:40::i;:::-;76977:60;-1:-1:-1;77060:36:0;:13;76977:60;77060:17;:36::i;:::-;77052:44;-1:-1:-1;77113:69:0;77133:12;77147:34;:17;77169:11;77147:21;:34::i;:::-;77113:19;:69::i;:::-;76807:453;;;;77235:13;77215:33;;76807:453;76424:843;;;;;:::o;14453:132::-;14511:7;14538:39;14542:1;14545;14538:39;;;;;;;;;;;;;;;;;:3;:39::i;82364:441::-;82467:40;;:::i;:::-;82526:271;;;;;;;;-1:-1:-1;82526:271:0;;;-1:-1:-1;;;;;82526:271:0;;;;;;;;;;;82618:4;;;;;82526:271;;;;;;;;;;82658:14;;82526:271;;;;;;;;;;82725:4;82526:271;;;;;;;;;;82773:13;;82526:271;;82618:4;82526:271;;;82773:13;;-1:-1:-1;82773:13:0;;:::i;:::-;;;;-1:-1:-1;;82773:13:0;;;;;;;;;82526:271;;82519:278;82364:441;-1:-1:-1;;;;82364:441:0:o;75149:1267::-;75256:16;;75238:15;;75232:3;:21;:40;75228:79;;;75289:7;;75228:79;75319:20;75342:17;:15;:17::i;:::-;75416:9;;75319:40;;-1:-1:-1;75370:29:0;;75416:9;;75402:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;75402:24:0;;75370:56;;75437:16;75456:43;75465:16;;75483:15;:13;:15::i;:::-;75456:8;:43::i;:::-;75523:10;;75510:24;;75437:62;;-1:-1:-1;75437:62:0;;75510:24;;75523:10;;;;;;75510:24;;;;;;;;;;;:35;;;;;75589:1;75562:12;75575:10;;;;;;;;;;;75562:24;;;;;;;;;;;;;;;;:28;75558:851;;;75650:9;;75607:26;;75650:9;;75636:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;75636:24:0;-1:-1:-1;75685:10:0;;75675:21;;;;-1:-1:-1;75699:8:0;;75675:21;;75685:10;;;;;;75675:21;;;;;;;;;;;:32;;;;;75722:21;75757:51;75810:9;75821:1;75746:77;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;75722:101;;75838:45;;:::i;:::-;75886:69;;;75917:6;75886:69;;;;;;;;;;;;;;;;;;;;;;;;75917:6;75886:69;;;75917:6;75886:69;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;75886:69:0;;;;;;;;;;;;;;;;-1:-1:-1;;;75886:69:0;;;-1:-1:-1;;75886:69:0;;;;;;;;;;;;;-1:-1:-1;75886:69:0;;;;;;;;75970:13;;75993:14;;75970:77;;-1:-1:-1;;;75970:77:0;;75838:117;;-1:-1:-1;75970:13:0;;;-1:-1:-1;;;;;75970:13:0;;:22;;:77;;76017:4;;;;75838:117;;75970:77;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76064:19;76086:35;76108:12;76086:17;:15;:17::i;:::-;:21;;:35::i;:::-;76064:57;;76136:19;76169:11;76158:8;:22;:54;;76211:1;76158:54;;;76183:25;:8;76196:11;76183:12;:25::i;:::-;76136:76;;76227:15;76245:41;72582:5;76245:27;76258:13;;76245:8;:12;;:27;;;;:::i;:41::-;76227:59;;76326:7;76311:11;:22;;76303:58;;;;-1:-1:-1;;;76303:58:0;;;;;;;:::i;:::-;-1:-1:-1;;76394:3:0;76376:15;:21;-1:-1:-1;;;;75558:851:0;75149:1267;;;;:::o;12616:136::-;12674:7;12701:43;12705:1;12708;12701:43;;;;;;;;;;;;;;;;;:3;:43::i;74400:741::-;74476:15;;;74544:20;;74540:112;;74605:35;74623:16;74605:17;:35::i;:::-;74581:59;-1:-1:-1;74581:59:0;-1:-1:-1;74540:112:0;74664:18;74685:15;:13;:15::i;:::-;74664:36;;74798:20;:18;:20::i;:::-;74829:13;:11;:13::i;:::-;74855:17;74875:15;:13;:15::i;:::-;74855:35;-1:-1:-1;74913:25:0;74855:35;74927:10;74913:13;:25::i;:::-;74903:35;;74963:5;74953:7;:15;74949:185;;;74995:18;:7;75007:5;74995:11;:18::i;:::-;74985:28;;75036:1;75028:9;;74949:185;;;75078:18;:5;75088:7;75078:9;:18::i;:::-;75070:26;;75121:1;75111:11;;74949:185;74400:741;;;;;;;:::o;78061:407::-;78138:3;;-1:-1:-1;;;;;78138:3:0;:12;78151;78165:14;:12;:14::i;:::-;78138:42;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;78196:6;78191:270;78212:12;:19;78208:23;;78191:270;;;78253:12;78268;78281:1;78268:15;;;;;;;;;;;;;;;;;78316:30;;-1:-1:-1;;;78316:30:0;;-1:-1:-1;;;;;78268:15:0;;;;-1:-1:-1;78268:15:0;;78316;;:30;;78340:4;;78316:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;78298:48;-1:-1:-1;78365:11:0;;78361:89;;78397:37;;-1:-1:-1;;;78397:37:0;;-1:-1:-1;;;;;78397:14:0;;;;;:37;;78412:12;;78426:7;;78397:37;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;78361:89;-1:-1:-1;;78233:3:0;;78191:270;;63367:1744;63474:4;63496:28;;:::i;:::-;63527:5;;:31;;-1:-1:-1;;;63527:31:0;;-1:-1:-1;;;;;63527:5:0;;;;:16;;:31;;63552:4;;63527:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63496:62;;63635:6;:17;;;63656:1;63635:22;63631:40;;;63666:5;63659:12;;;;;63631:40;63816:14;;63795:17;;;;63775:38;;:15;;:19;:38::i;:::-;:55;63771:86;;;63852:5;63845:12;;;;;63771:86;63976:14;;63954:17;;;;63934:38;;:15;;:19;:38::i;:::-;:56;63930:86;;64012:4;64005:11;;;;;63930:86;64446:5;;:23;;;-1:-1:-1;;;64446:23:0;;;;64424:19;;-1:-1:-1;;;;;64446:5:0;;:21;;:23;;;;;;;;;;;;;;:5;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64424:45;;64498:13;;64484:11;:27;64480:44;;;64520:4;64513:11;;;;;;64480:44;64578:13;64594:22;:20;:22::i;:::-;64578:38;;64706:6;:16;;;64679:24;64689:13;;64679:5;:9;;:24;;;;:::i;:::-;:43;64675:60;;;64731:4;64724:11;;;;;;;64675:60;64748:14;64789:6;:16;;;64781:5;:24;64777:66;;;64826:16;;;;64816:27;;:5;;:9;:27::i;:::-;64807:36;;64777:66;65013:5;;:23;;;-1:-1:-1;;;65013:23:0;;;;64996:14;;-1:-1:-1;;;;;65013:5:0;;:21;;:23;;;;;;;;;;;;;;:5;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64996:40;-1:-1:-1;65084:18:0;64996:40;65095:6;65084:10;:18::i;:::-;65055:12;;:26;;65072:8;65055:16;:26::i;:::-;:47;;63367:1744;-1:-1:-1;;;;;;;63367:1744:0:o;12152:181::-;12210:7;12242:5;;;12266:6;;;;12258:46;;;;-1:-1:-1;;;12258:46:0;;;;;;;:::i;38604:761::-;39028:23;39054:69;39082:4;39054:69;;;;;;;;;;;;;;;;;39062:5;-1:-1:-1;;;;;39054:27:0;;;:69;;;;;:::i;:::-;39138:17;;39028:95;;-1:-1:-1;39138:21:0;39134:224;;39280:10;39269:30;;;;;;;;;;;;:::i;:::-;39261:85;;;;-1:-1:-1;;;39261:85:0;;;;;;;:::i;5699:979::-;5829:12;5862:18;5873:6;5862:10;:18::i;:::-;5854:60;;;;-1:-1:-1;;;5854:60:0;;;;;;;:::i;:::-;5988:12;6002:23;6029:6;-1:-1:-1;;;;;6029:11:0;6049:8;6060:4;6029:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5987:78;;;;6080:7;6076:595;;;6111:10;-1:-1:-1;6104:17:0;;-1:-1:-1;6104:17:0;6076:595;6225:17;;:21;6221:439;;6488:10;6482:17;6549:15;6536:10;6532:2;6528:19;6521:44;6436:148;6631:12;6624:20;;-1:-1:-1;;;6624:20:0;;;;;;;;:::i;77275:778::-;77327:18;77358:8;77369:22;:20;:22::i;:::-;77358:33;;77402:12;77417:14;:12;:14::i;:::-;77402:29;-1:-1:-1;77446:8:0;;77442:488;;77585:21;77620:54;77676:4;77682:10;;;;;;;;;;;77609:84;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;77585:108;;77708:45;;:::i;:::-;77756:70;;;77787:6;77756:70;;;;;;;;;;;;;;;;;;;;;;;;77787:6;77756:70;;;77787:6;77756:70;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;77756:70:0;;;;;;;;;;;;;;;;;;;;;;;;;77795:13;77756:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;77756:70:0;;;-1:-1:-1;;77756:70:0;;;;;;-1:-1:-1;77756:70:0;;;;;77841:13;;77864:14;;77841:77;;-1:-1:-1;;;77841:77:0;;77708:118;;-1:-1:-1;77841:13:0;;;-1:-1:-1;;;;;77841:13:0;;:22;;:77;;77888:4;;;;77708:118;;77841:77;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77442:488;;;77955:15;:13;:15::i;:::-;77942:28;;77981:36;78001:3;78006:10;77981:19;:36::i;:::-;78028:17;;77275:778;:::o;82813:532::-;82933:9;;82889:27;;82933:9;;82919:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;82919:24:0;-1:-1:-1;82965:10:0;;82954:22;;;;-1:-1:-1;82979:15:0;;82954:22;;82965:10;;;;;;82954:22;;;;;;;;;;;:40;;;;;83005:21;83040:51;83093:10;83105:14;:12;:14::i;:::-;83029:91;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;83005:115;;83131:45;;:::i;:::-;83179:70;;;83210:6;83179:70;;;;;;;;;;;;;;;;;;;;;;;;83210:6;83179:70;;;83210:6;83179:70;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;83179:70:0;;;;;;;;;;;;;;;;;;;;;;;;;83218:13;83179:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;83179:70:0;;;-1:-1:-1;;83179:70:0;;;;;;-1:-1:-1;83179:70:0;;;;;83260:13;;83283:14;;83260:77;;-1:-1:-1;;;83260:77:0;;83131:118;;-1:-1:-1;83260:13:0;;;-1:-1:-1;;;;;83260:13:0;;:22;;:77;;83307:4;;;;83131:118;;83260:77;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82813:532;;;;:::o;10824:106::-;10882:7;10913:1;10909;:5;:13;;10921:1;10909:13;;;-1:-1:-1;10917:1:0;;10824:106;-1:-1:-1;10824:106:0:o;84581:422::-;84783:19;84817:7;84805:9;:19;:48;;84852:1;84805:48;;;84827:22;:9;84841:7;84827:13;:22::i;:::-;84783:70;;84864:15;84882:43;72582:5;84882:29;84896:14;;84882:9;:13;;:29;;;;:::i;:43::-;84864:61;;84959:7;84944:11;:22;;84936:59;;;;-1:-1:-1;;;84936:59:0;;;;;;;:::i;15081:278::-;15167:7;15202:12;15195:5;15187:28;;;;-1:-1:-1;;;15187:28:0;;;;;;;;:::i;:::-;;15226:9;15242:1;15238;:5;;;;;;;15081:278;-1:-1:-1;;;;;15081:278:0:o;13055:192::-;13141:7;13177:12;13169:6;;;;13161:29;;;;-1:-1:-1;;;13161:29:0;;;;;;;;:::i;:::-;-1:-1:-1;;;13213:5:0;;;13055:192::o;80770:294::-;80820:13;80836:22;:20;:22::i;:::-;80884:5;;:31;;-1:-1:-1;;;80884:31:0;;80820:38;;-1:-1:-1;80869:12:0;;-1:-1:-1;;;;;80884:5:0;;;;:16;;:31;;80909:4;;80884:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;;;80869:56;;80948:4;80940:5;:12;80936:121;;;80969:14;80986:15;:5;80996:4;80986:9;:15::i;:::-;80969:32;;81016:29;81038:6;81016:21;:29::i;79398:1364::-;79446:7;79441:1314;79463:12;:19;79459:23;;;;79441:1314;;;79504:17;79538:12;79551:1;79538:15;;;;;;;;;;;;;;;;;;;79587:36;;-1:-1:-1;;;79587:36:0;;-1:-1:-1;;;;;79538:15:0;;;;-1:-1:-1;79538:15:0;;79587:21;;:36;;79617:4;;79587:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79570:53;;79640:14;79657:11;-1:-1:-1;;;;;79657:20:0;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79640:39;;;;79694:12;79723:4;;;;;;;;;-1:-1:-1;;;;;79723:4:0;-1:-1:-1;;;;;79709:29:0;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79694:46;;;;79789:7;79777:9;:19;:48;;79824:1;79777:48;;;79799:22;:9;79813:7;79799:13;:22::i;:::-;79770:2;:56;79761:6;:65;79757:987;;;79847:11;79861:9;79871:1;79861:12;;;;;;;;;;;;;;;;;;;;;;;:27;;-1:-1:-1;79907:43:0;79861:27;79953:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;79907:88;;80014:19;80046:6;80055:1;80046:10;80036:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;80036:21:0;;80014:43;;80092:6;80076;80083:1;80076:9;;;;;;;;;;;;;:23;;;;;80123:6;80118:309;80139:6;80135:1;:10;80118:309;;;80186:221;;;;;;;;80215:9;80225:1;80215:12;;;;;;;;;;;;;;;;;;;;:20;;80236:1;80215:23;;;;;;;;;;;;;;;;80186:221;;;;80265:1;80186:221;;;;80293:1;80297;80293:5;80186:221;;;;80325:1;80330;80325:6;:19;;80343:1;80325:19;;;80334:6;80325:19;80186:221;;;;80382:1;80371:13;;;;;;;;:::i;:::-;;;;;;;;;;;;;80186:221;;;80175:5;80181:1;80175:8;;;;;;;;;;;;;;;;;:232;80147:3;;80118:309;;;;80445:13;;;;;;;;;-1:-1:-1;;;;;80445:13:0;-1:-1:-1;;;;;80445:23:0;;80469:32;80524:5;80552:9;80562:1;80552:12;;;;;;;;;;;;;;;;;;;;:19;;80594:73;;;;;;;;80632:4;-1:-1:-1;;;;;80594:73:0;;;;;80639:5;80594:73;;;;;;80654:4;-1:-1:-1;;;;;80594:73:0;;;;;80661:5;80594:73;;;;;80690:6;80719:3;80725:2;80719:8;80445:283;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;80445:283:0;;;;;;;;;;;;:::i;:::-;;79757:987;;;;-1:-1:-1;;79484:3:0;;;;;-1:-1:-1;79441:1314:0;;-1:-1:-1;79441:1314:0;1207:619;1267:4;1735:20;;1578:66;1775:23;;;;;;:42;;-1:-1:-1;;1802:15:0;;;1767:51;-1:-1:-1;;1207:619:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;1042:746::-;;1172:3;1165:4;1157:6;1153:17;1149:27;1139:2;;-1:-1;;1180:12;1139:2;1227:6;1214:20;1249:93;1264:77;1334:6;1264:77;:::i;:::-;1249:93;:::i;:::-;1370:21;;;1240:102;-1:-1;1414:4;1427:14;;;;1402:17;;;1516;;;1507:27;;;;1504:36;-1:-1;1501:2;;;1553:1;;1543:12;1501:2;1578:1;1563:219;1588:6;1585:1;1582:13;1563:219;;;4451:6;4438:20;4463:46;4503:5;4463:46;:::i;:::-;1656:63;;1733:14;;;;1761;;;;1610:1;1603:9;1563:219;;;1567:14;;;;;1132:656;;;;:::o;3356:722::-;;3484:3;3477:4;3469:6;3465:17;3461:27;3451:2;;-1:-1;;3492:12;3451:2;3532:6;3526:13;3554:80;3569:64;3626:6;3569:64;:::i;3554:80::-;3662:21;;;3545:89;-1:-1;3706:4;3719:14;;;;3694:17;;;3808;;;3799:27;;;;3796:36;-1:-1;3793:2;;;3845:1;;3835:12;3793:2;3870:1;3855:217;3880:6;3877:1;3874:13;3855:217;;;8305:13;;3948:61;;4023:14;;;;4051;;;;3902:1;3895:9;3855:217;;4521:162;4613:13;;4631:47;4613:13;4631:47;:::i;8505:241::-;;8609:2;8597:9;8588:7;8584:23;8580:32;8577:2;;;-1:-1;;8615:12;8577:2;85:6;72:20;97:33;124:5;97:33;:::i;8753:263::-;;8868:2;8856:9;8847:7;8843:23;8839:32;8836:2;;;-1:-1;;8874:12;8836:2;226:6;220:13;238:33;265:5;238:33;:::i;9023:506::-;;;9171:2;9159:9;9150:7;9146:23;9142:32;9139:2;;;-1:-1;;9177:12;9139:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;9229:63;-1:-1;9357:2;9342:18;;;9329:32;9381:18;9370:30;;;9367:2;;;-1:-1;;9403:12;9367:2;9481:22;;;;9171:2;7469:19;;;7465:30;7462:2;;;-1:-1;;7498:12;7462:2;7526:20;9171:2;7526:20;:::i;:::-;7612:17;7599:31;9381:18;7642:6;7639:30;7636:2;;;-1:-1;;7672:12;7636:2;7763:22;;411:4;399:17;;395:27;-1:-1;385:2;;-1:-1;;426:12;385:2;473:6;460:20;495:80;510:64;567:6;510:64;:::i;495:80::-;603:21;;;660:14;;;;635:17;;;749;;;740:27;;;;737:36;-1:-1;734:2;;;-1:-1;;776:12;734:2;-1:-1;802:10;;796:206;821:6;818:1;815:13;796:206;;;4288:20;;889:50;;843:1;836:9;;;;;953:14;;;;981;;796:206;;;-1:-1;7692:100;;-1:-1;;;7868:18;;;7855:32;7896:30;;;7893:2;;;-1:-1;;7929:12;7893:2;7974:87;8057:3;8048:6;8037:9;8033:22;7974:87;:::i;:::-;9357:2;7960:5;7956:16;7949:113;;9423:90;;;;;;;9133:396;;;;;:::o;9536:821::-;;;;9749:2;9737:9;9728:7;9724:23;9720:32;9717:2;;;-1:-1;;9755:12;9717:2;9806:17;9800:24;9844:18;;9836:6;9833:30;9830:2;;;-1:-1;;9866:12;9830:2;9982:6;9971:9;9967:22;;;1964:3;1957:4;1949:6;1945:17;1941:27;1931:2;;-1:-1;;1972:12;1931:2;2012:6;2006:13;2034:94;2049:78;2120:6;2049:78;:::i;2034:94::-;2134:16;2170:6;2163:5;2156:21;2200:4;;2217:3;2213:14;2206:21;;2200:4;2192:6;2188:17;2322:3;2200:4;;2306:6;2302:17;2192:6;2293:27;;2290:36;2287:2;;;-1:-1;;2329:12;2287:2;-1:-1;2355:10;;2349:231;2374:6;2371:1;2368:13;2349:231;;;2454:62;2512:3;2500:10;2454:62;:::i;:::-;2442:75;;2396:1;2389:9;;;;;2531:14;;;;2559;;2349:231;;;-1:-1;10042:18;;10036:25;9886:113;;-1:-1;10036:25;-1:-1;;;10070:30;;;10067:2;;;-1:-1;;10103:12;10067:2;;10133:89;10214:7;10205:6;10194:9;10190:22;10133:89;:::i;:::-;10123:99;;;10259:2;10313:9;10309:22;8305:13;10267:74;;9711:646;;;;;:::o;10364:390::-;;10503:2;;10491:9;10482:7;10478:23;10474:32;10471:2;;;-1:-1;;10509:12;10471:2;10560:17;10554:24;10598:18;10590:6;10587:30;10584:2;;;-1:-1;;10620:12;10584:2;10706:22;;2731:4;2719:17;;2715:27;-1:-1;2705:2;;-1:-1;;2746:12;2705:2;2786:6;2780:13;2808:79;2823:63;2879:6;2823:63;:::i;2808:79::-;2915:21;;;2972:14;;;;2947:17;;;3061;;;3052:27;;;;3049:36;-1:-1;3046:2;;;-1:-1;;3088:12;3046:2;-1:-1;3114:10;;3108:216;3133:6;3130:1;3127:13;3108:216;;;4942:13;;3201:60;;3155:1;3148:9;;;;;3275:14;;;;3303;;3108:216;;;-1:-1;10640:98;10465:289;-1:-1;;;;;;;10465:289::o;10761:257::-;;10873:2;10861:9;10852:7;10848:23;10844:32;10841:2;;;-1:-1;;10879:12;10841:2;4167:6;4161:13;73211:5;67435:13;67428:21;73189:5;73186:32;73176:2;;-1:-1;;73222:12;11329:367;;;11453:2;11441:9;11432:7;11428:23;11424:32;11421:2;;;-1:-1;;11459:12;11421:2;11517:17;11504:31;11555:18;;11547:6;11544:30;11541:2;;;-1:-1;;11577:12;11541:2;11663:6;11652:9;11648:22;;;5134:3;5127:4;5119:6;5115:17;5111:27;5101:2;;-1:-1;;5142:12;5101:2;5185:6;5172:20;11555:18;5204:6;5201:30;5198:2;;;-1:-1;;5234:12;5198:2;5329:3;11453:2;5309:17;5270:6;5295:32;;5292:41;5289:2;;;-1:-1;;5336:12;5289:2;11453;5266:17;;;;;11597:83;;-1:-1;11415:281;;-1:-1;;;;11415:281::o;11703:362::-;;11828:2;11816:9;11807:7;11803:23;11799:32;11796:2;;;-1:-1;;11834:12;11796:2;11885:17;11879:24;11923:18;;11915:6;11912:30;11909:2;;;-1:-1;;11945:12;11909:2;12032:6;12021:9;12017:22;;;5478:3;5471:4;5463:6;5459:17;5455:27;5445:2;;-1:-1;;5486:12;5445:2;5526:6;5520:13;11923:18;61211:6;61208:30;61205:2;;;-1:-1;;61241:12;61205:2;5548:65;61314:9;61295:17;;-1:-1;;61291:33;11828:2;61372:15;5548:65;:::i;:::-;5539:74;;5633:6;5626:5;5619:21;5737:3;11828:2;5728:6;5661;5719:16;;5716:25;5713:2;;;-1:-1;;5744:12;5713:2;5764:39;5796:6;11828:2;5695:5;5691:16;11828:2;5661:6;5657:17;5764:39;:::i;:::-;-1:-1;11965:84;11790:275;-1:-1;;;;11790:275::o;12072:324::-;;12217:3;;12205:9;12196:7;12192:23;12188:33;12185:2;;;-1:-1;;12224:12;12185:2;6013:22;12217:3;6013:22;:::i;:::-;6004:31;;6159:22;8305:13;6109:16;6102:86;6255:2;6324:9;6320:22;8305:13;6255:2;6274:5;6270:16;6263:86;6415:2;6484:9;6480:22;8305:13;6415:2;6434:5;6430:16;6423:86;6575:2;6644:9;6640:22;8305:13;6575:2;6594:5;6590:16;6583:86;6736:3;6806:9;6802:22;8305:13;6736:3;6756:5;6752:16;6745:86;6897:3;6967:9;6963:22;8305:13;6897:3;6917:5;6913:16;6906:86;7058:3;7128:9;7124:22;8305:13;7058:3;7078:5;7074:16;7067:86;7219:3;7289:9;7285:22;8305:13;7219:3;7239:5;7235:16;7228:86;12276:104;;;;12179:217;;;;:::o;12403:241::-;;12507:2;12495:9;12486:7;12482:23;12478:32;12475:2;;;-1:-1;;12513:12;12475:2;-1:-1;8157:20;;12469:175;-1:-1;12469:175::o;12651:263::-;;12766:2;12754:9;12745:7;12741:23;12737:32;12734:2;;;-1:-1;;12772:12;12734:2;-1:-1;8305:13;;12728:186;-1:-1;12728:186::o;12921:617::-;;;;;13076:3;13064:9;13055:7;13051:23;13047:33;13044:2;;;-1:-1;;13083:12;13044:2;-1:-1;;8157:20;;;13235:2;13274:22;;8157:20;;-1:-1;13343:2;13382:22;;8157:20;;13451:2;13490:22;8157:20;;-1:-1;13038:500;-1:-1;13038:500::o;13545:259::-;;13658:2;13646:9;13637:7;13633:23;13629:32;13626:2;;;-1:-1;;13664:12;13626:2;8450:6;8444:13;68782:4;74161:5;68771:16;74138:5;74135:33;74125:2;;-1:-1;;74172:12;15262:127;-1:-1;;;;;67099:54;15339:45;;15333:56::o;16518:735::-;;16727:5;62717:12;64970:6;64965:3;64958:19;65007:4;;65002:3;64998:14;16739:83;;65007:4;16906:5;61519:14;-1:-1;16945:286;16970:6;16967:1;16964:13;16945:286;;;17031:13;;-1:-1;;;;;67099:54;15339:45;;14173:14;;;;64054;;;;9381:18;16985:9;16945:286;;;-1:-1;17237:10;;16645:608;-1:-1;;;;;16645:608::o;17300:787::-;;17513:5;63034:12;64970:6;64965:3;64958:19;65007:4;;65002:3;64998:14;17525:93;;61866:3;-1:-1;61856:14;65007:4;-1:-1;61885:18;-1:-1;17738:327;17763:6;17760:1;17757:13;17738:327;;;72327:11;;-1:-1;;;;;67099:54;15339:45;;14173:14;;;;9381:18;64307:14;;;;17778:9;17738:327;;18124:682;;18314:5;62717:12;64970:6;64965:3;64958:19;65007:4;;65002:3;64998:14;18326:92;;65007:4;18488:5;61519:14;-1:-1;18527:257;18552:6;18549:1;18546:13;18527:257;;;18613:13;;22847:37;;14351:14;;;;64054;;;;18574:1;18567:9;18527:257;;23016:323;;23148:5;62717:12;64970:6;64965:3;64958:19;23231:52;23276:6;65007:4;65002:3;64998:14;65007:4;23257:5;23253:16;23231:52;:::i;:::-;61314:9;72419:14;-1:-1;;72415:28;23295:39;;;;65007:4;23295:39;;23096:243;-1:-1;;23096:243::o;24995:136::-;68232:45;68271:5;68232:45;:::i;:::-;25066:60;;25060:71::o;25547:138::-;68782:4;68771:16;25624:56;;25618:67::o;32610:1056::-;;32835:16;32829:23;22854:3;22847:37;33008:4;33001:5;32997:16;32991:23;33008:4;33072:3;33068:14;22847:37;33171:4;33164:5;33160:16;33154:23;33171:4;33235:3;33231:14;22847:37;33327:4;33320:5;33316:16;33310:23;33327:4;33391:3;33387:14;22847:37;33485:4;33478:5;33474:16;33468:23;32761:4;33485;33515:3;33511:14;33504:38;33557:71;32761:4;32756:3;32752:14;33609:12;33557:71;:::i;33758:1138::-;;33997:16;33991:23;33923:4;34034:14;34027:38;34080:116;33923:4;33918:3;33914:14;34177:12;34080:116;:::i;:::-;34072:124;;34290:4;34283:5;34279:16;34273:23;34342:3;34336:4;34332:14;34290:4;34320:3;34316:14;34309:38;34362:103;34460:4;34446:12;34362:103;:::i;:::-;34354:111;;;34554:4;34547:5;34543:16;34537:23;34606:3;34600:4;34596:14;34554:4;34584:3;34580:14;34573:38;34626:71;34692:4;34678:12;34626:71;:::i;:::-;34618:79;;;34795:4;34788:5;34784:16;34778:23;67435:13;67428:21;34795:4;34853:3;34849:14;22629:34;34880:11;;;;33896:1000;;;;:::o;34986:835::-;35209:23;;-1:-1;;;;;67099:54;;;15339:45;;35395:4;35384:16;;;35378:23;67435:13;67428:21;35449:14;;;22629:34;35548:4;35537:16;;;35531:23;67099:54;;;35624:14;;;15339:45;35731:4;35720:16;;;35714:23;67435:13;67428:21;35785:14;;22629:34;35114:707::o;40122:271::-;;23506:5;62717:12;23617:52;23662:6;23657:3;23650:4;23643:5;23639:16;23617:52;:::i;:::-;23681:16;;;;;40256:137;-1:-1;;40256:137::o;40400:970::-;;-1:-1;;;27999:11;27992:43;23506:5;62717:12;23617:52;23662:6;27976:2;28058:3;28054:12;23650:4;23643:5;23639:16;23617:52;:::i;:::-;-1:-1;;;27976:2;23681:16;;;;;;32057:28;62717:12;;23617:52;62717:12;32104:11;;;23650:4;23639:16;;23617:52;:::i;:::-;23681:16;32104:11;23681:16;;40786:584;-1:-1;;;;40786:584::o;41377:222::-;-1:-1;;;;;67099:54;;;;15339:45;;41504:2;41489:18;;41475:124::o;41851:333::-;-1:-1;;;;;67099:54;;;15339:45;;67099:54;;42170:2;42155:18;;15339:45;42006:2;41991:18;;41977:207::o;42191:349::-;-1:-1;;;;;67099:54;;;;15339:45;;42526:2;42511:18;;25477:58;42354:2;42339:18;;42325:215::o;42887:478::-;43118:2;43132:47;;;62717:12;;43103:18;;;64958:19;;;42887:478;;43118:2;64998:14;;;;;;20523:17;;;20514:27;;;;61519:14;;;42887:478;20678:411;20703:6;20700:1;20697:13;20678:411;;;20755:20;;;-1:-1;;20755:20;20743:33;;20804:13;;39137:23;;39173:38;;;62717:12;;39059:14;;;64958:19;;;61519:14;;;;-1:-1;;64998:14;;;;16189:260;16214:6;16211:1;16208:13;16189:260;;;16275:13;;22847:37;;64054:14;;;;20725:1;16229:9;;;;;13965:14;;;;16189:260;;;-1:-1;39405:16;;;39399:23;39458:14;;;39442;;;39435:38;39399:23;39488:116;39462:4;39399:23;39488:116;:::i;:::-;21068:14;;;;20824:126;-1:-1;;;64054:14;;;;-1:-1;;20725:1;20718:9;20678:411;;;-1:-1;43185:170;;43089:276;-1:-1;;;;;;;;43089:276::o;43372:210::-;67435:13;;67428:21;22629:34;;43493:2;43478:18;;43464:118::o;43589:222::-;22847:37;;;43716:2;43701:18;;43687:124::o;43818:780::-;22847:37;;;-1:-1;;;;;67099:54;;;44290:2;44275:18;;15192:58;67099:54;;44389:2;44374:18;;15339:45;44117:3;44426:2;44411:18;;44404:48;;;43818:780;;44466:122;;44102:19;;44574:6;44466:122;:::i;:::-;44458:130;44088:510;-1:-1;;;;;;44088:510::o;46440:612::-;;70500:36;24823:5;70500:36;:::i;:::-;24777:3;24770:60;46683:2;46811;46800:9;46796:18;46789:48;46851:108;46683:2;46672:9;46668:18;46945:6;46851:108;:::i;:::-;46843:116;;22877:5;47038:2;47027:9;47023:18;22847:37;46654:398;;;;;;:::o;47059:456::-;47248:2;47233:18;;70500:36;24823:5;70500:36;:::i;:::-;24777:3;24770:60;22877:5;47422:2;47411:9;47407:18;22847:37;68782:4;40103:5;68771:16;47501:2;47490:9;47486:18;40075:35;47219:296;;;;;;:::o;47522:624::-;;72757:1;72750:5;72747:12;72737:2;;72763:9;72737:2;70637:36;24930:3;24923:60;47771:2;47899;47888:9;47884:18;47877:48;47939:108;47771:2;47760:9;47756:18;48033:6;47939:108;:::i;:::-;47931:116;;68782:4;68775:5;68771:16;48132:2;48121:9;48117:18;25624:56;47742:404;;;;;;:::o;48153:1504::-;;48710:3;;48699:9;48695:19;68232:45;68271:5;68232:45;:::i;:::-;25219:60;;;48839:2;48824:18;;;48817:48;;;;62717:12;;64958:19;;;;64998:14;;;;;19372:17;;;19363:27;;;;;;61519:14;;;-1:-1;19530:420;19555:6;19552:1;19549:13;19530:420;;;19607:20;;48699:9;19611:4;19607:20;;19602:3;19595:33;14541:106;14643:3;19662:6;19656:13;14541:106;:::i;:::-;19929:14;;;;19676:132;-1:-1;64054:14;;;;19577:1;19570:9;19530:420;;;19534:14;;;;49095:9;49089:4;49085:20;49080:2;49069:9;49065:18;49058:48;49120:118;49233:4;49224:6;49120:118;:::i;:::-;49112:126;;;49249:134;49379:2;49368:9;49364:18;49355:6;49249:134;:::i;:::-;49432:9;49426:4;49422:20;49416:3;49405:9;49401:19;49394:49;49457:106;49558:4;49549:6;49457:106;:::i;:::-;49449:114;;;22877:5;49642:3;49631:9;49627:19;22847:37;48681:976;;;;;;;;;:::o;49664:234::-;68782:4;68771:16;;;;25624:56;;49797:2;49782:18;;49768:130::o;49905:330::-;;50062:2;50083:17;50076:47;64970:6;50062:2;50051:9;50047:18;64958:19;71637:6;71632:3;64998:14;50051:9;64998:14;71614:30;71675:16;;;64998:14;71675:16;;;71668:27;;;;61314:9;72419:14;;;-1:-1;;72415:28;25972:39;;;50033:202;-1:-1;50033:202::o;50242:310::-;;50389:2;50410:17;50403:47;50464:78;50389:2;50378:9;50374:18;50528:6;50464:78;:::i;50559:416::-;50759:2;50773:47;;;26971:2;50744:18;;;64958:19;-1:-1;;;64998:14;;;26987:34;27040:12;;;50730:245::o;50982:416::-;51182:2;51196:47;;;27291:1;51167:18;;;64958:19;-1:-1;;;64998:14;;;27306:28;27353:12;;;51153:245::o;51405:416::-;51605:2;51619:47;;;27604:2;51590:18;;;64958:19;27640:29;64998:14;;;27620:50;27689:12;;;51576:245::o;51828:416::-;52028:2;52042:47;;;28305:2;52013:18;;;64958:19;28341:25;64998:14;;;28321:46;28386:12;;;51999:245::o;52251:416::-;52451:2;52465:47;;;28637:2;52436:18;;;64958:19;28673:34;64998:14;;;28653:55;-1:-1;;;28728:12;;;28721:25;28765:12;;;52422:245::o;52674:416::-;52874:2;52888:47;;;29016:1;52859:18;;;64958:19;-1:-1;;;64998:14;;;29031:29;29079:12;;;52845:245::o;53097:416::-;53297:2;53311:47;;;29330:1;53282:18;;;64958:19;-1:-1;;;64998:14;;;29345:30;29394:12;;;53268:245::o;53520:416::-;53720:2;53734:47;;;29645:2;53705:18;;;64958:19;29681:26;64998:14;;;29661:47;29727:12;;;53691:245::o;53943:416::-;54143:2;54157:47;;;29978:2;54128:18;;;64958:19;-1:-1;;;64998:14;;;29994:45;30058:12;;;54114:245::o;54366:416::-;54566:2;54580:47;;;30309:2;54551:18;;;64958:19;30345:31;64998:14;;;30325:52;30396:12;;;54537:245::o;54789:416::-;54989:2;55003:47;;;30647:2;54974:18;;;64958:19;-1:-1;;;64998:14;;;30663:34;30716:12;;;54960:245::o;55212:416::-;55412:2;55426:47;;;30967:2;55397:18;;;64958:19;31003:34;64998:14;;;30983:55;-1:-1;;;31058:12;;;31051:34;31104:12;;;55383:245::o;55635:416::-;55835:2;55849:47;;;31355:2;55820:18;;;64958:19;-1:-1;;;64998:14;;;31371:33;31423:12;;;55806:245::o;56058:416::-;56258:2;56272:47;;;31674:2;56243:18;;;64958:19;31710:25;64998:14;;;31690:46;31755:12;;;56229:245::o;56481:416::-;56681:2;56695:47;;;32354:2;56666:18;;;64958:19;32390:34;64998:14;;;32370:55;-1:-1;;;32445:12;;;32438:46;32503:12;;;56652:245::o;56904:856::-;;57217:3;57239:17;57232:47;37388:73;57217:3;57206:9;57202:19;37365:16;37359:23;37388:73;:::i;:::-;37543:4;37536:5;37532:16;37526:23;37555:77;37617:14;57206:9;37617:14;37603:12;37555:77;:::i;:::-;;37715:4;37708:5;37704:16;37698:23;37727:77;37789:14;57206:9;37789:14;37775:12;37727:77;:::i;:::-;;37885:4;37878:5;37874:16;37868:23;37945:14;57206:9;37945:14;22847:37;57217:3;38034:5;38030:16;38024:23;38101:14;38024:23;38101:14;57206:9;38101:14;22847:37;37617:14;38199:5;38195:16;38189:23;;;37291:6;38189:23;37291:6;57206:9;38266:14;22847:37;37789:14;38353:5;38349:16;38343:23;38323:43;;38372:63;38420:14;57206:9;38420:14;38406:12;38372:63;:::i;:::-;37945:14;38505:5;38501:16;38495:23;38475:43;;38524:63;38572:14;57206:9;38572:14;38558:12;38524:63;:::i;:::-;38101:14;38663:5;38659:18;38653:25;38633:45;;37291:6;38698:16;57206:9;38698:16;38691:40;;;38746:71;37282:16;57206:9;37282:16;38798:12;38746:71;:::i;:::-;38839:11;;57455:9;57449:4;57445:20;37543:4;57429:9;57425:18;57418:48;57480:108;57583:4;57574:6;57480:108;:::i;:::-;57472:116;;;57599:70;37715:4;57654:9;57650:18;57641:6;57599:70;:::i;:::-;57680;37885:4;57735:9;57731:18;57722:6;57680:70;:::i;:::-;57188:572;;;;;;;:::o;57996:444::-;22847:37;;;58343:2;58328:18;;22847:37;;;;58426:2;58411:18;;22847:37;58179:2;58164:18;;58150:290::o;58447:556::-;22847:37;;;58823:2;58808:18;;22847:37;;;;58906:2;58891:18;;22847:37;58989:2;58974:18;;22847:37;58658:3;58643:19;;58629:374::o;59231:256::-;59293:2;59287:9;59319:17;;;59394:18;59379:34;;59415:22;;;59376:62;59373:2;;;59451:1;;59441:12;59373:2;59293;59460:22;59271:216;;-1:-1;59271:216::o;59494:304::-;;59653:18;59645:6;59642:30;59639:2;;;-1:-1;;59675:12;59639:2;-1:-1;59720:4;59708:17;;;59773:15;;59576:222::o;67878:130::-;67941:16;72647:1;72637:12;;72627:2;;72653:9;71710:268;71775:1;71782:101;71796:6;71793:1;71790:13;71782:101;;;71863:11;;;71857:18;71844:11;;;71837:39;71818:2;71811:10;71782:101;;;71898:6;71895:1;71892:13;71889:2;;;-1:-1;;71775:1;71945:16;;71938:27;71759:219::o;72786:103::-;72867:1;72860:5;72857:12;72847:2;;72873:9;73006:117;-1:-1;;;;;67099:54;;73065:35;;73055:2;;73114:1;;73104:12
Swarm Source
ipfs://b8132eac1c27d87194d17acc03827ffcfe07f7d5eb9cd3eb78d417c4e0001383
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.