Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
StrategyConvexCvxfxsLp
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-03-04 */ // Sources flattened with hardhat v2.6.8 https://hardhat.org // File src/lib/safe-math.sol pragma solidity ^0.6.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File src/lib/context.sol pragma solidity ^0.6.0; /* * @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; } } // File src/lib/erc20.sol // File: contracts/GSN/Context.sol pragma solidity ^0.6.0; // File: contracts/token/ERC20/IERC20.sol /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File: contracts/utils/Address.sol /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: contracts/token/ERC20/ERC20.sol /** * @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 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 { } } /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File src/interfaces/uniswapv2.sol pragma solidity ^0.6.2; interface UniswapRouterV2 { function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function addLiquidity( address tokenA, address tokenB, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external returns ( uint256 amountA, uint256 amountB, uint256 liquidity ); function addLiquidityETH( address token, uint256 amountTokenDesired, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external payable returns ( uint256 amountToken, uint256 amountETH, uint256 liquidity ); function removeLiquidity( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external returns (uint256 amountA, uint256 amountB); function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts); function swapETHForExactTokens( uint256 amountOut, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); function swapExactETHForTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); } interface IUniswapV2Pair { event Approval( address indexed owner, address indexed spender, uint256 value ); event Transfer(address indexed from, address indexed to, uint256 value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address owner) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 value) external returns (bool); function transfer(address to, uint256 value) external returns (bool); function transferFrom( address from, address to, uint256 value ) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint256); function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; event Mint(address indexed sender, uint256 amount0, uint256 amount1); event Burn( address indexed sender, uint256 amount0, uint256 amount1, address indexed to ); event Swap( address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint256); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns ( uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast ); function price0CumulativeLast() external view returns (uint256); function price1CumulativeLast() external view returns (uint256); function kLast() external view returns (uint256); function mint(address to) external returns (uint256 liquidity); function burn(address to) external returns (uint256 amount0, uint256 amount1); function swap( uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data ) external; function skim(address to) external; function sync() external; } interface IUniswapV2Factory { event PairCreated( address indexed token0, address indexed token1, address pair, uint256 ); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint256) external view returns (address pair); function allPairsLength() external view returns (uint256); function feeTo() external view returns (address); function feeToSetter() external view returns (address); function createPair(address tokenA, address tokenB) external returns (address pair); } // File src/interfaces/univ3/IERC165.sol pragma solidity ^0.6.12; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File src/interfaces/univ3/IERC721.sol pragma solidity ^0.6.12; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer( address indexed from, address indexed to, uint256 indexed tokenId ); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval( address indexed owner, address indexed approved, uint256 indexed tokenId ); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll( address indexed owner, address indexed operator, bool approved ); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; } // File src/interfaces/univ3/IUniswapV3PositionsNFT.sol pragma solidity ^0.6.12; pragma experimental ABIEncoderV2; // Originally INonfungiblePositionManager interface IUniswapV3PositionsNFT is IERC721 { struct CollectParams { uint256 tokenId; address recipient; uint128 amount0Max; uint128 amount1Max; } struct MintParams { address token0; address token1; uint24 fee; int24 tickLower; int24 tickUpper; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; address recipient; uint256 deadline; } struct IncreaseLiquidityParams { uint256 tokenId; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; uint256 deadline; } /// @notice Returns the position information associated with a given token ID. /// @dev Throws if the token ID is not valid. /// @param tokenId The ID of the token that represents the position /// @return nonce The nonce for permits /// @return operator The address that is approved for spending /// @return token0 The address of the token0 for a specific pool /// @return token1 The address of the token1 for a specific pool /// @return fee The fee associated with the pool /// @return tickLower The lower end of the tick range for the position /// @return tickUpper The higher end of the tick range for the position /// @return liquidity The liquidity of the position /// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position /// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position /// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation /// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation function positions(uint256 tokenId) external view returns ( uint96 nonce, // [0] address operator, // [1] address token0, // [2] address token1, // [3] uint24 fee, // [4] int24 tickLower, // [5] int24 tickUpper, // [6] uint128 liquidity, // [7] uint256 feeGrowthInside0LastX128, // [8] uint256 feeGrowthInside1LastX128, // [9] uint128 tokensOwed0, // [10] uint128 tokensOwed1 // [11] ); function increaseLiquidity(IncreaseLiquidityParams calldata params) external payable returns ( uint128 liquidity, uint256 amount0, uint256 amount1 ); struct DecreaseLiquidityParams { uint256 tokenId; uint128 liquidity; uint256 amount0Min; uint256 amount1Min; uint256 deadline; } /// @notice Decreases the amount of liquidity in a position and accounts it to the position /// @param params tokenId The ID of the token for which liquidity is being decreased, /// amount The amount by which liquidity will be decreased, /// amount0Min The minimum amount of token0 that should be accounted for the burned liquidity, /// amount1Min The minimum amount of token1 that should be accounted for the burned liquidity, /// deadline The time by which the transaction must be included to effect the change /// @return amount0 The amount of token0 accounted to the position's tokens owed /// @return amount1 The amount of token1 accounted to the position's tokens owed function decreaseLiquidity(DecreaseLiquidityParams calldata params) external payable returns (uint256 amount0, uint256 amount1); /// @notice Collects up to a maximum amount of fees owed to a specific position to the recipient /// @param params tokenId The ID of the NFT for which tokens are being collected, /// recipient The account that should receive the tokens, /// amount0Max The maximum amount of token0 to collect, /// amount1Max The maximum amount of token1 to collect /// @return amount0 The amount of fees collected in token0 /// @return amount1 The amount of fees collected in token1 function collect(CollectParams calldata params) external payable returns (uint256 amount0, uint256 amount1); function multicall(bytes[] calldata data) external payable returns (bytes[] memory results); function mint(MintParams calldata params) external payable returns ( uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1 ); function burn(uint256 tokenId) external payable; function refundETH() external payable; function unwrapWETH9(uint256 amountMinimum, address recipient) external payable; function sweepToken( address token, uint256 amountMinimum, address recipient ) external payable; } // File src/interfaces/univ3/ISwapRouter.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.7; interface ISwapRouter { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); } interface IUniswapV3Factory { function getPool( address tokenA, address tokenB, uint24 fee ) external view returns (address pool); } // File src/interfaces/controller.sol pragma solidity ^0.6.0; interface IController { function jars(address) external view returns (address); function rewards() external view returns (address); function devfund() external view returns (address); function treasury() external view returns (address); function balanceOf(address) external view returns (uint256); function withdraw(address, uint256) external; function withdrawReward(address, uint256) external; function earn(address, uint256) external; function strategies(address) external view returns (address); } // File src/strategies/strategy-base.sol pragma solidity ^0.6.7; // Strategy Contract Basics abstract contract StrategyBase { using SafeERC20 for IERC20; using Address for address; using SafeMath for uint256; // Perfomance fees - start with 20% uint256 public performanceTreasuryFee = 0; uint256 public constant performanceTreasuryMax = 10000; uint256 public performanceDevFee = 0; uint256 public constant performanceDevMax = 10000; // Withdrawal fee 0% // - 0% to treasury // - 0% to dev fund uint256 public withdrawalTreasuryFee = 0; uint256 public constant withdrawalTreasuryMax = 100000; uint256 public withdrawalDevFundFee = 0; uint256 public constant withdrawalDevFundMax = 100000; // Tokens address public want; address public constant weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; // User accounts address public governance; address public controller; address public strategist; address public timelock; // Dex address public univ2Router2 = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; address public sushiRouter = 0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F; address public constant nonFungiblePositionManager = 0xC36442b4a4522E871399CD717aBDD847Ab11FE88; address public constant univ3Factory = 0x1F98431c8aD98523631AE4a59f267346ea31F984; address public constant univ3Router = 0xE592427A0AEce92De3Edee1F18E0157C05861564; mapping(address => bool) public harvesters; constructor( address _want, address _governance, address _strategist, address _controller, address _timelock ) public { require(_want != address(0)); require(_governance != address(0)); require(_strategist != address(0)); require(_controller != address(0)); require(_timelock != address(0)); want = _want; governance = _governance; strategist = _strategist; controller = _controller; timelock = _timelock; } // **** Modifiers **** // modifier onlyBenevolent { require( harvesters[msg.sender] || msg.sender == governance || msg.sender == strategist ); _; } // **** Views **** // function balanceOfWant() public view returns (uint256) { return IERC20(want).balanceOf(address(this)); } function balanceOfPool() public view virtual returns (uint256); function balanceOf() public view returns (uint256) { return balanceOfWant().add(balanceOfPool()); } function getName() external pure virtual returns (string memory); // **** Setters **** // function whitelistHarvesters(address[] calldata _harvesters) external { require( msg.sender == governance || msg.sender == strategist || harvesters[msg.sender], "not authorized" ); for (uint256 i = 0; i < _harvesters.length; i++) { harvesters[_harvesters[i]] = true; } } function revokeHarvesters(address[] calldata _harvesters) external { require( msg.sender == governance || msg.sender == strategist, "not authorized" ); for (uint256 i = 0; i < _harvesters.length; i++) { harvesters[_harvesters[i]] = false; } } function setWithdrawalDevFundFee(uint256 _withdrawalDevFundFee) external { require(msg.sender == timelock, "!timelock"); withdrawalDevFundFee = _withdrawalDevFundFee; } function setWithdrawalTreasuryFee(uint256 _withdrawalTreasuryFee) external { require(msg.sender == timelock, "!timelock"); withdrawalTreasuryFee = _withdrawalTreasuryFee; } function setPerformanceDevFee(uint256 _performanceDevFee) external { require(msg.sender == timelock, "!timelock"); performanceDevFee = _performanceDevFee; } function setPerformanceTreasuryFee(uint256 _performanceTreasuryFee) external { require(msg.sender == timelock, "!timelock"); performanceTreasuryFee = _performanceTreasuryFee; } function setStrategist(address _strategist) external { require(msg.sender == governance, "!governance"); strategist = _strategist; } function setGovernance(address _governance) external { require(msg.sender == governance, "!governance"); governance = _governance; } function setTimelock(address _timelock) external { require(msg.sender == timelock, "!timelock"); timelock = _timelock; } function setController(address _controller) external { require(msg.sender == timelock, "!timelock"); controller = _controller; } // **** State mutations **** // function deposit() public virtual; // Controller only function for creating additional rewards from dust function withdraw(IERC20 _asset) external returns (uint256 balance) { require(msg.sender == controller, "!controller"); require(want != address(_asset), "want"); balance = _asset.balanceOf(address(this)); _asset.safeTransfer(controller, balance); } // Withdraw partial funds, normally used with a jar withdrawal function withdraw(uint256 _amount) external { require(msg.sender == controller, "!controller"); uint256 _balance = IERC20(want).balanceOf(address(this)); if (_balance < _amount) { _amount = _withdrawSome(_amount.sub(_balance)); _amount = _amount.add(_balance); } uint256 _feeDev = _amount.mul(withdrawalDevFundFee).div( withdrawalDevFundMax ); if (_feeDev > 0) { IERC20(want).safeTransfer(IController(controller).devfund(), _feeDev); } uint256 _feeTreasury = _amount.mul(withdrawalTreasuryFee).div( withdrawalTreasuryMax ); if (_feeTreasury > 0) { IERC20(want).safeTransfer( IController(controller).treasury(), _feeTreasury ); } address _jar = IController(controller).jars(address(want)); require(_jar != address(0), "!jar"); // additional protection so we don't burn the funds IERC20(want).safeTransfer(_jar, _amount.sub(_feeDev).sub(_feeTreasury)); } // Withdraw funds, used to swap between strategies function withdrawForSwap(uint256 _amount) external returns (uint256 balance) { require(msg.sender == controller, "!controller"); _withdrawSome(_amount); balance = IERC20(want).balanceOf(address(this)); address _jar = IController(controller).jars(address(want)); require(_jar != address(0), "!jar"); IERC20(want).safeTransfer(_jar, balance); } // Withdraw all funds, normally used when migrating strategies function withdrawAll() external returns (uint256 balance) { require(msg.sender == controller, "!controller"); _withdrawAll(); balance = IERC20(want).balanceOf(address(this)); address _jar = IController(controller).jars(address(want)); require(_jar != address(0), "!jar"); // additional protection so we don't burn the funds IERC20(want).safeTransfer(_jar, balance); } function _withdrawAll() internal { _withdrawSome(balanceOfPool()); } function _withdrawSome(uint256 _amount) internal virtual returns (uint256); function harvest() public virtual; // **** Emergency functions **** function execute(address _target, bytes memory _data) public payable returns (bytes memory response) { require(msg.sender == timelock, "!timelock"); require(_target != address(0), "!target"); // call contract in current context assembly { let succeeded := delegatecall( sub(gas(), 5000), _target, add(_data, 0x20), mload(_data), 0, 0 ) let size := returndatasize() response := mload(0x40) mstore( 0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))) ) mstore(response, size) returndatacopy(add(response, 0x20), 0, size) switch iszero(succeeded) case 1 { // throw if delegatecall failed revert(add(response, 0x20), size) } } } // **** Internal functions **** function _swapUniswap( address _from, address _to, uint256 _amount ) internal { require(_to != address(0)); address[] memory path; if (_from == weth || _to == weth) { path = new address[](2); path[0] = _from; path[1] = _to; } else { path = new address[](3); path[0] = _from; path[1] = weth; path[2] = _to; } UniswapRouterV2(univ2Router2).swapExactTokensForTokens( _amount, 0, path, address(this), now.add(60) ); } function _swapUniswapWithPath(address[] memory path, uint256 _amount) internal { require(path[1] != address(0)); UniswapRouterV2(univ2Router2).swapExactTokensForTokens( _amount, 0, path, address(this), now.add(60) ); } function _swapSushiswap( address _from, address _to, uint256 _amount ) internal { require(_to != address(0)); address[] memory path; if (_from == weth || _to == weth) { path = new address[](2); path[0] = _from; path[1] = _to; } else { path = new address[](3); path[0] = _from; path[1] = weth; path[2] = _to; } UniswapRouterV2(sushiRouter).swapExactTokensForTokens( _amount, 0, path, address(this), now.add(60) ); } function _swapSushiswapWithPath(address[] memory path, uint256 _amount) internal { require(path[1] != address(0)); UniswapRouterV2(sushiRouter).swapExactTokensForTokens( _amount, 0, path, address(this), now.add(60) ); } function _distributePerformanceFeesAndDeposit() internal { uint256 _want = IERC20(want).balanceOf(address(this)); if (_want > 0) { if (performanceTreasuryFee > 0) { // Treasury fees IERC20(want).safeTransfer( IController(controller).treasury(), _want.mul(performanceTreasuryFee).div(performanceTreasuryMax) ); } if (performanceDevFee > 0) { // Performance fee IERC20(want).safeTransfer( IController(controller).devfund(), _want.mul(performanceDevFee).div(performanceDevMax) ); } deposit(); } } } // File src/interfaces/curve.sol pragma solidity ^0.6.7; interface ICurveFi_2 { function get_virtual_price() external view returns (uint256); function add_liquidity(uint256[2] calldata amounts, uint256 min_mint_amount) external; function remove_liquidity_imbalance( uint256[2] calldata amounts, uint256 max_burn_amount ) external; function remove_liquidity(uint256 _amount, uint256[2] calldata amounts) external; function exchange( int128 from, int128 to, uint256 _from_amount, uint256 _min_to_amount ) external; function balances(int128) external view returns (uint256); } interface ICurveFi_3 { function get_virtual_price() external view returns (uint256); function add_liquidity(uint256[3] calldata amounts, uint256 min_mint_amount) external; function remove_liquidity_imbalance( uint256[3] calldata amounts, uint256 max_burn_amount ) external; function remove_liquidity(uint256 _amount, uint256[3] calldata amounts) external; function exchange( int128 from, int128 to, uint256 _from_amount, uint256 _min_to_amount ) external; function balances(uint256) external view returns (uint256); } interface ICurveFi_4 { function get_virtual_price() external view returns (uint256); function add_liquidity(uint256[4] calldata amounts, uint256 min_mint_amount) external; // stETH pool function add_liquidity( uint256[2] calldata amounts, uint256 min_mint_amount ) external payable; function remove_liquidity_imbalance( uint256[4] calldata amounts, uint256 max_burn_amount ) external; function remove_liquidity(uint256 _amount, uint256[4] calldata amounts) external; function exchange( int128 from, int128 to, uint256 _from_amount, uint256 _min_to_amount ) external; function exchange_underlying( int128 from, int128 to, uint256 _from_amount, uint256 _min_to_amount ) external; function balances(int128) external view returns (uint256); } interface ICurveZap_4 { function add_liquidity( uint256[4] calldata uamounts, uint256 min_mint_amount ) external; function remove_liquidity(uint256 _amount, uint256[4] calldata min_uamounts) external; function remove_liquidity_imbalance( uint256[4] calldata uamounts, uint256 max_burn_amount ) external; function calc_withdraw_one_coin(uint256 _token_amount, int128 i) external returns (uint256); function remove_liquidity_one_coin( uint256 _token_amount, int128 i, uint256 min_uamount ) external; function remove_liquidity_one_coin( uint256 _token_amount, int128 i, uint256 min_uamount, bool donate_dust ) external; function withdraw_donated_dust() external; function coins(int128 arg0) external returns (address); function underlying_coins(int128 arg0) external returns (address); function curve() external returns (address); function token() external returns (address); } interface ICurveZap { function remove_liquidity_one_coin( uint256 _token_amount, int128 i, uint256 min_uamount ) external; } interface ICurveFi_Polygon_3 { function get_virtual_price() external view returns (uint256); function add_liquidity(uint256[3] calldata amounts, uint256 min_mint_amount) external; function add_liquidity(uint256[3] calldata amounts, uint256 min_mint_amount, bool use_underlying) external; function remove_liquidity_imbalance( uint256[3] calldata amounts, uint256 max_burn_amount ) external; function remove_liquidity(uint256 _amount, uint256[3] calldata amounts) external; function exchange( int128 from, int128 to, uint256 _from_amount, uint256 _min_to_amount ) external; function balances(uint256) external view returns (uint256); } interface ICurveGauge { function deposit(uint256 _value) external; function deposit(uint256 _value, address addr) external; function balanceOf(address arg0) external view returns (uint256); function withdraw(uint256 _value) external; function withdraw(uint256 _value, bool claim_rewards) external; function claim_rewards() external; function claim_rewards(address addr) external; function claimable_tokens(address addr) external returns (uint256); function claimable_reward(address addr) external view returns (uint256); function claimable_reward(address, address) external view returns (uint256); function integrate_fraction(address arg0) external view returns (uint256); } interface ICurveMintr { function mint(address) external; function minted(address arg0, address arg1) external view returns (uint256); } interface ICurveVotingEscrow { function locked(address arg0) external view returns (int128 amount, uint256 end); function locked__end(address _addr) external view returns (uint256); function create_lock(uint256, uint256) external; function increase_amount(uint256) external; function increase_unlock_time(uint256 _unlock_time) external; function withdraw() external; function smart_wallet_checker() external returns (address); } interface ICurveSmartContractChecker { function wallets(address) external returns (bool); function approveWallet(address _wallet) external; } // File src/interfaces/convex-farm.sol pragma solidity ^0.6.7; interface IConvexBooster { function poolInfo(uint256) external view returns ( address, address, address, address, address, bool ); function deposit( uint256, uint256, bool ) external returns (bool); function depositAll(uint256, bool) external returns (bool); function withdraw(uint256, uint256) external returns (bool); function withdrawAll(uint256) external returns (bool); function rewardClaimed( uint256, address, uint256 ) external returns (bool); } interface IBaseRewardPool { function getReward(address, bool) external returns (bool); function getReward() external returns (bool); function stake(uint256 _amount) external returns (bool); function earned(address) external view returns (uint256); function balanceOf(address) external view returns (uint256); function extraRewards(uint256) external view returns (address); function withdraw(uint256, bool) external returns (bool); function withdrawAndUnwrap(uint256, bool) external returns (bool); function extraRewardsLength() external view returns (uint256); } interface IVirtualBalanceRewardPool { function getReward(address) external; function getReward() external; function balanceOf(address) external view returns (uint256); function earned(address) external view returns (uint256); } interface IConvexToken is IERC20 { function reductionPerCliff() external view returns (uint256); function totalCliffs() external view returns (uint256); function maxSupply() external view returns (uint256); } // File src/strategies/strategy-convex-farm-base.sol pragma solidity ^0.6.7; abstract contract StrategyConvexFarmBase is StrategyBase { address public convexBooster = 0xF403C135812408BFbE8713b5A23a04b3D48AAE31; uint256 public poolId; address public constant cvx = 0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B; address public constant crv = 0xD533a949740bb3306d119CC777fa900bA034cd52; constructor( address _lp, uint256 _poolId, address _governance, address _strategist, address _controller, address _timelock ) public StrategyBase(_lp, _governance, _strategist, _controller, _timelock) { poolId = _poolId; } function getCrvRewardContract() public view returns (address) { (, , , address crvRewards, , ) = IConvexBooster(convexBooster).poolInfo( poolId ); return crvRewards; } function balanceOfPool() public view virtual override returns (uint256) { return IBaseRewardPool(getCrvRewardContract()).balanceOf(address(this)); } function get_crv_earned() public view virtual returns (uint256) { return IBaseRewardPool(getCrvRewardContract()).earned(address(this)); } function get_cvx_earned() public view virtual returns (uint256) { uint256 crv_earned = get_crv_earned(); uint256 supply = IConvexToken(cvx).totalSupply(); if (supply == 0) { return crv_earned; } uint256 reductionPerCliff = IConvexToken(cvx).reductionPerCliff(); uint256 totalCliffs = IConvexToken(cvx).totalCliffs(); uint256 cliff = supply.div(reductionPerCliff); uint256 maxSupply = IConvexToken(cvx).maxSupply(); if (cliff < totalCliffs) { uint256 reduction = totalCliffs.sub(cliff); uint256 _amount = crv_earned; _amount = _amount.mul(reduction).div(totalCliffs); //supply cap check uint256 amtTillMax = maxSupply.sub(supply); if (_amount > amtTillMax) { _amount = amtTillMax; } return _amount; } return 0; } function deposit() public virtual override { uint256 _want = IERC20(want).balanceOf(address(this)); if (_want > 0) { IERC20(want).safeApprove(convexBooster, 0); IERC20(want).safeApprove(convexBooster, _want); IConvexBooster(convexBooster).deposit(poolId, _want, true); } } function _withdrawSome(uint256 _amount) internal virtual override returns (uint256) { IBaseRewardPool(getCrvRewardContract()).withdrawAndUnwrap( _amount, false ); return _amount; } } // File src/strategies/convex/strategy-convex-cvxfxs-lp.sol pragma solidity ^0.6.7; contract StrategyConvexCvxfxsLp is StrategyConvexFarmBase { address public constant lpToken = 0xF3A43307DcAFa93275993862Aae628fCB50dC768; uint256 public constant cvxfxsPoolId = 72; address public constant pool = 0xd658A338613198204DCa1143Ac3F01A722b5d94A; address public constant fxs = 0x3432B6A60D23Ca0dFCa7761B7ab56459D9C964D0; uint24 public constant poolFee = 10000; constructor( address _governance, address _strategist, address _controller, address _timelock ) public StrategyConvexFarmBase( lpToken, cvxfxsPoolId, _governance, _strategist, _controller, _timelock ) { IERC20(cvx).safeApprove(univ3Router, uint256(-1)); IERC20(crv).safeApprove(univ3Router, uint256(-1)); IERC20(fxs).safeApprove(pool, uint256(-1)); } function getName() external pure override returns (string memory) { return "StrategyConvexCvxfxsLp"; } function get_cvx_earned() public view override returns (uint256 cvxRewards) { address cvxRewardsContract = IBaseRewardPool(getCrvRewardContract()) .extraRewards(0); cvxRewards = IBaseRewardPool(cvxRewardsContract).earned(address(this)); } function get_fxs_earned() public view returns (uint256 fxsRewards) { address fxsRewardsContract = IBaseRewardPool(getCrvRewardContract()) .extraRewards(1); fxsRewards = IBaseRewardPool(fxsRewardsContract).earned(address(this)); } function getHarvestable() public view returns ( uint256, uint256, uint256 ) { return (get_crv_earned(), get_cvx_earned(), get_fxs_earned()); } function harvest() public override onlyBenevolent { IBaseRewardPool(getCrvRewardContract()).getReward(address(this), true); uint256 _cvx = IERC20(cvx).balanceOf(address(this)); if (_cvx > 0) { ISwapRouter(univ3Router).exactInput( ISwapRouter.ExactInputParams({ path: abi.encodePacked(cvx, poolFee, weth, poolFee, fxs), recipient: address(this), deadline: block.timestamp + 300, amountIn: _cvx, amountOutMinimum: 0 }) ); } uint256 _crv = IERC20(crv).balanceOf(address(this)); if (_crv > 0) { ISwapRouter(univ3Router).exactInput( ISwapRouter.ExactInputParams({ path: abi.encodePacked(crv, poolFee, weth, poolFee, fxs), recipient: address(this), deadline: block.timestamp + 300, amountIn: _crv, amountOutMinimum: 0 }) ); } uint256 _fxs = IERC20(fxs).balanceOf(address(this)); if (_fxs > 0) { uint256[2] memory amounts = [_fxs, 0]; ICurveFi_4(pool).add_liquidity(amounts, 0); } _distributePerformanceFeesAndDeposit(); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_governance","type":"address"},{"internalType":"address","name":"_strategist","type":"address"},{"internalType":"address","name":"_controller","type":"address"},{"internalType":"address","name":"_timelock","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balanceOfPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balanceOfWant","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"convexBooster","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crv","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cvx","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cvxfxsPoolId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"execute","outputs":[{"internalType":"bytes","name":"response","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"fxs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCrvRewardContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHarvestable","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"get_crv_earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"get_cvx_earned","outputs":[{"internalType":"uint256","name":"cvxRewards","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"get_fxs_earned","outputs":[{"internalType":"uint256","name":"fxsRewards","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"harvesters","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonFungiblePositionManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"performanceDevFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"performanceDevMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"performanceTreasuryFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"performanceTreasuryMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_harvesters","type":"address[]"}],"name":"revokeHarvesters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_governance","type":"address"}],"name":"setGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_performanceDevFee","type":"uint256"}],"name":"setPerformanceDevFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_performanceTreasuryFee","type":"uint256"}],"name":"setPerformanceTreasuryFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategist","type":"address"}],"name":"setStrategist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_timelock","type":"address"}],"name":"setTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_withdrawalDevFundFee","type":"uint256"}],"name":"setWithdrawalDevFundFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_withdrawalTreasuryFee","type":"uint256"}],"name":"setWithdrawalTreasuryFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strategist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sushiRouter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timelock","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"univ2Router2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"univ3Factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"univ3Router","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"want","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_harvesters","type":"address[]"}],"name":"whitelistHarvesters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_asset","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawForSwap","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawalDevFundFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalDevFundMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalTreasuryFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalTreasuryMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405260008055600060015560006002556000600355737a250d5630b4cf539739df2c5dacb4c659f2488d600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073d9e1ce17f2641f24ae83637ab66a2cca9c378b9f600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073f403c135812408bfbe8713b5a23a04b3d48aae31600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503480156200012357600080fd5b5060405162005cd438038062005cd4833981810160405281019062000149919062000954565b73f3a43307dcafa93275993862aae628fcb50dc7686048858585858584848484600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161415620001a457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415620001df57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156200021a57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156200025557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156200029057600080fd5b84600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050505084600d819055505050505050506200046173e592427a0aece92de3edee1f18e0157c058615647fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b73ffffffffffffffffffffffffffffffffffffffff166200055f60201b6200352a179092919060201c565b620004db73e592427a0aece92de3edee1f18e0157c058615647fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff73d533a949740bb3306d119cc777fa900ba034cd5273ffffffffffffffffffffffffffffffffffffffff166200055f60201b6200352a179092919060201c565b6200055573d658a338613198204dca1143ac3f01a722b5d94a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff733432b6a60d23ca0dfca7761b7ab56459d9c964d073ffffffffffffffffffffffffffffffffffffffff166200055f60201b6200352a179092919060201c565b5050505062000dd2565b6000811480620005ff575060008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30856040518363ffffffff1660e01b8152600401620005a992919062000bdd565b60206040518083038186803b158015620005c257600080fd5b505afa158015620005d7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005fd9190620009ec565b145b62000641576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620006389062000c9f565b60405180910390fd5b620006cc8363095ea7b360e01b84846040516024016200066392919062000c0a565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050620006d160201b60201c565b505050565b60606200073a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16620007a560201b62003688179092919060201c565b9050600081511115620007a057808060200190518101906200075d9190620009c0565b6200079f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620007969062000c7d565b60405180910390fd5b5b505050565b6060620007bc8484600085620007c560201b60201c565b90509392505050565b6060620007d885620008fc60201b60201c565b6200081a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620008119062000c5b565b60405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff16858760405162000846919062000bc4565b60006040518083038185875af1925050503d806000811462000885576040519150601f19603f3d011682016040523d82523d6000602084013e6200088a565b606091505b50915091508115620008a1578092505050620008f4565b600081511115620008b55780518082602001fd5b836040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620008eb919062000c37565b60405180910390fd5b949350505050565b600080823b905060008111915050919050565b600081519050620009208162000d84565b92915050565b600081519050620009378162000d9e565b92915050565b6000815190506200094e8162000db8565b92915050565b600080600080608085870312156200096b57600080fd5b60006200097b878288016200090f565b94505060206200098e878288016200090f565b9350506040620009a1878288016200090f565b9250506060620009b4878288016200090f565b91505092959194509250565b600060208284031215620009d357600080fd5b6000620009e38482850162000926565b91505092915050565b600060208284031215620009ff57600080fd5b600062000a0f848285016200093d565b91505092915050565b62000a238162000cf3565b82525050565b600062000a368262000cc1565b62000a42818562000cd7565b935062000a5481856020860162000d3d565b80840191505092915050565b600062000a6d8262000ccc565b62000a79818562000ce2565b935062000a8b81856020860162000d3d565b62000a968162000d73565b840191505092915050565b600062000ab0601d8362000ce2565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b600062000af2602a8362000ce2565b91507f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008301527f6f742073756363656564000000000000000000000000000000000000000000006020830152604082019050919050565b600062000b5a60368362000ce2565b91507f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60008301527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006020830152604082019050919050565b62000bbe8162000d33565b82525050565b600062000bd2828462000a29565b915081905092915050565b600060408201905062000bf4600083018562000a18565b62000c03602083018462000a18565b9392505050565b600060408201905062000c21600083018562000a18565b62000c30602083018462000bb3565b9392505050565b6000602082019050818103600083015262000c53818462000a60565b905092915050565b6000602082019050818103600083015262000c768162000aa1565b9050919050565b6000602082019050818103600083015262000c988162000ae3565b9050919050565b6000602082019050818103600083015262000cba8162000b4b565b9050919050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b600062000d008262000d13565b9050919050565b60008115159050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b8381101562000d5d57808201518184015260208101905062000d40565b8381111562000d6d576000848401525b50505050565b6000601f19601f8301169050919050565b62000d8f8162000cf3565b811462000d9b57600080fd5b50565b62000da98162000d07565b811462000db557600080fd5b50565b62000dc38162000d33565b811462000dcf57600080fd5b50565b614ef28062000de26000396000f3fe6080604052600436106103505760003560e01c80636d13582c116101c6578063ab033ea9116100f7578063c6223e2611610095578063d0e30db01161006f578063d0e30db014610bf9578063d33219b414610c10578063f77c479114610c3b578063fe1f8f7a14610c6657610350565b8063c6223e2614610b6a578063c65e324214610ba7578063c7b9d53014610bd057610350565b8063b9e37489116100d1578063b9e3748914610ac0578063bdacb30314610aeb578063bf28fa9514610b14578063c1a3d44c14610b3f57610350565b8063ab033ea914610a45578063ab73e43314610a6e578063b1f55bd414610a9757610350565b80638ccdbb7011610164578063923c1d611161013e578063923c1d611461099b57806392eefe9b146109c65780639b48fab5146109ef578063a6b614ec14610a1a57610350565b80638ccdbb701461091a5780638d4444251461094557806390e39de51461097057610350565b806382378594116101a0578063823785941461085e578063853828b61461088757806387976583146108b257806388993f22146108ef57610350565b80636d13582c146107dd578063722713f7146108085780637d4234461461083357610350565b80632e1a7d4d116102a05780634fe809cc1161023e57806359739ec41161021857806359739ec4146107315780635aa6e6751461075c5780635fcbd285146107875780636a4874a1146107b257610350565b80634fe809cc1461069e57806351cff8d9146106c957806351f3d0b81461070657610350565b80633e0dc34e1161027a5780633e0dc34e146106065780633fc8cef3146106315780634641257d1461065c578063479119be1461067357610350565b80632e1a7d4d14610587578063303b669d146105b05780633ced1929146105db57610350565b80631cff79cd1161030d578063249fb9b4116102e7578063249fb9b4146104dd57806326dd2c2a1461050657806326e886c6146105315780632cdacb501461055c57610350565b80631cff79cd146104575780631f1fcd51146104875780631fe4a686146104b257610350565b80630547104d14610355578063089fe6aa146103825780630e364fb6146103ad57806311588086146103d657806316f0115b1461040157806317d7de7c1461042c575b600080fd5b34801561036157600080fd5b5061036a610c91565b60405161037993929190614c1f565b60405180910390f35b34801561038e57600080fd5b50610397610cb9565b6040516103a49190614b89565b60405180910390f35b3480156103b957600080fd5b506103d460048036038101906103cf919061415b565b610cbf565b005b3480156103e257600080fd5b506103eb610e93565b6040516103f89190614ba4565b60405180910390f35b34801561040d57600080fd5b50610416610f2a565b6040516104239190614893565b60405180910390f35b34801561043857600080fd5b50610441610f42565b60405161044e91906149c5565b60405180910390f35b610471600480360381019061046c9190614107565b610f7f565b60405161047e919061496d565b60405180910390f35b34801561049357600080fd5b5061049c6110d1565b6040516104a99190614893565b60405180910390f35b3480156104be57600080fd5b506104c76110f7565b6040516104d49190614893565b60405180910390f35b3480156104e957600080fd5b5061050460048036038101906104ff91906141f2565b61111d565b005b34801561051257600080fd5b5061051b6111b7565b6040516105289190614893565b60405180910390f35b34801561053d57600080fd5b506105466111cf565b6040516105539190614ba4565b60405180910390f35b34801561056857600080fd5b506105716111d5565b60405161057e9190614893565b60405180910390f35b34801561059357600080fd5b506105ae60048036038101906105a991906141f2565b6111fb565b005b3480156105bc57600080fd5b506105c5611776565b6040516105d29190614ba4565b60405180910390f35b3480156105e757600080fd5b506105f061177b565b6040516105fd9190614893565b60405180910390f35b34801561061257600080fd5b5061061b611793565b6040516106289190614ba4565b60405180910390f35b34801561063d57600080fd5b50610646611799565b6040516106539190614893565b60405180910390f35b34801561066857600080fd5b506106716117b1565b005b34801561067f57600080fd5b50610688611e8e565b6040516106959190614ba4565b60405180910390f35b3480156106aa57600080fd5b506106b3611e95565b6040516106c09190614ba4565b60405180910390f35b3480156106d557600080fd5b506106f060048036038101906106eb91906141c9565b611e9b565b6040516106fd9190614ba4565b60405180910390f35b34801561071257600080fd5b5061071b61209b565b6040516107289190614ba4565b60405180910390f35b34801561073d57600080fd5b506107466120a1565b6040516107539190614ba4565b60405180910390f35b34801561076857600080fd5b506107716120a7565b60405161077e9190614893565b60405180910390f35b34801561079357600080fd5b5061079c6120cd565b6040516107a99190614893565b60405180910390f35b3480156107be57600080fd5b506107c76120e5565b6040516107d49190614893565b60405180910390f35b3480156107e957600080fd5b506107f26120fd565b6040516107ff9190614893565b60405180910390f35b34801561081457600080fd5b5061081d612123565b60405161082a9190614ba4565b60405180910390f35b34801561083f57600080fd5b5061084861214b565b6040516108559190614893565b60405180910390f35b34801561086a57600080fd5b50610885600480360381019061088091906141f2565b612163565b005b34801561089357600080fd5b5061089c6121fd565b6040516108a99190614ba4565b60405180910390f35b3480156108be57600080fd5b506108d960048036038101906108d4919061402c565b6124d6565b6040516108e69190614952565b60405180910390f35b3480156108fb57600080fd5b506109046124f6565b6040516109119190614ba4565b60405180910390f35b34801561092657600080fd5b5061092f6124fc565b60405161093c9190614ba4565b60405180910390f35b34801561095157600080fd5b5061095a612502565b6040516109679190614ba4565b60405180910390f35b34801561097c57600080fd5b50610985612598565b6040516109929190614893565b60405180910390f35b3480156109a757600080fd5b506109b0612656565b6040516109bd9190614893565b60405180910390f35b3480156109d257600080fd5b506109ed60048036038101906109e8919061402c565b61266e565b005b3480156109fb57600080fd5b50610a04612742565b604051610a119190614893565b60405180910390f35b348015610a2657600080fd5b50610a2f61275a565b604051610a3c9190614ba4565b60405180910390f35b348015610a5157600080fd5b50610a6c6004803603810190610a67919061402c565b61287e565b005b348015610a7a57600080fd5b50610a956004803603810190610a9091906141f2565b612952565b005b348015610aa357600080fd5b50610abe6004803603810190610ab9919061415b565b6129ec565b005b348015610acc57600080fd5b50610ad5612b6c565b604051610ae29190614893565b60405180910390f35b348015610af757600080fd5b50610b126004803603810190610b0d919061402c565b612b92565b005b348015610b2057600080fd5b50610b29612c66565b604051610b369190614ba4565b60405180910390f35b348015610b4b57600080fd5b50610b54612d8a565b604051610b619190614ba4565b60405180910390f35b348015610b7657600080fd5b50610b916004803603810190610b8c91906141f2565b612e3c565b604051610b9e9190614ba4565b60405180910390f35b348015610bb357600080fd5b50610bce6004803603810190610bc991906141f2565b613119565b005b348015610bdc57600080fd5b50610bf76004803603810190610bf2919061402c565b6131b3565b005b348015610c0557600080fd5b50610c0e613287565b005b348015610c1c57600080fd5b50610c256134d7565b604051610c329190614893565b60405180910390f35b348015610c4757600080fd5b50610c506134fd565b604051610c5d9190614893565b60405180910390f35b348015610c7257600080fd5b50610c7b613523565b604051610c889190614ba4565b60405180910390f35b6000806000610c9e612502565b610ca661275a565b610cae612c66565b925092509250909192565b61271081565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610d685750600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b80610dbc5750600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b610dfb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df290614a87565b60405180910390fd5b60005b82829050811015610e8e576001600b6000858585818110610e1b57fe5b9050602002016020810190610e30919061402c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508080600101915050610dfe565b505050565b6000610e9d612598565b73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610ed59190614893565b60206040518083038186803b158015610eed57600080fd5b505afa158015610f01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f25919061421b565b905090565b73d658a338613198204dca1143ac3f01a722b5d94a81565b60606040518060400160405280601681526020017f5374726174656779436f6e7665784376786678734c7000000000000000000000815250905090565b6060600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611011576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161100890614b27565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611081576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107890614a07565b60405180910390fd5b600080835160208501866113885a03f43d6040519250601f19601f6020830101168301604052808352806000602085013e8115600181146110c1576110c8565b8160208501fd5b50505092915050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146111ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a490614b27565b60405180910390fd5b8060008190555050565b73c36442b4a4522e871399cd717abdd847ab11fe8881565b61271081565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461128b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128290614a27565b60405180910390fd5b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016112e89190614893565b60206040518083038186803b15801561130057600080fd5b505afa158015611314573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611338919061421b565b9050818110156113755761135d61135882846136a090919063ffffffff16565b6136ea565b9150611372818361378a90919063ffffffff16565b91505b60006113a1620186a0611393600354866137df90919063ffffffff16565b61384f90919063ffffffff16565b9050600081111561149957611498600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638d8f1e676040518163ffffffff1660e01b815260040160206040518083038186803b15801561141757600080fd5b505afa15801561142b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061144f9190614055565b82600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166138999092919063ffffffff16565b5b60006114c5620186a06114b7600254876137df90919063ffffffff16565b61384f90919063ffffffff16565b905060008111156115bd576115bc600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166361d027b36040518163ffffffff1660e01b815260040160206040518083038186803b15801561153b57600080fd5b505afa15801561154f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115739190614055565b82600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166138999092919063ffffffff16565b5b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ca6a48c2600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040161163c9190614893565b60206040518083038186803b15801561165457600080fd5b505afa158015611668573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168c9190614055565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156116fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116f590614ac7565b60405180910390fd5b61176f8161172784611719878a6136a090919063ffffffff16565b6136a090919063ffffffff16565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166138999092919063ffffffff16565b5050505050565b604881565b73e592427a0aece92de3edee1f18e0157c0586156481565b600d5481565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16806118565750600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b806118ae5750600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6118b757600080fd5b6118bf612598565b73ffffffffffffffffffffffffffffffffffffffff16637050ccd93060016040518363ffffffff1660e01b81526004016118fa9291906148d7565b602060405180830381600087803b15801561191457600080fd5b505af1158015611928573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061194c91906141a0565b506000734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161199c9190614893565b60206040518083038186803b1580156119b457600080fd5b505afa1580156119c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ec919061421b565b90506000811115611b405773e592427a0aece92de3edee1f18e0157c0586156473ffffffffffffffffffffffffffffffffffffffff1663c04b8d596040518060a00160405280734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b61271073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2612710733432b6a60d23ca0dfca7761b7ab56459d9c964d0604051602001611a8b95949392919061481d565b60405160208183030381529060405281526020013073ffffffffffffffffffffffffffffffffffffffff16815260200161012c4201815260200184815260200160008152506040518263ffffffff1660e01b8152600401611aec9190614b67565b602060405180830381600087803b158015611b0657600080fd5b505af1158015611b1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3e919061421b565b505b600073d533a949740bb3306d119cc777fa900ba034cd5273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611b8f9190614893565b60206040518083038186803b158015611ba757600080fd5b505afa158015611bbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bdf919061421b565b90506000811115611d335773e592427a0aece92de3edee1f18e0157c0586156473ffffffffffffffffffffffffffffffffffffffff1663c04b8d596040518060a0016040528073d533a949740bb3306d119cc777fa900ba034cd5261271073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2612710733432b6a60d23ca0dfca7761b7ab56459d9c964d0604051602001611c7e95949392919061481d565b60405160208183030381529060405281526020013073ffffffffffffffffffffffffffffffffffffffff16815260200161012c4201815260200184815260200160008152506040518263ffffffff1660e01b8152600401611cdf9190614b67565b602060405180830381600087803b158015611cf957600080fd5b505af1158015611d0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d31919061421b565b505b6000733432b6a60d23ca0dfca7761b7ab56459d9c964d073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611d829190614893565b60206040518083038186803b158015611d9a57600080fd5b505afa158015611dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd2919061421b565b90506000811115611e8157611de5613eee565b60405180604001604052808381526020016000815250905073d658a338613198204dca1143ac3f01a722b5d94a73ffffffffffffffffffffffffffffffffffffffff16630b4c7e4d8260006040518363ffffffff1660e01b8152600401611e4d929190614929565b600060405180830381600087803b158015611e6757600080fd5b505af1158015611e7b573d6000803e3d6000fd5b50505050505b611e8961391f565b505050565b620186a081565b61271081565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f2d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f2490614a27565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611fbe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb590614a67565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611ff79190614893565b60206040518083038186803b15801561200f57600080fd5b505afa158015612023573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612047919061421b565b9050612096600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16828473ffffffffffffffffffffffffffffffffffffffff166138999092919063ffffffff16565b919050565b60035481565b60005481565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b73f3a43307dcafa93275993862aae628fcb50dc76881565b73d533a949740bb3306d119cc777fa900ba034cd5281565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000612146612130610e93565b612138612d8a565b61378a90919063ffffffff16565b905090565b733432b6a60d23ca0dfca7761b7ab56459d9c964d081565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146121f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121ea90614b27565b60405180910390fd5b8060028190555050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461228f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228690614a27565b60405180910390fd5b612297613c22565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016122f29190614893565b60206040518083038186803b15801561230a57600080fd5b505afa15801561231e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612342919061421b565b90506000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ca6a48c2600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016123c39190614893565b60206040518083038186803b1580156123db57600080fd5b505afa1580156123ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124139190614055565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247c90614ac7565b60405180910390fd5b6124d28183600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166138999092919063ffffffff16565b5090565b600b6020528060005260406000206000915054906101000a900460ff1681565b60015481565b60025481565b600061250c612598565b73ffffffffffffffffffffffffffffffffffffffff16628cc262306040518263ffffffff1660e01b81526004016125439190614893565b60206040518083038186803b15801561255b57600080fd5b505afa15801561256f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612593919061421b565b905090565b600080600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631526fe27600d546040518263ffffffff1660e01b81526004016125f89190614ba4565b60c06040518083038186803b15801561261057600080fd5b505afa158015612624573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612648919061407e565b505093505050508091505090565b734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b81565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146126fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126f590614b27565b60405180910390fd5b80600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b731f98431c8ad98523631ae4a59f267346ea31f98481565b600080612765612598565b73ffffffffffffffffffffffffffffffffffffffff166340c3544660006040518263ffffffff1660e01b815260040161279e919061498f565b60206040518083038186803b1580156127b657600080fd5b505afa1580156127ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ee9190614055565b90508073ffffffffffffffffffffffffffffffffffffffff16628cc262306040518263ffffffff1660e01b81526004016128289190614893565b60206040518083038186803b15801561284057600080fd5b505afa158015612854573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612878919061421b565b91505090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461290e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612905906149e7565b60405180910390fd5b80600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146129e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129d990614b27565b60405180910390fd5b8060038190555050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480612a955750600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612ad4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612acb90614a87565b60405180910390fd5b60005b82829050811015612b67576000600b6000858585818110612af457fe5b9050602002016020810190612b09919061402c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508080600101915050612ad7565b505050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612c22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c1990614b27565b60405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080612c71612598565b73ffffffffffffffffffffffffffffffffffffffff166340c3544660016040518263ffffffff1660e01b8152600401612caa91906149aa565b60206040518083038186803b158015612cc257600080fd5b505afa158015612cd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cfa9190614055565b90508073ffffffffffffffffffffffffffffffffffffffff16628cc262306040518263ffffffff1660e01b8152600401612d349190614893565b60206040518083038186803b158015612d4c57600080fd5b505afa158015612d60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d84919061421b565b91505090565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401612de79190614893565b60206040518083038186803b158015612dff57600080fd5b505afa158015612e13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e37919061421b565b905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612ece576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ec590614a27565b60405180910390fd5b612ed7826136ea565b50600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401612f339190614893565b60206040518083038186803b158015612f4b57600080fd5b505afa158015612f5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f83919061421b565b90506000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ca6a48c2600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016130049190614893565b60206040518083038186803b15801561301c57600080fd5b505afa158015613030573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130549190614055565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156130c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130bd90614ac7565b60405180910390fd5b6131138183600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166138999092919063ffffffff16565b50919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146131a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131a090614b27565b60405180910390fd5b8060018190555050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613243576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161323a906149e7565b60405180910390fd5b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016132e49190614893565b60206040518083038186803b1580156132fc57600080fd5b505afa158015613310573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613334919061421b565b905060008111156134d4576133af600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661352a9092919063ffffffff16565b61341e600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661352a9092919063ffffffff16565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166343a0d066600d548360016040518463ffffffff1660e01b815260040161348093929190614be8565b602060405180830381600087803b15801561349a57600080fd5b505af11580156134ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134d291906141a0565b505b50565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b620186a081565b60008114806135c3575060008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30856040518363ffffffff1660e01b81526004016135719291906148ae565b60206040518083038186803b15801561358957600080fd5b505afa15801561359d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135c1919061421b565b145b613602576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135f990614b47565b60405180910390fd5b6136838363095ea7b360e01b8484604051602401613621929190614900565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c35565b505050565b60606136978484600085613cfc565b90509392505050565b60006136e283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613e1f565b905092915050565b60006136f4612598565b73ffffffffffffffffffffffffffffffffffffffff1663c32e72028360006040518363ffffffff1660e01b815260040161372f929190614bbf565b602060405180830381600087803b15801561374957600080fd5b505af115801561375d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061378191906141a0565b50819050919050565b6000808284019050838110156137d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137cc90614a47565b60405180910390fd5b8091505092915050565b6000808314156137f25760009050613849565b600082840290508284828161380357fe5b0414613844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161383b90614aa7565b60405180910390fd5b809150505b92915050565b600061389183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613e7a565b905092915050565b61391a8363a9059cbb60e01b84846040516024016138b8929190614900565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c35565b505050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161397c9190614893565b60206040518083038186803b15801561399457600080fd5b505afa1580156139a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139cc919061421b565b90506000811115613c1f57600080541115613af657613af5600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166361d027b36040518163ffffffff1660e01b815260040160206040518083038186803b158015613a4c57600080fd5b505afa158015613a60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a849190614055565b613aad612710613a9f600054866137df90919063ffffffff16565b61384f90919063ffffffff16565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166138999092919063ffffffff16565b5b60006001541115613c1657613c15600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638d8f1e676040518163ffffffff1660e01b815260040160206040518083038186803b158015613b6c57600080fd5b505afa158015613b80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ba49190614055565b613bcd612710613bbf600154866137df90919063ffffffff16565b61384f90919063ffffffff16565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166138999092919063ffffffff16565b5b613c1e613287565b5b50565b613c32613c2d610e93565b6136ea565b50565b6060613c97826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166136889092919063ffffffff16565b9050600081511115613cf75780806020019051810190613cb791906141a0565b613cf6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613ced90614b07565b60405180910390fd5b5b505050565b6060613d0785613edb565b613d46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d3d90614ae7565b60405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff168587604051613d70919061487c565b60006040518083038185875af1925050503d8060008114613dad576040519150601f19603f3d011682016040523d82523d6000602084013e613db2565b606091505b50915091508115613dc7578092505050613e17565b600081511115613dda5780518082602001fd5b836040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613e0e91906149c5565b60405180910390fd5b949350505050565b6000838311158290613e67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613e5e91906149c5565b60405180910390fd5b5060008385039050809150509392505050565b60008083118290613ec1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613eb891906149c5565b60405180910390fd5b506000838581613ecd57fe5b049050809150509392505050565b600080823b905060008111915050919050565b6040518060400160405280600290602082028036833780820191505090505090565b600081359050613f1f81614e60565b92915050565b600081519050613f3481614e60565b92915050565b60008083601f840112613f4c57600080fd5b8235905067ffffffffffffffff811115613f6557600080fd5b602083019150836020820283011115613f7d57600080fd5b9250929050565b600081519050613f9381614e77565b92915050565b600082601f830112613faa57600080fd5b8135613fbd613fb882614c83565b614c56565b91508082526020830160208301858383011115613fd957600080fd5b613fe4838284614dbd565b50505092915050565b600081359050613ffc81614e8e565b92915050565b60008135905061401181614ea5565b92915050565b60008151905061402681614ea5565b92915050565b60006020828403121561403e57600080fd5b600061404c84828501613f10565b91505092915050565b60006020828403121561406757600080fd5b600061407584828501613f25565b91505092915050565b60008060008060008060c0878903121561409757600080fd5b60006140a589828a01613f25565b96505060206140b689828a01613f25565b95505060406140c789828a01613f25565b94505060606140d889828a01613f25565b93505060806140e989828a01613f25565b92505060a06140fa89828a01613f84565b9150509295509295509295565b6000806040838503121561411a57600080fd5b600061412885828601613f10565b925050602083013567ffffffffffffffff81111561414557600080fd5b61415185828601613f99565b9150509250929050565b6000806020838503121561416e57600080fd5b600083013567ffffffffffffffff81111561418857600080fd5b61419485828601613f3a565b92509250509250929050565b6000602082840312156141b257600080fd5b60006141c084828501613f84565b91505092915050565b6000602082840312156141db57600080fd5b60006141e984828501613fed565b91505092915050565b60006020828403121561420457600080fd5b600061421284828501614002565b91505092915050565b60006020828403121561422d57600080fd5b600061423b84828501614017565b91505092915050565b600061425083836147ff565b60208301905092915050565b61426581614d30565b82525050565b61427481614d30565b82525050565b61428b61428682614d30565b614dff565b82525050565b61429a81614cb9565b6142a48184614ce7565b92506142af82614caf565b8060005b838110156142e05781516142c78782614244565b96506142d283614cda565b9250506001810190506142b3565b505050505050565b6142f181614d42565b82525050565b600061430282614cc4565b61430c8185614cf2565b935061431c818560208601614dcc565b61432581614e35565b840191505092915050565b600061433b82614cc4565b6143458185614d03565b9350614355818560208601614dcc565b61435e81614e35565b840191505092915050565b600061437482614cc4565b61437e8185614d14565b935061438e818560208601614dcc565b80840191505092915050565b6143a381614d99565b82525050565b6143b281614dab565b82525050565b60006143c382614ccf565b6143cd8185614d1f565b93506143dd818560208601614dcc565b6143e681614e35565b840191505092915050565b60006143fe600b83614d1f565b91507f21676f7665726e616e63650000000000000000000000000000000000000000006000830152602082019050919050565b600061443e600783614d1f565b91507f21746172676574000000000000000000000000000000000000000000000000006000830152602082019050919050565b600061447e600b83614d1f565b91507f21636f6e74726f6c6c65720000000000000000000000000000000000000000006000830152602082019050919050565b60006144be601b83614d1f565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b60006144fe600483614d1f565b91507f77616e74000000000000000000000000000000000000000000000000000000006000830152602082019050919050565b600061453e600e83614d1f565b91507f6e6f7420617574686f72697a65640000000000000000000000000000000000006000830152602082019050919050565b600061457e602183614d1f565b91507f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60008301527f77000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006145e4600483614d1f565b91507f216a6172000000000000000000000000000000000000000000000000000000006000830152602082019050919050565b6000614624601d83614d1f565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b6000614664602a83614d1f565b91507f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008301527f6f742073756363656564000000000000000000000000000000000000000000006020830152604082019050919050565b60006146ca600983614d1f565b91507f2174696d656c6f636b00000000000000000000000000000000000000000000006000830152602082019050919050565b600061470a603683614d1f565b91507f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60008301527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006020830152604082019050919050565b600060a083016000830151848203600086015261478082826142f7565b9150506020830151614795602086018261425c565b5060408301516147a860408601826147ff565b5060608301516147bb60608601826147ff565b5060808301516147ce60808601826147ff565b508091505092915050565b6147e281614d80565b82525050565b6147f96147f482614d80565b614e23565b82525050565b61480881614d8f565b82525050565b61481781614d8f565b82525050565b6000614829828861427a565b60148201915061483982876147e8565b600382019150614849828661427a565b60148201915061485982856147e8565b600382019150614869828461427a565b6014820191508190509695505050505050565b60006148888284614369565b915081905092915050565b60006020820190506148a8600083018461426b565b92915050565b60006040820190506148c3600083018561426b565b6148d0602083018461426b565b9392505050565b60006040820190506148ec600083018561426b565b6148f960208301846142e8565b9392505050565b6000604082019050614915600083018561426b565b614922602083018461480e565b9392505050565b600060608201905061493e6000830185614291565b61494b604083018461439a565b9392505050565b600060208201905061496760008301846142e8565b92915050565b600060208201905081810360008301526149878184614330565b905092915050565b60006020820190506149a4600083018461439a565b92915050565b60006020820190506149bf60008301846143a9565b92915050565b600060208201905081810360008301526149df81846143b8565b905092915050565b60006020820190508181036000830152614a00816143f1565b9050919050565b60006020820190508181036000830152614a2081614431565b9050919050565b60006020820190508181036000830152614a4081614471565b9050919050565b60006020820190508181036000830152614a60816144b1565b9050919050565b60006020820190508181036000830152614a80816144f1565b9050919050565b60006020820190508181036000830152614aa081614531565b9050919050565b60006020820190508181036000830152614ac081614571565b9050919050565b60006020820190508181036000830152614ae0816145d7565b9050919050565b60006020820190508181036000830152614b0081614617565b9050919050565b60006020820190508181036000830152614b2081614657565b9050919050565b60006020820190508181036000830152614b40816146bd565b9050919050565b60006020820190508181036000830152614b60816146fd565b9050919050565b60006020820190508181036000830152614b818184614763565b905092915050565b6000602082019050614b9e60008301846147d9565b92915050565b6000602082019050614bb9600083018461480e565b92915050565b6000604082019050614bd4600083018561480e565b614be160208301846142e8565b9392505050565b6000606082019050614bfd600083018661480e565b614c0a602083018561480e565b614c1760408301846142e8565b949350505050565b6000606082019050614c34600083018661480e565b614c41602083018561480e565b614c4e604083018461480e565b949350505050565b6000604051905081810181811067ffffffffffffffff82111715614c7957600080fd5b8060405250919050565b600067ffffffffffffffff821115614c9a57600080fd5b601f19601f8301169050602081019050919050565b6000819050919050565b600060029050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b6000614d3b82614d60565b9050919050565b60008115159050919050565b6000614d5982614d30565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062ffffff82169050919050565b6000819050919050565b6000614da482614d8f565b9050919050565b6000614db682614d8f565b9050919050565b82818337600083830152505050565b60005b83811015614dea578082015181840152602081019050614dcf565b83811115614df9576000848401525b50505050565b6000614e0a82614e11565b9050919050565b6000614e1c82614e53565b9050919050565b6000614e2e82614e46565b9050919050565b6000601f19601f8301169050919050565b60008160e81b9050919050565b60008160601b9050919050565b614e6981614d30565b8114614e7457600080fd5b50565b614e8081614d42565b8114614e8b57600080fd5b50565b614e9781614d4e565b8114614ea257600080fd5b50565b614eae81614d8f565b8114614eb957600080fd5b5056fea26469706673582212208ce2bace2ede7508a184ecd61d926c526844a85884024e8350d5d8fb7d00bf4364736f6c634300060c00330000000000000000000000009d074e37d408542fd38be78848e8814afb38db17000000000000000000000000acfe4511ce883c14c4ea40563f176c3c09b4c47c0000000000000000000000006847259b2b3a4c17e7c43c54409810af48ba5210000000000000000000000000d92c7faa0ca0e6ae4918f3a83d9832d9caeaa0d3
Deployed Bytecode
0x6080604052600436106103505760003560e01c80636d13582c116101c6578063ab033ea9116100f7578063c6223e2611610095578063d0e30db01161006f578063d0e30db014610bf9578063d33219b414610c10578063f77c479114610c3b578063fe1f8f7a14610c6657610350565b8063c6223e2614610b6a578063c65e324214610ba7578063c7b9d53014610bd057610350565b8063b9e37489116100d1578063b9e3748914610ac0578063bdacb30314610aeb578063bf28fa9514610b14578063c1a3d44c14610b3f57610350565b8063ab033ea914610a45578063ab73e43314610a6e578063b1f55bd414610a9757610350565b80638ccdbb7011610164578063923c1d611161013e578063923c1d611461099b57806392eefe9b146109c65780639b48fab5146109ef578063a6b614ec14610a1a57610350565b80638ccdbb701461091a5780638d4444251461094557806390e39de51461097057610350565b806382378594116101a0578063823785941461085e578063853828b61461088757806387976583146108b257806388993f22146108ef57610350565b80636d13582c146107dd578063722713f7146108085780637d4234461461083357610350565b80632e1a7d4d116102a05780634fe809cc1161023e57806359739ec41161021857806359739ec4146107315780635aa6e6751461075c5780635fcbd285146107875780636a4874a1146107b257610350565b80634fe809cc1461069e57806351cff8d9146106c957806351f3d0b81461070657610350565b80633e0dc34e1161027a5780633e0dc34e146106065780633fc8cef3146106315780634641257d1461065c578063479119be1461067357610350565b80632e1a7d4d14610587578063303b669d146105b05780633ced1929146105db57610350565b80631cff79cd1161030d578063249fb9b4116102e7578063249fb9b4146104dd57806326dd2c2a1461050657806326e886c6146105315780632cdacb501461055c57610350565b80631cff79cd146104575780631f1fcd51146104875780631fe4a686146104b257610350565b80630547104d14610355578063089fe6aa146103825780630e364fb6146103ad57806311588086146103d657806316f0115b1461040157806317d7de7c1461042c575b600080fd5b34801561036157600080fd5b5061036a610c91565b60405161037993929190614c1f565b60405180910390f35b34801561038e57600080fd5b50610397610cb9565b6040516103a49190614b89565b60405180910390f35b3480156103b957600080fd5b506103d460048036038101906103cf919061415b565b610cbf565b005b3480156103e257600080fd5b506103eb610e93565b6040516103f89190614ba4565b60405180910390f35b34801561040d57600080fd5b50610416610f2a565b6040516104239190614893565b60405180910390f35b34801561043857600080fd5b50610441610f42565b60405161044e91906149c5565b60405180910390f35b610471600480360381019061046c9190614107565b610f7f565b60405161047e919061496d565b60405180910390f35b34801561049357600080fd5b5061049c6110d1565b6040516104a99190614893565b60405180910390f35b3480156104be57600080fd5b506104c76110f7565b6040516104d49190614893565b60405180910390f35b3480156104e957600080fd5b5061050460048036038101906104ff91906141f2565b61111d565b005b34801561051257600080fd5b5061051b6111b7565b6040516105289190614893565b60405180910390f35b34801561053d57600080fd5b506105466111cf565b6040516105539190614ba4565b60405180910390f35b34801561056857600080fd5b506105716111d5565b60405161057e9190614893565b60405180910390f35b34801561059357600080fd5b506105ae60048036038101906105a991906141f2565b6111fb565b005b3480156105bc57600080fd5b506105c5611776565b6040516105d29190614ba4565b60405180910390f35b3480156105e757600080fd5b506105f061177b565b6040516105fd9190614893565b60405180910390f35b34801561061257600080fd5b5061061b611793565b6040516106289190614ba4565b60405180910390f35b34801561063d57600080fd5b50610646611799565b6040516106539190614893565b60405180910390f35b34801561066857600080fd5b506106716117b1565b005b34801561067f57600080fd5b50610688611e8e565b6040516106959190614ba4565b60405180910390f35b3480156106aa57600080fd5b506106b3611e95565b6040516106c09190614ba4565b60405180910390f35b3480156106d557600080fd5b506106f060048036038101906106eb91906141c9565b611e9b565b6040516106fd9190614ba4565b60405180910390f35b34801561071257600080fd5b5061071b61209b565b6040516107289190614ba4565b60405180910390f35b34801561073d57600080fd5b506107466120a1565b6040516107539190614ba4565b60405180910390f35b34801561076857600080fd5b506107716120a7565b60405161077e9190614893565b60405180910390f35b34801561079357600080fd5b5061079c6120cd565b6040516107a99190614893565b60405180910390f35b3480156107be57600080fd5b506107c76120e5565b6040516107d49190614893565b60405180910390f35b3480156107e957600080fd5b506107f26120fd565b6040516107ff9190614893565b60405180910390f35b34801561081457600080fd5b5061081d612123565b60405161082a9190614ba4565b60405180910390f35b34801561083f57600080fd5b5061084861214b565b6040516108559190614893565b60405180910390f35b34801561086a57600080fd5b50610885600480360381019061088091906141f2565b612163565b005b34801561089357600080fd5b5061089c6121fd565b6040516108a99190614ba4565b60405180910390f35b3480156108be57600080fd5b506108d960048036038101906108d4919061402c565b6124d6565b6040516108e69190614952565b60405180910390f35b3480156108fb57600080fd5b506109046124f6565b6040516109119190614ba4565b60405180910390f35b34801561092657600080fd5b5061092f6124fc565b60405161093c9190614ba4565b60405180910390f35b34801561095157600080fd5b5061095a612502565b6040516109679190614ba4565b60405180910390f35b34801561097c57600080fd5b50610985612598565b6040516109929190614893565b60405180910390f35b3480156109a757600080fd5b506109b0612656565b6040516109bd9190614893565b60405180910390f35b3480156109d257600080fd5b506109ed60048036038101906109e8919061402c565b61266e565b005b3480156109fb57600080fd5b50610a04612742565b604051610a119190614893565b60405180910390f35b348015610a2657600080fd5b50610a2f61275a565b604051610a3c9190614ba4565b60405180910390f35b348015610a5157600080fd5b50610a6c6004803603810190610a67919061402c565b61287e565b005b348015610a7a57600080fd5b50610a956004803603810190610a9091906141f2565b612952565b005b348015610aa357600080fd5b50610abe6004803603810190610ab9919061415b565b6129ec565b005b348015610acc57600080fd5b50610ad5612b6c565b604051610ae29190614893565b60405180910390f35b348015610af757600080fd5b50610b126004803603810190610b0d919061402c565b612b92565b005b348015610b2057600080fd5b50610b29612c66565b604051610b369190614ba4565b60405180910390f35b348015610b4b57600080fd5b50610b54612d8a565b604051610b619190614ba4565b60405180910390f35b348015610b7657600080fd5b50610b916004803603810190610b8c91906141f2565b612e3c565b604051610b9e9190614ba4565b60405180910390f35b348015610bb357600080fd5b50610bce6004803603810190610bc991906141f2565b613119565b005b348015610bdc57600080fd5b50610bf76004803603810190610bf2919061402c565b6131b3565b005b348015610c0557600080fd5b50610c0e613287565b005b348015610c1c57600080fd5b50610c256134d7565b604051610c329190614893565b60405180910390f35b348015610c4757600080fd5b50610c506134fd565b604051610c5d9190614893565b60405180910390f35b348015610c7257600080fd5b50610c7b613523565b604051610c889190614ba4565b60405180910390f35b6000806000610c9e612502565b610ca661275a565b610cae612c66565b925092509250909192565b61271081565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610d685750600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b80610dbc5750600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b610dfb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610df290614a87565b60405180910390fd5b60005b82829050811015610e8e576001600b6000858585818110610e1b57fe5b9050602002016020810190610e30919061402c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508080600101915050610dfe565b505050565b6000610e9d612598565b73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610ed59190614893565b60206040518083038186803b158015610eed57600080fd5b505afa158015610f01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f25919061421b565b905090565b73d658a338613198204dca1143ac3f01a722b5d94a81565b60606040518060400160405280601681526020017f5374726174656779436f6e7665784376786678734c7000000000000000000000815250905090565b6060600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611011576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161100890614b27565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611081576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107890614a07565b60405180910390fd5b600080835160208501866113885a03f43d6040519250601f19601f6020830101168301604052808352806000602085013e8115600181146110c1576110c8565b8160208501fd5b50505092915050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146111ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111a490614b27565b60405180910390fd5b8060008190555050565b73c36442b4a4522e871399cd717abdd847ab11fe8881565b61271081565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461128b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128290614a27565b60405180910390fd5b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016112e89190614893565b60206040518083038186803b15801561130057600080fd5b505afa158015611314573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611338919061421b565b9050818110156113755761135d61135882846136a090919063ffffffff16565b6136ea565b9150611372818361378a90919063ffffffff16565b91505b60006113a1620186a0611393600354866137df90919063ffffffff16565b61384f90919063ffffffff16565b9050600081111561149957611498600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638d8f1e676040518163ffffffff1660e01b815260040160206040518083038186803b15801561141757600080fd5b505afa15801561142b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061144f9190614055565b82600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166138999092919063ffffffff16565b5b60006114c5620186a06114b7600254876137df90919063ffffffff16565b61384f90919063ffffffff16565b905060008111156115bd576115bc600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166361d027b36040518163ffffffff1660e01b815260040160206040518083038186803b15801561153b57600080fd5b505afa15801561154f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115739190614055565b82600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166138999092919063ffffffff16565b5b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ca6a48c2600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b815260040161163c9190614893565b60206040518083038186803b15801561165457600080fd5b505afa158015611668573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168c9190614055565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156116fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116f590614ac7565b60405180910390fd5b61176f8161172784611719878a6136a090919063ffffffff16565b6136a090919063ffffffff16565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166138999092919063ffffffff16565b5050505050565b604881565b73e592427a0aece92de3edee1f18e0157c0586156481565b600d5481565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16806118565750600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b806118ae5750600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6118b757600080fd5b6118bf612598565b73ffffffffffffffffffffffffffffffffffffffff16637050ccd93060016040518363ffffffff1660e01b81526004016118fa9291906148d7565b602060405180830381600087803b15801561191457600080fd5b505af1158015611928573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061194c91906141a0565b506000734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b73ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161199c9190614893565b60206040518083038186803b1580156119b457600080fd5b505afa1580156119c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ec919061421b565b90506000811115611b405773e592427a0aece92de3edee1f18e0157c0586156473ffffffffffffffffffffffffffffffffffffffff1663c04b8d596040518060a00160405280734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b61271073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2612710733432b6a60d23ca0dfca7761b7ab56459d9c964d0604051602001611a8b95949392919061481d565b60405160208183030381529060405281526020013073ffffffffffffffffffffffffffffffffffffffff16815260200161012c4201815260200184815260200160008152506040518263ffffffff1660e01b8152600401611aec9190614b67565b602060405180830381600087803b158015611b0657600080fd5b505af1158015611b1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3e919061421b565b505b600073d533a949740bb3306d119cc777fa900ba034cd5273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611b8f9190614893565b60206040518083038186803b158015611ba757600080fd5b505afa158015611bbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bdf919061421b565b90506000811115611d335773e592427a0aece92de3edee1f18e0157c0586156473ffffffffffffffffffffffffffffffffffffffff1663c04b8d596040518060a0016040528073d533a949740bb3306d119cc777fa900ba034cd5261271073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2612710733432b6a60d23ca0dfca7761b7ab56459d9c964d0604051602001611c7e95949392919061481d565b60405160208183030381529060405281526020013073ffffffffffffffffffffffffffffffffffffffff16815260200161012c4201815260200184815260200160008152506040518263ffffffff1660e01b8152600401611cdf9190614b67565b602060405180830381600087803b158015611cf957600080fd5b505af1158015611d0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d31919061421b565b505b6000733432b6a60d23ca0dfca7761b7ab56459d9c964d073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611d829190614893565b60206040518083038186803b158015611d9a57600080fd5b505afa158015611dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd2919061421b565b90506000811115611e8157611de5613eee565b60405180604001604052808381526020016000815250905073d658a338613198204dca1143ac3f01a722b5d94a73ffffffffffffffffffffffffffffffffffffffff16630b4c7e4d8260006040518363ffffffff1660e01b8152600401611e4d929190614929565b600060405180830381600087803b158015611e6757600080fd5b505af1158015611e7b573d6000803e3d6000fd5b50505050505b611e8961391f565b505050565b620186a081565b61271081565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f2d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f2490614a27565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611fbe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fb590614a67565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611ff79190614893565b60206040518083038186803b15801561200f57600080fd5b505afa158015612023573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612047919061421b565b9050612096600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16828473ffffffffffffffffffffffffffffffffffffffff166138999092919063ffffffff16565b919050565b60035481565b60005481565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b73f3a43307dcafa93275993862aae628fcb50dc76881565b73d533a949740bb3306d119cc777fa900ba034cd5281565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000612146612130610e93565b612138612d8a565b61378a90919063ffffffff16565b905090565b733432b6a60d23ca0dfca7761b7ab56459d9c964d081565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146121f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121ea90614b27565b60405180910390fd5b8060028190555050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461228f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228690614a27565b60405180910390fd5b612297613c22565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016122f29190614893565b60206040518083038186803b15801561230a57600080fd5b505afa15801561231e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612342919061421b565b90506000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ca6a48c2600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016123c39190614893565b60206040518083038186803b1580156123db57600080fd5b505afa1580156123ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124139190614055565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247c90614ac7565b60405180910390fd5b6124d28183600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166138999092919063ffffffff16565b5090565b600b6020528060005260406000206000915054906101000a900460ff1681565b60015481565b60025481565b600061250c612598565b73ffffffffffffffffffffffffffffffffffffffff16628cc262306040518263ffffffff1660e01b81526004016125439190614893565b60206040518083038186803b15801561255b57600080fd5b505afa15801561256f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612593919061421b565b905090565b600080600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631526fe27600d546040518263ffffffff1660e01b81526004016125f89190614ba4565b60c06040518083038186803b15801561261057600080fd5b505afa158015612624573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612648919061407e565b505093505050508091505090565b734e3fbd56cd56c3e72c1403e103b45db9da5b9d2b81565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146126fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126f590614b27565b60405180910390fd5b80600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b731f98431c8ad98523631ae4a59f267346ea31f98481565b600080612765612598565b73ffffffffffffffffffffffffffffffffffffffff166340c3544660006040518263ffffffff1660e01b815260040161279e919061498f565b60206040518083038186803b1580156127b657600080fd5b505afa1580156127ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ee9190614055565b90508073ffffffffffffffffffffffffffffffffffffffff16628cc262306040518263ffffffff1660e01b81526004016128289190614893565b60206040518083038186803b15801561284057600080fd5b505afa158015612854573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612878919061421b565b91505090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461290e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612905906149e7565b60405180910390fd5b80600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146129e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129d990614b27565b60405180910390fd5b8060038190555050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480612a955750600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612ad4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612acb90614a87565b60405180910390fd5b60005b82829050811015612b67576000600b6000858585818110612af457fe5b9050602002016020810190612b09919061402c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508080600101915050612ad7565b505050565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612c22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c1990614b27565b60405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080612c71612598565b73ffffffffffffffffffffffffffffffffffffffff166340c3544660016040518263ffffffff1660e01b8152600401612caa91906149aa565b60206040518083038186803b158015612cc257600080fd5b505afa158015612cd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cfa9190614055565b90508073ffffffffffffffffffffffffffffffffffffffff16628cc262306040518263ffffffff1660e01b8152600401612d349190614893565b60206040518083038186803b158015612d4c57600080fd5b505afa158015612d60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d84919061421b565b91505090565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401612de79190614893565b60206040518083038186803b158015612dff57600080fd5b505afa158015612e13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e37919061421b565b905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612ece576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ec590614a27565b60405180910390fd5b612ed7826136ea565b50600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401612f339190614893565b60206040518083038186803b158015612f4b57600080fd5b505afa158015612f5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f83919061421b565b90506000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ca6a48c2600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016130049190614893565b60206040518083038186803b15801561301c57600080fd5b505afa158015613030573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130549190614055565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156130c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130bd90614ac7565b60405180910390fd5b6131138183600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166138999092919063ffffffff16565b50919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146131a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131a090614b27565b60405180910390fd5b8060018190555050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613243576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161323a906149e7565b60405180910390fd5b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016132e49190614893565b60206040518083038186803b1580156132fc57600080fd5b505afa158015613310573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613334919061421b565b905060008111156134d4576133af600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661352a9092919063ffffffff16565b61341e600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661352a9092919063ffffffff16565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166343a0d066600d548360016040518463ffffffff1660e01b815260040161348093929190614be8565b602060405180830381600087803b15801561349a57600080fd5b505af11580156134ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134d291906141a0565b505b50565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b620186a081565b60008114806135c3575060008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30856040518363ffffffff1660e01b81526004016135719291906148ae565b60206040518083038186803b15801561358957600080fd5b505afa15801561359d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135c1919061421b565b145b613602576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135f990614b47565b60405180910390fd5b6136838363095ea7b360e01b8484604051602401613621929190614900565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c35565b505050565b60606136978484600085613cfc565b90509392505050565b60006136e283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613e1f565b905092915050565b60006136f4612598565b73ffffffffffffffffffffffffffffffffffffffff1663c32e72028360006040518363ffffffff1660e01b815260040161372f929190614bbf565b602060405180830381600087803b15801561374957600080fd5b505af115801561375d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061378191906141a0565b50819050919050565b6000808284019050838110156137d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137cc90614a47565b60405180910390fd5b8091505092915050565b6000808314156137f25760009050613849565b600082840290508284828161380357fe5b0414613844576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161383b90614aa7565b60405180910390fd5b809150505b92915050565b600061389183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613e7a565b905092915050565b61391a8363a9059cbb60e01b84846040516024016138b8929190614900565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613c35565b505050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161397c9190614893565b60206040518083038186803b15801561399457600080fd5b505afa1580156139a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139cc919061421b565b90506000811115613c1f57600080541115613af657613af5600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166361d027b36040518163ffffffff1660e01b815260040160206040518083038186803b158015613a4c57600080fd5b505afa158015613a60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a849190614055565b613aad612710613a9f600054866137df90919063ffffffff16565b61384f90919063ffffffff16565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166138999092919063ffffffff16565b5b60006001541115613c1657613c15600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638d8f1e676040518163ffffffff1660e01b815260040160206040518083038186803b158015613b6c57600080fd5b505afa158015613b80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ba49190614055565b613bcd612710613bbf600154866137df90919063ffffffff16565b61384f90919063ffffffff16565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166138999092919063ffffffff16565b5b613c1e613287565b5b50565b613c32613c2d610e93565b6136ea565b50565b6060613c97826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166136889092919063ffffffff16565b9050600081511115613cf75780806020019051810190613cb791906141a0565b613cf6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613ced90614b07565b60405180910390fd5b5b505050565b6060613d0785613edb565b613d46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d3d90614ae7565b60405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff168587604051613d70919061487c565b60006040518083038185875af1925050503d8060008114613dad576040519150601f19603f3d011682016040523d82523d6000602084013e613db2565b606091505b50915091508115613dc7578092505050613e17565b600081511115613dda5780518082602001fd5b836040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613e0e91906149c5565b60405180910390fd5b949350505050565b6000838311158290613e67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613e5e91906149c5565b60405180910390fd5b5060008385039050809150509392505050565b60008083118290613ec1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613eb891906149c5565b60405180910390fd5b506000838581613ecd57fe5b049050809150509392505050565b600080823b905060008111915050919050565b6040518060400160405280600290602082028036833780820191505090505090565b600081359050613f1f81614e60565b92915050565b600081519050613f3481614e60565b92915050565b60008083601f840112613f4c57600080fd5b8235905067ffffffffffffffff811115613f6557600080fd5b602083019150836020820283011115613f7d57600080fd5b9250929050565b600081519050613f9381614e77565b92915050565b600082601f830112613faa57600080fd5b8135613fbd613fb882614c83565b614c56565b91508082526020830160208301858383011115613fd957600080fd5b613fe4838284614dbd565b50505092915050565b600081359050613ffc81614e8e565b92915050565b60008135905061401181614ea5565b92915050565b60008151905061402681614ea5565b92915050565b60006020828403121561403e57600080fd5b600061404c84828501613f10565b91505092915050565b60006020828403121561406757600080fd5b600061407584828501613f25565b91505092915050565b60008060008060008060c0878903121561409757600080fd5b60006140a589828a01613f25565b96505060206140b689828a01613f25565b95505060406140c789828a01613f25565b94505060606140d889828a01613f25565b93505060806140e989828a01613f25565b92505060a06140fa89828a01613f84565b9150509295509295509295565b6000806040838503121561411a57600080fd5b600061412885828601613f10565b925050602083013567ffffffffffffffff81111561414557600080fd5b61415185828601613f99565b9150509250929050565b6000806020838503121561416e57600080fd5b600083013567ffffffffffffffff81111561418857600080fd5b61419485828601613f3a565b92509250509250929050565b6000602082840312156141b257600080fd5b60006141c084828501613f84565b91505092915050565b6000602082840312156141db57600080fd5b60006141e984828501613fed565b91505092915050565b60006020828403121561420457600080fd5b600061421284828501614002565b91505092915050565b60006020828403121561422d57600080fd5b600061423b84828501614017565b91505092915050565b600061425083836147ff565b60208301905092915050565b61426581614d30565b82525050565b61427481614d30565b82525050565b61428b61428682614d30565b614dff565b82525050565b61429a81614cb9565b6142a48184614ce7565b92506142af82614caf565b8060005b838110156142e05781516142c78782614244565b96506142d283614cda565b9250506001810190506142b3565b505050505050565b6142f181614d42565b82525050565b600061430282614cc4565b61430c8185614cf2565b935061431c818560208601614dcc565b61432581614e35565b840191505092915050565b600061433b82614cc4565b6143458185614d03565b9350614355818560208601614dcc565b61435e81614e35565b840191505092915050565b600061437482614cc4565b61437e8185614d14565b935061438e818560208601614dcc565b80840191505092915050565b6143a381614d99565b82525050565b6143b281614dab565b82525050565b60006143c382614ccf565b6143cd8185614d1f565b93506143dd818560208601614dcc565b6143e681614e35565b840191505092915050565b60006143fe600b83614d1f565b91507f21676f7665726e616e63650000000000000000000000000000000000000000006000830152602082019050919050565b600061443e600783614d1f565b91507f21746172676574000000000000000000000000000000000000000000000000006000830152602082019050919050565b600061447e600b83614d1f565b91507f21636f6e74726f6c6c65720000000000000000000000000000000000000000006000830152602082019050919050565b60006144be601b83614d1f565b91507f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006000830152602082019050919050565b60006144fe600483614d1f565b91507f77616e74000000000000000000000000000000000000000000000000000000006000830152602082019050919050565b600061453e600e83614d1f565b91507f6e6f7420617574686f72697a65640000000000000000000000000000000000006000830152602082019050919050565b600061457e602183614d1f565b91507f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60008301527f77000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006145e4600483614d1f565b91507f216a6172000000000000000000000000000000000000000000000000000000006000830152602082019050919050565b6000614624601d83614d1f565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b6000614664602a83614d1f565b91507f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008301527f6f742073756363656564000000000000000000000000000000000000000000006020830152604082019050919050565b60006146ca600983614d1f565b91507f2174696d656c6f636b00000000000000000000000000000000000000000000006000830152602082019050919050565b600061470a603683614d1f565b91507f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60008301527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006020830152604082019050919050565b600060a083016000830151848203600086015261478082826142f7565b9150506020830151614795602086018261425c565b5060408301516147a860408601826147ff565b5060608301516147bb60608601826147ff565b5060808301516147ce60808601826147ff565b508091505092915050565b6147e281614d80565b82525050565b6147f96147f482614d80565b614e23565b82525050565b61480881614d8f565b82525050565b61481781614d8f565b82525050565b6000614829828861427a565b60148201915061483982876147e8565b600382019150614849828661427a565b60148201915061485982856147e8565b600382019150614869828461427a565b6014820191508190509695505050505050565b60006148888284614369565b915081905092915050565b60006020820190506148a8600083018461426b565b92915050565b60006040820190506148c3600083018561426b565b6148d0602083018461426b565b9392505050565b60006040820190506148ec600083018561426b565b6148f960208301846142e8565b9392505050565b6000604082019050614915600083018561426b565b614922602083018461480e565b9392505050565b600060608201905061493e6000830185614291565b61494b604083018461439a565b9392505050565b600060208201905061496760008301846142e8565b92915050565b600060208201905081810360008301526149878184614330565b905092915050565b60006020820190506149a4600083018461439a565b92915050565b60006020820190506149bf60008301846143a9565b92915050565b600060208201905081810360008301526149df81846143b8565b905092915050565b60006020820190508181036000830152614a00816143f1565b9050919050565b60006020820190508181036000830152614a2081614431565b9050919050565b60006020820190508181036000830152614a4081614471565b9050919050565b60006020820190508181036000830152614a60816144b1565b9050919050565b60006020820190508181036000830152614a80816144f1565b9050919050565b60006020820190508181036000830152614aa081614531565b9050919050565b60006020820190508181036000830152614ac081614571565b9050919050565b60006020820190508181036000830152614ae0816145d7565b9050919050565b60006020820190508181036000830152614b0081614617565b9050919050565b60006020820190508181036000830152614b2081614657565b9050919050565b60006020820190508181036000830152614b40816146bd565b9050919050565b60006020820190508181036000830152614b60816146fd565b9050919050565b60006020820190508181036000830152614b818184614763565b905092915050565b6000602082019050614b9e60008301846147d9565b92915050565b6000602082019050614bb9600083018461480e565b92915050565b6000604082019050614bd4600083018561480e565b614be160208301846142e8565b9392505050565b6000606082019050614bfd600083018661480e565b614c0a602083018561480e565b614c1760408301846142e8565b949350505050565b6000606082019050614c34600083018661480e565b614c41602083018561480e565b614c4e604083018461480e565b949350505050565b6000604051905081810181811067ffffffffffffffff82111715614c7957600080fd5b8060405250919050565b600067ffffffffffffffff821115614c9a57600080fd5b601f19601f8301169050602081019050919050565b6000819050919050565b600060029050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b6000614d3b82614d60565b9050919050565b60008115159050919050565b6000614d5982614d30565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062ffffff82169050919050565b6000819050919050565b6000614da482614d8f565b9050919050565b6000614db682614d8f565b9050919050565b82818337600083830152505050565b60005b83811015614dea578082015181840152602081019050614dcf565b83811115614df9576000848401525b50505050565b6000614e0a82614e11565b9050919050565b6000614e1c82614e53565b9050919050565b6000614e2e82614e46565b9050919050565b6000601f19601f8301169050919050565b60008160e81b9050919050565b60008160601b9050919050565b614e6981614d30565b8114614e7457600080fd5b50565b614e8081614d42565b8114614e8b57600080fd5b50565b614e9781614d4e565b8114614ea257600080fd5b50565b614eae81614d8f565b8114614eb957600080fd5b5056fea26469706673582212208ce2bace2ede7508a184ecd61d926c526844a85884024e8350d5d8fb7d00bf4364736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000009d074e37d408542fd38be78848e8814afb38db17000000000000000000000000acfe4511ce883c14c4ea40563f176c3c09b4c47c0000000000000000000000006847259b2b3a4c17e7c43c54409810af48ba5210000000000000000000000000d92c7faa0ca0e6ae4918f3a83d9832d9caeaa0d3
-----Decoded View---------------
Arg [0] : _governance (address): 0x9d074E37d408542FD38be78848e8814AFB38db17
Arg [1] : _strategist (address): 0xaCfE4511CE883C14c4eA40563F176C3C09b4c47C
Arg [2] : _controller (address): 0x6847259b2B3A4c17e7c43C54409810aF48bA5210
Arg [3] : _timelock (address): 0xD92c7fAa0Ca0e6AE4918f3a83d9832d9CAEAA0d3
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000009d074e37d408542fd38be78848e8814afb38db17
Arg [1] : 000000000000000000000000acfe4511ce883c14c4ea40563f176c3c09b4c47c
Arg [2] : 0000000000000000000000006847259b2b3a4c17e7c43c54409810af48ba5210
Arg [3] : 000000000000000000000000d92c7faa0ca0e6ae4918f3a83d9832d9caeaa0d3
Deployed Bytecode Sourcemap
70728:3336:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72434:236;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;71094:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50962:386;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68703:162;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70933:73;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71682:116;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56039:1037;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48922:19;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49116:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52277:213;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;49351:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48449:54;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67887:73;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53653:1125;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70885:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49559:89;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67967:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48948:73;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72678:1383;;;;;;;;;;;;;:::i;:::-;;48845:53;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48555:49;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53288:289;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48799:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48401:41;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49052:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70793:85;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68076:72;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49271:71;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50737:113;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71013:72;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51887:195;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55346:430;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49657:42;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48512:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48689:40;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68873:151;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68483:212;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67997:72;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52975:151;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;49462:90;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71806:315;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52661:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51688:191;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51356:324;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;49192:72;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52824:143;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72129:297;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50540:118;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54842:428;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52090:179;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;52498:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69997:345;;;;;;;;;;;;;:::i;:::-;;49148:23;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49084:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48736:54;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72434:236;72522:7;72544;72566;72609:16;:14;:16::i;:::-;72627;:14;:16::i;:::-;72645;:14;:16::i;:::-;72601:61;;;;;;72434:236;;;:::o;71094:38::-;71127:5;71094:38;:::o;50962:386::-;51079:10;;;;;;;;;;;51065:24;;:10;:24;;;:69;;;;51124:10;;;;;;;;;;;51110:24;;:10;:24;;;51065:69;:112;;;;51155:10;:22;51166:10;51155:22;;;;;;;;;;;;;;;;;;;;;;;;;51065:112;51043:176;;;;;;;;;;;;:::i;:::-;;;;;;;;;51237:9;51232:109;51256:11;;:18;;51252:1;:22;51232:109;;;51325:4;51296:10;:26;51307:11;;51319:1;51307:14;;;;;;;;;;;;;;;;;;;;:::i;:::-;51296:26;;;;;;;;;;;;;;;;:33;;;;;;;;;;;;;;;;;;51276:3;;;;;;;51232:109;;;;50962:386;;:::o;68703:162::-;68766:7;68809:22;:20;:22::i;:::-;68793:49;;;68851:4;68793:64;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68786:71;;68703:162;:::o;70933:73::-;70964:42;70933:73;:::o;71682:116::-;71733:13;71759:31;;;;;;;;;;;;;;;;;;;71682:116;:::o;56039:1037::-;56144:21;56205:8;;;;;;;;;;;56191:22;;:10;:22;;;56183:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;56265:1;56246:21;;:7;:21;;;;56238:41;;;;;;;;;;;;:::i;:::-;;;;;;;;;56556:1;56536;56511:5;56505:12;56481:4;56474:5;56470:16;56444:7;56420:4;56413:5;56409:16;56378:194;56598:16;56648:4;56642:11;56630:23;;56765:4;56761:9;56754:4;56747;56741;56737:15;56733:26;56729:42;56719:8;56715:57;56692:4;56667:120;56818:4;56808:8;56801:22;56876:4;56873:1;56866:4;56856:8;56852:19;56837:44;56911:9;56904:17;56940:1;56935:123;;;;56897:161;;56935:123;57038:4;57031;57021:8;57017:19;57010:33;56897:161;;56346:723;;;;;;:::o;48922:19::-;;;;;;;;;;;;;:::o;49116:25::-;;;;;;;;;;;;;:::o;52277:213::-;52401:8;;;;;;;;;;;52387:22;;:10;:22;;;52379:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;52459:23;52434:22;:48;;;;52277:213;:::o;49351:104::-;49413:42;49351:104;:::o;48449:54::-;48498:5;48449:54;:::o;67887:73::-;;;;;;;;;;;;;:::o;53653:1125::-;53730:10;;;;;;;;;;;53716:24;;:10;:24;;;53708:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;53767:16;53793:4;;;;;;;;;;;53786:22;;;53817:4;53786:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53767:56;;53849:7;53838:8;:18;53834:143;;;53883:36;53897:21;53909:8;53897:7;:11;;:21;;;;:::i;:::-;53883:13;:36::i;:::-;53873:46;;53944:21;53956:8;53944:7;:11;;:21;;;;:::i;:::-;53934:31;;53834:143;53989:15;54007:83;48892:6;54007:33;54019:20;;54007:7;:11;;:33;;;;:::i;:::-;:37;;:83;;;;:::i;:::-;53989:101;;54115:1;54105:7;:11;54101:113;;;54133:69;54171:10;;;;;;;;;;;54159:31;;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54194:7;54140:4;;;;;;;;;;;54133:25;;;;:69;;;;;:::i;:::-;54101:113;54226:20;54249:85;48784:6;54249:34;54261:21;;54249:7;:11;;:34;;;;:::i;:::-;:38;;:85;;;;:::i;:::-;54226:108;;54364:1;54349:12;:16;54345:173;;;54382:124;54438:10;;;;;;;;;;;54426:32;;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54479:12;54389:4;;;;;;;;;;;54382:25;;;;:124;;;;;:::i;:::-;54345:173;54530:12;54557:10;;;;;;;;;;;54545:28;;;54582:4;;;;;;;;;;;54545:43;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54530:58;;54623:1;54607:18;;:4;:18;;;;54599:35;;;;;;;;;;;;:::i;:::-;;;;;;;;;54699:71;54725:4;54731:38;54756:12;54731:20;54743:7;54731;:11;;:20;;;;:::i;:::-;:24;;:38;;;;:::i;:::-;54706:4;;;;;;;;;;;54699:25;;;;:71;;;;;:::i;:::-;53653:1125;;;;;:::o;70885:41::-;70924:2;70885:41;:::o;49559:89::-;49606:42;49559:89;:::o;67967:21::-;;;;:::o;48948:73::-;48979:42;48948:73;:::o;72678:1383::-;50360:10;:22;50371:10;50360:22;;;;;;;;;;;;;;;;;;;;;;;;;:67;;;;50417:10;;;;;;;;;;;50403:24;;:10;:24;;;50360:67;:112;;;;50462:10;;;;;;;;;;;50448:24;;:10;:24;;;50360:112;50338:145;;;;;;72755:22:::1;:20;:22::i;:::-;72739:49;;;72797:4;72804;72739:70;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;72822:12;68027:42;72837:21;;;72867:4;72837:36;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72822:51;;72897:1;72890:4;:8;72886:418;;;49606:42;72915:35;;;72969:308;;;;;;;;68027:42;71127:5;48979:42;71127:5;71043:42;73027:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;72969:308;;;;73119:4;72969:308;;;;;;73175:3;73157:15;:21;72969:308;;;;73211:4;72969:308;;;;73256:1;72969:308;;::::0;72915:377:::1;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;72886:418;73314:12;68106:42;73329:21;;;73359:4;73329:36;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73314:51;;73389:1;73382:4;:8;73378:418;;;49606:42;73407:35;;;73461:308;;;;;;;;68106:42;71127:5;48979:42;71127:5;71043:42;73519:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;73461:308;;;;73611:4;73461:308;;;;;;73667:3;73649:15;:21;73461:308;;;;73703:4;73461:308;;;;73748:1;73461:308;;::::0;73407:377:::1;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;73378:418;73806:12;71043:42;73821:21;;;73851:4;73821:36;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73806:51;;73879:1;73872:4;:8;73868:135;;;73897:25;;:::i;:::-;:37;;;;;;;;73926:4;73897:37;;;;73932:1;73897:37;;::::0;::::1;;70964:42;73949:30;;;73980:7;73989:1;73949:42;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;73868:135;;74015:38;:36;:38::i;:::-;50494:1;;;72678:1383::o:0;48845:53::-;48892:6;48845:53;:::o;48555:49::-;48599:5;48555:49;:::o;53288:289::-;53339:15;53389:10;;;;;;;;;;;53375:24;;:10;:24;;;53367:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;53450:6;53434:23;;:4;;;;;;;;;;;:23;;;;53426:40;;;;;;;;;;;;:::i;:::-;;;;;;;;;53487:6;:16;;;53512:4;53487:31;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53477:41;;53529:40;53549:10;;;;;;;;;;;53561:7;53529:6;:19;;;;:40;;;;;:::i;:::-;53288:289;;;:::o;48799:39::-;;;;:::o;48401:41::-;;;;:::o;49052:25::-;;;;;;;;;;;;;:::o;70793:85::-;70836:42;70793:85;:::o;68076:72::-;68106:42;68076:72;:::o;49271:71::-;;;;;;;;;;;;;:::o;50737:113::-;50779:7;50806:36;50826:15;:13;:15::i;:::-;50806;:13;:15::i;:::-;:19;;:36;;;;:::i;:::-;50799:43;;50737:113;:::o;71013:72::-;71043:42;71013:72;:::o;51887:195::-;51995:8;;;;;;;;;;;51981:22;;:10;:22;;;51973:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;52052:22;52028:21;:46;;;;51887:195;:::o;55346:430::-;55387:15;55437:10;;;;;;;;;;;55423:24;;:10;:24;;;55415:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;55474:14;:12;:14::i;:::-;55518:4;;;;;;;;;;;55511:22;;;55542:4;55511:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55501:47;;55561:12;55588:10;;;;;;;;;;;55576:28;;;55613:4;;;;;;;;;;;55576:43;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55561:58;;55654:1;55638:18;;:4;:18;;;;55630:35;;;;;;;;;;;;:::i;:::-;;;;;;;;;55728:40;55754:4;55760:7;55735:4;;;;;;;;;;;55728:25;;;;:40;;;;;:::i;:::-;55346:430;;:::o;49657:42::-;;;;;;;;;;;;;;;;;;;;;;:::o;48512:36::-;;;;:::o;48689:40::-;;;;:::o;68873:151::-;68928:7;68971:22;:20;:22::i;:::-;68955:46;;;69010:4;68955:61;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68948:68;;68873:151;:::o;68483:212::-;68536:7;68563:18;68604:13;;;;;;;;;;;68589:38;;;68642:6;;68589:70;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68556:103;;;;;;;68677:10;68670:17;;;68483:212;:::o;67997:72::-;68027:42;67997:72;:::o;52975:151::-;53061:8;;;;;;;;;;;53047:22;;:10;:22;;;53039:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;53107:11;53094:10;;:24;;;;;;;;;;;;;;;;;;52975:151;:::o;49462:90::-;49510:42;49462:90;:::o;71806:315::-;71898:18;71934:26;71979:22;:20;:22::i;:::-;71963:66;;;72030:1;71963:69;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71934:98;;72072:18;72056:42;;;72107:4;72056:57;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72043:70;;71806:315;;:::o;52661:155::-;52747:10;;;;;;;;;;;52733:24;;:10;:24;;;52725:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;52797:11;52784:10;;:24;;;;;;;;;;;;;;;;;;52661:155;:::o;51688:191::-;51794:8;;;;;;;;;;;51780:22;;:10;:22;;;51772:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;51850:21;51827:20;:44;;;;51688:191;:::o;51356:324::-;51470:10;;;;;;;;;;;51456:24;;:10;:24;;;:52;;;;51498:10;;;;;;;;;;;51484:24;;:10;:24;;;51456:52;51434:116;;;;;;;;;;;;:::i;:::-;;;;;;;;;51568:9;51563:110;51587:11;;:18;;51583:1;:22;51563:110;;;51656:5;51627:10;:26;51638:11;;51650:1;51638:14;;;;;;;;;;;;;;;;;;;;:::i;:::-;51627:26;;;;;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;51607:3;;;;;;;51563:110;;;;51356:324;;:::o;49192:72::-;;;;;;;;;;;;;:::o;52824:143::-;52906:8;;;;;;;;;;;52892:22;;:10;:22;;;52884:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;52950:9;52939:8;;:20;;;;;;;;;;;;;;;;;;52824:143;:::o;72129:297::-;72203:18;72239:26;72284:22;:20;:22::i;:::-;72268:66;;;72335:1;72268:69;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72239:98;;72377:18;72361:42;;;72412:4;72361:57;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72348:70;;72129:297;;:::o;50540:118::-;50586:7;50620:4;;;;;;;;;;;50613:22;;;50644:4;50613:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50606:44;;50540:118;:::o;54842:428::-;54920:15;54975:10;;;;;;;;;;;54961:24;;:10;:24;;;54953:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;55012:22;55026:7;55012:13;:22::i;:::-;;55064:4;;;;;;;;;;;55057:22;;;55088:4;55057:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55047:47;;55107:12;55134:10;;;;;;;;;;;55122:28;;;55159:4;;;;;;;;;;;55122:43;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55107:58;;55200:1;55184:18;;:4;:18;;;;55176:35;;;;;;;;;;;;:::i;:::-;;;;;;;;;55222:40;55248:4;55254:7;55229:4;;;;;;;;;;;55222:25;;;;:40;;;;;:::i;:::-;54842:428;;;;:::o;52090:179::-;52190:8;;;;;;;;;;;52176:22;;:10;:22;;;52168:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;52243:18;52223:17;:38;;;;52090:179;:::o;52498:155::-;52584:10;;;;;;;;;;;52570:24;;:10;:24;;;52562:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;52634:11;52621:10;;:24;;;;;;;;;;;;;;;;;;52498:155;:::o;69997:345::-;70051:13;70074:4;;;;;;;;;;;70067:22;;;70098:4;70067:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;70051:53;;70127:1;70119:5;:9;70115:220;;;70145:42;70170:13;;;;;;;;;;;70185:1;70152:4;;;;;;;;;;;70145:24;;;;:42;;;;;:::i;:::-;70202:46;70227:13;;;;;;;;;;;70242:5;70209:4;;;;;;;;;;;70202:24;;;;:46;;;;;:::i;:::-;70280:13;;;;;;;;;;;70265:37;;;70303:6;;70311:5;70318:4;70265:58;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;70115:220;69997:345;:::o;49148:23::-;;;;;;;;;;;;;:::o;49084:25::-;;;;;;;;;;;;;:::o;48736:54::-;48784:6;48736:54;:::o;27413:622::-;27792:1;27783:5;:10;27782:62;;;;27842:1;27799:5;:15;;;27823:4;27830:7;27799:39;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;27782:62;27774:152;;;;;;;;;;;;:::i;:::-;;;;;;;;;27937:90;27957:5;27987:22;;;28011:7;28020:5;27964:62;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27937:19;:90::i;:::-;27413:622;;;:::o;12880:196::-;12983:12;13015:53;13038:6;13046:4;13052:1;13055:12;13015:22;:53::i;:::-;13008:60;;12880:196;;;;;:::o;1428:136::-;1486:7;1513:43;1517:1;1520;1513:43;;;;;;;;;;;;;;;;;:3;:43::i;:::-;1506:50;;1428:136;;;;:::o;70350:279::-;70461:7;70502:22;:20;:22::i;:::-;70486:57;;;70558:7;70580:5;70486:110;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;70614:7;70607:14;;70350:279;;;:::o;964:181::-;1022:7;1042:9;1058:1;1054;:5;1042:17;;1083:1;1078;:6;;1070:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;1136:1;1129:8;;;964:181;;;;:::o;2318:471::-;2376:7;2626:1;2621;:6;2617:47;;;2651:1;2644:8;;;;2617:47;2676:9;2692:1;2688;:5;2676:17;;2721:1;2716;2712;:5;;;;;;:10;2704:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;2780:1;2773:8;;;2318:471;;;;;:::o;3265:132::-;3323:7;3350:39;3354:1;3357;3350:39;;;;;;;;;;;;;;;;;:3;:39::i;:::-;3343:46;;3265:132;;;;:::o;26754:177::-;26837:86;26857:5;26887:23;;;26912:2;26916:5;26864:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26837:19;:86::i;:::-;26754:177;;;:::o;59167:782::-;59235:13;59258:4;;;;;;;;;;;59251:22;;;59282:4;59251:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59235:53;;59313:1;59305:5;:9;59301:641;;;59360:1;59335:22;;:26;59331:286;;;59416:185;59476:10;;;;;;;;;;;59464:32;;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59521:61;48498:5;59521:33;59531:22;;59521:5;:9;;:33;;;;:::i;:::-;:37;;:61;;;;:::i;:::-;59423:4;;;;;;;;;;;59416:25;;;;:185;;;;;:::i;:::-;59331:286;59657:1;59637:17;;:21;59633:272;;;59715:174;59775:10;;;;;;;;;;;59763:31;;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59819:51;48599:5;59819:28;59829:17;;59819:5;:9;;:28;;;;:::i;:::-;:32;;:51;;;;:::i;:::-;59722:4;;;;;;;;;;;59715:25;;;;:174;;;;;:::i;:::-;59633:272;59921:9;:7;:9::i;:::-;59301:641;59167:782;:::o;55784:82::-;55828:30;55842:15;:13;:15::i;:::-;55828:13;:30::i;:::-;;55784:82::o;29059:761::-;29483:23;29509:69;29537:4;29509:69;;;;;;;;;;;;;;;;;29517:5;29509:27;;;;:69;;;;;:::i;:::-;29483:95;;29613:1;29593:10;:17;:21;29589:224;;;29735:10;29724:30;;;;;;;;;;;;:::i;:::-;29716:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;29589:224;29059:761;;;:::o;14257:979::-;14387:12;14420:18;14431:6;14420:10;:18::i;:::-;14412:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;14546:12;14560:23;14587:6;:11;;14607:8;14618:4;14587:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14545:78;;;;14638:7;14634:595;;;14669:10;14662:17;;;;;;14634:595;14803:1;14783:10;:17;:21;14779:439;;;15046:10;15040:17;15107:15;15094:10;15090:2;15086:19;15079:44;14994:148;15189:12;15182:20;;;;;;;;;;;:::i;:::-;;;;;;;;14257:979;;;;;;;:::o;1867:192::-;1953:7;1986:1;1981;:6;;1989:12;1973:29;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;2013:9;2029:1;2025;:5;2013:17;;2050:1;2043:8;;;1867:192;;;;;:::o;3893:278::-;3979:7;4011:1;4007;:5;4014:12;3999:28;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;4038:9;4054:1;4050;:5;;;;;;4038:17;;4162:1;4155:8;;;3893:278;;;;;:::o;9962:422::-;10022:4;10230:12;10341:7;10329:20;10321:28;;10375:1;10368:4;:8;10361:15;;;9962:422;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5:130::-;;85:6;72:20;63:29;;97:33;124:5;97:33;:::i;:::-;57:78;;;;:::o;142:134::-;;226:6;220:13;211:22;;238:33;265:5;238:33;:::i;:::-;205:71;;;;:::o;301:352::-;;;431:3;424:4;416:6;412:17;408:27;398:2;;449:1;446;439:12;398:2;482:6;469:20;459:30;;509:18;501:6;498:30;495:2;;;541:1;538;531:12;495:2;575:4;567:6;563:17;551:29;;626:3;618:4;610:6;606:17;596:8;592:32;589:41;586:2;;;643:1;640;633:12;586:2;391:262;;;;;:::o;661:128::-;;742:6;736:13;727:22;;754:30;778:5;754:30;:::i;:::-;721:68;;;;:::o;797:440::-;;898:3;891:4;883:6;879:17;875:27;865:2;;916:1;913;906:12;865:2;953:6;940:20;975:64;990:48;1031:6;990:48;:::i;:::-;975:64;:::i;:::-;966:73;;1059:6;1052:5;1045:21;1095:4;1087:6;1083:17;1128:4;1121:5;1117:16;1163:3;1154:6;1149:3;1145:16;1142:25;1139:2;;;1180:1;1177;1170:12;1139:2;1190:41;1224:6;1219:3;1214;1190:41;:::i;:::-;858:379;;;;;;;:::o;1245:158::-;;1339:6;1326:20;1317:29;;1351:47;1392:5;1351:47;:::i;:::-;1311:92;;;;:::o;1410:130::-;;1490:6;1477:20;1468:29;;1502:33;1529:5;1502:33;:::i;:::-;1462:78;;;;:::o;1547:134::-;;1631:6;1625:13;1616:22;;1643:33;1670:5;1643:33;:::i;:::-;1610:71;;;;:::o;1688:241::-;;1792:2;1780:9;1771:7;1767:23;1763:32;1760:2;;;1808:1;1805;1798:12;1760:2;1843:1;1860:53;1905:7;1896:6;1885:9;1881:22;1860:53;:::i;:::-;1850:63;;1822:97;1754:175;;;;:::o;1936:263::-;;2051:2;2039:9;2030:7;2026:23;2022:32;2019:2;;;2067:1;2064;2057:12;2019:2;2102:1;2119:64;2175:7;2166:6;2155:9;2151:22;2119:64;:::i;:::-;2109:74;;2081:108;2013:186;;;;:::o;2206:940::-;;;;;;;2403:3;2391:9;2382:7;2378:23;2374:33;2371:2;;;2420:1;2417;2410:12;2371:2;2455:1;2472:64;2528:7;2519:6;2508:9;2504:22;2472:64;:::i;:::-;2462:74;;2434:108;2573:2;2591:64;2647:7;2638:6;2627:9;2623:22;2591:64;:::i;:::-;2581:74;;2552:109;2692:2;2710:64;2766:7;2757:6;2746:9;2742:22;2710:64;:::i;:::-;2700:74;;2671:109;2811:2;2829:64;2885:7;2876:6;2865:9;2861:22;2829:64;:::i;:::-;2819:74;;2790:109;2930:3;2949:64;3005:7;2996:6;2985:9;2981:22;2949:64;:::i;:::-;2939:74;;2909:110;3050:3;3069:61;3122:7;3113:6;3102:9;3098:22;3069:61;:::i;:::-;3059:71;;3029:107;2365:781;;;;;;;;:::o;3153:470::-;;;3283:2;3271:9;3262:7;3258:23;3254:32;3251:2;;;3299:1;3296;3289:12;3251:2;3334:1;3351:53;3396:7;3387:6;3376:9;3372:22;3351:53;:::i;:::-;3341:63;;3313:97;3469:2;3458:9;3454:18;3441:32;3493:18;3485:6;3482:30;3479:2;;;3525:1;3522;3515:12;3479:2;3545:62;3599:7;3590:6;3579:9;3575:22;3545:62;:::i;:::-;3535:72;;3420:193;3245:378;;;;;:::o;3630:397::-;;;3769:2;3757:9;3748:7;3744:23;3740:32;3737:2;;;3785:1;3782;3775:12;3737:2;3848:1;3837:9;3833:17;3820:31;3871:18;3863:6;3860:30;3857:2;;;3903:1;3900;3893:12;3857:2;3931:80;4003:7;3994:6;3983:9;3979:22;3931:80;:::i;:::-;3913:98;;;;3799:218;3731:296;;;;;:::o;4034:257::-;;4146:2;4134:9;4125:7;4121:23;4117:32;4114:2;;;4162:1;4159;4152:12;4114:2;4197:1;4214:61;4267:7;4258:6;4247:9;4243:22;4214:61;:::i;:::-;4204:71;;4176:105;4108:183;;;;:::o;4298:269::-;;4416:2;4404:9;4395:7;4391:23;4387:32;4384:2;;;4432:1;4429;4422:12;4384:2;4467:1;4484:67;4543:7;4534:6;4523:9;4519:22;4484:67;:::i;:::-;4474:77;;4446:111;4378:189;;;;:::o;4574:241::-;;4678:2;4666:9;4657:7;4653:23;4649:32;4646:2;;;4694:1;4691;4684:12;4646:2;4729:1;4746:53;4791:7;4782:6;4771:9;4767:22;4746:53;:::i;:::-;4736:63;;4708:97;4640:175;;;;:::o;4822:263::-;;4937:2;4925:9;4916:7;4912:23;4908:32;4905:2;;;4953:1;4950;4943:12;4905:2;4988:1;5005:64;5061:7;5052:6;5041:9;5037:22;5005:64;:::i;:::-;4995:74;;4967:108;4899:186;;;;:::o;5093:173::-;;5180:46;5222:3;5214:6;5180:46;:::i;:::-;5255:4;5250:3;5246:14;5232:28;;5173:93;;;;:::o;5274:103::-;5347:24;5365:5;5347:24;:::i;:::-;5342:3;5335:37;5329:48;;:::o;5384:113::-;5467:24;5485:5;5467:24;:::i;:::-;5462:3;5455:37;5449:48;;:::o;5504:152::-;5605:45;5625:24;5643:5;5625:24;:::i;:::-;5605:45;:::i;:::-;5600:3;5593:58;5587:69;;:::o;5696:660::-;5829:52;5875:5;5829:52;:::i;:::-;5894:84;5971:6;5966:3;5894:84;:::i;:::-;5887:91;;5999:54;6047:5;5999:54;:::i;:::-;6073:7;6101:1;6086:258;6111:6;6108:1;6105:13;6086:258;;;6178:6;6172:13;6199:63;6258:3;6243:13;6199:63;:::i;:::-;6192:70;;6279:58;6330:6;6279:58;:::i;:::-;6269:68;;6143:201;6133:1;6130;6126:9;6121:14;;6086:258;;;6090:14;5808:548;;;;;:::o;6364:104::-;6441:21;6456:5;6441:21;:::i;:::-;6436:3;6429:34;6423:45;;:::o;6475:323::-;;6575:38;6607:5;6575:38;:::i;:::-;6625:60;6678:6;6673:3;6625:60;:::i;:::-;6618:67;;6690:52;6735:6;6730:3;6723:4;6716:5;6712:16;6690:52;:::i;:::-;6763:29;6785:6;6763:29;:::i;:::-;6758:3;6754:39;6747:46;;6555:243;;;;;:::o;6805:343::-;;6915:38;6947:5;6915:38;:::i;:::-;6965:70;7028:6;7023:3;6965:70;:::i;:::-;6958:77;;7040:52;7085:6;7080:3;7073:4;7066:5;7062:16;7040:52;:::i;:::-;7113:29;7135:6;7113:29;:::i;:::-;7108:3;7104:39;7097:46;;6895:253;;;;;:::o;7155:356::-;;7283:38;7315:5;7283:38;:::i;:::-;7333:88;7414:6;7409:3;7333:88;:::i;:::-;7326:95;;7426:52;7471:6;7466:3;7459:4;7452:5;7448:16;7426:52;:::i;:::-;7499:6;7494:3;7490:16;7483:23;;7263:248;;;;;:::o;7518:142::-;7609:45;7648:5;7609:45;:::i;:::-;7604:3;7597:58;7591:69;;:::o;7667:142::-;7758:45;7797:5;7758:45;:::i;:::-;7753:3;7746:58;7740:69;;:::o;7816:347::-;;7928:39;7961:5;7928:39;:::i;:::-;7979:71;8043:6;8038:3;7979:71;:::i;:::-;7972:78;;8055:52;8100:6;8095:3;8088:4;8081:5;8077:16;8055:52;:::i;:::-;8128:29;8150:6;8128:29;:::i;:::-;8123:3;8119:39;8112:46;;7908:255;;;;;:::o;8171:311::-;;8331:67;8395:2;8390:3;8331:67;:::i;:::-;8324:74;;8431:13;8427:1;8422:3;8418:11;8411:34;8473:2;8468:3;8464:12;8457:19;;8317:165;;;:::o;8491:306::-;;8651:66;8715:1;8710:3;8651:66;:::i;:::-;8644:73;;8750:9;8746:1;8741:3;8737:11;8730:30;8788:2;8783:3;8779:12;8772:19;;8637:160;;;:::o;8806:311::-;;8966:67;9030:2;9025:3;8966:67;:::i;:::-;8959:74;;9066:13;9062:1;9057:3;9053:11;9046:34;9108:2;9103:3;9099:12;9092:19;;8952:165;;;:::o;9126:327::-;;9286:67;9350:2;9345:3;9286:67;:::i;:::-;9279:74;;9386:29;9382:1;9377:3;9373:11;9366:50;9444:2;9439:3;9435:12;9428:19;;9272:181;;;:::o;9462:303::-;;9622:66;9686:1;9681:3;9622:66;:::i;:::-;9615:73;;9721:6;9717:1;9712:3;9708:11;9701:27;9756:2;9751:3;9747:12;9740:19;;9608:157;;;:::o;9774:314::-;;9934:67;9998:2;9993:3;9934:67;:::i;:::-;9927:74;;10034:16;10030:1;10025:3;10021:11;10014:37;10079:2;10074:3;10070:12;10063:19;;9920:168;;;:::o;10097:370::-;;10257:67;10321:2;10316:3;10257:67;:::i;:::-;10250:74;;10357:34;10353:1;10348:3;10344:11;10337:55;10426:3;10421:2;10416:3;10412:12;10405:25;10458:2;10453:3;10449:12;10442:19;;10243:224;;;:::o;10476:303::-;;10636:66;10700:1;10695:3;10636:66;:::i;:::-;10629:73;;10735:6;10731:1;10726:3;10722:11;10715:27;10770:2;10765:3;10761:12;10754:19;;10622:157;;;:::o;10788:329::-;;10948:67;11012:2;11007:3;10948:67;:::i;:::-;10941:74;;11048:31;11044:1;11039:3;11035:11;11028:52;11108:2;11103:3;11099:12;11092:19;;10934:183;;;:::o;11126:379::-;;11286:67;11350:2;11345:3;11286:67;:::i;:::-;11279:74;;11386:34;11382:1;11377:3;11373:11;11366:55;11455:12;11450:2;11445:3;11441:12;11434:34;11496:2;11491:3;11487:12;11480:19;;11272:233;;;:::o;11514:308::-;;11674:66;11738:1;11733:3;11674:66;:::i;:::-;11667:73;;11773:11;11769:1;11764:3;11760:11;11753:32;11813:2;11808:3;11804:12;11797:19;;11660:162;;;:::o;11831:391::-;;11991:67;12055:2;12050:3;11991:67;:::i;:::-;11984:74;;12091:34;12087:1;12082:3;12078:11;12071:55;12160:24;12155:2;12150:3;12146:12;12139:46;12213:2;12208:3;12204:12;12197:19;;11977:245;;;:::o;12311:1074::-;;12480:4;12475:3;12471:14;12563:4;12556:5;12552:16;12546:23;12615:3;12609:4;12605:14;12598:4;12593:3;12589:14;12582:38;12635:71;12701:4;12687:12;12635:71;:::i;:::-;12627:79;;12500:218;12796:4;12789:5;12785:16;12779:23;12808:63;12865:4;12860:3;12856:14;12842:12;12808:63;:::i;:::-;12728:149;12954:4;12947:5;12943:16;12937:23;12966:63;13023:4;13018:3;13014:14;13000:12;12966:63;:::i;:::-;12887:148;13112:4;13105:5;13101:16;13095:23;13124:63;13181:4;13176:3;13172:14;13158:12;13124:63;:::i;:::-;13045:148;13278:4;13271:5;13267:16;13261:23;13290:63;13347:4;13342:3;13338:14;13324:12;13290:63;:::i;:::-;13203:156;13376:4;13369:11;;12453:932;;;;;:::o;13392:110::-;13473:23;13490:5;13473:23;:::i;:::-;13468:3;13461:36;13455:47;;:::o;13509:148::-;13608:43;13627:23;13644:5;13627:23;:::i;:::-;13608:43;:::i;:::-;13603:3;13596:56;13590:67;;:::o;13664:103::-;13737:24;13755:5;13737:24;:::i;:::-;13732:3;13725:37;13719:48;;:::o;13774:113::-;13857:24;13875:5;13857:24;:::i;:::-;13852:3;13845:37;13839:48;;:::o;13894:799::-;;14130:75;14201:3;14192:6;14130:75;:::i;:::-;14227:2;14222:3;14218:12;14211:19;;14241:73;14310:3;14301:6;14241:73;:::i;:::-;14336:1;14331:3;14327:11;14320:18;;14349:75;14420:3;14411:6;14349:75;:::i;:::-;14446:2;14441:3;14437:12;14430:19;;14460:73;14529:3;14520:6;14460:73;:::i;:::-;14555:1;14550:3;14546:11;14539:18;;14568:75;14639:3;14630:6;14568:75;:::i;:::-;14665:2;14660:3;14656:12;14649:19;;14685:3;14678:10;;14118:575;;;;;;;;:::o;14700:271::-;;14853:93;14942:3;14933:6;14853:93;:::i;:::-;14846:100;;14963:3;14956:10;;14834:137;;;;:::o;14978:222::-;;15105:2;15094:9;15090:18;15082:26;;15119:71;15187:1;15176:9;15172:17;15163:6;15119:71;:::i;:::-;15076:124;;;;:::o;15207:333::-;;15362:2;15351:9;15347:18;15339:26;;15376:71;15444:1;15433:9;15429:17;15420:6;15376:71;:::i;:::-;15458:72;15526:2;15515:9;15511:18;15502:6;15458:72;:::i;:::-;15333:207;;;;;:::o;15547:321::-;;15696:2;15685:9;15681:18;15673:26;;15710:71;15778:1;15767:9;15763:17;15754:6;15710:71;:::i;:::-;15792:66;15854:2;15843:9;15839:18;15830:6;15792:66;:::i;:::-;15667:201;;;;;:::o;15875:333::-;;16030:2;16019:9;16015:18;16007:26;;16044:71;16112:1;16101:9;16097:17;16088:6;16044:71;:::i;:::-;16126:72;16194:2;16183:9;16179:18;16170:6;16126:72;:::i;:::-;16001:207;;;;;:::o;16215:441::-;;16424:2;16413:9;16409:18;16401:26;;16438:117;16552:1;16541:9;16537:17;16528:6;16438:117;:::i;:::-;16566:80;16642:2;16631:9;16627:18;16618:6;16566:80;:::i;:::-;16395:261;;;;;:::o;16663:210::-;;16784:2;16773:9;16769:18;16761:26;;16798:65;16860:1;16849:9;16845:17;16836:6;16798:65;:::i;:::-;16755:118;;;;:::o;16880:306::-;;17025:2;17014:9;17010:18;17002:26;;17075:9;17069:4;17065:20;17061:1;17050:9;17046:17;17039:47;17100:76;17171:4;17162:6;17100:76;:::i;:::-;17092:84;;16996:190;;;;:::o;17193:238::-;;17328:2;17317:9;17313:18;17305:26;;17342:79;17418:1;17407:9;17403:17;17394:6;17342:79;:::i;:::-;17299:132;;;;:::o;17438:238::-;;17573:2;17562:9;17558:18;17550:26;;17587:79;17663:1;17652:9;17648:17;17639:6;17587:79;:::i;:::-;17544:132;;;;:::o;17683:310::-;;17830:2;17819:9;17815:18;17807:26;;17880:9;17874:4;17870:20;17866:1;17855:9;17851:17;17844:47;17905:78;17978:4;17969:6;17905:78;:::i;:::-;17897:86;;17801:192;;;;:::o;18000:416::-;;18200:2;18189:9;18185:18;18177:26;;18250:9;18244:4;18240:20;18236:1;18225:9;18221:17;18214:47;18275:131;18401:4;18275:131;:::i;:::-;18267:139;;18171:245;;;:::o;18423:416::-;;18623:2;18612:9;18608:18;18600:26;;18673:9;18667:4;18663:20;18659:1;18648:9;18644:17;18637:47;18698:131;18824:4;18698:131;:::i;:::-;18690:139;;18594:245;;;:::o;18846:416::-;;19046:2;19035:9;19031:18;19023:26;;19096:9;19090:4;19086:20;19082:1;19071:9;19067:17;19060:47;19121:131;19247:4;19121:131;:::i;:::-;19113:139;;19017:245;;;:::o;19269:416::-;;19469:2;19458:9;19454:18;19446:26;;19519:9;19513:4;19509:20;19505:1;19494:9;19490:17;19483:47;19544:131;19670:4;19544:131;:::i;:::-;19536:139;;19440:245;;;:::o;19692:416::-;;19892:2;19881:9;19877:18;19869:26;;19942:9;19936:4;19932:20;19928:1;19917:9;19913:17;19906:47;19967:131;20093:4;19967:131;:::i;:::-;19959:139;;19863:245;;;:::o;20115:416::-;;20315:2;20304:9;20300:18;20292:26;;20365:9;20359:4;20355:20;20351:1;20340:9;20336:17;20329:47;20390:131;20516:4;20390:131;:::i;:::-;20382:139;;20286:245;;;:::o;20538:416::-;;20738:2;20727:9;20723:18;20715:26;;20788:9;20782:4;20778:20;20774:1;20763:9;20759:17;20752:47;20813:131;20939:4;20813:131;:::i;:::-;20805:139;;20709:245;;;:::o;20961:416::-;;21161:2;21150:9;21146:18;21138:26;;21211:9;21205:4;21201:20;21197:1;21186:9;21182:17;21175:47;21236:131;21362:4;21236:131;:::i;:::-;21228:139;;21132:245;;;:::o;21384:416::-;;21584:2;21573:9;21569:18;21561:26;;21634:9;21628:4;21624:20;21620:1;21609:9;21605:17;21598:47;21659:131;21785:4;21659:131;:::i;:::-;21651:139;;21555:245;;;:::o;21807:416::-;;22007:2;21996:9;21992:18;21984:26;;22057:9;22051:4;22047:20;22043:1;22032:9;22028:17;22021:47;22082:131;22208:4;22082:131;:::i;:::-;22074:139;;21978:245;;;:::o;22230:416::-;;22430:2;22419:9;22415:18;22407:26;;22480:9;22474:4;22470:20;22466:1;22455:9;22451:17;22444:47;22505:131;22631:4;22505:131;:::i;:::-;22497:139;;22401:245;;;:::o;22653:416::-;;22853:2;22842:9;22838:18;22830:26;;22903:9;22897:4;22893:20;22889:1;22878:9;22874:17;22867:47;22928:131;23054:4;22928:131;:::i;:::-;22920:139;;22824:245;;;:::o;23076:406::-;;23271:2;23260:9;23256:18;23248:26;;23321:9;23315:4;23311:20;23307:1;23296:9;23292:17;23285:47;23346:126;23467:4;23458:6;23346:126;:::i;:::-;23338:134;;23242:240;;;;:::o;23489:218::-;;23614:2;23603:9;23599:18;23591:26;;23628:69;23694:1;23683:9;23679:17;23670:6;23628:69;:::i;:::-;23585:122;;;;:::o;23714:222::-;;23841:2;23830:9;23826:18;23818:26;;23855:71;23923:1;23912:9;23908:17;23899:6;23855:71;:::i;:::-;23812:124;;;;:::o;23943:321::-;;24092:2;24081:9;24077:18;24069:26;;24106:71;24174:1;24163:9;24159:17;24150:6;24106:71;:::i;:::-;24188:66;24250:2;24239:9;24235:18;24226:6;24188:66;:::i;:::-;24063:201;;;;;:::o;24271:432::-;;24448:2;24437:9;24433:18;24425:26;;24462:71;24530:1;24519:9;24515:17;24506:6;24462:71;:::i;:::-;24544:72;24612:2;24601:9;24597:18;24588:6;24544:72;:::i;:::-;24627:66;24689:2;24678:9;24674:18;24665:6;24627:66;:::i;:::-;24419:284;;;;;;:::o;24710:444::-;;24893:2;24882:9;24878:18;24870:26;;24907:71;24975:1;24964:9;24960:17;24951:6;24907:71;:::i;:::-;24989:72;25057:2;25046:9;25042:18;25033:6;24989:72;:::i;:::-;25072;25140:2;25129:9;25125:18;25116:6;25072:72;:::i;:::-;24864:290;;;;;;:::o;25161:256::-;;25223:2;25217:9;25207:19;;25261:4;25253:6;25249:17;25360:6;25348:10;25345:22;25324:18;25312:10;25309:34;25306:62;25303:2;;;25381:1;25378;25371:12;25303:2;25401:10;25397:2;25390:22;25201:216;;;;:::o;25424:321::-;;25567:18;25559:6;25556:30;25553:2;;;25599:1;25596;25589:12;25553:2;25666:4;25662:9;25655:4;25647:6;25643:17;25639:33;25631:41;;25730:4;25724;25720:15;25712:23;;25490:255;;;:::o;25752:97::-;;25836:3;25828:11;;25822:27;;;:::o;25856:108::-;;25950:4;25940:14;;25928:36;;;:::o;25971:121::-;;26064:5;26058:12;26048:22;;26029:63;;;:::o;26099:122::-;;26193:5;26187:12;26177:22;;26158:63;;;:::o;26228:106::-;;26324:4;26319:3;26315:14;26307:22;;26301:33;;;:::o;26342:140::-;;26473:3;26458:18;;26451:31;;;;:::o;26491:152::-;;26595:6;26590:3;26583:19;26632:4;26627:3;26623:14;26608:29;;26576:67;;;;:::o;26652:162::-;;26766:6;26761:3;26754:19;26803:4;26798:3;26794:14;26779:29;;26747:67;;;;:::o;26823:144::-;;26958:3;26943:18;;26936:31;;;;:::o;26976:163::-;;27091:6;27086:3;27079:19;27128:4;27123:3;27119:14;27104:29;;27072:67;;;;:::o;27147:91::-;;27209:24;27227:5;27209:24;:::i;:::-;27198:35;;27192:46;;;:::o;27245:85::-;;27318:5;27311:13;27304:21;27293:32;;27287:43;;;:::o;27337:105::-;;27413:24;27431:5;27413:24;:::i;:::-;27402:35;;27396:46;;;:::o;27449:121::-;;27522:42;27515:5;27511:54;27500:65;;27494:76;;;:::o;27577:86::-;;27649:8;27642:5;27638:20;27627:31;;27621:42;;;:::o;27670:72::-;;27732:5;27721:16;;27715:27;;;:::o;27749:116::-;;27836:24;27854:5;27836:24;:::i;:::-;27823:37;;27817:48;;;:::o;27872:116::-;;27959:24;27977:5;27959:24;:::i;:::-;27946:37;;27940:48;;;:::o;27996:145::-;28077:6;28072:3;28067;28054:30;28133:1;28124:6;28119:3;28115:16;28108:27;28047:94;;;:::o;28150:268::-;28215:1;28222:101;28236:6;28233:1;28230:13;28222:101;;;28312:1;28307:3;28303:11;28297:18;28293:1;28288:3;28284:11;28277:39;28258:2;28255:1;28251:10;28246:15;;28222:101;;;28338:6;28335:1;28332:13;28329:2;;;28403:1;28394:6;28389:3;28385:16;28378:27;28329:2;28199:219;;;;:::o;28426:95::-;;28490:26;28510:5;28490:26;:::i;:::-;28479:37;;28473:48;;;:::o;28528:89::-;;28592:20;28606:5;28592:20;:::i;:::-;28581:31;;28575:42;;;:::o;28624:89::-;;28687:21;28702:5;28687:21;:::i;:::-;28676:32;;28670:43;;;:::o;28720:97::-;;28808:2;28804:7;28799:2;28792:5;28788:14;28784:28;28774:38;;28768:49;;;:::o;28825:96::-;;28905:5;28900:3;28896:15;28874:37;;28868:53;;;:::o;28929:94::-;;29007:5;29003:2;28999:14;28977:36;;28971:52;;;:::o;29031:117::-;29100:24;29118:5;29100:24;:::i;:::-;29093:5;29090:35;29080:2;;29139:1;29136;29129:12;29080:2;29074:74;:::o;29155:111::-;29221:21;29236:5;29221:21;:::i;:::-;29214:5;29211:32;29201:2;;29257:1;29254;29247:12;29201:2;29195:71;:::o;29273:145::-;29356:38;29388:5;29356:38;:::i;:::-;29349:5;29346:49;29336:2;;29409:1;29406;29399:12;29336:2;29330:88;:::o;29425:117::-;29494:24;29512:5;29494:24;:::i;:::-;29487:5;29484:35;29474:2;;29533:1;29530;29523:12;29474:2;29468:74;:::o
Swarm Source
ipfs://8ce2bace2ede7508a184ecd61d926c526844a85884024e8350d5d8fb7d00bf43
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.