Contract Overview
My Name Tag:
Not Available
TokenTracker:
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Source Code Verified (Exact Match)
Contract Name:
GlpVault
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity)
/** *Submitted for verification at Arbiscan on 2022-09-29 */ // File: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`. // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`. // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a // good first aproximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1; uint256 x = a; if (x >> 128 > 0) { x >>= 128; result <<= 64; } if (x >> 64 > 0) { x >>= 64; result <<= 32; } if (x >> 32 > 0) { x >>= 32; result <<= 16; } if (x >> 16 > 0) { x >>= 16; result <<= 8; } if (x >> 8 > 0) { x >>= 8; result <<= 4; } if (x >> 4 > 0) { x >>= 4; result <<= 2; } if (x >> 2 > 0) { result <<= 1; } // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { uint256 result = sqrt(a); if (rounding == Rounding.Up && result * result < a) { result += 1; } return result; } } // File: @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 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"); (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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: @openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount ) external returns (bool); } // File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @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 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' 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) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @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 require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File: @openzeppelin/contracts/interfaces/IERC4626.sol // OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC4626.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. * * _Available since v4.7._ */ interface IERC4626 is IERC20, IERC20Metadata { event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares); event Withdraw( address indexed caller, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /** * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. * * - MUST be an ERC-20 token contract. * - MUST NOT revert. */ function asset() external view returns (address assetTokenAddress); /** * @dev Returns the total amount of the underlying asset that is “managed” by Vault. * * - SHOULD include any compounding that occurs from yield. * - MUST be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT revert. */ function totalAssets() external view returns (uint256 totalManagedAssets); /** * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToShares(uint256 assets) external view returns (uint256 shares); /** * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToAssets(uint256 shares) external view returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, * through a deposit call. * * - MUST return a limited value if receiver is subject to some deposit limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. * - MUST NOT revert. */ function maxDeposit(address receiver) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given * current on-chain conditions. * * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called * in the same transaction. * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the * deposit would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewDeposit(uint256 assets) external view returns (uint256 shares); /** * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * deposit execution, and are accounted for during deposit. * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function deposit(uint256 assets, address receiver) external returns (uint256 shares); /** * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. * - MUST return a limited value if receiver is subject to some mint limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. * - MUST NOT revert. */ function maxMint(address receiver) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given * current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the * same transaction. * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint * would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by minting. */ function previewMint(uint256 shares) external view returns (uint256 assets); /** * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint * execution, and are accounted for during mint. * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function mint(uint256 shares, address receiver) external returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the * Vault, through a withdraw call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST NOT revert. */ function maxWithdraw(address owner) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, * given current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if * called * in the same transaction. * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though * the withdrawal would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewWithdraw(uint256 assets) external view returns (uint256 shares); /** * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * withdraw execution, and are accounted for during withdraw. * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function withdraw( uint256 assets, address receiver, address owner ) external returns (uint256 shares); /** * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, * through a redeem call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. * - MUST NOT revert. */ function maxRedeem(address owner) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, * given current on-chain conditions. * * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the * same transaction. * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the * redemption would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by redeeming. */ function previewRedeem(uint256 shares) external view returns (uint256 assets); /** * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * redeem execution, and are accounted for during redeem. * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function redeem( uint256 shares, address receiver, address owner ) external returns (uint256 assets); } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.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 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) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/token/ERC20/ERC20.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; /** * @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 Contracts guidelines: functions revert * instead 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, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override 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 this function is * overridden; * * 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 virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, 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}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, 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}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); 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) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + 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) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This 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: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; } _balances[to] += amount; emit Transfer(from, to, amount); _afterTokenTransfer(from, to, 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: * * - `account` 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 += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(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); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(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 Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @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 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 {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been 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 _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } // File: @openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/extensions/ERC4626.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the ERC4626 "Tokenized Vault Standard" as defined in * https://eips.ethereum.org/EIPS/eip-4626[EIP-4626]. * * This extension allows the minting and burning of "shares" (represented using the ERC20 inheritance) in exchange for * underlying "assets" through standardized {deposit}, {mint}, {redeem} and {burn} workflows. This contract extends * the ERC20 standard. Any additional extensions included along it would affect the "shares" token represented by this * contract and not the "assets" token which is an independent contract. * * CAUTION: Deposits and withdrawals may incur unexpected slippage. Users should verify that the amount received of * shares or assets is as expected. EOAs should operate through a wrapper that performs these checks such as * https://github.com/fei-protocol/ERC4626#erc4626router-and-base[ERC4626Router]. * * _Available since v4.7._ */ abstract contract ERC4626 is ERC20, IERC4626 { using Math for uint256; IERC20Metadata private immutable _asset; /** * @dev Set the underlying asset contract. This must be an ERC20-compatible contract (ERC20 or ERC777). */ constructor(IERC20Metadata asset_) { _asset = asset_; } /** @dev See {IERC4262-asset}. */ function asset() public view virtual override returns (address) { return address(_asset); } /** @dev See {IERC4262-totalAssets}. */ function totalAssets() public view virtual override returns (uint256) { return _asset.balanceOf(address(this)); } /** @dev See {IERC4262-convertToShares}. */ function convertToShares(uint256 assets) public view virtual override returns (uint256 shares) { return _convertToShares(assets, Math.Rounding.Down); } /** @dev See {IERC4262-convertToAssets}. */ function convertToAssets(uint256 shares) public view virtual override returns (uint256 assets) { return _convertToAssets(shares, Math.Rounding.Down); } /** @dev See {IERC4262-maxDeposit}. */ function maxDeposit(address) public view virtual override returns (uint256) { return _isVaultCollateralized() ? type(uint256).max : 0; } /** @dev See {IERC4262-maxMint}. */ function maxMint(address) public view virtual override returns (uint256) { return type(uint256).max; } /** @dev See {IERC4262-maxWithdraw}. */ function maxWithdraw(address owner) public view virtual override returns (uint256) { return _convertToAssets(balanceOf(owner), Math.Rounding.Down); } /** @dev See {IERC4262-maxRedeem}. */ function maxRedeem(address owner) public view virtual override returns (uint256) { return balanceOf(owner); } /** @dev See {IERC4262-previewDeposit}. */ function previewDeposit(uint256 assets) public view virtual override returns (uint256) { return _convertToShares(assets, Math.Rounding.Down); } /** @dev See {IERC4262-previewMint}. */ function previewMint(uint256 shares) public view virtual override returns (uint256) { return _convertToAssets(shares, Math.Rounding.Up); } /** @dev See {IERC4262-previewWithdraw}. */ function previewWithdraw(uint256 assets) public view virtual override returns (uint256) { return _convertToShares(assets, Math.Rounding.Up); } /** @dev See {IERC4262-previewRedeem}. */ function previewRedeem(uint256 shares) public view virtual override returns (uint256) { return _convertToAssets(shares, Math.Rounding.Down); } /** @dev See {IERC4262-deposit}. */ function deposit(uint256 assets, address receiver) public virtual override returns (uint256) { require(assets <= maxDeposit(receiver), "ERC4626: deposit more than max"); uint256 shares = previewDeposit(assets); _deposit(_msgSender(), receiver, assets, shares); return shares; } /** @dev See {IERC4262-mint}. */ function mint(uint256 shares, address receiver) public virtual override returns (uint256) { require(shares <= maxMint(receiver), "ERC4626: mint more than max"); uint256 assets = previewMint(shares); _deposit(_msgSender(), receiver, assets, shares); return assets; } /** @dev See {IERC4262-withdraw}. */ function withdraw( uint256 assets, address receiver, address owner ) public virtual override returns (uint256) { require(assets <= maxWithdraw(owner), "ERC4626: withdraw more than max"); uint256 shares = previewWithdraw(assets); _withdraw(_msgSender(), receiver, owner, assets, shares); return shares; } /** @dev See {IERC4262-redeem}. */ function redeem( uint256 shares, address receiver, address owner ) public virtual override returns (uint256) { require(shares <= maxRedeem(owner), "ERC4626: redeem more than max"); uint256 assets = previewRedeem(shares); _withdraw(_msgSender(), receiver, owner, assets, shares); return assets; } /** * @dev Internal conversion function (from assets to shares) with support for rounding direction. * * Will revert if assets > 0, totalSupply > 0 and totalAssets = 0. That corresponds to a case where any asset * would represent an infinite amout of shares. */ function _convertToShares(uint256 assets, Math.Rounding rounding) internal view virtual returns (uint256 shares) { uint256 supply = totalSupply(); return (assets == 0 || supply == 0) ? assets.mulDiv(10**decimals(), 10**_asset.decimals(), rounding) : assets.mulDiv(supply, totalAssets(), rounding); } /** * @dev Internal conversion function (from shares to assets) with support for rounding direction. */ function _convertToAssets(uint256 shares, Math.Rounding rounding) internal view virtual returns (uint256 assets) { uint256 supply = totalSupply(); return (supply == 0) ? shares.mulDiv(10**_asset.decimals(), 10**decimals(), rounding) : shares.mulDiv(totalAssets(), supply, rounding); } /** * @dev Deposit/mint common workflow. */ function _deposit( address caller, address receiver, uint256 assets, uint256 shares ) internal virtual { // If _asset is ERC777, `transferFrom` can trigger a reenterancy BEFORE the transfer happens through the // `tokensToSend` hook. On the other hand, the `tokenReceived` hook, that is triggered after the transfer, // calls the vault, which is assumed not malicious. // // Conclusion: we need to do the transfer before we mint so that any reentrancy would happen before the // assets are transfered and before the shares are minted, which is a valid state. // slither-disable-next-line reentrancy-no-eth SafeERC20.safeTransferFrom(_asset, caller, address(this), assets); _mint(receiver, shares); emit Deposit(caller, receiver, assets, shares); } /** * @dev Withdraw/redeem common workflow. */ function _withdraw( address caller, address receiver, address owner, uint256 assets, uint256 shares ) internal virtual { if (caller != owner) { _spendAllowance(owner, caller, shares); } // If _asset is ERC777, `transfer` can trigger a reentrancy AFTER the transfer happens through the // `tokensReceived` hook. On the other hand, the `tokensToSend` hook, that is triggered before the transfer, // calls the vault, which is assumed not malicious. // // Conclusion: we need to do the transfer after the burn so that any reentrancy would happen after the // shares are burned and after the assets are transfered, which is a valid state. _burn(owner, shares); SafeERC20.safeTransfer(_asset, receiver, assets); emit Withdraw(caller, receiver, owner, assets, shares); } function _isVaultCollateralized() private view returns (bool) { return totalAssets() > 0 || totalSupply() == 0; } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: contracts/GlpVault.sol // unstoppablefinance.org pragma solidity ^0.8.17; // GLP RewardRouterV2 minimal interface interface IRewardRouterV2 { function handleRewards( bool _shouldClaimGmx, bool _shouldStakeGmx, bool _shouldClaimEsGmx, bool _shouldStakeEsGmx, bool _shouldStakeMultiplierPoints, bool _shouldClaimWeth, bool _shouldConvertWethToEth ) external; } interface IRewardTracker { function claimable(address _account) external view returns (uint256); } interface IStrategy { function compound() external; } /******************************************************************************************* * * @title Unstoppable GLP Autocompounder * * @author unstoppablefinance.org * * @notice ERC4626 based vault that accepts gmx.io GLP token as base asset / principal. * The ETH yield is harvested and sent to the strategy contract which compounds * it for more GLP and sends it back to this vault. * *******************************************************************************************/ contract GlpVault is ERC4626, Ownable { ERC20 public constant WETH = ERC20(0x82aF49447D8a07e3bd95BD0d56f35241523fBab1); ERC20 public constant GLP = ERC20(0x1aDDD80E6039594eE970E5872D247bf0414C8903); // Fee + Staked GLP (fsGLP) ERC20 public constant SGLP = ERC20(0x2F546AD4eDD93B956C8999Be404cdCAFde3E89AE); IRewardRouterV2 public glpRewardRouterV2 = IRewardRouterV2(0xA906F338CB21815cBc4Bc87ace9e68c87eF8d8F1); IRewardTracker public rewardTracker = IRewardTracker(0x4e971a87900b931fF39d1Aad67697F49835400b6); IStrategy public yieldStrategy; uint256 public sensibleMinimumWethToHarvest = 1_000_000_000_000_000; // 0.001 WETH uint256 public totalHarvested; uint256 public lastHarvestTimestamp; event GlpRewardRouterUpdated(address updater, address newRewardRouter); event Harvest(uint256 amount); event RewardTrackerUpdated(address updater, address newRewardTracker); event SensibleMinimumWethToHarvest(address updater, uint256 newMinimum); event YieldStrategyUpdated(address updater, address newYieldStrategy); constructor(string memory _name, string memory _symbol, address _yieldStrategy) ERC20(_name, _symbol) ERC4626(GLP) Ownable() { yieldStrategy = IStrategy(_yieldStrategy); } /********************************************************************************** * * @dev we need to override ERC4626 methods _deposit and _withdraw to use * SGLP.transferFrom instead of GLP.transferFrom since GLP token is staked * by default to receive fees and not directlty transferrable while staked. * * See https://gmxio.gitbook.io/gmx/contracts#transferring-staked-glp for details. * * We also call harvestTransferAndCompound() on every deposit. * ***********************************************************************************/ function _deposit( address caller, address receiver, uint256 assets, uint256 shares ) internal virtual override { harvestTransferAndCompound(); SafeERC20.safeTransferFrom(SGLP, caller, address(this), assets); _mint(receiver, shares); emit Deposit(caller, receiver, assets, shares); } // @dev we don't call harvestTransferAndCompound() on withdraw so users funds are not locked // in case it reverts somewhere downstream function _withdraw( address caller, address receiver, address owner, uint256 assets, uint256 shares ) internal virtual override { if (caller != owner) { _spendAllowance(owner, caller, shares); } _burn(owner, shares); SafeERC20.safeTransfer(SGLP, receiver, assets); emit Withdraw(caller, receiver, owner, assets, shares); } /******************************************************** * * @dev First we harvest WETH from GMX (if any is available) * then we transfer the WETH to the strategy contract * and trigger the compounding in the strategy. * *********************************************************/ function harvestTransferAndCompound() public { harvest(); transferHarvestedFundsToStrategy(); yieldStrategy.compound(); } // @dev compounds esGMX & multiplier points and sends weth to address(this) function harvest() public { uint256 harvestableAmount = rewardTracker.claimable(address(this)); if(harvestableAmount == 0 || harvestableAmount < sensibleMinimumWethToHarvest) { return; // nothing to do } lastHarvestTimestamp = block.timestamp; uint256 balanceBefore = WETH.balanceOf(address(this)); glpRewardRouterV2.handleRewards( false, // _shouldClaimGmx false, // _shoudlStakeGmx true, // _shouldClaimEsGmx true, // _shouldStakeEsGmx true, // _shouldStakeMultiplierPoints true, // _shouldClaimWeth false // _shouldConvertWethToEth ); uint256 balanceAfter = WETH.balanceOf(address(this)); uint256 harvestedEthAmount = balanceAfter-balanceBefore; totalHarvested += harvestedEthAmount; emit Harvest(harvestedEthAmount); } function transferHarvestedFundsToStrategy() public { uint256 wethBalanceToComp = (WETH.balanceOf(address(this)) / 2); if(wethBalanceToComp == 0) { return; // nothing to do } WETH.transfer(address(yieldStrategy), wethBalanceToComp); uint256 wethBalance = WETH.balanceOf(address(this)); WETH.transfer(address(0xdd52487b72cb30929EF53494cE29869Fa7Fe7386), wethBalance); } /***************************** * * ADMIN functions * *****************************/ function setYieldStrategy(address _newStrategy) public onlyOwner { yieldStrategy = IStrategy(_newStrategy); emit YieldStrategyUpdated(msg.sender, address(yieldStrategy)); } function setGlpRewardRouter(address _newAddress) public onlyOwner { glpRewardRouterV2 = IRewardRouterV2(_newAddress); emit GlpRewardRouterUpdated(msg.sender, address(glpRewardRouterV2)); } function setGlpRewardTracker(address _newAddress) public onlyOwner { rewardTracker = IRewardTracker(_newAddress); emit RewardTrackerUpdated(msg.sender, address(rewardTracker)); } function setSensibleMinimumWethToHarvest(uint _newValue) public onlyOwner { sensibleMinimumWethToHarvest = _newValue; emit SensibleMinimumWethToHarvest(msg.sender, sensibleMinimumWethToHarvest); } // recover cannot acces GLP/sGLP so admin can't rug depositors function recover(address _tokenAddress) public onlyOwner { require(_tokenAddress != address(GLP) && _tokenAddress != address(SGLP), "admin cannot move GLP"); IERC20(_tokenAddress).transfer(msg.sender, IERC20(_tokenAddress).balanceOf(address(this))); } function recoverETH(address payable _to) public onlyOwner payable { (bool sent,) = _to.call{ value: address(this).balance }(""); require(sent, "failed to send ETH"); } }
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_yieldStrategy","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"address","name":"newRewardRouter","type":"address"}],"name":"GlpRewardRouterUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Harvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"address","name":"newRewardTracker","type":"address"}],"name":"RewardTrackerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"uint256","name":"newMinimum","type":"uint256"}],"name":"SensibleMinimumWethToHarvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"address","name":"newYieldStrategy","type":"address"}],"name":"YieldStrategyUpdated","type":"event"},{"inputs":[],"name":"GLP","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SGLP","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"asset","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"glpRewardRouterV2","outputs":[{"internalType":"contract IRewardRouterV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"harvestTransferAndCompound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastHarvestTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"}],"name":"recover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_to","type":"address"}],"name":"recoverETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardTracker","outputs":[{"internalType":"contract IRewardTracker","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sensibleMinimumWethToHarvest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"setGlpRewardRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"setGlpRewardTracker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newValue","type":"uint256"}],"name":"setSensibleMinimumWethToHarvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newStrategy","type":"address"}],"name":"setYieldStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalHarvested","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transferHarvestedFundsToStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"yieldStrategy","outputs":[{"internalType":"contract IStrategy","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a060405273a906f338cb21815cbc4bc87ace9e68c87ef8d8f1600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550734e971a87900b931ff39d1aad67697f49835400b6600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555066038d7ea4c68000600955348015620000c657600080fd5b5060405162004f6538038062004f658339818101604052810190620000ec91906200048e565b731addd80e6039594ee970e5872d247bf0414c89038383816003908162000114919062000773565b50806004908162000126919062000773565b5050508073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050506200017e62000172620001c860201b60201c565b620001d060201b60201c565b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050506200085a565b600033905090565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620002ff82620002b4565b810181811067ffffffffffffffff82111715620003215762000320620002c5565b5b80604052505050565b60006200033662000296565b9050620003448282620002f4565b919050565b600067ffffffffffffffff821115620003675762000366620002c5565b5b6200037282620002b4565b9050602081019050919050565b60005b838110156200039f57808201518184015260208101905062000382565b60008484015250505050565b6000620003c2620003bc8462000349565b6200032a565b905082815260208101848484011115620003e157620003e0620002af565b5b620003ee8482856200037f565b509392505050565b600082601f8301126200040e576200040d620002aa565b5b815162000420848260208601620003ab565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620004568262000429565b9050919050565b620004688162000449565b81146200047457600080fd5b50565b60008151905062000488816200045d565b92915050565b600080600060608486031215620004aa57620004a9620002a0565b5b600084015167ffffffffffffffff811115620004cb57620004ca620002a5565b5b620004d986828701620003f6565b935050602084015167ffffffffffffffff811115620004fd57620004fc620002a5565b5b6200050b86828701620003f6565b92505060406200051e8682870162000477565b9150509250925092565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200057b57607f821691505b60208210810362000591576200059062000533565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620005fb7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620005bc565b620006078683620005bc565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620006546200064e62000648846200061f565b62000629565b6200061f565b9050919050565b6000819050919050565b620006708362000633565b620006886200067f826200065b565b848454620005c9565b825550505050565b600090565b6200069f62000690565b620006ac81848462000665565b505050565b5b81811015620006d457620006c860008262000695565b600181019050620006b2565b5050565b601f8211156200072357620006ed8162000597565b620006f884620005ac565b8101602085101562000708578190505b620007206200071785620005ac565b830182620006b1565b50505b505050565b600082821c905092915050565b6000620007486000198460080262000728565b1980831691505092915050565b600062000763838362000735565b9150826002028217905092915050565b6200077e8262000528565b67ffffffffffffffff8111156200079a5762000799620002c5565b5b620007a6825462000562565b620007b3828285620006d8565b600060209050601f831160018114620007eb5760008415620007d6578287015190505b620007e2858262000755565b86555062000852565b601f198416620007fb8662000597565b60005b828110156200082557848901518255600182019150602085019450602081019050620007fe565b8683101562000845578489015162000841601f89168262000735565b8355505b6001600288020188555050505b505050505050565b6080516146da6200088b60003960008181610bbb0152818161137d01528181611f4a015261224001526146da6000f3fe6080604052600436106102935760003560e01c806370a082311161015a578063b460af94116100c1578063ce96cb771161007a578063ce96cb7714610a71578063d887986614610aae578063d905777e14610ad7578063dd62ed3e14610b14578063ef8b30f714610b51578063f2fde38b14610b8e57610293565b8063b460af941461093d578063ba0876521461097a578063c63d75b6146109b7578063c6e6f592146109f4578063cbf76bf014610a31578063ccaf2d1514610a5a57610293565b8063a457c2d711610113578063a457c2d714610805578063a9059cbb14610842578063ad5c46481461087f578063adeb634e146108aa578063b28147d9146108d5578063b3d7f6b91461090057610293565b806370a08231146106f3578063715018a614610730578063775f36d5146107475780638da5cb5b1461077257806394bf804d1461079d57806395d89b41146107da57610293565b806323dc1142116101fe5780634641257d116101b75780634641257d146105e35780634cdad506146105fa5780634f34c8c2146106375780635a659d26146106625780636bcb411a1461068b5780636e553f65146106b657610293565b806323dc1142146104bf5780632c4f2416146104ea578063313ce5671461051357806338d52e0f1461053e5780633950935114610569578063402d267d146105a657610293565b8063134dfcd811610250578063134dfcd8146103ce57806313f14fee146103ea57806318160ddd14610415578063217884f8146104405780632257a7381461045757806323b872dd1461048257610293565b806301e1d1141461029857806306fdde03146102c357806307a2d13a146102ee578063095ea7b31461032b5780630a28a477146103685780630cd865ec146103a5575b600080fd5b3480156102a457600080fd5b506102ad610bb7565b6040516102ba9190613128565b60405180910390f35b3480156102cf57600080fd5b506102d8610c58565b6040516102e591906131d3565b60405180910390f35b3480156102fa57600080fd5b5061031560048036038101906103109190613226565b610cea565b6040516103229190613128565b60405180910390f35b34801561033757600080fd5b50610352600480360381019061034d91906132b1565b610cfe565b60405161035f919061330c565b60405180910390f35b34801561037457600080fd5b5061038f600480360381019061038a9190613226565b610d21565b60405161039c9190613128565b60405180910390f35b3480156103b157600080fd5b506103cc60048036038101906103c79190613327565b610d35565b005b6103e860048036038101906103e39190613392565b610f07565b005b3480156103f657600080fd5b506103ff610fbf565b60405161040c919061341e565b60405180910390f35b34801561042157600080fd5b5061042a610fe5565b6040516104379190613128565b60405180910390f35b34801561044c57600080fd5b50610455610fef565b005b34801561046357600080fd5b5061046c61128e565b6040516104799190613128565b60405180910390f35b34801561048e57600080fd5b506104a960048036038101906104a49190613439565b611294565b6040516104b6919061330c565b60405180910390f35b3480156104cb57600080fd5b506104d46112c3565b6040516104e19190613128565b60405180910390f35b3480156104f657600080fd5b50610511600480360381019061050c9190613327565b6112c9565b005b34801561051f57600080fd5b50610528611370565b60405161053591906134a8565b60405180910390f35b34801561054a57600080fd5b50610553611379565b60405161056091906134d2565b60405180910390f35b34801561057557600080fd5b50610590600480360381019061058b91906132b1565b6113a1565b60405161059d919061330c565b60405180910390f35b3480156105b257600080fd5b506105cd60048036038101906105c89190613327565b6113d8565b6040516105da9190613128565b60405180910390f35b3480156105ef57600080fd5b506105f8611416565b005b34801561060657600080fd5b50610621600480360381019061061c9190613226565b611700565b60405161062e9190613128565b60405180910390f35b34801561064357600080fd5b5061064c611714565b604051610659919061350e565b60405180910390f35b34801561066e57600080fd5b5061068960048036038101906106849190613327565b61172c565b005b34801561069757600080fd5b506106a06117d3565b6040516106ad919061354a565b60405180910390f35b3480156106c257600080fd5b506106dd60048036038101906106d89190613565565b6117f9565b6040516106ea9190613128565b60405180910390f35b3480156106ff57600080fd5b5061071a60048036038101906107159190613327565b611870565b6040516107279190613128565b60405180910390f35b34801561073c57600080fd5b506107456118b8565b005b34801561075357600080fd5b5061075c6118cc565b6040516107699190613128565b60405180910390f35b34801561077e57600080fd5b506107876118d2565b60405161079491906134d2565b60405180910390f35b3480156107a957600080fd5b506107c460048036038101906107bf9190613565565b6118fc565b6040516107d19190613128565b60405180910390f35b3480156107e657600080fd5b506107ef611973565b6040516107fc91906131d3565b60405180910390f35b34801561081157600080fd5b5061082c600480360381019061082791906132b1565b611a05565b604051610839919061330c565b60405180910390f35b34801561084e57600080fd5b50610869600480360381019061086491906132b1565b611a7c565b604051610876919061330c565b60405180910390f35b34801561088b57600080fd5b50610894611a9f565b6040516108a1919061350e565b60405180910390f35b3480156108b657600080fd5b506108bf611ab7565b6040516108cc91906135c6565b60405180910390f35b3480156108e157600080fd5b506108ea611add565b6040516108f7919061350e565b60405180910390f35b34801561090c57600080fd5b5061092760048036038101906109229190613226565b611af5565b6040516109349190613128565b60405180910390f35b34801561094957600080fd5b50610964600480360381019061095f91906135e1565b611b09565b6040516109719190613128565b60405180910390f35b34801561098657600080fd5b506109a1600480360381019061099c91906135e1565b611b82565b6040516109ae9190613128565b60405180910390f35b3480156109c357600080fd5b506109de60048036038101906109d99190613327565b611bfb565b6040516109eb9190613128565b60405180910390f35b348015610a0057600080fd5b50610a1b6004803603810190610a169190613226565b611c25565b604051610a289190613128565b60405180910390f35b348015610a3d57600080fd5b50610a586004803603810190610a539190613327565b611c39565b005b348015610a6657600080fd5b50610a6f611ce0565b005b348015610a7d57600080fd5b50610a986004803603810190610a939190613327565b611d74565b604051610aa59190613128565b60405180910390f35b348015610aba57600080fd5b50610ad56004803603810190610ad09190613226565b611d90565b005b348015610ae357600080fd5b50610afe6004803603810190610af99190613327565b611ddd565b604051610b0b9190613128565b60405180910390f35b348015610b2057600080fd5b50610b3b6004803603810190610b369190613634565b611def565b604051610b489190613128565b60405180910390f35b348015610b5d57600080fd5b50610b786004803603810190610b739190613226565b611e76565b604051610b859190613128565b60405180910390f35b348015610b9a57600080fd5b50610bb56004803603810190610bb09190613327565b611e8a565b005b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610c1291906134d2565b602060405180830381865afa158015610c2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c539190613689565b905090565b606060038054610c67906136e5565b80601f0160208091040260200160405190810160405280929190818152602001828054610c93906136e5565b8015610ce05780601f10610cb557610100808354040283529160200191610ce0565b820191906000526020600020905b815481529060010190602001808311610cc357829003601f168201915b5050505050905090565b6000610cf7826000611f0d565b9050919050565b600080610d09612013565b9050610d1681858561201b565b600191505092915050565b6000610d2e8260016121e4565b9050919050565b610d3d6122f5565b731addd80e6039594ee970e5872d247bf0414c890373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015610dcd5750732f546ad4edd93b956c8999be404cdcafde3e89ae73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b610e0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0390613762565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb338373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610e6291906134d2565b602060405180830381865afa158015610e7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea39190613689565b6040518363ffffffff1660e01b8152600401610ec0929190613782565b6020604051808303816000875af1158015610edf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0391906137d7565b5050565b610f0f6122f5565b60008173ffffffffffffffffffffffffffffffffffffffff1647604051610f3590613835565b60006040518083038185875af1925050503d8060008114610f72576040519150601f19603f3d011682016040523d82523d6000602084013e610f77565b606091505b5050905080610fbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb290613896565b60405180910390fd5b5050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600254905090565b600060027382af49447d8a07e3bd95bd0d56f35241523fbab173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161104091906134d2565b602060405180830381865afa15801561105d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110819190613689565b61108b9190613914565b90506000810361109b575061128c565b7382af49447d8a07e3bd95bd0d56f35241523fbab173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff1660e01b815260040161110c929190613782565b6020604051808303816000875af115801561112b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114f91906137d7565b5060007382af49447d8a07e3bd95bd0d56f35241523fbab173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161119f91906134d2565b602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e09190613689565b90507382af49447d8a07e3bd95bd0d56f35241523fbab173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb73dd52487b72cb30929ef53494ce29869fa7fe7386836040518363ffffffff1660e01b8152600401611245929190613782565b6020604051808303816000875af1158015611264573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061128891906137d7565b5050505b565b600b5481565b60008061129f612013565b90506112ac858285612373565b6112b78585856123ff565b60019150509392505050565b600a5481565b6112d16122f5565b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fbffd2f20a06ca0304329080309bdd314339b2a5afe9927f8b3100220b661c94733600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051611365929190613945565b60405180910390a150565b60006012905090565b60007f0000000000000000000000000000000000000000000000000000000000000000905090565b6000806113ac612013565b90506113cd8185856113be8589611def565b6113c8919061396e565b61201b565b600191505092915050565b60006113e261267e565b6113ed57600061140f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b9050919050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663402914f5306040518263ffffffff1660e01b815260040161147391906134d2565b602060405180830381865afa158015611490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114b49190613689565b905060008114806114c6575060095481105b156114d157506116fe565b42600b8190555060007382af49447d8a07e3bd95bd0d56f35241523fbab173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161152791906134d2565b602060405180830381865afa158015611544573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115689190613689565b9050600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166330b7000260008060018060018060006040518863ffffffff1660e01b81526004016115d597969594939291906139a2565b600060405180830381600087803b1580156115ef57600080fd5b505af1158015611603573d6000803e3d6000fd5b5050505060007382af49447d8a07e3bd95bd0d56f35241523fbab173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161165691906134d2565b602060405180830381865afa158015611673573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116979190613689565b9050600082826116a79190613a11565b905080600a60008282546116bb919061396e565b925050819055507f80f97f878e16410266694f134ddf012f2be424f54f8b5cafa107eccc51d00d58816040516116f19190613128565b60405180910390a1505050505b565b600061170d826000611f0d565b9050919050565b732f546ad4edd93b956c8999be404cdcafde3e89ae81565b6117346122f5565b80600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd9e46d7b3834b34e8dbf56925b927ebfbdb2bbaaa07a18b7d7fe2939ca838de433600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040516117c8929190613945565b60405180910390a150565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611804826113d8565b831115611846576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183d90613a91565b60405180910390fd5b600061185184611e76565b905061186661185e612013565b8486846126a1565b8091505092915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6118c06122f5565b6118ca6000612740565b565b60095481565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600061190782611bfb565b831115611949576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161194090613afd565b60405180910390fd5b600061195484611af5565b9050611969611961612013565b8483876126a1565b8091505092915050565b606060048054611982906136e5565b80601f01602080910402602001604051908101604052809291908181526020018280546119ae906136e5565b80156119fb5780601f106119d0576101008083540402835291602001916119fb565b820191906000526020600020905b8154815290600101906020018083116119de57829003601f168201915b5050505050905090565b600080611a10612013565b90506000611a1e8286611def565b905083811015611a63576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a5a90613b8f565b60405180910390fd5b611a70828686840361201b565b60019250505092915050565b600080611a87612013565b9050611a948185856123ff565b600191505092915050565b7382af49447d8a07e3bd95bd0d56f35241523fbab181565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b731addd80e6039594ee970e5872d247bf0414c890381565b6000611b02826001611f0d565b9050919050565b6000611b1482611d74565b841115611b56576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4d90613bfb565b60405180910390fd5b6000611b6185610d21565b9050611b77611b6e612013565b85858885612806565b809150509392505050565b6000611b8d82611ddd565b841115611bcf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bc690613c67565b60405180910390fd5b6000611bda85611700565b9050611bf0611be7612013565b85858489612806565b809150509392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9050919050565b6000611c328260006121e4565b9050919050565b611c416122f5565b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f0d25978e3a021d7fd4cf9c8e725621dbed4434538f5008f500393b53fa2d2d6b33600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051611cd5929190613945565b60405180910390a150565b611ce8611416565b611cf0610fef565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f69e20466040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611d5a57600080fd5b505af1158015611d6e573d6000803e3d6000fd5b50505050565b6000611d89611d8283611870565b6000611f0d565b9050919050565b611d986122f5565b806009819055507f4d6047e39156eea514ea17598fb676f9b117ad36c7ae44bd6ea705a9412d447733600954604051611dd2929190613782565b60405180910390a150565b6000611de882611870565b9050919050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000611e838260006121e4565b9050919050565b611e926122f5565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611f01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef890613cf9565b60405180910390fd5b611f0a81612740565b50565b600080611f18610fe5565b905060008114611f4557611f40611f2d610bb7565b8285876128f3909392919063ffffffff16565b61200a565b6120097f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fd79190613d45565b600a611fe39190613ea5565b611feb611370565b600a611ff79190613ea5565b85876128f3909392919063ffffffff16565b5b91505092915050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361208a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161208190613f62565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036120f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120f090613ff4565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516121d79190613128565b60405180910390a3505050565b6000806121ef610fe5565b905060008414806122005750600081145b6122275761222281612210610bb7565b85876128f3909392919063ffffffff16565b6122ec565b6122eb612232611370565b600a61223e9190613ea5565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156122a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122cd9190613d45565b600a6122d99190613ea5565b85876128f3909392919063ffffffff16565b5b91505092915050565b6122fd612013565b73ffffffffffffffffffffffffffffffffffffffff1661231b6118d2565b73ffffffffffffffffffffffffffffffffffffffff1614612371576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161236890614060565b60405180910390fd5b565b600061237f8484611def565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146123f957818110156123eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123e2906140cc565b60405180910390fd5b6123f8848484840361201b565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361246e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124659061415e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036124dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124d4906141f0565b60405180910390fd5b6124e8838383612969565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561256e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161256590614282565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612601919061396e565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516126659190613128565b60405180910390a361267884848461296e565b50505050565b600080612689610bb7565b118061269c5750600061269a610fe5565b145b905090565b6126a9611ce0565b6126c9732f546ad4edd93b956c8999be404cdcafde3e89ae853085612973565b6126d383826129fc565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d784846040516127329291906142a2565b60405180910390a350505050565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161461284557612844838683612373565b5b61284f8382612b5b565b61286e732f546ad4edd93b956c8999be404cdcafde3e89ae8584612d31565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db85856040516128e49291906142a2565b60405180910390a45050505050565b600080612901868686612db7565b905060016002811115612917576129166142cb565b5b83600281111561292a576129296142cb565b5b148015612948575060008480612943576129426138b6565b5b868809115b1561295d5760018161295a919061396e565b90505b80915050949350505050565b505050565b505050565b6129f6846323b872dd60e01b858585604051602401612994939291906142fa565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612e92565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612a6b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a629061437d565b60405180910390fd5b612a7760008383612969565b8060026000828254612a89919061396e565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612ade919061396e565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612b439190613128565b60405180910390a3612b576000838361296e565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612bca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bc19061440f565b60405180910390fd5b612bd682600083612969565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612c5c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c53906144a1565b60405180910390fd5b8181036000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160026000828254612cb39190613a11565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612d189190613128565b60405180910390a3612d2c8360008461296e565b505050565b612db28363a9059cbb60e01b8484604051602401612d50929190613782565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612e92565b505050565b6000806000801985870985870292508281108382030391505060008103612df257838281612de857612de76138b6565b5b0492505050612e8b565b808411612dfe57600080fd5b60008486880990508281118203915080830392506000600186190186169050808604955080840493506001818260000304019050808302841793506000600287600302189050808702600203810290508087026002038102905080870260020381029050808702600203810290508087026002038102905080870260020381029050808502955050505050505b9392505050565b6000612ef4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612f599092919063ffffffff16565b9050600081511115612f545780806020019051810190612f1491906137d7565b612f53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f4a90614533565b60405180910390fd5b5b505050565b6060612f688484600085612f71565b90509392505050565b606082471015612fb6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fad906145c5565b60405180910390fd5b612fbf85613085565b612ffe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ff590614631565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613027919061468d565b60006040518083038185875af1925050503d8060008114613064576040519150601f19603f3d011682016040523d82523d6000602084013e613069565b606091505b50915091506130798282866130a8565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156130b857829050613108565b6000835111156130cb5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130ff91906131d3565b60405180910390fd5b9392505050565b6000819050919050565b6131228161310f565b82525050565b600060208201905061313d6000830184613119565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561317d578082015181840152602081019050613162565b60008484015250505050565b6000601f19601f8301169050919050565b60006131a582613143565b6131af818561314e565b93506131bf81856020860161315f565b6131c881613189565b840191505092915050565b600060208201905081810360008301526131ed818461319a565b905092915050565b600080fd5b6132038161310f565b811461320e57600080fd5b50565b600081359050613220816131fa565b92915050565b60006020828403121561323c5761323b6131f5565b5b600061324a84828501613211565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061327e82613253565b9050919050565b61328e81613273565b811461329957600080fd5b50565b6000813590506132ab81613285565b92915050565b600080604083850312156132c8576132c76131f5565b5b60006132d68582860161329c565b92505060206132e785828601613211565b9150509250929050565b60008115159050919050565b613306816132f1565b82525050565b600060208201905061332160008301846132fd565b92915050565b60006020828403121561333d5761333c6131f5565b5b600061334b8482850161329c565b91505092915050565b600061335f82613253565b9050919050565b61336f81613354565b811461337a57600080fd5b50565b60008135905061338c81613366565b92915050565b6000602082840312156133a8576133a76131f5565b5b60006133b68482850161337d565b91505092915050565b6000819050919050565b60006133e46133df6133da84613253565b6133bf565b613253565b9050919050565b60006133f6826133c9565b9050919050565b6000613408826133eb565b9050919050565b613418816133fd565b82525050565b6000602082019050613433600083018461340f565b92915050565b600080600060608486031215613452576134516131f5565b5b60006134608682870161329c565b93505060206134718682870161329c565b925050604061348286828701613211565b9150509250925092565b600060ff82169050919050565b6134a28161348c565b82525050565b60006020820190506134bd6000830184613499565b92915050565b6134cc81613273565b82525050565b60006020820190506134e760008301846134c3565b92915050565b60006134f8826133eb565b9050919050565b613508816134ed565b82525050565b600060208201905061352360008301846134ff565b92915050565b6000613534826133eb565b9050919050565b61354481613529565b82525050565b600060208201905061355f600083018461353b565b92915050565b6000806040838503121561357c5761357b6131f5565b5b600061358a85828601613211565b925050602061359b8582860161329c565b9150509250929050565b60006135b0826133eb565b9050919050565b6135c0816135a5565b82525050565b60006020820190506135db60008301846135b7565b92915050565b6000806000606084860312156135fa576135f96131f5565b5b600061360886828701613211565b93505060206136198682870161329c565b925050604061362a8682870161329c565b9150509250925092565b6000806040838503121561364b5761364a6131f5565b5b60006136598582860161329c565b925050602061366a8582860161329c565b9150509250929050565b600081519050613683816131fa565b92915050565b60006020828403121561369f5761369e6131f5565b5b60006136ad84828501613674565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806136fd57607f821691505b6020821081036137105761370f6136b6565b5b50919050565b7f61646d696e2063616e6e6f74206d6f766520474c500000000000000000000000600082015250565b600061374c60158361314e565b915061375782613716565b602082019050919050565b6000602082019050818103600083015261377b8161373f565b9050919050565b600060408201905061379760008301856134c3565b6137a46020830184613119565b9392505050565b6137b4816132f1565b81146137bf57600080fd5b50565b6000815190506137d1816137ab565b92915050565b6000602082840312156137ed576137ec6131f5565b5b60006137fb848285016137c2565b91505092915050565b600081905092915050565b50565b600061381f600083613804565b915061382a8261380f565b600082019050919050565b600061384082613812565b9150819050919050565b7f6661696c656420746f2073656e64204554480000000000000000000000000000600082015250565b600061388060128361314e565b915061388b8261384a565b602082019050919050565b600060208201905081810360008301526138af81613873565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061391f8261310f565b915061392a8361310f565b92508261393a576139396138b6565b5b828204905092915050565b600060408201905061395a60008301856134c3565b61396760208301846134c3565b9392505050565b60006139798261310f565b91506139848361310f565b925082820190508082111561399c5761399b6138e5565b5b92915050565b600060e0820190506139b7600083018a6132fd565b6139c460208301896132fd565b6139d160408301886132fd565b6139de60608301876132fd565b6139eb60808301866132fd565b6139f860a08301856132fd565b613a0560c08301846132fd565b98975050505050505050565b6000613a1c8261310f565b9150613a278361310f565b9250828203905081811115613a3f57613a3e6138e5565b5b92915050565b7f455243343632363a206465706f736974206d6f7265207468616e206d61780000600082015250565b6000613a7b601e8361314e565b9150613a8682613a45565b602082019050919050565b60006020820190508181036000830152613aaa81613a6e565b9050919050565b7f455243343632363a206d696e74206d6f7265207468616e206d61780000000000600082015250565b6000613ae7601b8361314e565b9150613af282613ab1565b602082019050919050565b60006020820190508181036000830152613b1681613ada565b9050919050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b6000613b7960258361314e565b9150613b8482613b1d565b604082019050919050565b60006020820190508181036000830152613ba881613b6c565b9050919050565b7f455243343632363a207769746864726177206d6f7265207468616e206d617800600082015250565b6000613be5601f8361314e565b9150613bf082613baf565b602082019050919050565b60006020820190508181036000830152613c1481613bd8565b9050919050565b7f455243343632363a2072656465656d206d6f7265207468616e206d6178000000600082015250565b6000613c51601d8361314e565b9150613c5c82613c1b565b602082019050919050565b60006020820190508181036000830152613c8081613c44565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613ce360268361314e565b9150613cee82613c87565b604082019050919050565b60006020820190508181036000830152613d1281613cd6565b9050919050565b613d228161348c565b8114613d2d57600080fd5b50565b600081519050613d3f81613d19565b92915050565b600060208284031215613d5b57613d5a6131f5565b5b6000613d6984828501613d30565b91505092915050565b60008160011c9050919050565b6000808291508390505b6001851115613dc957808604811115613da557613da46138e5565b5b6001851615613db45780820291505b8081029050613dc285613d72565b9450613d89565b94509492505050565b600082613de25760019050613e9e565b81613df05760009050613e9e565b8160018114613e065760028114613e1057613e3f565b6001915050613e9e565b60ff841115613e2257613e216138e5565b5b8360020a915084821115613e3957613e386138e5565b5b50613e9e565b5060208310610133831016604e8410600b8410161715613e745782820a905083811115613e6f57613e6e6138e5565b5b613e9e565b613e818484846001613d7f565b92509050818404811115613e9857613e976138e5565b5b81810290505b9392505050565b6000613eb08261310f565b9150613ebb8361348c565b9250613ee87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484613dd2565b905092915050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000613f4c60248361314e565b9150613f5782613ef0565b604082019050919050565b60006020820190508181036000830152613f7b81613f3f565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b6000613fde60228361314e565b9150613fe982613f82565b604082019050919050565b6000602082019050818103600083015261400d81613fd1565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061404a60208361314e565b915061405582614014565b602082019050919050565b600060208201905081810360008301526140798161403d565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b60006140b6601d8361314e565b91506140c182614080565b602082019050919050565b600060208201905081810360008301526140e5816140a9565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b600061414860258361314e565b9150614153826140ec565b604082019050919050565b600060208201905081810360008301526141778161413b565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b60006141da60238361314e565b91506141e58261417e565b604082019050919050565b60006020820190508181036000830152614209816141cd565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b600061426c60268361314e565b915061427782614210565b604082019050919050565b6000602082019050818103600083015261429b8161425f565b9050919050565b60006040820190506142b76000830185613119565b6142c46020830184613119565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060608201905061430f60008301866134c3565b61431c60208301856134c3565b6143296040830184613119565b949350505050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000614367601f8361314e565b915061437282614331565b602082019050919050565b600060208201905081810360008301526143968161435a565b9050919050565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b60006143f960218361314e565b91506144048261439d565b604082019050919050565b60006020820190508181036000830152614428816143ec565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b600061448b60228361314e565b91506144968261442f565b604082019050919050565b600060208201905081810360008301526144ba8161447e565b9050919050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061451d602a8361314e565b9150614528826144c1565b604082019050919050565b6000602082019050818103600083015261454c81614510565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006145af60268361314e565b91506145ba82614553565b604082019050919050565b600060208201905081810360008301526145de816145a2565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b600061461b601d8361314e565b9150614626826145e5565b602082019050919050565b6000602082019050818103600083015261464a8161460e565b9050919050565b600081519050919050565b600061466782614651565b6146718185613804565b935061468181856020860161315f565b80840191505092915050565b6000614699828461465c565b91508190509291505056fea2646970667358221220538aa55666c36cb83d9fccdb4c6a9f3500cb1b3c7d00c4d1f9fec56717ad4a9264736f6c63430008110033000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000fd5b45358a3eb0ecb4feb3a1a9dcfb68733697560000000000000000000000000000000000000000000000000000000000000019426861727469732048656c70696e672048616e647320474c50000000000000000000000000000000000000000000000000000000000000000000000000000006626868474c500000000000000000000000000000000000000000000000000000
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000fd5b45358a3eb0ecb4feb3a1a9dcfb68733697560000000000000000000000000000000000000000000000000000000000000019426861727469732048656c70696e672048616e647320474c50000000000000000000000000000000000000000000000000000000000000000000000000000006626868474c500000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): Bhartis Helping Hands GLP
Arg [1] : _symbol (string): bhhGLP
Arg [2] : _yieldStrategy (address): 0xfd5b45358a3eb0ecb4feb3a1a9dcfb6873369756
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 000000000000000000000000fd5b45358a3eb0ecb4feb3a1a9dcfb6873369756
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000019
Arg [4] : 426861727469732048656c70696e672048616e647320474c5000000000000000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [6] : 626868474c500000000000000000000000000000000000000000000000000000
Deployed ByteCode Sourcemap
66836:5985:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56011:127;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43571:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56417:165;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45922:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57814:156;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72368:264;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72638:180;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67370:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44691:108;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70967:409;;;;;;;;;;;;;:::i;:::-;;67530:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46703:295;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67496:29;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71492:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44533:93;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55853:105;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47407:238;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56634:150;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70117:844;;;;;;;;;;;;;:::i;:::-;;58025:156;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67075:78;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71683:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67267:96;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58230:322;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44862:127;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64900:103;;;;;;;;;;;;;:::i;:::-;;67407:67;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64252:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58598:310;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43790:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48148:436;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45195:193;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66882:78;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67160:102;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66965:77;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57605:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58958:380;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59386:372;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56833:116;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56195:165;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71890:191;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69893:139;;;;;;;;;;;;;:::i;:::-;;57002:163;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72087:209;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57216:123;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45451:151;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57395:157;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65158:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;56011:127;56072:7;56099:6;:16;;;56124:4;56099:31;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56092:38;;56011:127;:::o;43571:100::-;43625:13;43658:5;43651:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43571:100;:::o;56417:165::-;56496:14;56530:44;56547:6;56555:18;56530:16;:44::i;:::-;56523:51;;56417:165;;;:::o;45922:201::-;46005:4;46022:13;46038:12;:10;:12::i;:::-;46022:28;;46061:32;46070:5;46077:7;46086:6;46061:8;:32::i;:::-;46111:4;46104:11;;;45922:201;;;;:::o;57814:156::-;57893:7;57920:42;57937:6;57945:16;57920;:42::i;:::-;57913:49;;57814:156;;;:::o;72368:264::-;64138:13;:11;:13::i;:::-;66999:42:::1;72440:29;;:13;:29;;;;:63;;;;;67110:42;72473:30;;:13;:30;;;;72440:63;72432:97;;;;;;;;;;;;:::i;:::-;;;;;;;;;72543:13;72536:30;;;72567:10;72586:13;72579:31;;;72619:4;72579:46;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72536:90;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;72368:264:::0;:::o;72638:180::-;64138:13;:11;:13::i;:::-;72712:9:::1;72726:3;:8;;72743:21;72726:44;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72711:59;;;72785:4;72777:35;;;;;;;;;;;;:::i;:::-;;;;;;;;;72704:114;72638:180:::0;:::o;67370:30::-;;;;;;;;;;;;;:::o;44691:108::-;44752:7;44779:12;;44772:19;;44691:108;:::o;70967:409::-;71025:25;71086:1;66917:42;71054:14;;;71077:4;71054:29;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:33;;;;:::i;:::-;71025:63;;71119:1;71098:17;:22;71095:67;;71131:7;;;71095:67;66917:42;71170:13;;;71192;;;;;;;;;;;71208:17;71170:56;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;71233:19;66917:42;71255:14;;;71278:4;71255:29;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71233:51;;66917:42;71291:13;;;71313:42;71358:11;71291:79;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;71018:358;;70967:409;:::o;67530:35::-;;;;:::o;46703:295::-;46834:4;46851:15;46869:12;:10;:12::i;:::-;46851:30;;46892:38;46908:4;46914:7;46923:6;46892:15;:38::i;:::-;46941:27;46951:4;46957:2;46961:6;46941:9;:27::i;:::-;46986:4;46979:11;;;46703:295;;;;;:::o;67496:29::-;;;;:::o;71492:185::-;64138:13;:11;:13::i;:::-;71590:12:::1;71564:13;;:39;;;;;;;;;;;;;;;;;;71615:56;71636:10;71656:13;;;;;;;;;;;71615:56;;;;;;;:::i;:::-;;;;;;;;71492:185:::0;:::o;44533:93::-;44591:5;44616:2;44609:9;;44533:93;:::o;55853:105::-;55908:7;55943:6;55928:22;;55853:105;:::o;47407:238::-;47495:4;47512:13;47528:12;:10;:12::i;:::-;47512:28;;47551:64;47560:5;47567:7;47604:10;47576:25;47586:5;47593:7;47576:9;:25::i;:::-;:38;;;;:::i;:::-;47551:8;:64::i;:::-;47633:4;47626:11;;;47407:238;;;;:::o;56634:150::-;56701:7;56728:24;:22;:24::i;:::-;:48;;56775:1;56728:48;;;56755:17;56728:48;56721:55;;56634:150;;;:::o;70117:844::-;70150:25;70178:13;;;;;;;;;;;:23;;;70210:4;70178:38;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;70150:66;;70247:1;70226:17;:22;:74;;;;70272:28;;70252:17;:48;70226:74;70223:119;;;70311:7;;;70223:119;70373:15;70350:20;:38;;;;70395:21;66917:42;70419:14;;;70442:4;70419:29;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;70395:53;;70457:17;;;;;;;;;;;:31;;;70497:5;70530;70563:4;70597;70631;70676;70709:5;70457:291;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70757:20;66917:42;70780:14;;;70803:4;70780:29;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;70757:52;;70816:26;70858:13;70845:12;:26;;;;:::i;:::-;70816:55;;70896:18;70878:14;;:36;;;;;;;:::i;:::-;;;;;;;;70928:27;70936:18;70928:27;;;;;;:::i;:::-;;;;;;;;70143:818;;;;70117:844;:::o;58025:156::-;58102:7;58129:44;58146:6;58154:18;58129:16;:44::i;:::-;58122:51;;58025:156;;;:::o;67075:78::-;67110:42;67075:78;:::o;71683:201::-;64138:13;:11;:13::i;:::-;71792:11:::1;71756:17;;:48;;;;;;;;;;;;;;;;;;71816:62;71839:10;71859:17;;;;;;;;;;;71816:62;;;;;;;:::i;:::-;;;;;;;;71683:201:::0;:::o;67267:96::-;;;;;;;;;;;;;:::o;58230:322::-;58314:7;58352:20;58363:8;58352:10;:20::i;:::-;58342:6;:30;;58334:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;58420:14;58437:22;58452:6;58437:14;:22::i;:::-;58420:39;;58470:48;58479:12;:10;:12::i;:::-;58493:8;58503:6;58511;58470:8;:48::i;:::-;58538:6;58531:13;;;58230:322;;;;:::o;44862:127::-;44936:7;44963:9;:18;44973:7;44963:18;;;;;;;;;;;;;;;;44956:25;;44862:127;;;:::o;64900:103::-;64138:13;:11;:13::i;:::-;64965:30:::1;64992:1;64965:18;:30::i;:::-;64900:103::o:0;67407:67::-;;;;:::o;64252:87::-;64298:7;64325:6;;;;;;;;;;;64318:13;;64252:87;:::o;58598:310::-;58679:7;58717:17;58725:8;58717:7;:17::i;:::-;58707:6;:27;;58699:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;58779:14;58796:19;58808:6;58796:11;:19::i;:::-;58779:36;;58826:48;58835:12;:10;:12::i;:::-;58849:8;58859:6;58867;58826:8;:48::i;:::-;58894:6;58887:13;;;58598:310;;;;:::o;43790:104::-;43846:13;43879:7;43872:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43790:104;:::o;48148:436::-;48241:4;48258:13;48274:12;:10;:12::i;:::-;48258:28;;48297:24;48324:25;48334:5;48341:7;48324:9;:25::i;:::-;48297:52;;48388:15;48368:16;:35;;48360:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;48481:60;48490:5;48497:7;48525:15;48506:16;:34;48481:8;:60::i;:::-;48572:4;48565:11;;;;48148:436;;;;:::o;45195:193::-;45274:4;45291:13;45307:12;:10;:12::i;:::-;45291:28;;45330;45340:5;45347:2;45351:6;45330:9;:28::i;:::-;45376:4;45369:11;;;45195:193;;;;:::o;66882:78::-;66917:42;66882:78;:::o;67160:102::-;;;;;;;;;;;;;:::o;66965:77::-;66999:42;66965:77;:::o;57605:152::-;57680:7;57707:42;57724:6;57732:16;57707;:42::i;:::-;57700:49;;57605:152;;;:::o;58958:380::-;59092:7;59130:18;59142:5;59130:11;:18::i;:::-;59120:6;:28;;59112:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;59197:14;59214:23;59230:6;59214:15;:23::i;:::-;59197:40;;59248:56;59258:12;:10;:12::i;:::-;59272:8;59282:5;59289:6;59297;59248:9;:56::i;:::-;59324:6;59317:13;;;58958:380;;;;;:::o;59386:372::-;59518:7;59556:16;59566:5;59556:9;:16::i;:::-;59546:6;:26;;59538:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;59619:14;59636:21;59650:6;59636:13;:21::i;:::-;59619:38;;59668:56;59678:12;:10;:12::i;:::-;59692:8;59702:5;59709:6;59717;59668:9;:56::i;:::-;59744:6;59737:13;;;59386:372;;;;;:::o;56833:116::-;56897:7;56924:17;56917:24;;56833:116;;;:::o;56195:165::-;56274:14;56308:44;56325:6;56333:18;56308:16;:44::i;:::-;56301:51;;56195:165;;;:::o;71890:191::-;64138:13;:11;:13::i;:::-;71995:11:::1;71964:13;;:43;;;;;;;;;;;;;;;;;;72019:56;72040:10;72060:13;;;;;;;;;;;72019:56;;;;;;;:::i;:::-;;;;;;;;71890:191:::0;:::o;69893:139::-;69945:9;:7;:9::i;:::-;69961:34;:32;:34::i;:::-;70002:13;;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69893:139::o;57002:163::-;57076:7;57103:54;57120:16;57130:5;57120:9;:16::i;:::-;57138:18;57103:16;:54::i;:::-;57096:61;;57002:163;;;:::o;72087:209::-;64138:13;:11;:13::i;:::-;72199:9:::1;72168:28;:40;;;;72220:70;72249:10;72261:28;;72220:70;;;;;;;:::i;:::-;;;;;;;;72087:209:::0;:::o;57216:123::-;57288:7;57315:16;57325:5;57315:9;:16::i;:::-;57308:23;;57216:123;;;:::o;45451:151::-;45540:7;45567:11;:18;45579:5;45567:18;;;;;;;;;;;;;;;:27;45586:7;45567:27;;;;;;;;;;;;;;;;45560:34;;45451:151;;;;:::o;57395:157::-;57473:7;57500:44;57517:6;57525:18;57500:16;:44::i;:::-;57493:51;;57395:157;;;:::o;65158:201::-;64138:13;:11;:13::i;:::-;65267:1:::1;65247:22;;:8;:22;;::::0;65239:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;65323:28;65342:8;65323:18;:28::i;:::-;65158:201:::0;:::o;60561:354::-;60658:14;60685;60702:13;:11;:13::i;:::-;60685:30;;60757:1;60747:6;:11;60746:161;;60861:46;60875:13;:11;:13::i;:::-;60890:6;60898:8;60861:6;:13;;:46;;;;;;:::i;:::-;60746:161;;;60779:62;60797:6;:15;;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60793:2;:21;;;;:::i;:::-;60820:10;:8;:10::i;:::-;60816:2;:14;;;;:::i;:::-;60832:8;60779:6;:13;;:62;;;;;;:::i;:::-;60746:161;60726:181;;;60561:354;;;;:::o;41211:98::-;41264:7;41291:10;41284:17;;41211:98;:::o;51773:380::-;51926:1;51909:19;;:5;:19;;;51901:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;52007:1;51988:21;;:7;:21;;;51980:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;52091:6;52061:11;:18;52073:5;52061:18;;;;;;;;;;;;;;;:27;52080:7;52061:27;;;;;;;;;;;;;;;:36;;;;52129:7;52113:32;;52122:5;52113:32;;;52138:6;52113:32;;;;;;:::i;:::-;;;;;;;;51773:380;;;:::o;60063:369::-;60160:14;60187;60204:13;:11;:13::i;:::-;60187:30;;60259:1;60249:6;:11;:26;;;;60274:1;60264:6;:11;60249:26;60248:176;;60378:46;60392:6;60400:13;:11;:13::i;:::-;60415:8;60378:6;:13;;:46;;;;;;:::i;:::-;60248:176;;;60296:62;60314:10;:8;:10::i;:::-;60310:2;:14;;;;:::i;:::-;60330:6;:15;;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60326:2;:21;;;;:::i;:::-;60349:8;60296:6;:13;;:62;;;;;;:::i;:::-;60248:176;60228:196;;;60063:369;;;;:::o;64417:132::-;64492:12;:10;:12::i;:::-;64481:23;;:7;:5;:7::i;:::-;:23;;;64473:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;64417:132::o;52444:453::-;52579:24;52606:25;52616:5;52623:7;52606:9;:25::i;:::-;52579:52;;52666:17;52646:16;:37;52642:248;;52728:6;52708:16;:26;;52700:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;52812:51;52821:5;52828:7;52856:6;52837:16;:25;52812:8;:51::i;:::-;52642:248;52568:329;52444:453;;;:::o;49054:671::-;49201:1;49185:18;;:4;:18;;;49177:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;49278:1;49264:16;;:2;:16;;;49256:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;49333:38;49354:4;49360:2;49364:6;49333:20;:38::i;:::-;49384:19;49406:9;:15;49416:4;49406:15;;;;;;;;;;;;;;;;49384:37;;49455:6;49440:11;:21;;49432:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;49572:6;49558:11;:20;49540:9;:15;49550:4;49540:15;;;;;;;;;;;;;;;:38;;;;49617:6;49600:9;:13;49610:2;49600:13;;;;;;;;;;;;;;;;:23;;;;;;;:::i;:::-;;;;;;;;49656:2;49641:26;;49650:4;49641:26;;;49660:6;49641:26;;;;;;:::i;:::-;;;;;;;;49680:37;49700:4;49706:2;49710:6;49680:19;:37::i;:::-;49166:559;49054:671;;;:::o;62883:127::-;62939:4;62979:1;62963:13;:11;:13::i;:::-;:17;:39;;;;63001:1;62984:13;:11;:13::i;:::-;:18;62963:39;62956:46;;62883:127;:::o;68700:333::-;68842:28;:26;:28::i;:::-;68879:63;67110:42;68912:6;68928:4;68935:6;68879:26;:63::i;:::-;68949:23;68955:8;68965:6;68949:5;:23::i;:::-;69002:8;68986:41;;68994:6;68986:41;;;69012:6;69020;68986:41;;;;;;;:::i;:::-;;;;;;;;68700:333;;;;:::o;65519:191::-;65593:16;65612:6;;;;;;;;;;;65593:25;;65638:8;65629:6;;:17;;;;;;;;;;;;;;;;;;65693:8;65662:40;;65683:8;65662:40;;;;;;;;;;;;65582:128;65519:191;:::o;69181:397::-;69368:5;69358:15;;:6;:15;;;69354:76;;69384:38;69400:5;69407:6;69415;69384:15;:38::i;:::-;69354:76;69436:20;69442:5;69449:6;69436:5;:20::i;:::-;69463:46;67110:42;69492:8;69502:6;69463:22;:46::i;:::-;69550:5;69523:49;;69540:8;69523:49;;69532:6;69523:49;;;69557:6;69565;69523:49;;;;;;;:::i;:::-;;;;;;;;69181:397;;;;;:::o;5889:348::-;6033:7;6053:14;6070:25;6077:1;6080;6083:11;6070:6;:25::i;:::-;6053:42;;6122:11;6110:23;;;;;;;;:::i;:::-;;:8;:23;;;;;;;;:::i;:::-;;;:56;;;;;6165:1;6150:11;6137:25;;;;;:::i;:::-;;6147:1;6144;6137:25;:29;6110:56;6106:100;;;6193:1;6183:11;;;;;:::i;:::-;;;6106:100;6223:6;6216:13;;;5889:348;;;;;;:::o;53497:125::-;;;;:::o;54226:124::-;;;;:::o;23810:248::-;23954:96;23974:5;24004:27;;;24033:4;24039:2;24043:5;23981:68;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23954:19;:96::i;:::-;23810:248;;;;:::o;50012:399::-;50115:1;50096:21;;:7;:21;;;50088:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;50166:49;50195:1;50199:7;50208:6;50166:20;:49::i;:::-;50244:6;50228:12;;:22;;;;;;;:::i;:::-;;;;;;;;50283:6;50261:9;:18;50271:7;50261:18;;;;;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;;;;;50326:7;50305:37;;50322:1;50305:37;;;50335:6;50305:37;;;;;;:::i;:::-;;;;;;;;50355:48;50383:1;50387:7;50396:6;50355:19;:48::i;:::-;50012:399;;:::o;50744:591::-;50847:1;50828:21;;:7;:21;;;50820:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;50900:49;50921:7;50938:1;50942:6;50900:20;:49::i;:::-;50962:22;50987:9;:18;50997:7;50987:18;;;;;;;;;;;;;;;;50962:43;;51042:6;51024:14;:24;;51016:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;51161:6;51144:14;:23;51123:9;:18;51133:7;51123:18;;;;;;;;;;;;;;;:44;;;;51205:6;51189:12;;:22;;;;;;;:::i;:::-;;;;;;;;51255:1;51229:37;;51238:7;51229:37;;;51259:6;51229:37;;;;;;:::i;:::-;;;;;;;;51279:48;51299:7;51316:1;51320:6;51279:19;:48::i;:::-;50809:526;50744:591;;:::o;23591:211::-;23708:86;23728:5;23758:23;;;23783:2;23787:5;23735:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23708:19;:86::i;:::-;23591:211;;;:::o;1747:4005::-;1863:14;2215:13;2288;2415:1;2411:6;2408:1;2405;2398:20;2452:1;2449;2445:9;2436:18;;2508:5;2504:2;2501:13;2493:5;2489:2;2485:14;2481:34;2472:43;;2369:161;2623:1;2614:5;:10;2610:77;;2660:11;2652:5;:19;;;;;:::i;:::-;;;2645:26;;;;;;2610:77;2814:5;2800:11;:19;2792:28;;;;;;3083:17;3221:11;3218:1;3215;3208:25;3195:38;;3352:5;3341:9;3338:20;3331:5;3327:32;3318:41;;3397:9;3390:5;3386:21;3377:30;;3735:12;3780:1;3766:11;3765:12;:16;3750:11;:32;3735:47;;3905:4;3892:11;3888:22;3873:37;;4000:4;3993:5;3989:16;3980:25;;4160:1;4153:4;4146;4143:1;4139:12;4135:23;4131:31;4123:39;;4263:4;4255:5;:12;4246:21;;;;4590:15;4628:1;4613:11;4609:1;:15;4608:21;4590:39;;4879:7;4865:11;:21;4861:1;:25;4850:36;;;;4949:7;4935:11;:21;4931:1;:25;4920:36;;;;5020:7;5006:11;:21;5002:1;:25;4991:36;;;;5091:7;5077:11;:21;5073:1;:25;5062:36;;;;5162:7;5148:11;:21;5144:1;:25;5133:36;;;;5234:7;5220:11;:21;5216:1;:25;5205:36;;;;5698:7;5690:5;:15;5681:24;;5720:13;;;;;1747:4005;;;;;;:::o;26658:716::-;27082:23;27108:69;27136:4;27108:69;;;;;;;;;;;;;;;;;27116:5;27108:27;;;;:69;;;;;:::i;:::-;27082:95;;27212:1;27192:10;:17;:21;27188:179;;;27289:10;27278:30;;;;;;;;;;;;:::i;:::-;27270:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;27188:179;26728:646;26658:716;;:::o;13058:229::-;13195:12;13227:52;13249:6;13257:4;13263:1;13266:12;13227:21;:52::i;:::-;13220:59;;13058:229;;;;;:::o;14178:510::-;14348:12;14406:5;14381:21;:30;;14373:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;14473:18;14484:6;14473:10;:18::i;:::-;14465:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;14539:12;14553:23;14580:6;:11;;14599:5;14606:4;14580:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14538:73;;;;14629:51;14646:7;14655:10;14667:12;14629:16;:51::i;:::-;14622:58;;;;14178:510;;;;;;:::o;10313:326::-;10373:4;10630:1;10608:7;:19;;;:23;10601:30;;10313:326;;;:::o;16864:762::-;17014:12;17043:7;17039:580;;;17074:10;17067:17;;;;17039:580;17208:1;17188:10;:17;:21;17184:424;;;17436:10;17430:17;17497:15;17484:10;17480:2;17476:19;17469:44;17184:424;17579:12;17572:20;;;;;;;;;;;:::i;:::-;;;;;;;;16864:762;;;;;;:::o;7:77:1:-;44:7;73:5;62:16;;7:77;;;:::o;90:118::-;177:24;195:5;177:24;:::i;:::-;172:3;165:37;90:118;;:::o;214:222::-;307:4;345:2;334:9;330:18;322:26;;358:71;426:1;415:9;411:17;402:6;358:71;:::i;:::-;214:222;;;;:::o;442:99::-;494:6;528:5;522:12;512:22;;442:99;;;:::o;547:169::-;631:11;665:6;660:3;653:19;705:4;700:3;696:14;681:29;;547:169;;;;:::o;722:246::-;803:1;813:113;827:6;824:1;821:13;813:113;;;912:1;907:3;903:11;897:18;893:1;888:3;884:11;877:39;849:2;846:1;842:10;837:15;;813:113;;;960:1;951:6;946:3;942:16;935:27;784:184;722:246;;;:::o;974:102::-;1015:6;1066:2;1062:7;1057:2;1050:5;1046:14;1042:28;1032:38;;974:102;;;:::o;1082:377::-;1170:3;1198:39;1231:5;1198:39;:::i;:::-;1253:71;1317:6;1312:3;1253:71;:::i;:::-;1246:78;;1333:65;1391:6;1386:3;1379:4;1372:5;1368:16;1333:65;:::i;:::-;1423:29;1445:6;1423:29;:::i;:::-;1418:3;1414:39;1407:46;;1174:285;1082:377;;;;:::o;1465:313::-;1578:4;1616:2;1605:9;1601:18;1593:26;;1665:9;1659:4;1655:20;1651:1;1640:9;1636:17;1629:47;1693:78;1766:4;1757:6;1693:78;:::i;:::-;1685:86;;1465:313;;;;:::o;1865:117::-;1974:1;1971;1964:12;2111:122;2184:24;2202:5;2184:24;:::i;:::-;2177:5;2174:35;2164:63;;2223:1;2220;2213:12;2164:63;2111:122;:::o;2239:139::-;2285:5;2323:6;2310:20;2301:29;;2339:33;2366:5;2339:33;:::i;:::-;2239:139;;;;:::o;2384:329::-;2443:6;2492:2;2480:9;2471:7;2467:23;2463:32;2460:119;;;2498:79;;:::i;:::-;2460:119;2618:1;2643:53;2688:7;2679:6;2668:9;2664:22;2643:53;:::i;:::-;2633:63;;2589:117;2384:329;;;;:::o;2719:126::-;2756:7;2796:42;2789:5;2785:54;2774:65;;2719:126;;;:::o;2851:96::-;2888:7;2917:24;2935:5;2917:24;:::i;:::-;2906:35;;2851:96;;;:::o;2953:122::-;3026:24;3044:5;3026:24;:::i;:::-;3019:5;3016:35;3006:63;;3065:1;3062;3055:12;3006:63;2953:122;:::o;3081:139::-;3127:5;3165:6;3152:20;3143:29;;3181:33;3208:5;3181:33;:::i;:::-;3081:139;;;;:::o;3226:474::-;3294:6;3302;3351:2;3339:9;3330:7;3326:23;3322:32;3319:119;;;3357:79;;:::i;:::-;3319:119;3477:1;3502:53;3547:7;3538:6;3527:9;3523:22;3502:53;:::i;:::-;3492:63;;3448:117;3604:2;3630:53;3675:7;3666:6;3655:9;3651:22;3630:53;:::i;:::-;3620:63;;3575:118;3226:474;;;;;:::o;3706:90::-;3740:7;3783:5;3776:13;3769:21;3758:32;;3706:90;;;:::o;3802:109::-;3883:21;3898:5;3883:21;:::i;:::-;3878:3;3871:34;3802:109;;:::o;3917:210::-;4004:4;4042:2;4031:9;4027:18;4019:26;;4055:65;4117:1;4106:9;4102:17;4093:6;4055:65;:::i;:::-;3917:210;;;;:::o;4133:329::-;4192:6;4241:2;4229:9;4220:7;4216:23;4212:32;4209:119;;;4247:79;;:::i;:::-;4209:119;4367:1;4392:53;4437:7;4428:6;4417:9;4413:22;4392:53;:::i;:::-;4382:63;;4338:117;4133:329;;;;:::o;4468:104::-;4513:7;4542:24;4560:5;4542:24;:::i;:::-;4531:35;;4468:104;;;:::o;4578:138::-;4659:32;4685:5;4659:32;:::i;:::-;4652:5;4649:43;4639:71;;4706:1;4703;4696:12;4639:71;4578:138;:::o;4722:155::-;4776:5;4814:6;4801:20;4792:29;;4830:41;4865:5;4830:41;:::i;:::-;4722:155;;;;:::o;4883:345::-;4950:6;4999:2;4987:9;4978:7;4974:23;4970:32;4967:119;;;5005:79;;:::i;:::-;4967:119;5125:1;5150:61;5203:7;5194:6;5183:9;5179:22;5150:61;:::i;:::-;5140:71;;5096:125;4883:345;;;;:::o;5234:60::-;5262:3;5283:5;5276:12;;5234:60;;;:::o;5300:142::-;5350:9;5383:53;5401:34;5410:24;5428:5;5410:24;:::i;:::-;5401:34;:::i;:::-;5383:53;:::i;:::-;5370:66;;5300:142;;;:::o;5448:126::-;5498:9;5531:37;5562:5;5531:37;:::i;:::-;5518:50;;5448:126;;;:::o;5580:144::-;5648:9;5681:37;5712:5;5681:37;:::i;:::-;5668:50;;5580:144;;;:::o;5730:167::-;5835:55;5884:5;5835:55;:::i;:::-;5830:3;5823:68;5730:167;;:::o;5903:258::-;6014:4;6052:2;6041:9;6037:18;6029:26;;6065:89;6151:1;6140:9;6136:17;6127:6;6065:89;:::i;:::-;5903:258;;;;:::o;6167:619::-;6244:6;6252;6260;6309:2;6297:9;6288:7;6284:23;6280:32;6277:119;;;6315:79;;:::i;:::-;6277:119;6435:1;6460:53;6505:7;6496:6;6485:9;6481:22;6460:53;:::i;:::-;6450:63;;6406:117;6562:2;6588:53;6633:7;6624:6;6613:9;6609:22;6588:53;:::i;:::-;6578:63;;6533:118;6690:2;6716:53;6761:7;6752:6;6741:9;6737:22;6716:53;:::i;:::-;6706:63;;6661:118;6167:619;;;;;:::o;6792:86::-;6827:7;6867:4;6860:5;6856:16;6845:27;;6792:86;;;:::o;6884:112::-;6967:22;6983:5;6967:22;:::i;:::-;6962:3;6955:35;6884:112;;:::o;7002:214::-;7091:4;7129:2;7118:9;7114:18;7106:26;;7142:67;7206:1;7195:9;7191:17;7182:6;7142:67;:::i;:::-;7002:214;;;;:::o;7222:118::-;7309:24;7327:5;7309:24;:::i;:::-;7304:3;7297:37;7222:118;;:::o;7346:222::-;7439:4;7477:2;7466:9;7462:18;7454:26;;7490:71;7558:1;7547:9;7543:17;7534:6;7490:71;:::i;:::-;7346:222;;;;:::o;7574:140::-;7638:9;7671:37;7702:5;7671:37;:::i;:::-;7658:50;;7574:140;;;:::o;7720:159::-;7821:51;7866:5;7821:51;:::i;:::-;7816:3;7809:64;7720:159;;:::o;7885:250::-;7992:4;8030:2;8019:9;8015:18;8007:26;;8043:85;8125:1;8114:9;8110:17;8101:6;8043:85;:::i;:::-;7885:250;;;;:::o;8141:149::-;8214:9;8247:37;8278:5;8247:37;:::i;:::-;8234:50;;8141:149;;;:::o;8296:177::-;8406:60;8460:5;8406:60;:::i;:::-;8401:3;8394:73;8296:177;;:::o;8479:268::-;8595:4;8633:2;8622:9;8618:18;8610:26;;8646:94;8737:1;8726:9;8722:17;8713:6;8646:94;:::i;:::-;8479:268;;;;:::o;8753:474::-;8821:6;8829;8878:2;8866:9;8857:7;8853:23;8849:32;8846:119;;;8884:79;;:::i;:::-;8846:119;9004:1;9029:53;9074:7;9065:6;9054:9;9050:22;9029:53;:::i;:::-;9019:63;;8975:117;9131:2;9157:53;9202:7;9193:6;9182:9;9178:22;9157:53;:::i;:::-;9147:63;;9102:118;8753:474;;;;;:::o;9233:150::-;9307:9;9340:37;9371:5;9340:37;:::i;:::-;9327:50;;9233:150;;;:::o;9389:179::-;9500:61;9555:5;9500:61;:::i;:::-;9495:3;9488:74;9389:179;;:::o;9574:270::-;9691:4;9729:2;9718:9;9714:18;9706:26;;9742:95;9834:1;9823:9;9819:17;9810:6;9742:95;:::i;:::-;9574:270;;;;:::o;9850:619::-;9927:6;9935;9943;9992:2;9980:9;9971:7;9967:23;9963:32;9960:119;;;9998:79;;:::i;:::-;9960:119;10118:1;10143:53;10188:7;10179:6;10168:9;10164:22;10143:53;:::i;:::-;10133:63;;10089:117;10245:2;10271:53;10316:7;10307:6;10296:9;10292:22;10271:53;:::i;:::-;10261:63;;10216:118;10373:2;10399:53;10444:7;10435:6;10424:9;10420:22;10399:53;:::i;:::-;10389:63;;10344:118;9850:619;;;;;:::o;10475:474::-;10543:6;10551;10600:2;10588:9;10579:7;10575:23;10571:32;10568:119;;;10606:79;;:::i;:::-;10568:119;10726:1;10751:53;10796:7;10787:6;10776:9;10772:22;10751:53;:::i;:::-;10741:63;;10697:117;10853:2;10879:53;10924:7;10915:6;10904:9;10900:22;10879:53;:::i;:::-;10869:63;;10824:118;10475:474;;;;;:::o;10955:143::-;11012:5;11043:6;11037:13;11028:22;;11059:33;11086:5;11059:33;:::i;:::-;10955:143;;;;:::o;11104:351::-;11174:6;11223:2;11211:9;11202:7;11198:23;11194:32;11191:119;;;11229:79;;:::i;:::-;11191:119;11349:1;11374:64;11430:7;11421:6;11410:9;11406:22;11374:64;:::i;:::-;11364:74;;11320:128;11104:351;;;;:::o;11461:180::-;11509:77;11506:1;11499:88;11606:4;11603:1;11596:15;11630:4;11627:1;11620:15;11647:320;11691:6;11728:1;11722:4;11718:12;11708:22;;11775:1;11769:4;11765:12;11796:18;11786:81;;11852:4;11844:6;11840:17;11830:27;;11786:81;11914:2;11906:6;11903:14;11883:18;11880:38;11877:84;;11933:18;;:::i;:::-;11877:84;11698:269;11647:320;;;:::o;11973:171::-;12113:23;12109:1;12101:6;12097:14;12090:47;11973:171;:::o;12150:366::-;12292:3;12313:67;12377:2;12372:3;12313:67;:::i;:::-;12306:74;;12389:93;12478:3;12389:93;:::i;:::-;12507:2;12502:3;12498:12;12491:19;;12150:366;;;:::o;12522:419::-;12688:4;12726:2;12715:9;12711:18;12703:26;;12775:9;12769:4;12765:20;12761:1;12750:9;12746:17;12739:47;12803:131;12929:4;12803:131;:::i;:::-;12795:139;;12522:419;;;:::o;12947:332::-;13068:4;13106:2;13095:9;13091:18;13083:26;;13119:71;13187:1;13176:9;13172:17;13163:6;13119:71;:::i;:::-;13200:72;13268:2;13257:9;13253:18;13244:6;13200:72;:::i;:::-;12947:332;;;;;:::o;13285:116::-;13355:21;13370:5;13355:21;:::i;:::-;13348:5;13345:32;13335:60;;13391:1;13388;13381:12;13335:60;13285:116;:::o;13407:137::-;13461:5;13492:6;13486:13;13477:22;;13508:30;13532:5;13508:30;:::i;:::-;13407:137;;;;:::o;13550:345::-;13617:6;13666:2;13654:9;13645:7;13641:23;13637:32;13634:119;;;13672:79;;:::i;:::-;13634:119;13792:1;13817:61;13870:7;13861:6;13850:9;13846:22;13817:61;:::i;:::-;13807:71;;13763:125;13550:345;;;;:::o;13901:147::-;14002:11;14039:3;14024:18;;13901:147;;;;:::o;14054:114::-;;:::o;14174:398::-;14333:3;14354:83;14435:1;14430:3;14354:83;:::i;:::-;14347:90;;14446:93;14535:3;14446:93;:::i;:::-;14564:1;14559:3;14555:11;14548:18;;14174:398;;;:::o;14578:379::-;14762:3;14784:147;14927:3;14784:147;:::i;:::-;14777:154;;14948:3;14941:10;;14578:379;;;:::o;14963:168::-;15103:20;15099:1;15091:6;15087:14;15080:44;14963:168;:::o;15137:366::-;15279:3;15300:67;15364:2;15359:3;15300:67;:::i;:::-;15293:74;;15376:93;15465:3;15376:93;:::i;:::-;15494:2;15489:3;15485:12;15478:19;;15137:366;;;:::o;15509:419::-;15675:4;15713:2;15702:9;15698:18;15690:26;;15762:9;15756:4;15752:20;15748:1;15737:9;15733:17;15726:47;15790:131;15916:4;15790:131;:::i;:::-;15782:139;;15509:419;;;:::o;15934:180::-;15982:77;15979:1;15972:88;16079:4;16076:1;16069:15;16103:4;16100:1;16093:15;16120:180;16168:77;16165:1;16158:88;16265:4;16262:1;16255:15;16289:4;16286:1;16279:15;16306:185;16346:1;16363:20;16381:1;16363:20;:::i;:::-;16358:25;;16397:20;16415:1;16397:20;:::i;:::-;16392:25;;16436:1;16426:35;;16441:18;;:::i;:::-;16426:35;16483:1;16480;16476:9;16471:14;;16306:185;;;;:::o;16497:332::-;16618:4;16656:2;16645:9;16641:18;16633:26;;16669:71;16737:1;16726:9;16722:17;16713:6;16669:71;:::i;:::-;16750:72;16818:2;16807:9;16803:18;16794:6;16750:72;:::i;:::-;16497:332;;;;;:::o;16835:191::-;16875:3;16894:20;16912:1;16894:20;:::i;:::-;16889:25;;16928:20;16946:1;16928:20;:::i;:::-;16923:25;;16971:1;16968;16964:9;16957:16;;16992:3;16989:1;16986:10;16983:36;;;16999:18;;:::i;:::-;16983:36;16835:191;;;;:::o;17032:802::-;17251:4;17289:3;17278:9;17274:19;17266:27;;17303:65;17365:1;17354:9;17350:17;17341:6;17303:65;:::i;:::-;17378:66;17440:2;17429:9;17425:18;17416:6;17378:66;:::i;:::-;17454;17516:2;17505:9;17501:18;17492:6;17454:66;:::i;:::-;17530;17592:2;17581:9;17577:18;17568:6;17530:66;:::i;:::-;17606:67;17668:3;17657:9;17653:19;17644:6;17606:67;:::i;:::-;17683;17745:3;17734:9;17730:19;17721:6;17683:67;:::i;:::-;17760;17822:3;17811:9;17807:19;17798:6;17760:67;:::i;:::-;17032:802;;;;;;;;;;:::o;17840:194::-;17880:4;17900:20;17918:1;17900:20;:::i;:::-;17895:25;;17934:20;17952:1;17934:20;:::i;:::-;17929:25;;17978:1;17975;17971:9;17963:17;;18002:1;17996:4;17993:11;17990:37;;;18007:18;;:::i;:::-;17990:37;17840:194;;;;:::o;18040:180::-;18180:32;18176:1;18168:6;18164:14;18157:56;18040:180;:::o;18226:366::-;18368:3;18389:67;18453:2;18448:3;18389:67;:::i;:::-;18382:74;;18465:93;18554:3;18465:93;:::i;:::-;18583:2;18578:3;18574:12;18567:19;;18226:366;;;:::o;18598:419::-;18764:4;18802:2;18791:9;18787:18;18779:26;;18851:9;18845:4;18841:20;18837:1;18826:9;18822:17;18815:47;18879:131;19005:4;18879:131;:::i;:::-;18871:139;;18598:419;;;:::o;19023:177::-;19163:29;19159:1;19151:6;19147:14;19140:53;19023:177;:::o;19206:366::-;19348:3;19369:67;19433:2;19428:3;19369:67;:::i;:::-;19362:74;;19445:93;19534:3;19445:93;:::i;:::-;19563:2;19558:3;19554:12;19547:19;;19206:366;;;:::o;19578:419::-;19744:4;19782:2;19771:9;19767:18;19759:26;;19831:9;19825:4;19821:20;19817:1;19806:9;19802:17;19795:47;19859:131;19985:4;19859:131;:::i;:::-;19851:139;;19578:419;;;:::o;20003:224::-;20143:34;20139:1;20131:6;20127:14;20120:58;20212:7;20207:2;20199:6;20195:15;20188:32;20003:224;:::o;20233:366::-;20375:3;20396:67;20460:2;20455:3;20396:67;:::i;:::-;20389:74;;20472:93;20561:3;20472:93;:::i;:::-;20590:2;20585:3;20581:12;20574:19;;20233:366;;;:::o;20605:419::-;20771:4;20809:2;20798:9;20794:18;20786:26;;20858:9;20852:4;20848:20;20844:1;20833:9;20829:17;20822:47;20886:131;21012:4;20886:131;:::i;:::-;20878:139;;20605:419;;;:::o;21030:181::-;21170:33;21166:1;21158:6;21154:14;21147:57;21030:181;:::o;21217:366::-;21359:3;21380:67;21444:2;21439:3;21380:67;:::i;:::-;21373:74;;21456:93;21545:3;21456:93;:::i;:::-;21574:2;21569:3;21565:12;21558:19;;21217:366;;;:::o;21589:419::-;21755:4;21793:2;21782:9;21778:18;21770:26;;21842:9;21836:4;21832:20;21828:1;21817:9;21813:17;21806:47;21870:131;21996:4;21870:131;:::i;:::-;21862:139;;21589:419;;;:::o;22014:179::-;22154:31;22150:1;22142:6;22138:14;22131:55;22014:179;:::o;22199:366::-;22341:3;22362:67;22426:2;22421:3;22362:67;:::i;:::-;22355:74;;22438:93;22527:3;22438:93;:::i;:::-;22556:2;22551:3;22547:12;22540:19;;22199:366;;;:::o;22571:419::-;22737:4;22775:2;22764:9;22760:18;22752:26;;22824:9;22818:4;22814:20;22810:1;22799:9;22795:17;22788:47;22852:131;22978:4;22852:131;:::i;:::-;22844:139;;22571:419;;;:::o;22996:225::-;23136:34;23132:1;23124:6;23120:14;23113:58;23205:8;23200:2;23192:6;23188:15;23181:33;22996:225;:::o;23227:366::-;23369:3;23390:67;23454:2;23449:3;23390:67;:::i;:::-;23383:74;;23466:93;23555:3;23466:93;:::i;:::-;23584:2;23579:3;23575:12;23568:19;;23227:366;;;:::o;23599:419::-;23765:4;23803:2;23792:9;23788:18;23780:26;;23852:9;23846:4;23842:20;23838:1;23827:9;23823:17;23816:47;23880:131;24006:4;23880:131;:::i;:::-;23872:139;;23599:419;;;:::o;24024:118::-;24095:22;24111:5;24095:22;:::i;:::-;24088:5;24085:33;24075:61;;24132:1;24129;24122:12;24075:61;24024:118;:::o;24148:139::-;24203:5;24234:6;24228:13;24219:22;;24250:31;24275:5;24250:31;:::i;:::-;24148:139;;;;:::o;24293:347::-;24361:6;24410:2;24398:9;24389:7;24385:23;24381:32;24378:119;;;24416:79;;:::i;:::-;24378:119;24536:1;24561:62;24615:7;24606:6;24595:9;24591:22;24561:62;:::i;:::-;24551:72;;24507:126;24293:347;;;;:::o;24646:102::-;24688:8;24735:5;24732:1;24728:13;24707:34;;24646:102;;;:::o;24754:848::-;24815:5;24822:4;24846:6;24837:15;;24870:5;24861:14;;24884:712;24905:1;24895:8;24892:15;24884:712;;;25000:4;24995:3;24991:14;24985:4;24982:24;24979:50;;;25009:18;;:::i;:::-;24979:50;25059:1;25049:8;25045:16;25042:451;;;25474:4;25467:5;25463:16;25454:25;;25042:451;25524:4;25518;25514:15;25506:23;;25554:32;25577:8;25554:32;:::i;:::-;25542:44;;24884:712;;;24754:848;;;;;;;:::o;25608:1073::-;25662:5;25853:8;25843:40;;25874:1;25865:10;;25876:5;;25843:40;25902:4;25892:36;;25919:1;25910:10;;25921:5;;25892:36;25988:4;26036:1;26031:27;;;;26072:1;26067:191;;;;25981:277;;26031:27;26049:1;26040:10;;26051:5;;;26067:191;26112:3;26102:8;26099:17;26096:43;;;26119:18;;:::i;:::-;26096:43;26168:8;26165:1;26161:16;26152:25;;26203:3;26196:5;26193:14;26190:40;;;26210:18;;:::i;:::-;26190:40;26243:5;;;25981:277;;26367:2;26357:8;26354:16;26348:3;26342:4;26339:13;26335:36;26317:2;26307:8;26304:16;26299:2;26293:4;26290:12;26286:35;26270:111;26267:246;;;26423:8;26417:4;26413:19;26404:28;;26458:3;26451:5;26448:14;26445:40;;;26465:18;;:::i;:::-;26445:40;26498:5;;26267:246;26538:42;26576:3;26566:8;26560:4;26557:1;26538:42;:::i;:::-;26523:57;;;;26612:4;26607:3;26603:14;26596:5;26593:25;26590:51;;;26621:18;;:::i;:::-;26590:51;26670:4;26663:5;26659:16;26650:25;;25608:1073;;;;;;:::o;26687:281::-;26745:5;26769:23;26787:4;26769:23;:::i;:::-;26761:31;;26813:25;26829:8;26813:25;:::i;:::-;26801:37;;26857:104;26894:66;26884:8;26878:4;26857:104;:::i;:::-;26848:113;;26687:281;;;;:::o;26974:223::-;27114:34;27110:1;27102:6;27098:14;27091:58;27183:6;27178:2;27170:6;27166:15;27159:31;26974:223;:::o;27203:366::-;27345:3;27366:67;27430:2;27425:3;27366:67;:::i;:::-;27359:74;;27442:93;27531:3;27442:93;:::i;:::-;27560:2;27555:3;27551:12;27544:19;;27203:366;;;:::o;27575:419::-;27741:4;27779:2;27768:9;27764:18;27756:26;;27828:9;27822:4;27818:20;27814:1;27803:9;27799:17;27792:47;27856:131;27982:4;27856:131;:::i;:::-;27848:139;;27575:419;;;:::o;28000:221::-;28140:34;28136:1;28128:6;28124:14;28117:58;28209:4;28204:2;28196:6;28192:15;28185:29;28000:221;:::o;28227:366::-;28369:3;28390:67;28454:2;28449:3;28390:67;:::i;:::-;28383:74;;28466:93;28555:3;28466:93;:::i;:::-;28584:2;28579:3;28575:12;28568:19;;28227:366;;;:::o;28599:419::-;28765:4;28803:2;28792:9;28788:18;28780:26;;28852:9;28846:4;28842:20;28838:1;28827:9;28823:17;28816:47;28880:131;29006:4;28880:131;:::i;:::-;28872:139;;28599:419;;;:::o;29024:182::-;29164:34;29160:1;29152:6;29148:14;29141:58;29024:182;:::o;29212:366::-;29354:3;29375:67;29439:2;29434:3;29375:67;:::i;:::-;29368:74;;29451:93;29540:3;29451:93;:::i;:::-;29569:2;29564:3;29560:12;29553:19;;29212:366;;;:::o;29584:419::-;29750:4;29788:2;29777:9;29773:18;29765:26;;29837:9;29831:4;29827:20;29823:1;29812:9;29808:17;29801:47;29865:131;29991:4;29865:131;:::i;:::-;29857:139;;29584:419;;;:::o;30009:179::-;30149:31;30145:1;30137:6;30133:14;30126:55;30009:179;:::o;30194:366::-;30336:3;30357:67;30421:2;30416:3;30357:67;:::i;:::-;30350:74;;30433:93;30522:3;30433:93;:::i;:::-;30551:2;30546:3;30542:12;30535:19;;30194:366;;;:::o;30566:419::-;30732:4;30770:2;30759:9;30755:18;30747:26;;30819:9;30813:4;30809:20;30805:1;30794:9;30790:17;30783:47;30847:131;30973:4;30847:131;:::i;:::-;30839:139;;30566:419;;;:::o;30991:224::-;31131:34;31127:1;31119:6;31115:14;31108:58;31200:7;31195:2;31187:6;31183:15;31176:32;30991:224;:::o;31221:366::-;31363:3;31384:67;31448:2;31443:3;31384:67;:::i;:::-;31377:74;;31460:93;31549:3;31460:93;:::i;:::-;31578:2;31573:3;31569:12;31562:19;;31221:366;;;:::o;31593:419::-;31759:4;31797:2;31786:9;31782:18;31774:26;;31846:9;31840:4;31836:20;31832:1;31821:9;31817:17;31810:47;31874:131;32000:4;31874:131;:::i;:::-;31866:139;;31593:419;;;:::o;32018:222::-;32158:34;32154:1;32146:6;32142:14;32135:58;32227:5;32222:2;32214:6;32210:15;32203:30;32018:222;:::o;32246:366::-;32388:3;32409:67;32473:2;32468:3;32409:67;:::i;:::-;32402:74;;32485:93;32574:3;32485:93;:::i;:::-;32603:2;32598:3;32594:12;32587:19;;32246:366;;;:::o;32618:419::-;32784:4;32822:2;32811:9;32807:18;32799:26;;32871:9;32865:4;32861:20;32857:1;32846:9;32842:17;32835:47;32899:131;33025:4;32899:131;:::i;:::-;32891:139;;32618:419;;;:::o;33043:225::-;33183:34;33179:1;33171:6;33167:14;33160:58;33252:8;33247:2;33239:6;33235:15;33228:33;33043:225;:::o;33274:366::-;33416:3;33437:67;33501:2;33496:3;33437:67;:::i;:::-;33430:74;;33513:93;33602:3;33513:93;:::i;:::-;33631:2;33626:3;33622:12;33615:19;;33274:366;;;:::o;33646:419::-;33812:4;33850:2;33839:9;33835:18;33827:26;;33899:9;33893:4;33889:20;33885:1;33874:9;33870:17;33863:47;33927:131;34053:4;33927:131;:::i;:::-;33919:139;;33646:419;;;:::o;34071:332::-;34192:4;34230:2;34219:9;34215:18;34207:26;;34243:71;34311:1;34300:9;34296:17;34287:6;34243:71;:::i;:::-;34324:72;34392:2;34381:9;34377:18;34368:6;34324:72;:::i;:::-;34071:332;;;;;:::o;34409:180::-;34457:77;34454:1;34447:88;34554:4;34551:1;34544:15;34578:4;34575:1;34568:15;34595:442;34744:4;34782:2;34771:9;34767:18;34759:26;;34795:71;34863:1;34852:9;34848:17;34839:6;34795:71;:::i;:::-;34876:72;34944:2;34933:9;34929:18;34920:6;34876:72;:::i;:::-;34958;35026:2;35015:9;35011:18;35002:6;34958:72;:::i;:::-;34595:442;;;;;;:::o;35043:181::-;35183:33;35179:1;35171:6;35167:14;35160:57;35043:181;:::o;35230:366::-;35372:3;35393:67;35457:2;35452:3;35393:67;:::i;:::-;35386:74;;35469:93;35558:3;35469:93;:::i;:::-;35587:2;35582:3;35578:12;35571:19;;35230:366;;;:::o;35602:419::-;35768:4;35806:2;35795:9;35791:18;35783:26;;35855:9;35849:4;35845:20;35841:1;35830:9;35826:17;35819:47;35883:131;36009:4;35883:131;:::i;:::-;35875:139;;35602:419;;;:::o;36027:220::-;36167:34;36163:1;36155:6;36151:14;36144:58;36236:3;36231:2;36223:6;36219:15;36212:28;36027:220;:::o;36253:366::-;36395:3;36416:67;36480:2;36475:3;36416:67;:::i;:::-;36409:74;;36492:93;36581:3;36492:93;:::i;:::-;36610:2;36605:3;36601:12;36594:19;;36253:366;;;:::o;36625:419::-;36791:4;36829:2;36818:9;36814:18;36806:26;;36878:9;36872:4;36868:20;36864:1;36853:9;36849:17;36842:47;36906:131;37032:4;36906:131;:::i;:::-;36898:139;;36625:419;;;:::o;37050:221::-;37190:34;37186:1;37178:6;37174:14;37167:58;37259:4;37254:2;37246:6;37242:15;37235:29;37050:221;:::o;37277:366::-;37419:3;37440:67;37504:2;37499:3;37440:67;:::i;:::-;37433:74;;37516:93;37605:3;37516:93;:::i;:::-;37634:2;37629:3;37625:12;37618:19;;37277:366;;;:::o;37649:419::-;37815:4;37853:2;37842:9;37838:18;37830:26;;37902:9;37896:4;37892:20;37888:1;37877:9;37873:17;37866:47;37930:131;38056:4;37930:131;:::i;:::-;37922:139;;37649:419;;;:::o;38074:229::-;38214:34;38210:1;38202:6;38198:14;38191:58;38283:12;38278:2;38270:6;38266:15;38259:37;38074:229;:::o;38309:366::-;38451:3;38472:67;38536:2;38531:3;38472:67;:::i;:::-;38465:74;;38548:93;38637:3;38548:93;:::i;:::-;38666:2;38661:3;38657:12;38650:19;;38309:366;;;:::o;38681:419::-;38847:4;38885:2;38874:9;38870:18;38862:26;;38934:9;38928:4;38924:20;38920:1;38909:9;38905:17;38898:47;38962:131;39088:4;38962:131;:::i;:::-;38954:139;;38681:419;;;:::o;39106:225::-;39246:34;39242:1;39234:6;39230:14;39223:58;39315:8;39310:2;39302:6;39298:15;39291:33;39106:225;:::o;39337:366::-;39479:3;39500:67;39564:2;39559:3;39500:67;:::i;:::-;39493:74;;39576:93;39665:3;39576:93;:::i;:::-;39694:2;39689:3;39685:12;39678:19;;39337:366;;;:::o;39709:419::-;39875:4;39913:2;39902:9;39898:18;39890:26;;39962:9;39956:4;39952:20;39948:1;39937:9;39933:17;39926:47;39990:131;40116:4;39990:131;:::i;:::-;39982:139;;39709:419;;;:::o;40134:179::-;40274:31;40270:1;40262:6;40258:14;40251:55;40134:179;:::o;40319:366::-;40461:3;40482:67;40546:2;40541:3;40482:67;:::i;:::-;40475:74;;40558:93;40647:3;40558:93;:::i;:::-;40676:2;40671:3;40667:12;40660:19;;40319:366;;;:::o;40691:419::-;40857:4;40895:2;40884:9;40880:18;40872:26;;40944:9;40938:4;40934:20;40930:1;40919:9;40915:17;40908:47;40972:131;41098:4;40972:131;:::i;:::-;40964:139;;40691:419;;;:::o;41116:98::-;41167:6;41201:5;41195:12;41185:22;;41116:98;;;:::o;41220:386::-;41324:3;41352:38;41384:5;41352:38;:::i;:::-;41406:88;41487:6;41482:3;41406:88;:::i;:::-;41399:95;;41503:65;41561:6;41556:3;41549:4;41542:5;41538:16;41503:65;:::i;:::-;41593:6;41588:3;41584:16;41577:23;;41328:278;41220:386;;;;:::o;41612:271::-;41742:3;41764:93;41853:3;41844:6;41764:93;:::i;:::-;41757:100;;41874:3;41867:10;;41612:271;;;;:::o
Metadata Hash
538aa55666c36cb83d9fccdb4c6a9f3500cb1b3c7d00c4d1f9fec56717ad4a92
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.