Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x61018060 | 20099056 | 106 days ago | IN | 0 ETH | 0.02280755 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
SophonFarming
Compiler Version
v0.8.26+commit.8a97fa7a
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-06-15 */ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.26; /** * @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 value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` 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 value) external returns (bool); } /** * @dev Interface for the optional metadata functions from the ERC20 standard. */ 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); } /** * @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. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ 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]. * * CAUTION: See Security Considerations above. */ 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); } /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @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 or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * 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. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @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`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // 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 FailedInnerCall(); } } } /** * @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; /** * @dev An operation with an ERC20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @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); if (returndata.length != 0 && !abi.decode(returndata, (bool))) { revert SafeERC20FailedOperation(address(token)); } } /** * @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). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // 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 cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0; } } /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Muldiv operation overflow. */ error MathOverflowedMulDiv(); enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an overflow flag. */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @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 towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. return a / b; } // (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 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. if (denominator <= prod1) { revert MathOverflowedMulDiv(); } /////////////////////////////////////////////// // 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. uint256 twos = denominator & (0 - denominator); 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 (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * 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)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 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) { unchecked { uint256 result = sqrt(a); return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } } interface IWeth { event Approval(address indexed src, address indexed guy, uint wad); event Transfer(address indexed src, address indexed dst, uint wad); event Deposit(address indexed dst, uint wad); event Withdrawal(address indexed src, uint wad); function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function balanceOf(address user) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function totalSupply() external view returns (uint); function deposit() external payable; function withdraw(uint256 wad) external; function approve(address guy, uint wad) external returns (bool); function transfer(address dst, uint wad) external returns (bool); function transferFrom(address src, address dst, uint wad) external returns (bool); } interface IstETH { function submit(address _referral) external payable returns (uint256); function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256); function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256); } interface IwstETH { function wrap(uint256 _stETHAmount) external returns (uint256); function unwrap(uint256 _wstETHAmount) external returns (uint256); function getWstETHByStETH(uint256 _stETHAmount) external view returns (uint256); function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256); function stEthPerToken() external view returns (uint256); function tokensPerStEth() external view returns (uint256); } interface IsDAI { function deposit(uint256 assets, address receiver) external returns (uint256 shares); function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); function convertToShares(uint256 assets) external view returns (uint256); function convertToAssets(uint256 shares) external view returns (uint256); } interface IeETHLiquidityPool { function deposit(address _referral) external payable returns (uint256); function sharesForAmount(uint256 _amount) external view returns (uint256); function amountForShare(uint256 _share) external view returns (uint256); } interface IweETH { function wrap(uint256 _eETHAmount) external returns (uint256); } /** * @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; } function _contextSuffixLength() internal view virtual returns (uint256) { return 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. * * The initial owner is set to the address provided by the deployer. 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; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @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 { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling 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 { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _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); } } /** * @dev Contract module which provides access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is specified at deployment time in the constructor for `Ownable`. This * can later be changed with {transferOwnership} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ abstract contract Ownable2Step is Ownable { address private _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() public virtual { address sender = _msgSender(); if (pendingOwner() != sender) { revert OwnableUnauthorizedAccount(sender); } _transferOwnership(sender); } } event ReplaceImplementationStarted(address indexed previousImplementation, address indexed newImplementation); event ReplaceImplementation(address indexed previousImplementation, address indexed newImplementation); error Unauthorized(); contract Upgradeable2Step is Ownable2Step { address public pendingImplementation; address public implementation; constructor() Ownable(msg.sender) {} // called on an inheriting proxy contract function replaceImplementation(address impl_) public onlyOwner { pendingImplementation = impl_; emit ReplaceImplementationStarted(implementation, impl_); } // called from an inheriting implementation contract function acceptImplementation() public { if (msg.sender != pendingImplementation) { revert OwnableUnauthorizedAccount(msg.sender); } emit ReplaceImplementation(implementation, msg.sender); delete pendingImplementation; implementation = msg.sender; } // called on an inheriting implementation contract function becomeImplementation(Upgradeable2Step proxy) public { if (msg.sender != proxy.owner()) { revert Unauthorized(); } proxy.acceptImplementation(); } } interface BridgeLike { function deposit( address _l2Receiver, address _l1Token, uint256 _amount, uint256 _l2TxGasLimit, uint256 _l2TxGasPerPubdataByte, address _refundRecipient ) external payable returns (bytes32 l2TxHash); } contract SophonFarmingState { // Info of each pool. struct PoolInfo { IERC20 lpToken; // Address of LP token contract. address l2Farm; // Address of the farming contract on Sophon chain uint256 amount; // total amount of LP tokens earning yield from deposits and boosts uint256 boostAmount; // total boosted value purchased by users uint256 depositAmount; // remaining deposits not applied to a boost purchases uint256 allocPoint; // How many allocation points assigned to this pool. Points to distribute per block. uint256 lastRewardBlock; // Last block number that points distribution occurs. uint256 accPointsPerShare; // Accumulated points per share. uint256 totalRewards; // Total rewards earned by the pool. string description; // Description of pool. } // Info of each user. struct UserInfo { uint256 amount; // Amount of LP tokens the user is earning yield on from deposits and boosts uint256 boostAmount; // Boosted value purchased by the user uint256 depositAmount; // remaining deposits not applied to a boost purchases uint256 rewardSettled; // rewards settled uint256 rewardDebt; // rewards debt } enum PredefinedPool { sDAI, // MakerDAO (sDAI) wstETH, // Lido (wstETH) weETH // ether.fi (weETH) } mapping(PredefinedPool => uint256) public typeToId; // held proceeds from booster sales mapping(uint256 => uint256) public heldProceeds; uint256 public boosterMultiplier; // Points created per block. uint256 public pointsPerBlock; // Info of each pool. PoolInfo[] public poolInfo; // Info of each user that stakes LP tokens. mapping(uint256 => mapping(address => UserInfo)) public userInfo; // Total allocation points. Must be the sum of all allocation points in all pools. uint256 public totalAllocPoint; // The block number when point mining ends. uint256 public endBlock; bool internal _initialized; mapping(address => bool) public poolExists; uint256 public endBlockForWithdrawals; BridgeLike public bridge; mapping(uint256 => bool) public isBridged; mapping(address userAdmin => mapping(address user => bool inWhitelist)) public whitelist; } /** * @title Sophon Farming Contract * @author Sophon */ contract SophonFarming is Upgradeable2Step, SophonFarmingState { using SafeERC20 for IERC20; /// @notice Emitted when a new pool is added event Add(address indexed lpToken, uint256 indexed pid, uint256 allocPoint); /// @notice Emitted when a pool is updated event Set(address indexed lpToken, uint256 indexed pid, uint256 allocPoint); /// @notice Emitted when a user deposits to a pool event Deposit(address indexed user, uint256 indexed pid, uint256 depositAmount, uint256 boostAmount); /// @notice Emitted when a user withdraws from a pool event Withdraw(address indexed user, uint256 indexed pid, uint256 amount); /// @notice Emitted when a whitelisted admin transfers points from one user to another event TransferPoints(address indexed sender, address indexed receiver, uint256 indexed pid, uint256 amount); /// @notice Emitted when a user increases the boost of an existing deposit event IncreaseBoost(address indexed user, uint256 indexed pid, uint256 boostAmount); /// @notice Emitted when all pool funds are bridged to Sophon blockchain event BridgePool(address indexed user, uint256 indexed pid, uint256 amount); /// @notice Emitted when the admin bridges booster proceeds event BridgeProceeds(uint256 indexed pid, uint256 proceeds); /// @notice Emitted when the the revertFailedBridge function is called event RevertFailedBridge(uint256 indexed pid); /// @notice Emitted when the the updatePool function is called event PoolUpdated(uint256 indexed pid); /// @notice Emitted when setPointsPerBlock is called event SetPointsPerBlock(uint256 oldValue, uint256 newValue); error ZeroAddress(); error PoolExists(); error PoolDoesNotExist(); error AlreadyInitialized(); error NotFound(address lpToken); error FarmingIsStarted(); error FarmingIsEnded(); error TransferNotAllowed(); error TransferTooHigh(uint256 maxAllowed); error InvalidEndBlock(); error InvalidDeposit(); error InvalidBooster(); error InvalidPointsPerBlock(); error InvalidTransfer(); error WithdrawNotAllowed(); error WithdrawTooHigh(uint256 maxAllowed); error WithdrawIsZero(); error NothingInPool(); error NoEthSent(); error BoostTooHigh(uint256 maxAllowed); error BoostIsZero(); error BridgeInvalid(); address public immutable dai; address public immutable sDAI; address public immutable weth; address public immutable stETH; address public immutable wstETH; address public immutable eETH; address public immutable eETHLiquidityPool; address public immutable weETH; /** * @notice Construct SophonFarming * @param tokens_ Immutable token addresses * @dev 0:dai, 1:sDAI, 2:weth, 3:stETH, 4:wstETH, 5:eETH, 6:eETHLiquidityPool, 7:weETH */ constructor(address[8] memory tokens_) { dai = tokens_[0]; sDAI = tokens_[1]; weth = tokens_[2]; stETH = tokens_[3]; wstETH = tokens_[4]; eETH = tokens_[5]; eETHLiquidityPool = tokens_[6]; weETH = tokens_[7]; } /** * @notice Allows direct deposits of ETH for deposit to the wstETH pool */ receive() external payable { if (msg.sender == weth) { return; } depositEth(0, PredefinedPool.wstETH); } /** * @notice Initialize the farm * @param wstEthAllocPoint_ wstEth alloc points * @param weEthAllocPoint_ weEth alloc points * @param sDAIAllocPoint_ sdai alloc points * @param _pointsPerBlock points per block * @param _initialPoolStartBlock start block * @param _boosterMultiplier booster multiplier */ function initialize(uint256 wstEthAllocPoint_, uint256 weEthAllocPoint_, uint256 sDAIAllocPoint_, uint256 _pointsPerBlock, uint256 _initialPoolStartBlock, uint256 _boosterMultiplier) public virtual onlyOwner { if (_initialized) { revert AlreadyInitialized(); } if (_pointsPerBlock < 1e18 || _pointsPerBlock > 1000e18) { revert InvalidPointsPerBlock(); } pointsPerBlock = _pointsPerBlock; if (_boosterMultiplier < 1e18 || _boosterMultiplier > 10e18) { revert InvalidBooster(); } boosterMultiplier = _boosterMultiplier; poolExists[dai] = true; poolExists[weth] = true; poolExists[stETH] = true; poolExists[eETH] = true; _initialized = true; // sDAI typeToId[PredefinedPool.sDAI] = add(sDAIAllocPoint_, sDAI, "sDAI", _initialPoolStartBlock, 0); IERC20(dai).approve(sDAI, 2**256-1); // wstETH typeToId[PredefinedPool.wstETH] = add(wstEthAllocPoint_, wstETH, "wstETH", _initialPoolStartBlock, 0); IERC20(stETH).approve(wstETH, 2**256-1); // weETH typeToId[PredefinedPool.weETH] = add(weEthAllocPoint_, weETH, "weETH", _initialPoolStartBlock, 0); IERC20(eETH).approve(weETH, 2**256-1); } /** * @notice Adds a new pool to the farm. Can only be called by the owner. * @param _allocPoint alloc point for new pool * @param _lpToken lpToken address * @param _description description of new pool * @param _poolStartBlock block at which points start to accrue for the pool * @param _newPointsPerBlock update global points per block; 0 means no update * @return uint256 The pid of the newly created asset */ function add(uint256 _allocPoint, address _lpToken, string memory _description, uint256 _poolStartBlock, uint256 _newPointsPerBlock) public onlyOwner returns (uint256) { if (_lpToken == address(0)) { revert ZeroAddress(); } if (poolExists[_lpToken]) { revert PoolExists(); } if (isFarmingEnded()) { revert FarmingIsEnded(); } if (_newPointsPerBlock != 0) { setPointsPerBlock(_newPointsPerBlock); } else { massUpdatePools(); } uint256 lastRewardBlock = getBlockNumber() > _poolStartBlock ? getBlockNumber() : _poolStartBlock; totalAllocPoint = totalAllocPoint + _allocPoint; poolExists[_lpToken] = true; uint256 pid = poolInfo.length; poolInfo.push( PoolInfo({ lpToken: IERC20(_lpToken), l2Farm: address(0), amount: 0, boostAmount: 0, depositAmount: 0, allocPoint: _allocPoint, lastRewardBlock: lastRewardBlock, accPointsPerShare: 0, totalRewards: 0, description: _description }) ); emit Add(_lpToken, pid, _allocPoint); return pid; } /** * @notice Updates the given pool's allocation point. Can only be called by the owner. * @param _pid The pid to update * @param _allocPoint The new alloc point to set for the pool * @param _poolStartBlock block at which points start to accrue for the pool; 0 means no update * @param _newPointsPerBlock update global points per block; 0 means no update */ function set(uint256 _pid, uint256 _allocPoint, uint256 _poolStartBlock, uint256 _newPointsPerBlock) external onlyOwner { if (isFarmingEnded()) { revert FarmingIsEnded(); } if (_newPointsPerBlock != 0) { setPointsPerBlock(_newPointsPerBlock); } else { massUpdatePools(); } PoolInfo storage pool = poolInfo[_pid]; address lpToken = address(pool.lpToken); if (lpToken == address(0) || !poolExists[lpToken]) { revert PoolDoesNotExist(); } totalAllocPoint = totalAllocPoint - pool.allocPoint + _allocPoint; pool.allocPoint = _allocPoint; // pool starting block is updated if farming hasn't started and _poolStartBlock is non-zero if (_poolStartBlock != 0 && getBlockNumber() < pool.lastRewardBlock) { pool.lastRewardBlock = getBlockNumber() > _poolStartBlock ? getBlockNumber() : _poolStartBlock; } emit Set(lpToken, _pid, _allocPoint); } /** * @notice Returns the number of pools in the farm * @return uint256 number of pools */ function poolLength() external view returns (uint256) { return poolInfo.length; } /** * @notice Checks if farming is ended * @return bool True if farming is ended */ function isFarmingEnded() public view returns (bool) { uint256 _endBlock = endBlock; if (_endBlock != 0 && getBlockNumber() > _endBlock) { return true; } else { return false; } } /** * @notice Checks if the withdrawal period is ended * @return bool True if withdrawal period is ended */ function isWithdrawPeriodEnded() public view returns (bool) { uint256 _endBlockForWithdrawals = endBlockForWithdrawals; if (_endBlockForWithdrawals != 0 && getBlockNumber() > _endBlockForWithdrawals) { return true; } else { return false; } } /** * @notice Updates the bridge contract */ function setBridge(address _bridge) external onlyOwner { if (_bridge == address(0)) { revert ZeroAddress(); } bridge = BridgeLike(_bridge); } /** * @notice Updates the L2 Farm for the pool * @param _pid the pid * @param _l2Farm the l2Farm address */ function setL2FarmForPool(uint256 _pid, address _l2Farm) external onlyOwner { if (_l2Farm == address(0)) { revert ZeroAddress(); } if (address(poolInfo[_pid].lpToken) == address(0)) { revert PoolDoesNotExist(); } poolInfo[_pid].l2Farm = _l2Farm; } /** * @notice Set the end block of the farm * @param _endBlock the end block * @param _withdrawalBlocks the last block that withdrawals are allowed */ function setEndBlock(uint256 _endBlock, uint256 _withdrawalBlocks) external onlyOwner { if (isFarmingEnded()) { revert FarmingIsEnded(); } uint256 _endBlockForWithdrawals; if (_endBlock != 0) { if (getBlockNumber() > _endBlock) { revert InvalidEndBlock(); } _endBlockForWithdrawals = _endBlock + _withdrawalBlocks; } else { // withdrawal blocks needs an endBlock _endBlockForWithdrawals = 0; } massUpdatePools(); endBlock = _endBlock; endBlockForWithdrawals = _endBlockForWithdrawals; } /** * @notice Set points per block * @param _pointsPerBlock points per block to set */ function setPointsPerBlock(uint256 _pointsPerBlock) public onlyOwner { if (isFarmingEnded()) { revert FarmingIsEnded(); } if (_pointsPerBlock < 1e18 || _pointsPerBlock > 1000e18) { revert InvalidPointsPerBlock(); } massUpdatePools(); emit SetPointsPerBlock(pointsPerBlock, _pointsPerBlock); pointsPerBlock = _pointsPerBlock; } /** * @notice Set booster multiplier * @param _boosterMultiplier booster multiplier to set */ function setBoosterMultiplier(uint256 _boosterMultiplier) external onlyOwner { if (_boosterMultiplier < 1e18 || _boosterMultiplier > 10e18) { revert InvalidBooster(); } if (isFarmingEnded()) { revert FarmingIsEnded(); } massUpdatePools(); boosterMultiplier = _boosterMultiplier; } /** * @notice Returns the block multiplier * @param _from from block * @param _to to block * @return uint256 The block multiplier */ function _getBlockMultiplier(uint256 _from, uint256 _to) internal view returns (uint256) { uint256 _endBlock = endBlock; if (_endBlock != 0) { _to = Math.min(_to, _endBlock); } if (_to > _from) { return (_to - _from) * 1e18; } else { return 0; } } /** * @notice Adds or removes users from the whitelist * @param _userAdmin an admin user who can transfer points for users * @param _users list of users * @param _isInWhitelist to add or remove */ function setUsersWhitelisted(address _userAdmin, address[] memory _users, bool _isInWhitelist) external onlyOwner { for(uint i = 0; i < _users.length; i++) { whitelist[_userAdmin][_users[i]] = _isInWhitelist; } } /** * @notice Returns pending points for user in a pool * @param _pid pid of the pool * @param _user user in the pool * @return uint256 pendings points */ function _pendingPoints(uint256 _pid, address _user) internal view returns (uint256) { UserInfo storage user = userInfo[_pid][_user]; (uint256 accPointsPerShare, ) = _settlePool(_pid); return user.amount * accPointsPerShare / 1e18 + user.rewardSettled - user.rewardDebt; } /** * @notice Returns accPointsPerShare and totalRewards to date for the pool * @param _pid pid of the pool * @return accPointsPerShare * @return totalRewards */ function _settlePool(uint256 _pid) internal view returns (uint256 accPointsPerShare, uint256 totalRewards) { PoolInfo storage pool = poolInfo[_pid]; accPointsPerShare = pool.accPointsPerShare; totalRewards = pool.totalRewards; uint256 lpSupply = pool.amount; if (getBlockNumber() > pool.lastRewardBlock && lpSupply != 0) { uint256 blockMultiplier = _getBlockMultiplier(pool.lastRewardBlock, getBlockNumber()); uint256 pointReward = blockMultiplier * pointsPerBlock * pool.allocPoint / totalAllocPoint; totalRewards = totalRewards + pointReward / 1e18; accPointsPerShare = pointReward / lpSupply + accPointsPerShare; } } /** * @notice Returns pending points for user in a pool * @param _pid pid of the pool * @param _user user in the pool * @return uint256 pendings points */ function pendingPoints(uint256 _pid, address _user) external view returns (uint256) { return _pendingPoints(_pid, _user); } /** * @notice Update accounting of all pools */ function massUpdatePools() public { uint256 length = poolInfo.length; for(uint256 pid = 0; pid < length; ++pid) { updatePool(pid); } } /** * @notice Updating accounting of a single pool * @param _pid pid to update */ function updatePool(uint256 _pid) public { PoolInfo storage pool = poolInfo[_pid]; if (getBlockNumber() <= pool.lastRewardBlock) { return; } uint256 lpSupply = pool.amount; uint256 _pointsPerBlock = pointsPerBlock; uint256 _allocPoint = pool.allocPoint; if (lpSupply == 0 || _pointsPerBlock == 0 || _allocPoint == 0) { pool.lastRewardBlock = getBlockNumber(); return; } uint256 blockMultiplier = _getBlockMultiplier(pool.lastRewardBlock, getBlockNumber()); uint256 pointReward = blockMultiplier * _pointsPerBlock * _allocPoint / totalAllocPoint; pool.totalRewards = pool.totalRewards + pointReward / 1e18; pool.accPointsPerShare = pointReward / lpSupply + pool.accPointsPerShare; pool.lastRewardBlock = getBlockNumber(); emit PoolUpdated(_pid); } /** * @notice Deposit assets to SophonFarming * @param _pid pid of the pool * @param _amount amount of the deposit * @param _boostAmount amount to boost */ function deposit(uint256 _pid, uint256 _amount, uint256 _boostAmount) external { poolInfo[_pid].lpToken.safeTransferFrom( msg.sender, address(this), _amount ); _deposit(_pid, _amount, _boostAmount); } /** * @notice Deposit DAI to SophonFarming * @param _amount amount of the deposit * @param _boostAmount amount to boost */ function depositDai(uint256 _amount, uint256 _boostAmount) external { IERC20(dai).safeTransferFrom( msg.sender, address(this), _amount ); _depositPredefinedAsset(_amount, _amount, _boostAmount, PredefinedPool.sDAI); } /** * @notice Deposit stETH to SophonFarming * @param _amount amount of the deposit * @param _boostAmount amount to boost */ function depositStEth(uint256 _amount, uint256 _boostAmount) external { uint256 beforeBalance = IERC20(stETH).balanceOf(address(this)); IERC20(stETH).safeTransferFrom( msg.sender, address(this), _amount ); uint256 _finalAmount = IERC20(stETH).balanceOf(address(this)) - beforeBalance; _depositPredefinedAsset(_finalAmount, _amount, _boostAmount, PredefinedPool.wstETH); } /** * @notice Deposit eETH to SophonFarming * @param _amount amount of the deposit * @param _boostAmount amount to boost */ function depositeEth(uint256 _amount, uint256 _boostAmount) external { uint256 beforeBalance = IERC20(eETH).balanceOf(address(this)); IERC20(eETH).safeTransferFrom( msg.sender, address(this), _amount ); uint256 _finalAmount = IERC20(eETH).balanceOf(address(this)) - beforeBalance; _depositPredefinedAsset(_finalAmount, _amount, _boostAmount, PredefinedPool.weETH); } /** * @notice Deposit ETH to SophonFarming when specifying a pool * @param _boostAmount amount to boost * @param _predefinedPool specific pool type to deposit to */ function depositEth(uint256 _boostAmount, PredefinedPool _predefinedPool) public payable { if (msg.value == 0) { revert NoEthSent(); } uint256 _finalAmount = msg.value; if (_predefinedPool == PredefinedPool.wstETH) { _finalAmount = _ethTOstEth(_finalAmount); } else if (_predefinedPool == PredefinedPool.weETH) { _finalAmount = _ethTOeEth(_finalAmount); } else { revert InvalidDeposit(); } _depositPredefinedAsset(_finalAmount, msg.value, _boostAmount, _predefinedPool); } /** * @notice Deposit WETH to SophonFarming when specifying a pool * @param _amount amount of the deposit * @param _boostAmount amount to boost * @param _predefinedPool specific pool type to deposit to */ function depositWeth(uint256 _amount, uint256 _boostAmount, PredefinedPool _predefinedPool) external { IERC20(weth).safeTransferFrom( msg.sender, address(this), _amount ); uint256 _finalAmount = _wethTOEth(_amount); if (_predefinedPool == PredefinedPool.wstETH) { _finalAmount = _ethTOstEth(_finalAmount); } else if (_predefinedPool == PredefinedPool.weETH) { _finalAmount = _ethTOeEth(_finalAmount); } else { revert InvalidDeposit(); } _depositPredefinedAsset(_finalAmount, _amount, _boostAmount, _predefinedPool); } /** * @notice Deposit a predefined asset to SophonFarming * @param _amount amount of the deposit * @param _initalAmount amount of the deposit prior to conversions * @param _boostAmount amount to boost * @param _predefinedPool specific pool type to deposit to */ function _depositPredefinedAsset(uint256 _amount, uint256 _initalAmount, uint256 _boostAmount, PredefinedPool _predefinedPool) internal { uint256 _finalAmount; if (_predefinedPool == PredefinedPool.sDAI) { _finalAmount = _daiTOsDai(_amount); } else if (_predefinedPool == PredefinedPool.wstETH) { _finalAmount = _stEthTOwstEth(_amount); } else if (_predefinedPool == PredefinedPool.weETH) { _finalAmount = _eethTOweEth(_amount); } else { revert InvalidDeposit(); } // adjust boostAmount for the new asset _boostAmount = _boostAmount * _finalAmount / _initalAmount; _deposit(typeToId[_predefinedPool], _finalAmount, _boostAmount); } /** * @notice Deposit an asset to SophonFarming * @param _pid pid of the deposit * @param _depositAmount amount of the deposit * @param _boostAmount amount to boost */ function _deposit(uint256 _pid, uint256 _depositAmount, uint256 _boostAmount) internal { if (isFarmingEnded()) { revert FarmingIsEnded(); } if (_depositAmount == 0) { revert InvalidDeposit(); } if (_boostAmount > _depositAmount) { revert BoostTooHigh(_depositAmount); } PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; updatePool(_pid); uint256 userAmount = user.amount; user.rewardSettled = userAmount * pool.accPointsPerShare / 1e18 + user.rewardSettled - user.rewardDebt; // booster purchase proceeds heldProceeds[_pid] = heldProceeds[_pid] + _boostAmount; // deposit amount is reduced by amount of the deposit to boost _depositAmount = _depositAmount - _boostAmount; // set deposit amount user.depositAmount = user.depositAmount + _depositAmount; pool.depositAmount = pool.depositAmount + _depositAmount; // apply the boost multiplier _boostAmount = _boostAmount * boosterMultiplier / 1e18; user.boostAmount = user.boostAmount + _boostAmount; pool.boostAmount = pool.boostAmount + _boostAmount; // userAmount is increased by remaining deposit amount + full boosted amount userAmount = userAmount + _depositAmount + _boostAmount; user.amount = userAmount; pool.amount = pool.amount + _depositAmount + _boostAmount; user.rewardDebt = userAmount * pool.accPointsPerShare / 1e18; emit Deposit(msg.sender, _pid, _depositAmount, _boostAmount); } /** * @notice Increase boost from existing deposits * @param _pid pid to pool * @param _boostAmount amount to boost */ function increaseBoost(uint256 _pid, uint256 _boostAmount) external { if (isFarmingEnded()) { revert FarmingIsEnded(); } if (_boostAmount == 0) { revert BoostIsZero(); } uint256 maxAdditionalBoost = getMaxAdditionalBoost(msg.sender, _pid); if (_boostAmount > maxAdditionalBoost) { revert BoostTooHigh(maxAdditionalBoost); } PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; updatePool(_pid); uint256 userAmount = user.amount; user.rewardSettled = userAmount * pool.accPointsPerShare / 1e18 + user.rewardSettled - user.rewardDebt; // booster purchase proceeds heldProceeds[_pid] = heldProceeds[_pid] + _boostAmount; // user's remaining deposit is reduced by amount of the deposit to boost user.depositAmount = user.depositAmount - _boostAmount; pool.depositAmount = pool.depositAmount - _boostAmount; // apply the multiplier uint256 finalBoostAmount = _boostAmount * boosterMultiplier / 1e18; user.boostAmount = user.boostAmount + finalBoostAmount; pool.boostAmount = pool.boostAmount + finalBoostAmount; // user amount is increased by the full boosted amount - deposit amount used to boost userAmount = userAmount + finalBoostAmount - _boostAmount; user.amount = userAmount; pool.amount = pool.amount + finalBoostAmount - _boostAmount; user.rewardDebt = userAmount * pool.accPointsPerShare / 1e18; emit IncreaseBoost(msg.sender, _pid, finalBoostAmount); } /** * @notice Returns max additional boost amount allowed to boost current deposits * @dev total allowed boost is 100% of total deposit * @param _user user in pool * @param _pid pid of pool * @return uint256 max additional boost */ function getMaxAdditionalBoost(address _user, uint256 _pid) public view returns (uint256) { return userInfo[_pid][_user].depositAmount; } /** * @notice Withdraw an asset to SophonFarming * @param _pid pid of the withdraw * @param _withdrawAmount amount of the withdraw */ function withdraw(uint256 _pid, uint256 _withdrawAmount) external { if (isWithdrawPeriodEnded()) { revert WithdrawNotAllowed(); } if (_withdrawAmount == 0) { revert WithdrawIsZero(); } PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; updatePool(_pid); uint256 userDepositAmount = user.depositAmount; if (_withdrawAmount == type(uint256).max) { _withdrawAmount = userDepositAmount; } else if (_withdrawAmount > userDepositAmount) { revert WithdrawTooHigh(userDepositAmount); } uint256 userAmount = user.amount; user.rewardSettled = userAmount * pool.accPointsPerShare / 1e18 + user.rewardSettled - user.rewardDebt; user.depositAmount = userDepositAmount - _withdrawAmount; pool.depositAmount = pool.depositAmount - _withdrawAmount; userAmount = userAmount - _withdrawAmount; user.amount = userAmount; pool.amount = pool.amount - _withdrawAmount; user.rewardDebt = userAmount * pool.accPointsPerShare / 1e18; pool.lpToken.safeTransfer(msg.sender, _withdrawAmount); emit Withdraw(msg.sender, _pid, _withdrawAmount); } /** * @notice Permissionless function to allow anyone to bridge during the correct period * @param _pid pid to bridge * @param _l2TxGasLimit l2TxGasLimit for the bridge txn * @param _l2TxGasPerPubdataByte l2TxGasPerPubdataByte for the bridge txn */ function bridgePool(uint256 _pid, uint256 _l2TxGasLimit, uint256 _l2TxGasPerPubdataByte) external payable { revert Unauthorized(); // NOTE: function not fully implemented, an upgrade will implement this later if (!isFarmingEnded() || !isWithdrawPeriodEnded() || isBridged[_pid]) { revert Unauthorized(); } updatePool(_pid); PoolInfo storage pool = poolInfo[_pid]; uint256 depositAmount = pool.depositAmount; if (depositAmount == 0 || address(bridge) == address(0) || pool.l2Farm == address(0)) { revert BridgeInvalid(); } isBridged[_pid] = true; IERC20 lpToken = pool.lpToken; lpToken.approve(address(bridge), depositAmount); // Actual values are pending the launch of Sophon testnet bridge.deposit{value: msg.value}( pool.l2Farm, // _l2Receiver address(lpToken), // _l1Token depositAmount, // _amount _l2TxGasLimit, // _l2TxGasLimit _l2TxGasPerPubdataByte, // _l2TxGasPerPubdataByte owner() // _refundRecipient ); emit BridgePool(msg.sender, _pid, depositAmount); } // TODO: does this function need to call claimFailedDeposit on the bridge? // This is pending the launch of Sophon testnet /** * @notice Called by an admin if a bridge process to Sophon fails * @param _pid pid of the failed bridge to revert */ function revertFailedBridge(uint256 _pid) external onlyOwner { revert Unauthorized(); // NOTE: function not fully implemented, an upgrade will implement this later if (address(poolInfo[_pid].lpToken) == address(0)) { revert PoolDoesNotExist(); } isBridged[_pid] = false; emit RevertFailedBridge(_pid); } /** * @notice Called by an whitelisted admin to transfer points to another user * @param _pid pid of the pool to transfer points from * @param _sender address to send accrued points * @param _receiver address to receive accrued points * @param _transferAmount amount of points to transfer */ function transferPoints(uint256 _pid, address _sender, address _receiver, uint256 _transferAmount) external { if (!whitelist[msg.sender][_sender]) { revert TransferNotAllowed(); } if (_sender == _receiver || _receiver == address(this) || _transferAmount == 0) { revert InvalidTransfer(); } PoolInfo storage pool = poolInfo[_pid]; if (address(pool.lpToken) == address(0)) { revert PoolDoesNotExist(); } updatePool(_pid); uint256 accPointsPerShare = pool.accPointsPerShare; UserInfo storage userFrom = userInfo[_pid][_sender]; UserInfo storage userTo = userInfo[_pid][_receiver]; uint256 userFromAmount = userFrom.amount; uint256 userToAmount = userTo.amount; uint userFromRewardSettled = userFromAmount * accPointsPerShare / 1e18 + userFrom.rewardSettled - userFrom.rewardDebt; if (_transferAmount == type(uint256).max) { _transferAmount = userFromRewardSettled; } else if (_transferAmount > userFromRewardSettled) { revert TransferTooHigh(userFromRewardSettled); } userFrom.rewardSettled = userFromRewardSettled - _transferAmount; userTo.rewardSettled = userToAmount * accPointsPerShare / 1e18 + userTo.rewardSettled - userTo.rewardDebt + _transferAmount; userFrom.rewardDebt = userFromAmount * accPointsPerShare / 1e18; userTo.rewardDebt = userToAmount * accPointsPerShare / 1e18; emit TransferPoints(_sender, _receiver, _pid, _transferAmount); } /** * @notice Converts WETH to ETH * @dev WETH withdrawl * @param _amount in amount * @return uint256 out amount */ function _wethTOEth(uint256 _amount) internal returns (uint256) { // unwrap weth to eth IWeth(weth).withdraw(_amount); return _amount; } /** * @notice Converts ETH to stETH * @dev Lido * @param _amount in amount * @return uint256 out amount */ function _ethTOstEth(uint256 _amount) internal returns (uint256) { return IstETH(stETH).getPooledEthByShares( IstETH(stETH).submit{value: _amount}(owner()) ); } /** * @notice Converts stETH to wstETH * @dev Lido * @param _amount in amount * @return uint256 out amount */ function _stEthTOwstEth(uint256 _amount) internal returns (uint256) { // wrap returns exact amount of wstETH return IwstETH(wstETH).wrap(_amount); } /** * @notice Converts ETH to eETH * @dev ether.fi * @param _amount in amount * @return uint256 out amount */ function _ethTOeEth(uint256 _amount) internal returns (uint256) { return IeETHLiquidityPool(eETHLiquidityPool).amountForShare( IeETHLiquidityPool(eETHLiquidityPool).deposit{value: _amount}(owner()) ); } /** * @notice Converts eETH to weETH * @dev ether.fi * @param _amount in amount * @return uint256 out amount */ function _eethTOweEth(uint256 _amount) internal returns (uint256) { // wrap returns exact amount of weETH return IweETH(weETH).wrap(_amount); } /** * @notice Converts DAI to sDAI * @dev MakerDao * @param _amount in amount * @return uint256 out amount */ function _daiTOsDai(uint256 _amount) internal returns (uint256) { // deposit DAI to sDAI return IsDAI(sDAI).deposit(_amount, address(this)); } // This is pending the launch of Sophon testnet /** * @notice Allows an admin to bridge booster proceeds * @param _pid pid to bridge proceeds from * @param _l2TxGasLimit l2TxGasLimit for the bridge txn * @param _l2TxGasPerPubdataByte l2TxGasPerPubdataByte for the bridge txn */ function bridgeProceeds(uint256 _pid, uint256 _l2TxGasLimit, uint256 _l2TxGasPerPubdataByte) external payable onlyOwner { revert Unauthorized(); // NOTE: function not fully implemented, an upgrade will implement this later uint256 _proceeds = heldProceeds[_pid]; heldProceeds[_pid] = 0; // TODO: add bridging logic emit BridgeProceeds(_pid, _proceeds); } /** * @notice Returns the current block number * @dev Included to help with testing since it can be overridden for custom functionality * @return uint256 current block number */ function getBlockNumber() virtual public view returns (uint256) { return block.number; } /** * @notice Returns info about each pool * @return poolInfos all pool info */ function getPoolInfo() external view returns (PoolInfo[] memory poolInfos) { uint256 length = poolInfo.length; poolInfos = new PoolInfo[](length); for(uint256 pid = 0; pid < length; ++pid) { poolInfos[pid] = poolInfo[pid]; (, poolInfos[pid].totalRewards) = _settlePool(pid); } } /** * @notice Returns user info for a list of users * @param _users list of users * @return userInfos optimized user info */ function getOptimizedUserInfo(address[] memory _users) external view returns (uint256[4][][] memory userInfos) { uint256 usersLen = _users.length; userInfos = new uint256[4][][](usersLen); uint256 poolLen = poolInfo.length; for(uint256 i = 0; i < usersLen; i++) { address _user = _users[i]; userInfos[i] = new uint256[4][](poolLen); for(uint256 pid = 0; pid < poolLen; ++pid) { UserInfo memory uinfo = userInfo[pid][_user]; userInfos[i][pid][0] = uinfo.amount; userInfos[i][pid][1] = uinfo.boostAmount; userInfos[i][pid][2] = uinfo.depositAmount; userInfos[i][pid][3] = _pendingPoints(pid, _user); } } } /** * @notice Returns accrued points for a list of users * @param _users list of users * @return pendings accured points for user */ function getPendingPoints(address[] memory _users) external view returns (uint256[][] memory pendings) { uint256 usersLen = _users.length; pendings = new uint256[][](usersLen); uint256 poolLen = poolInfo.length; for(uint256 i = 0; i < usersLen; i++) { address _user = _users[i]; pendings[i] = new uint256[](poolLen); for(uint256 pid = 0; pid < poolLen; ++pid) { pendings[i][pid] = _pendingPoints(pid, _user); } } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address[8]","name":"tokens_","type":"address[8]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"BoostIsZero","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxAllowed","type":"uint256"}],"name":"BoostTooHigh","type":"error"},{"inputs":[],"name":"BridgeInvalid","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"FarmingIsEnded","type":"error"},{"inputs":[],"name":"FarmingIsStarted","type":"error"},{"inputs":[],"name":"InvalidBooster","type":"error"},{"inputs":[],"name":"InvalidDeposit","type":"error"},{"inputs":[],"name":"InvalidEndBlock","type":"error"},{"inputs":[],"name":"InvalidPointsPerBlock","type":"error"},{"inputs":[],"name":"InvalidTransfer","type":"error"},{"inputs":[],"name":"NoEthSent","type":"error"},{"inputs":[{"internalType":"address","name":"lpToken","type":"address"}],"name":"NotFound","type":"error"},{"inputs":[],"name":"NothingInPool","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"PoolDoesNotExist","type":"error"},{"inputs":[],"name":"PoolExists","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"TransferNotAllowed","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxAllowed","type":"uint256"}],"name":"TransferTooHigh","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"WithdrawIsZero","type":"error"},{"inputs":[],"name":"WithdrawNotAllowed","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxAllowed","type":"uint256"}],"name":"WithdrawTooHigh","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lpToken","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"}],"name":"Add","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BridgePool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"proceeds","type":"uint256"}],"name":"BridgeProceeds","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"depositAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"boostAmount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"boostAmount","type":"uint256"}],"name":"IncreaseBoost","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","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":true,"internalType":"uint256","name":"pid","type":"uint256"}],"name":"PoolUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousImplementation","type":"address"},{"indexed":true,"internalType":"address","name":"newImplementation","type":"address"}],"name":"ReplaceImplementation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousImplementation","type":"address"},{"indexed":true,"internalType":"address","name":"newImplementation","type":"address"}],"name":"ReplaceImplementationStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"}],"name":"RevertFailedBridge","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lpToken","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"}],"name":"Set","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"SetPointsPerBlock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferPoints","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"acceptImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"address","name":"_lpToken","type":"address"},{"internalType":"string","name":"_description","type":"string"},{"internalType":"uint256","name":"_poolStartBlock","type":"uint256"},{"internalType":"uint256","name":"_newPointsPerBlock","type":"uint256"}],"name":"add","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Upgradeable2Step","name":"proxy","type":"address"}],"name":"becomeImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"boosterMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bridge","outputs":[{"internalType":"contract BridgeLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_l2TxGasLimit","type":"uint256"},{"internalType":"uint256","name":"_l2TxGasPerPubdataByte","type":"uint256"}],"name":"bridgePool","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_l2TxGasLimit","type":"uint256"},{"internalType":"uint256","name":"_l2TxGasPerPubdataByte","type":"uint256"}],"name":"bridgeProceeds","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"dai","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_boostAmount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_boostAmount","type":"uint256"}],"name":"depositDai","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_boostAmount","type":"uint256"},{"internalType":"enum SophonFarmingState.PredefinedPool","name":"_predefinedPool","type":"uint8"}],"name":"depositEth","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_boostAmount","type":"uint256"}],"name":"depositStEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_boostAmount","type":"uint256"},{"internalType":"enum SophonFarmingState.PredefinedPool","name":"_predefinedPool","type":"uint8"}],"name":"depositWeth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_boostAmount","type":"uint256"}],"name":"depositeEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"eETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eETHLiquidityPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endBlockForWithdrawals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBlockNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"getMaxAdditionalBoost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"}],"name":"getOptimizedUserInfo","outputs":[{"internalType":"uint256[4][][]","name":"userInfos","type":"uint256[4][][]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"}],"name":"getPendingPoints","outputs":[{"internalType":"uint256[][]","name":"pendings","type":"uint256[][]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPoolInfo","outputs":[{"components":[{"internalType":"contract IERC20","name":"lpToken","type":"address"},{"internalType":"address","name":"l2Farm","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"boostAmount","type":"uint256"},{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardBlock","type":"uint256"},{"internalType":"uint256","name":"accPointsPerShare","type":"uint256"},{"internalType":"uint256","name":"totalRewards","type":"uint256"},{"internalType":"string","name":"description","type":"string"}],"internalType":"struct SophonFarmingState.PoolInfo[]","name":"poolInfos","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"heldProceeds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_boostAmount","type":"uint256"}],"name":"increaseBoost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"wstEthAllocPoint_","type":"uint256"},{"internalType":"uint256","name":"weEthAllocPoint_","type":"uint256"},{"internalType":"uint256","name":"sDAIAllocPoint_","type":"uint256"},{"internalType":"uint256","name":"_pointsPerBlock","type":"uint256"},{"internalType":"uint256","name":"_initialPoolStartBlock","type":"uint256"},{"internalType":"uint256","name":"_boosterMultiplier","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isBridged","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isFarmingEnded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isWithdrawPeriodEnded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pointsPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"poolExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"contract IERC20","name":"lpToken","type":"address"},{"internalType":"address","name":"l2Farm","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"boostAmount","type":"uint256"},{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardBlock","type":"uint256"},{"internalType":"uint256","name":"accPointsPerShare","type":"uint256"},{"internalType":"uint256","name":"totalRewards","type":"uint256"},{"internalType":"string","name":"description","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"impl_","type":"address"}],"name":"replaceImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"revertFailedBridge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sDAI","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"uint256","name":"_poolStartBlock","type":"uint256"},{"internalType":"uint256","name":"_newPointsPerBlock","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_boosterMultiplier","type":"uint256"}],"name":"setBoosterMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_bridge","type":"address"}],"name":"setBridge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_endBlock","type":"uint256"},{"internalType":"uint256","name":"_withdrawalBlocks","type":"uint256"}],"name":"setEndBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_l2Farm","type":"address"}],"name":"setL2FarmForPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pointsPerBlock","type":"uint256"}],"name":"setPointsPerBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_userAdmin","type":"address"},{"internalType":"address[]","name":"_users","type":"address[]"},{"internalType":"bool","name":"_isInWhitelist","type":"bool"}],"name":"setUsersWhitelisted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_sender","type":"address"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_transferAmount","type":"uint256"}],"name":"transferPoints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum SophonFarmingState.PredefinedPool","name":"","type":"uint8"}],"name":"typeToId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"boostAmount","type":"uint256"},{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"uint256","name":"rewardSettled","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAdmin","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"whitelist","outputs":[{"internalType":"bool","name":"inWhitelist","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_withdrawAmount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wstETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
610180604052348015610010575f80fd5b5060405161462938038061462983398101604081905261002f91610159565b338061005457604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b61005d816100bf565b5080516001600160a01b0390811660809081526020830151821660a09081526040840151831660c09081526060850151841660e090815292850151841661010052908401518316610120528301518216610140529091015116610160526101dc565b600180546001600160a01b03191690556100d8816100db565b50565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b634e487b7160e01b5f52604160045260245ffd5b80516001600160a01b0381168114610154575f80fd5b919050565b5f610100828403121561016a575f80fd5b82601f830112610178575f80fd5b60405161010081016001600160401b038111828210171561019b5761019b61012a565b604052806101008401858111156101b0575f80fd5b845b818110156101d1576101c38161013e565b8352602092830192016101b2565b509195945050505050565b60805160a05160c05160e0516101005161012051610140516101605161432e6102fb5f395f8181610afb015281816117270152818161179a015261376201525f818161085b015261305e01525f818161045a015281816114c3015281816117c901528181611f0601528181611f860152611fcf01525f81816106f10152818161161301528181611687015261371301525f8181610ac801528181611493015281816116b6015281816126ea0152818161276a015281816127b30152612f5101525f81816103b901528181610659015281816114630152818161284201526135b201525f8181610b610152818161151d0152818161157301526136ac01525f8181610c2101528181611420015281816115a2015261218c015261432e5ff3fe6080604052600436106103aa575f3560e01c80636e910bfd116101e9578063aff206d811610108578063e30c39781161009d578063f2fde38b1161006d578063f2fde38b14610bf1578063f4b9fa7514610c10578063fb8d81f114610c43578063fff52ee814610c62575f80fd5b8063e30c397814610b83578063e78cea9214610ba0578063e8760c1414610bbf578063eaac8c3214610bd2575f80fd5b8063c72bf7a5116100d8578063c72bf7a514610aea578063d69efdc514610b1d578063de26c3c614610b3c578063de8b614914610b50575f80fd5b8063aff206d814610a4f578063b092145e14610a69578063beece24b14610aa2578063c1fe3e4814610ab7575f80fd5b80638dd148021161017e5780639644369c1161014e5780639644369c146109d257806399d8f74a146109f1578063a8a77a1914610a1d578063af8f99bd14610a3c575f80fd5b80638dd14802146108eb578063933f39581461090a57806393f1a40b14610938578063958df164146109b3575f80fd5b806379ba5097116101b957806379ba50971461087d5780637a94c068146108915780638b3b7934146108bc5780638da5cb5b146108cf575f80fd5b80636e910bfd146108025780636f52daaf14610821578063715018a61461083657806372e26a6f1461084a575f80fd5b8063396f7b23116102d557806351bd78751161026a57806360246c881161023a57806360246c881461078f578063606ce3bf146107b0578063630b5ba1146107cf5780636b1033c4146107e3575f80fd5b806351bd78751461071357806351eb05a6146107325780635c60da1b146107515780635dfd7e9b14610770575f80fd5b806342cbb15c116102a557806342cbb15c14610690578063441a3e70146106a257806347c8b1a9146106c15780634aa07e64146106e0575f80fd5b8063396f7b231461060a5780633ee9375a146106295780633fc8cef3146106485780633fdb1e8f1461067b575f80fd5b806317caf6f11161034b5780632a4f6df21161031b5780632a4f6df2146105825780632c8e418a146105a15780632d7aa82b146105c057806330cdb3c6146105df575f80fd5b806317caf6f1146105015780631abbeb54146105165780631e1c6a071461053557806326076f9714610563575f80fd5b80630de371e2116103865780630de371e21461044957806312863f02146104945780631526fe27146104b857806315ba56e5146104ed575f80fd5b8062aeef8a146103f2578063081e3eda14610411578063083c632314610434575f80fd5b366103ee576001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633036103e157005b6103ec5f6001610c8e565b005b5f80fd5b3480156103fd575f80fd5b506103ec61040c36600461397e565b610d24565b34801561041c575f80fd5b506008545b6040519081526020015b60405180910390f35b34801561043f575f80fd5b50610421600b5481565b348015610454575f80fd5b5061047c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161042b565b34801561049f575f80fd5b506104a8610d69565b604051901515815260200161042b565b3480156104c3575f80fd5b506104d76104d23660046139a7565b610d91565b60405161042b9a99989796959493929190613a0b565b3480156104f8575f80fd5b506103ec610e8b565b34801561050c575f80fd5b50610421600a5481565b348015610521575f80fd5b506103ec610530366004613a77565b610f14565b348015610540575f80fd5b506104a861054f366004613aab565b600d6020525f908152604090205460ff1681565b34801561056e575f80fd5b506103ec61057d366004613ac6565b610f92565b34801561058d575f80fd5b506103ec61059c366004613b0b565b611227565b3480156105ac575f80fd5b506103ec6105bb3660046139a7565b6112f4565b3480156105cb575f80fd5b506103ec6105da366004613b39565b61136a565b3480156105ea575f80fd5b506104216105f9366004613b8b565b60046020525f908152604090205481565b348015610615575f80fd5b5060025461047c906001600160a01b031681565b348015610634575f80fd5b50610421610643366004613be9565b61183c565b348015610653575f80fd5b5061047c7f000000000000000000000000000000000000000000000000000000000000000081565b348015610686575f80fd5b5061042160075481565b34801561069b575f80fd5b5043610421565b3480156106ad575f80fd5b506103ec6106bc366004613a77565b611ad6565b3480156106cc575f80fd5b506103ec6106db366004613a77565b611ca8565b3480156106eb575f80fd5b5061047c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561071e575f80fd5b506103ec61072d366004613a77565b611eef565b34801561073d575f80fd5b506103ec61074c3660046139a7565b612057565b34801561075c575f80fd5b5060035461047c906001600160a01b031681565b34801561077b575f80fd5b506103ec61078a366004613a77565b61217f565b34801561079a575f80fd5b506107a36121c4565b60405161042b9190613ca9565b3480156107bb575f80fd5b506103ec6107ca366004613d93565b612402565b3480156107da575f80fd5b506103ec61254f565b3480156107ee575f80fd5b506103ec6107fd366004613e4e565b61256d565b34801561080d575f80fd5b5061042161081c366004613eae565b6125e7565b34801561082c575f80fd5b5061042160065481565b348015610841575f80fd5b506103ec612613565b348015610855575f80fd5b5061047c7f000000000000000000000000000000000000000000000000000000000000000081565b348015610888575f80fd5b506103ec612626565b34801561089c575f80fd5b506104216108ab3660046139a7565b60056020525f908152604090205481565b6103ec6108ca36600461397e565b61266a565b3480156108da575f80fd5b505f546001600160a01b031661047c565b3480156108f6575f80fd5b506103ec610905366004613aab565b612682565b348015610915575f80fd5b506104a86109243660046139a7565b60106020525f908152604090205460ff1681565b348015610943575f80fd5b5061098b610952366004613b0b565b600960209081525f9283526040808420909152908252902080546001820154600283015460038401546004909401549293919290919085565b604080519586526020860194909452928401919091526060830152608082015260a00161042b565b3480156109be575f80fd5b506103ec6109cd366004613a77565b6126d3565b3480156109dd575f80fd5b506103ec6109ec366004613ed8565b612835565b3480156109fc575f80fd5b50610a10610a0b366004613f0a565b6128cd565b60405161042b9190613f44565b348015610a28575f80fd5b50610421610a37366004613b0b565b612b7e565b6103ec610a4a36600461397e565b612b90565b348015610a5a575f80fd5b506103ec610a4a3660046139a7565b348015610a74575f80fd5b506104a8610a83366004613feb565b601160209081525f928352604080842090915290825290205460ff1681565b348015610aad575f80fd5b50610421600e5481565b348015610ac2575f80fd5b5061047c7f000000000000000000000000000000000000000000000000000000000000000081565b348015610af5575f80fd5b5061047c7f000000000000000000000000000000000000000000000000000000000000000081565b348015610b28575f80fd5b506103ec610b37366004613aab565b612b98565b348015610b47575f80fd5b506104a8612bf1565b348015610b5b575f80fd5b5061047c7f000000000000000000000000000000000000000000000000000000000000000081565b348015610b8e575f80fd5b506001546001600160a01b031661047c565b348015610bab575f80fd5b50600f5461047c906001600160a01b031681565b6103ec610bcd366004614017565b610c8e565b348015610bdd575f80fd5b506103ec610bec366004613aab565b612c07565b348015610bfc575f80fd5b506103ec610c0b366004613aab565b612ce8565b348015610c1b575f80fd5b5061047c7f000000000000000000000000000000000000000000000000000000000000000081565b348015610c4e575f80fd5b506103ec610c5d3660046139a7565b612d58565b348015610c6d575f80fd5b50610c81610c7c366004613f0a565b612e0b565b60405161042b9190614041565b345f03610cae5760405163717e6b7b60e01b815260040160405180910390fd5b346001826002811115610cc357610cc36140c1565b03610cd857610cd181612f46565b9050610d13565b6002826002811115610cec57610cec6140c1565b03610cfa57610cd181613053565b604051635972996f60e11b815260040160405180910390fd5b610d1f8134858561309b565b505050565b610d5e33308460088781548110610d3d57610d3d6140d5565b5f9182526020909120600a90910201546001600160a01b031692919061315d565b610d1f8383836131c4565b600e545f908015801590610d7d575080435b115b15610d8a57600191505090565b5f91505090565b60088181548110610da0575f80fd5b5f9182526020909120600a9091020180546001820154600283015460038401546004850154600586015460068701546007880154600889015460098a0180546001600160a01b039a8b169c50989099169996989597949693959294919390929091610e0a906140e9565b80601f0160208091040260200160405190810160405280929190818152602001828054610e36906140e9565b8015610e815780601f10610e5857610100808354040283529160200191610e81565b820191905f5260205f20905b815481529060010190602001808311610e6457829003601f168201915b505050505090508a565b6002546001600160a01b03163314610ebd5760405163118cdaa760e01b81523360048201526024015b60405180910390fd5b60035460405133916001600160a01b0316907feb7a7d62743daf8cf4055aea544d0a89e2011279ed4105567d010759e6fa4de2905f90a3600280546001600160a01b03199081169091556003805490911633179055565b610f1c613402565b610f24612bf1565b15610f425760405163442400af60e01b815260040160405180910390fd5b5f8215610f7b5782431115610f6a57604051633dea3a3b60e11b815260040160405180910390fd5b610f748284614135565b9050610f7e565b505f5b610f8661254f565b600b9290925550600e55565b335f9081526011602090815260408083206001600160a01b038716845290915290205460ff16610fd557604051638cd22d1960e01b815260040160405180910390fd5b816001600160a01b0316836001600160a01b03161480610ffd57506001600160a01b03821630145b80611006575080155b1561102457604051632f35253160e01b815260040160405180910390fd5b5f60088581548110611038576110386140d5565b5f9182526020909120600a9091020180549091506001600160a01b0316611072576040516302721e1f60e61b815260040160405180910390fd5b61107b85612057565b60078101545f8681526009602090815260408083206001600160a01b03898116855292528083209187168352822081548154600484015460038501549495939492939192670de0b6b3a76400006110d28987614148565b6110dc919061415f565b6110e69190614135565b6110f0919061417e565b90505f19880361110257809750611126565b808811156111265760405163061008d160e01b815260048101829052602401610eb4565b611130888261417e565b85600301819055508784600401548560030154670de0b6b3a764000089866111589190614148565b611162919061415f565b61116c9190614135565b611176919061417e565b6111809190614135565b6003850155670de0b6b3a76400006111988785614148565b6111a2919061415f565b6004860155670de0b6b3a76400006111ba8784614148565b6111c4919061415f565b84600401819055508a896001600160a01b03168b6001600160a01b03167f0e2d25f1d1094599e7ad7c5abf20c243dd116941d455eb79616135defbc6fb9b8b60405161121291815260200190565b60405180910390a45050505050505050505050565b61122f613402565b6001600160a01b0381166112565760405163d92e233d60e01b815260040160405180910390fd5b5f6001600160a01b031660088381548110611273576112736140d5565b5f9182526020909120600a90910201546001600160a01b0316036112aa576040516302721e1f60e61b815260040160405180910390fd5b80600883815481106112be576112be6140d5565b905f5260205f2090600a02016001015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055505050565b6112fc613402565b670de0b6b3a76400008110806113195750678ac7230489e8000081115b156113375760405163135257c760e21b815260040160405180910390fd5b61133f612bf1565b1561135d5760405163442400af60e01b815260040160405180910390fd5b61136561254f565b600655565b611372613402565b600c5460ff16156113955760405162dc149f60e41b815260040160405180910390fd5b670de0b6b3a76400008310806113b35750683635c9adc5dea0000083115b156113d1576040516376f18c4360e11b815260040160405180910390fd5b6007839055670de0b6b3a76400008110806113f35750678ac7230489e8000081115b156114115760405163135257c760e21b815260040160405180910390fd5b60068190556001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081165f908152600d60209081526040808320805460ff1990811660019081179092557f00000000000000000000000000000000000000000000000000000000000000008616855282852080548216831790557f00000000000000000000000000000000000000000000000000000000000000008616855282852080548216831790557f000000000000000000000000000000000000000000000000000000000000000090951684528184208054861682179055600c805490951617909355825180840190935260048352637344414960e01b908301526115459186917f00000000000000000000000000000000000000000000000000000000000000009190869061183c565b60045f808152602081019190915260409081015f20919091555163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f1960248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156115e8573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061160c9190614191565b50611658867f0000000000000000000000000000000000000000000000000000000000000000604051806040016040528060068152602001650eee6e88aa8960d31b815250855f61183c565b60045f60018152602081019190915260409081015f20919091555163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f1960248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156116fc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117209190614191565b5061176b857f0000000000000000000000000000000000000000000000000000000000000000604051806040016040528060058152602001640eeca8aa8960db1b815250855f61183c565b60045f60028152602081019190915260409081015f20919091555163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f1960248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af115801561180f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118339190614191565b50505050505050565b5f611845613402565b6001600160a01b03851661186c5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0385165f908152600d602052604090205460ff16156118a557604051637a471e1360e11b815260040160405180910390fd5b6118ad612bf1565b156118cb5760405163442400af60e01b815260040160405180910390fd5b81156118df576118da82612d58565b6118e7565b6118e761254f565b5f8343116118f557836118f7565b435b905086600a546119079190614135565b600a819055506001600d5f886001600160a01b03166001600160a01b031681526020019081526020015f205f6101000a81548160ff0219169083151502179055505f60088054905090506008604051806101400160405280896001600160a01b031681526020015f6001600160a01b031681526020015f81526020015f81526020015f81526020018a81526020018481526020015f81526020015f815260200188815250908060018154018082558091505060019003905f5260205f2090600a02015f909190919091505f820151815f015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701556101008201518160080155610120820151816009019081611a8491906141f0565b50505080876001600160a01b03167fc264f49177bdbe55a01fae0e77c3fdc75d515d242b32bc4d56c565f5b47865ba8a604051611ac391815260200190565b60405180910390a3979650505050505050565b611ade610d69565b15611afc576040516315e34e0560e01b815260040160405180910390fd5b805f03611b1c5760405163214671ad60e01b815260040160405180910390fd5b5f60088381548110611b3057611b306140d5565b5f91825260208083208684526009825260408085203386529092529220600a9091029091019150611b6084612057565b600281015460018401611b7557809350611b99565b80841115611b9957604051632f14e52760e21b815260048101829052602401610eb4565b8154600483015460038401546007860154670de0b6b3a764000090611bbe9085614148565b611bc8919061415f565b611bd29190614135565b611bdc919061417e565b6003840155611beb858361417e565b60028401556004840154611c0090869061417e565b6004850155611c0f858261417e565b8084556002850154909150611c2590869061417e565b60028501556007840154670de0b6b3a764000090611c439083614148565b611c4d919061415f565b60048401558354611c68906001600160a01b0316338761342e565b604051858152869033907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568906020015b60405180910390a3505050505050565b611cb0612bf1565b15611cce5760405163442400af60e01b815260040160405180910390fd5b805f03611cee57604051633ff7215360e01b815260040160405180910390fd5b5f611cf933846125e7565b905080821115611d1f576040516301bdd0f160e21b815260048101829052602401610eb4565b5f60088481548110611d3357611d336140d5565b5f91825260208083208784526009825260408085203386529092529220600a9091029091019150611d6385612057565b8054600482015460038301546007850154670de0b6b3a764000090611d889085614148565b611d92919061415f565b611d9c9190614135565b611da6919061417e565b60038301555f86815260056020526040902054611dc4908690614135565b5f878152600560205260409020556002820154611de290869061417e565b60028301556004830154611df790869061417e565b60048401556006545f90670de0b6b3a764000090611e159088614148565b611e1f919061415f565b9050808360010154611e319190614135565b60018401556003840154611e46908290614135565b600385015585611e568284614135565b611e60919061417e565b80845560028501549092508690611e78908390614135565b611e82919061417e565b60028501556007840154670de0b6b3a764000090611ea09084614148565b611eaa919061415f565b6004840155604051818152879033907fc0314854fdea1f413e5498dd58aa7953bae1e4e5d587ea2f4e3dacceaa244dea9060200160405180910390a350505050505050565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611f53573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f7791906142ab565b9050611fae6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308661315d565b6040516370a0823160e01b81523060048201525f9082906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612014573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061203891906142ab565b612042919061417e565b9050612051818585600261309b565b50505050565b5f6008828154811061206b5761206b6140d5565b905f5260205f2090600a0201905080600601546120854390565b1161208e575050565b600281015460075460058301548215806120a6575081155b806120af575080155b156120c4574384600601819055505050505050565b5f6120d985600601546120d44390565b61345f565b90505f600a548385846120ec9190614148565b6120f69190614148565b612100919061415f565b9050612114670de0b6b3a76400008261415f565b86600801546121239190614135565b60088701556007860154612137868361415f565b6121419190614135565b600787015543600687015560405187907f141d729c29cc848b27c53f7dbe9f9542cedc4ed2efa7bd2aeb2a4bdce06a407f905f90a250505050505050565b6121b46001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308561315d565b6121c08283835f61309b565b5050565b6008546060908067ffffffffffffffff8111156121e3576121e3613ba4565b60405190808252806020026020018201604052801561227357816020015b6122606040518061014001604052805f6001600160a01b031681526020015f6001600160a01b031681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b8152602001906001900390816122015790505b5091505f5b818110156123fd5760088181548110612293576122936140d5565b5f9182526020918290206040805161014081018252600a90930290910180546001600160a01b039081168452600182015416938301939093526002830154908201526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e082015260088201546101008201526009820180549192916101208401919061232b906140e9565b80601f0160208091040260200160405190810160405280929190818152602001828054612357906140e9565b80156123a25780601f10612379576101008083540402835291602001916123a2565b820191905f5260205f20905b81548152906001019060200180831161238557829003601f168201915b5050505050815250508382815181106123bd576123bd6140d5565b60200260200101819052506123d1816134ac565b90508382815181106123e5576123e56140d5565b60209081029190910101516101000152600101612278565b505090565b61240a613402565b612412612bf1565b156124305760405163442400af60e01b815260040160405180910390fd5b80156124445761243f81612d58565b61244c565b61244c61254f565b5f60088581548110612460576124606140d5565b5f9182526020909120600a9091020180549091506001600160a01b03168015806124a257506001600160a01b0381165f908152600d602052604090205460ff16155b156124c0576040516302721e1f60e61b815260040160405180910390fd5b848260050154600a546124d3919061417e565b6124dd9190614135565b600a556005820185905583158015906124f95750600682015443105b156125135783431161250b578361250d565b435b60068301555b85816001600160a01b03167f9eca8f7bcfb868d72b4ed95b71c627c194ab6bcb9b83adb2280e8a0320bb847687604051611c9891815260200190565b6008545f5b818110156121c05761256581612057565b600101612554565b612575613402565b5f5b8251811015612051576001600160a01b0384165f90815260116020526040812084518492908690859081106125ae576125ae6140d5565b6020908102919091018101516001600160a01b031682528101919091526040015f20805460ff1916911515919091179055600101612577565b5f8181526009602090815260408083206001600160a01b03861684529091529020600201545b92915050565b61261b613402565b6126245f613581565b565b60015433906001600160a01b0316811461265e5760405163118cdaa760e01b81526001600160a01b0382166004820152602401610eb4565b61266781613581565b50565b6040516282b42960e81b815260040160405180910390fd5b61268a613402565b6001600160a01b0381166126b15760405163d92e233d60e01b815260040160405180910390fd5b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612737573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061275b91906142ab565b90506127926001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308661315d565b6040516370a0823160e01b81523060048201525f9082906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156127f8573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061281c91906142ab565b612826919061417e565b9050612051818585600161309b565b61286a6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308661315d565b5f6128748461359a565b9050600182600281111561288a5761288a6140c1565b0361289f5761289881612f46565b90506128c1565b60028260028111156128b3576128b36140c1565b03610cfa5761289881613053565b6120518185858561309b565b80516060908067ffffffffffffffff8111156128eb576128eb613ba4565b60405190808252806020026020018201604052801561291e57816020015b60608152602001906001900390816129095790505b506008549092505f5b82811015612b76575f858281518110612942576129426140d5565b602002602001015190508267ffffffffffffffff81111561296557612965613ba4565b60405190808252806020026020018201604052801561299e57816020015b61298b613960565b8152602001906001900390816129835790505b508583815181106129b1576129b16140d5565b60200260200101819052505f5b83811015612b6c575f8181526009602090815260408083206001600160a01b0386168452825291829020825160a0810184528154808252600183015493820193909352600282015493810193909352600381015460608401526004015460808301528751889086908110612a3457612a346140d5565b60200260200101518381518110612a4d57612a4d6140d5565b60200260200101515f60048110612a6657612a666140d5565b6020020181815250508060200151878581518110612a8657612a866140d5565b60200260200101518381518110612a9f57612a9f6140d5565b6020026020010151600160048110612ab957612ab96140d5565b602002015260408101518751889086908110612ad757612ad76140d5565b60200260200101518381518110612af057612af06140d5565b6020026020010151600260048110612b0a57612b0a6140d5565b6020020152612b198284613617565b878581518110612b2b57612b2b6140d5565b60200260200101518381518110612b4457612b446140d5565b6020026020010151600360048110612b5e57612b5e6140d5565b6020020152506001016129be565b5050600101612927565b505050919050565b5f612b898383613617565b9392505050565b61266a613402565b612ba0613402565b600280546001600160a01b0319166001600160a01b03838116918217909255600354604051919216907f67f679e13fe9dca16f3079221965ec41838cb8881cbc0f440bc13507c6b214c2905f90a350565b600b545f908015801590610d7d57508043610d7b565b806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c43573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c6791906142c2565b6001600160a01b0316336001600160a01b031614612c97576040516282b42960e81b815260040160405180910390fd5b806001600160a01b03166315ba56e56040518163ffffffff1660e01b81526004015f604051808303815f87803b158015612ccf575f80fd5b505af1158015612ce1573d5f803e3d5ffd5b5050505050565b612cf0613402565b600180546001600160a01b0383166001600160a01b03199091168117909155612d205f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b612d60613402565b612d68612bf1565b15612d865760405163442400af60e01b815260040160405180910390fd5b670de0b6b3a7640000811080612da45750683635c9adc5dea0000081115b15612dc2576040516376f18c4360e11b815260040160405180910390fd5b612dca61254f565b60075460408051918252602082018390527fb48e36a0869514773506a41441177faf21ebdda362731b7363ee174f3a007728910160405180910390a1600755565b80516060908067ffffffffffffffff811115612e2957612e29613ba4565b604051908082528060200260200182016040528015612e5c57816020015b6060815260200190600190039081612e475790505b506008549092505f5b82811015612b76575f858281518110612e8057612e806140d5565b602002602001015190508267ffffffffffffffff811115612ea357612ea3613ba4565b604051908082528060200260200182016040528015612ecc578160200160208202803683370190505b50858381518110612edf57612edf6140d5565b60200260200101819052505f5b83811015612f3c57612efe8183613617565b868481518110612f1057612f106140d5565b60200260200101518281518110612f2957612f296140d5565b6020908102919091010152600101612eec565b5050600101612e65565b5f6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016637a28fb888163a1903eab85612f8e5f546001600160a01b031690565b6040516001600160e01b031960e085901b1681526001600160a01b03909116600482015260240160206040518083038185885af1158015612fd1573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190612ff691906142ab565b6040518263ffffffff1660e01b815260040161301491815260200190565b602060405180830381865afa15801561302f573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061260d91906142ab565b5f6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663561bddf88163f340fa0185612f8e5f546001600160a01b031690565b5f808260028111156130af576130af6140c1565b036130c4576130bd8561368e565b9050613108565b60018260028111156130d8576130d86140c1565b036130e6576130bd856136fb565b60028260028111156130fa576130fa6140c1565b03610cfa576130bd8561374a565b836131138285614148565b61311d919061415f565b9250612ce160045f846002811115613137576131376140c1565b6002811115613148576131486140c1565b81526020019081526020015f205482856131c4565b6040516001600160a01b0384811660248301528381166044830152606482018390526120519186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050613799565b6131cc612bf1565b156131ea5760405163442400af60e01b815260040160405180910390fd5b815f0361320a57604051635972996f60e11b815260040160405180910390fd5b8181111561322e576040516301bdd0f160e21b815260048101839052602401610eb4565b5f60088481548110613242576132426140d5565b5f91825260208083208784526009825260408085203386529092529220600a909102909101915061327285612057565b8054600482015460038301546007850154670de0b6b3a7640000906132979085614148565b6132a1919061415f565b6132ab9190614135565b6132b5919061417e565b60038301555f868152600560205260409020546132d3908590614135565b5f878152600560205260409020556132eb848661417e565b94508482600201546132fd9190614135565b60028301556004830154613312908690614135565b6004840155600654670de0b6b3a76400009061332e9086614148565b613338919061415f565b935083826001015461334a9190614135565b6001830155600383015461335f908590614135565b60038401558361336f8683614135565b6133799190614135565b80835560028401549091508490613391908790614135565b61339b9190614135565b60028401556007830154670de0b6b3a7640000906133b99083614148565b6133c3919061415f565b60048301556040805186815260208101869052879133917f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e9101611c98565b5f546001600160a01b031633146126245760405163118cdaa760e01b8152336004820152602401610eb4565b6040516001600160a01b03838116602483015260448201839052610d1f91859182169063a9059cbb90606401613192565b600b545f9080156134775761347483826137fa565b92505b838311156134a357613489848461417e565b61349b90670de0b6b3a7640000614148565b91505061260d565b5f91505061260d565b5f805f600884815481106134c2576134c26140d5565b905f5260205f2090600a0201905080600701549250806008015491505f8160020154905081600601546134f24390565b1180156134fe57508015155b1561357a575f61351383600601546120d44390565b90505f600a5484600501546007548461352c9190614148565b6135369190614148565b613540919061415f565b9050613554670de0b6b3a76400008261415f565b61355e9086614135565b94508561356b848361415f565b6135759190614135565b955050505b5050915091565b600180546001600160a01b03191690556126678161380f565b604051632e1a7d4d60e01b8152600481018290525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d906024015f604051808303815f87803b1580156135fb575f80fd5b505af115801561360d573d5f803e3d5ffd5b5093949350505050565b5f8281526009602090815260408083206001600160a01b0385168452909152812081613642856134ac565b50905081600401548260030154670de0b6b3a764000083855f01546136679190614148565b613671919061415f565b61367b9190614135565b613685919061417e565b95945050505050565b604051636e553f6560e01b8152600481018290523060248201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636e553f65906044015b6020604051808303815f875af115801561302f573d5f803e3d5ffd5b604051630ea598cb60e41b8152600481018290525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ea598cb0906024016136df565b604051630ea598cb60e41b8152600481018290525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ea598cb0906024016136df565b5f6137ad6001600160a01b0384168361385e565b905080515f141580156137d15750808060200190518101906137cf9190614191565b155b15610d1f57604051635274afe760e01b81526001600160a01b0384166004820152602401610eb4565b5f8183106138085781612b89565b5090919050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060612b8983835f845f80856001600160a01b0316848660405161388291906142dd565b5f6040518083038185875af1925050503d805f81146138bc576040519150601f19603f3d011682016040523d82523d5f602084013e6138c1565b606091505b50915091506138d18683836138db565b9695505050505050565b6060826138f0576138eb82613937565b612b89565b815115801561390757506001600160a01b0384163b155b1561393057604051639996b31560e01b81526001600160a01b0385166004820152602401610eb4565b5080612b89565b8051156139475780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b60405180608001604052806004906020820280368337509192915050565b5f805f60608486031215613990575f80fd5b505081359360208301359350604090920135919050565b5f602082840312156139b7575f80fd5b5035919050565b5f5b838110156139d85781810151838201526020016139c0565b50505f910152565b5f81518084526139f78160208601602086016139be565b601f01601f19169290920160200192915050565b60018060a01b038b16815260018060a01b038a1660208201528860408201528760608201528660808201528560a08201528460c08201528360e0820152826101008201526101406101208201525f613a676101408301846139e0565b9c9b505050505050505050505050565b5f8060408385031215613a88575f80fd5b50508035926020909101359150565b6001600160a01b0381168114612667575f80fd5b5f60208284031215613abb575f80fd5b8135612b8981613a97565b5f805f8060808587031215613ad9575f80fd5b843593506020850135613aeb81613a97565b92506040850135613afb81613a97565b9396929550929360600135925050565b5f8060408385031215613b1c575f80fd5b823591506020830135613b2e81613a97565b809150509250929050565b5f805f805f8060c08789031215613b4e575f80fd5b505084359660208601359650604086013595606081013595506080810135945060a0013592509050565b803560038110613b86575f80fd5b919050565b5f60208284031215613b9b575f80fd5b612b8982613b78565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613be157613be1613ba4565b604052919050565b5f805f805f60a08688031215613bfd575f80fd5b853594506020860135613c0f81613a97565b9350604086013567ffffffffffffffff811115613c2a575f80fd5b8601601f81018813613c3a575f80fd5b803567ffffffffffffffff811115613c5457613c54613ba4565b613c67601f8201601f1916602001613bb8565b818152896020838501011115613c7b575f80fd5b816020840160208301375f918101602001919091529598949750949560608101359550608001359392505050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b82811015613d8757868503603f19018452815180516001600160a01b031686526020810151613d0960208801826001600160a01b03169052565b5060408101516040870152606081015160608701526080810151608087015260a081015160a087015260c081015160c087015260e081015160e08701526101008101516101008701526101208101519050610140610120870152613d716101408701826139e0565b9550506020938401939190910190600101613ccf565b50929695505050505050565b5f805f8060808587031215613da6575f80fd5b5050823594602084013594506040840135936060013592509050565b5f82601f830112613dd1575f80fd5b813567ffffffffffffffff811115613deb57613deb613ba4565b8060051b613dfb60208201613bb8565b91825260208185018101929081019086841115613e16575f80fd5b6020860192505b838310156138d1578235613e3081613a97565b825260209283019290910190613e1d565b8015158114612667575f80fd5b5f805f60608486031215613e60575f80fd5b8335613e6b81613a97565b9250602084013567ffffffffffffffff811115613e86575f80fd5b613e9286828701613dc2565b9250506040840135613ea381613e41565b809150509250925092565b5f8060408385031215613ebf575f80fd5b8235613eca81613a97565b946020939093013593505050565b5f805f60608486031215613eea575f80fd5b8335925060208401359150613f0160408501613b78565b90509250925092565b5f60208284031215613f1a575f80fd5b813567ffffffffffffffff811115613f30575f80fd5b613f3c84828501613dc2565b949350505050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b82811015613d8757868503603f19018452815180518087526020918201918701905f5b81811015613fd2578351835f5b6004811015613fb9578251825260209283019290910190600101613f9a565b5050506020939093019260809290920191600101613f8d565b5090965050506020938401939190910190600101613f6a565b5f8060408385031215613ffc575f80fd5b823561400781613a97565b91506020830135613b2e81613a97565b5f8060408385031215614028575f80fd5b8235915061403860208401613b78565b90509250929050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b82811015613d8757868503603f19018452815180518087526020918201918701905f5b818110156140a857835183526020938401939092019160010161408a565b5090965050506020938401939190910190600101614067565b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b600181811c908216806140fd57607f821691505b60208210810361411b57634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561260d5761260d614121565b808202811582820484141761260d5761260d614121565b5f8261417957634e487b7160e01b5f52601260045260245ffd5b500490565b8181038181111561260d5761260d614121565b5f602082840312156141a1575f80fd5b8151612b8981613e41565b601f821115610d1f57805f5260205f20601f840160051c810160208510156141d15750805b601f840160051c820191505b81811015612ce1575f81556001016141dd565b815167ffffffffffffffff81111561420a5761420a613ba4565b61421e8161421884546140e9565b846141ac565b6020601f821160018114614250575f83156142395750848201515b5f19600385901b1c1916600184901b178455612ce1565b5f84815260208120601f198516915b8281101561427f578785015182556020948501946001909201910161425f565b508482101561429c57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f602082840312156142bb575f80fd5b5051919050565b5f602082840312156142d2575f80fd5b8151612b8981613a97565b5f82516142ee8184602087016139be565b919091019291505056fea26469706673582212202a9096c7b91493f04491379bf7799f31bb09e5510bcf8f08f751a226d98ac78964736f6c634300081a00330000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000083f20f44975d03b1b09e64809b757c47f942beea000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe840000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca000000000000000000000000035fa164735182de50811e8e2e824cfb9b6118ac2000000000000000000000000308861a430be4cce5502d0a12724771fc6daf216000000000000000000000000cd5fe23c85820f7b72d0926fc9b05b43e359b7ee
Deployed Bytecode
0x6080604052600436106103aa575f3560e01c80636e910bfd116101e9578063aff206d811610108578063e30c39781161009d578063f2fde38b1161006d578063f2fde38b14610bf1578063f4b9fa7514610c10578063fb8d81f114610c43578063fff52ee814610c62575f80fd5b8063e30c397814610b83578063e78cea9214610ba0578063e8760c1414610bbf578063eaac8c3214610bd2575f80fd5b8063c72bf7a5116100d8578063c72bf7a514610aea578063d69efdc514610b1d578063de26c3c614610b3c578063de8b614914610b50575f80fd5b8063aff206d814610a4f578063b092145e14610a69578063beece24b14610aa2578063c1fe3e4814610ab7575f80fd5b80638dd148021161017e5780639644369c1161014e5780639644369c146109d257806399d8f74a146109f1578063a8a77a1914610a1d578063af8f99bd14610a3c575f80fd5b80638dd14802146108eb578063933f39581461090a57806393f1a40b14610938578063958df164146109b3575f80fd5b806379ba5097116101b957806379ba50971461087d5780637a94c068146108915780638b3b7934146108bc5780638da5cb5b146108cf575f80fd5b80636e910bfd146108025780636f52daaf14610821578063715018a61461083657806372e26a6f1461084a575f80fd5b8063396f7b23116102d557806351bd78751161026a57806360246c881161023a57806360246c881461078f578063606ce3bf146107b0578063630b5ba1146107cf5780636b1033c4146107e3575f80fd5b806351bd78751461071357806351eb05a6146107325780635c60da1b146107515780635dfd7e9b14610770575f80fd5b806342cbb15c116102a557806342cbb15c14610690578063441a3e70146106a257806347c8b1a9146106c15780634aa07e64146106e0575f80fd5b8063396f7b231461060a5780633ee9375a146106295780633fc8cef3146106485780633fdb1e8f1461067b575f80fd5b806317caf6f11161034b5780632a4f6df21161031b5780632a4f6df2146105825780632c8e418a146105a15780632d7aa82b146105c057806330cdb3c6146105df575f80fd5b806317caf6f1146105015780631abbeb54146105165780631e1c6a071461053557806326076f9714610563575f80fd5b80630de371e2116103865780630de371e21461044957806312863f02146104945780631526fe27146104b857806315ba56e5146104ed575f80fd5b8062aeef8a146103f2578063081e3eda14610411578063083c632314610434575f80fd5b366103ee576001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21633036103e157005b6103ec5f6001610c8e565b005b5f80fd5b3480156103fd575f80fd5b506103ec61040c36600461397e565b610d24565b34801561041c575f80fd5b506008545b6040519081526020015b60405180910390f35b34801561043f575f80fd5b50610421600b5481565b348015610454575f80fd5b5061047c7f00000000000000000000000035fa164735182de50811e8e2e824cfb9b6118ac281565b6040516001600160a01b03909116815260200161042b565b34801561049f575f80fd5b506104a8610d69565b604051901515815260200161042b565b3480156104c3575f80fd5b506104d76104d23660046139a7565b610d91565b60405161042b9a99989796959493929190613a0b565b3480156104f8575f80fd5b506103ec610e8b565b34801561050c575f80fd5b50610421600a5481565b348015610521575f80fd5b506103ec610530366004613a77565b610f14565b348015610540575f80fd5b506104a861054f366004613aab565b600d6020525f908152604090205460ff1681565b34801561056e575f80fd5b506103ec61057d366004613ac6565b610f92565b34801561058d575f80fd5b506103ec61059c366004613b0b565b611227565b3480156105ac575f80fd5b506103ec6105bb3660046139a7565b6112f4565b3480156105cb575f80fd5b506103ec6105da366004613b39565b61136a565b3480156105ea575f80fd5b506104216105f9366004613b8b565b60046020525f908152604090205481565b348015610615575f80fd5b5060025461047c906001600160a01b031681565b348015610634575f80fd5b50610421610643366004613be9565b61183c565b348015610653575f80fd5b5061047c7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b348015610686575f80fd5b5061042160075481565b34801561069b575f80fd5b5043610421565b3480156106ad575f80fd5b506103ec6106bc366004613a77565b611ad6565b3480156106cc575f80fd5b506103ec6106db366004613a77565b611ca8565b3480156106eb575f80fd5b5061047c7f0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca081565b34801561071e575f80fd5b506103ec61072d366004613a77565b611eef565b34801561073d575f80fd5b506103ec61074c3660046139a7565b612057565b34801561075c575f80fd5b5060035461047c906001600160a01b031681565b34801561077b575f80fd5b506103ec61078a366004613a77565b61217f565b34801561079a575f80fd5b506107a36121c4565b60405161042b9190613ca9565b3480156107bb575f80fd5b506103ec6107ca366004613d93565b612402565b3480156107da575f80fd5b506103ec61254f565b3480156107ee575f80fd5b506103ec6107fd366004613e4e565b61256d565b34801561080d575f80fd5b5061042161081c366004613eae565b6125e7565b34801561082c575f80fd5b5061042160065481565b348015610841575f80fd5b506103ec612613565b348015610855575f80fd5b5061047c7f000000000000000000000000308861a430be4cce5502d0a12724771fc6daf21681565b348015610888575f80fd5b506103ec612626565b34801561089c575f80fd5b506104216108ab3660046139a7565b60056020525f908152604090205481565b6103ec6108ca36600461397e565b61266a565b3480156108da575f80fd5b505f546001600160a01b031661047c565b3480156108f6575f80fd5b506103ec610905366004613aab565b612682565b348015610915575f80fd5b506104a86109243660046139a7565b60106020525f908152604090205460ff1681565b348015610943575f80fd5b5061098b610952366004613b0b565b600960209081525f9283526040808420909152908252902080546001820154600283015460038401546004909401549293919290919085565b604080519586526020860194909452928401919091526060830152608082015260a00161042b565b3480156109be575f80fd5b506103ec6109cd366004613a77565b6126d3565b3480156109dd575f80fd5b506103ec6109ec366004613ed8565b612835565b3480156109fc575f80fd5b50610a10610a0b366004613f0a565b6128cd565b60405161042b9190613f44565b348015610a28575f80fd5b50610421610a37366004613b0b565b612b7e565b6103ec610a4a36600461397e565b612b90565b348015610a5a575f80fd5b506103ec610a4a3660046139a7565b348015610a74575f80fd5b506104a8610a83366004613feb565b601160209081525f928352604080842090915290825290205460ff1681565b348015610aad575f80fd5b50610421600e5481565b348015610ac2575f80fd5b5061047c7f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe8481565b348015610af5575f80fd5b5061047c7f000000000000000000000000cd5fe23c85820f7b72d0926fc9b05b43e359b7ee81565b348015610b28575f80fd5b506103ec610b37366004613aab565b612b98565b348015610b47575f80fd5b506104a8612bf1565b348015610b5b575f80fd5b5061047c7f00000000000000000000000083f20f44975d03b1b09e64809b757c47f942beea81565b348015610b8e575f80fd5b506001546001600160a01b031661047c565b348015610bab575f80fd5b50600f5461047c906001600160a01b031681565b6103ec610bcd366004614017565b610c8e565b348015610bdd575f80fd5b506103ec610bec366004613aab565b612c07565b348015610bfc575f80fd5b506103ec610c0b366004613aab565b612ce8565b348015610c1b575f80fd5b5061047c7f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f81565b348015610c4e575f80fd5b506103ec610c5d3660046139a7565b612d58565b348015610c6d575f80fd5b50610c81610c7c366004613f0a565b612e0b565b60405161042b9190614041565b345f03610cae5760405163717e6b7b60e01b815260040160405180910390fd5b346001826002811115610cc357610cc36140c1565b03610cd857610cd181612f46565b9050610d13565b6002826002811115610cec57610cec6140c1565b03610cfa57610cd181613053565b604051635972996f60e11b815260040160405180910390fd5b610d1f8134858561309b565b505050565b610d5e33308460088781548110610d3d57610d3d6140d5565b5f9182526020909120600a90910201546001600160a01b031692919061315d565b610d1f8383836131c4565b600e545f908015801590610d7d575080435b115b15610d8a57600191505090565b5f91505090565b60088181548110610da0575f80fd5b5f9182526020909120600a9091020180546001820154600283015460038401546004850154600586015460068701546007880154600889015460098a0180546001600160a01b039a8b169c50989099169996989597949693959294919390929091610e0a906140e9565b80601f0160208091040260200160405190810160405280929190818152602001828054610e36906140e9565b8015610e815780601f10610e5857610100808354040283529160200191610e81565b820191905f5260205f20905b815481529060010190602001808311610e6457829003601f168201915b505050505090508a565b6002546001600160a01b03163314610ebd5760405163118cdaa760e01b81523360048201526024015b60405180910390fd5b60035460405133916001600160a01b0316907feb7a7d62743daf8cf4055aea544d0a89e2011279ed4105567d010759e6fa4de2905f90a3600280546001600160a01b03199081169091556003805490911633179055565b610f1c613402565b610f24612bf1565b15610f425760405163442400af60e01b815260040160405180910390fd5b5f8215610f7b5782431115610f6a57604051633dea3a3b60e11b815260040160405180910390fd5b610f748284614135565b9050610f7e565b505f5b610f8661254f565b600b9290925550600e55565b335f9081526011602090815260408083206001600160a01b038716845290915290205460ff16610fd557604051638cd22d1960e01b815260040160405180910390fd5b816001600160a01b0316836001600160a01b03161480610ffd57506001600160a01b03821630145b80611006575080155b1561102457604051632f35253160e01b815260040160405180910390fd5b5f60088581548110611038576110386140d5565b5f9182526020909120600a9091020180549091506001600160a01b0316611072576040516302721e1f60e61b815260040160405180910390fd5b61107b85612057565b60078101545f8681526009602090815260408083206001600160a01b03898116855292528083209187168352822081548154600484015460038501549495939492939192670de0b6b3a76400006110d28987614148565b6110dc919061415f565b6110e69190614135565b6110f0919061417e565b90505f19880361110257809750611126565b808811156111265760405163061008d160e01b815260048101829052602401610eb4565b611130888261417e565b85600301819055508784600401548560030154670de0b6b3a764000089866111589190614148565b611162919061415f565b61116c9190614135565b611176919061417e565b6111809190614135565b6003850155670de0b6b3a76400006111988785614148565b6111a2919061415f565b6004860155670de0b6b3a76400006111ba8784614148565b6111c4919061415f565b84600401819055508a896001600160a01b03168b6001600160a01b03167f0e2d25f1d1094599e7ad7c5abf20c243dd116941d455eb79616135defbc6fb9b8b60405161121291815260200190565b60405180910390a45050505050505050505050565b61122f613402565b6001600160a01b0381166112565760405163d92e233d60e01b815260040160405180910390fd5b5f6001600160a01b031660088381548110611273576112736140d5565b5f9182526020909120600a90910201546001600160a01b0316036112aa576040516302721e1f60e61b815260040160405180910390fd5b80600883815481106112be576112be6140d5565b905f5260205f2090600a02016001015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055505050565b6112fc613402565b670de0b6b3a76400008110806113195750678ac7230489e8000081115b156113375760405163135257c760e21b815260040160405180910390fd5b61133f612bf1565b1561135d5760405163442400af60e01b815260040160405180910390fd5b61136561254f565b600655565b611372613402565b600c5460ff16156113955760405162dc149f60e41b815260040160405180910390fd5b670de0b6b3a76400008310806113b35750683635c9adc5dea0000083115b156113d1576040516376f18c4360e11b815260040160405180910390fd5b6007839055670de0b6b3a76400008110806113f35750678ac7230489e8000081115b156114115760405163135257c760e21b815260040160405180910390fd5b60068190556001600160a01b037f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f81165f908152600d60209081526040808320805460ff1990811660019081179092557f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28616855282852080548216831790557f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe848616855282852080548216831790557f00000000000000000000000035fa164735182de50811e8e2e824cfb9b6118ac290951684528184208054861682179055600c805490951617909355825180840190935260048352637344414960e01b908301526115459186917f00000000000000000000000083f20f44975d03b1b09e64809b757c47f942beea9190869061183c565b60045f808152602081019190915260409081015f20919091555163095ea7b360e01b81526001600160a01b037f00000000000000000000000083f20f44975d03b1b09e64809b757c47f942beea811660048301525f1960248301527f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f169063095ea7b3906044016020604051808303815f875af11580156115e8573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061160c9190614191565b50611658867f0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0604051806040016040528060068152602001650eee6e88aa8960d31b815250855f61183c565b60045f60018152602081019190915260409081015f20919091555163095ea7b360e01b81526001600160a01b037f0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0811660048301525f1960248301527f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84169063095ea7b3906044016020604051808303815f875af11580156116fc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117209190614191565b5061176b857f000000000000000000000000cd5fe23c85820f7b72d0926fc9b05b43e359b7ee604051806040016040528060058152602001640eeca8aa8960db1b815250855f61183c565b60045f60028152602081019190915260409081015f20919091555163095ea7b360e01b81526001600160a01b037f000000000000000000000000cd5fe23c85820f7b72d0926fc9b05b43e359b7ee811660048301525f1960248301527f00000000000000000000000035fa164735182de50811e8e2e824cfb9b6118ac2169063095ea7b3906044016020604051808303815f875af115801561180f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118339190614191565b50505050505050565b5f611845613402565b6001600160a01b03851661186c5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0385165f908152600d602052604090205460ff16156118a557604051637a471e1360e11b815260040160405180910390fd5b6118ad612bf1565b156118cb5760405163442400af60e01b815260040160405180910390fd5b81156118df576118da82612d58565b6118e7565b6118e761254f565b5f8343116118f557836118f7565b435b905086600a546119079190614135565b600a819055506001600d5f886001600160a01b03166001600160a01b031681526020019081526020015f205f6101000a81548160ff0219169083151502179055505f60088054905090506008604051806101400160405280896001600160a01b031681526020015f6001600160a01b031681526020015f81526020015f81526020015f81526020018a81526020018481526020015f81526020015f815260200188815250908060018154018082558091505060019003905f5260205f2090600a02015f909190919091505f820151815f015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701556101008201518160080155610120820151816009019081611a8491906141f0565b50505080876001600160a01b03167fc264f49177bdbe55a01fae0e77c3fdc75d515d242b32bc4d56c565f5b47865ba8a604051611ac391815260200190565b60405180910390a3979650505050505050565b611ade610d69565b15611afc576040516315e34e0560e01b815260040160405180910390fd5b805f03611b1c5760405163214671ad60e01b815260040160405180910390fd5b5f60088381548110611b3057611b306140d5565b5f91825260208083208684526009825260408085203386529092529220600a9091029091019150611b6084612057565b600281015460018401611b7557809350611b99565b80841115611b9957604051632f14e52760e21b815260048101829052602401610eb4565b8154600483015460038401546007860154670de0b6b3a764000090611bbe9085614148565b611bc8919061415f565b611bd29190614135565b611bdc919061417e565b6003840155611beb858361417e565b60028401556004840154611c0090869061417e565b6004850155611c0f858261417e565b8084556002850154909150611c2590869061417e565b60028501556007840154670de0b6b3a764000090611c439083614148565b611c4d919061415f565b60048401558354611c68906001600160a01b0316338761342e565b604051858152869033907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568906020015b60405180910390a3505050505050565b611cb0612bf1565b15611cce5760405163442400af60e01b815260040160405180910390fd5b805f03611cee57604051633ff7215360e01b815260040160405180910390fd5b5f611cf933846125e7565b905080821115611d1f576040516301bdd0f160e21b815260048101829052602401610eb4565b5f60088481548110611d3357611d336140d5565b5f91825260208083208784526009825260408085203386529092529220600a9091029091019150611d6385612057565b8054600482015460038301546007850154670de0b6b3a764000090611d889085614148565b611d92919061415f565b611d9c9190614135565b611da6919061417e565b60038301555f86815260056020526040902054611dc4908690614135565b5f878152600560205260409020556002820154611de290869061417e565b60028301556004830154611df790869061417e565b60048401556006545f90670de0b6b3a764000090611e159088614148565b611e1f919061415f565b9050808360010154611e319190614135565b60018401556003840154611e46908290614135565b600385015585611e568284614135565b611e60919061417e565b80845560028501549092508690611e78908390614135565b611e82919061417e565b60028501556007840154670de0b6b3a764000090611ea09084614148565b611eaa919061415f565b6004840155604051818152879033907fc0314854fdea1f413e5498dd58aa7953bae1e4e5d587ea2f4e3dacceaa244dea9060200160405180910390a350505050505050565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000035fa164735182de50811e8e2e824cfb9b6118ac26001600160a01b0316906370a0823190602401602060405180830381865afa158015611f53573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f7791906142ab565b9050611fae6001600160a01b037f00000000000000000000000035fa164735182de50811e8e2e824cfb9b6118ac21633308661315d565b6040516370a0823160e01b81523060048201525f9082906001600160a01b037f00000000000000000000000035fa164735182de50811e8e2e824cfb9b6118ac216906370a0823190602401602060405180830381865afa158015612014573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061203891906142ab565b612042919061417e565b9050612051818585600261309b565b50505050565b5f6008828154811061206b5761206b6140d5565b905f5260205f2090600a0201905080600601546120854390565b1161208e575050565b600281015460075460058301548215806120a6575081155b806120af575080155b156120c4574384600601819055505050505050565b5f6120d985600601546120d44390565b61345f565b90505f600a548385846120ec9190614148565b6120f69190614148565b612100919061415f565b9050612114670de0b6b3a76400008261415f565b86600801546121239190614135565b60088701556007860154612137868361415f565b6121419190614135565b600787015543600687015560405187907f141d729c29cc848b27c53f7dbe9f9542cedc4ed2efa7bd2aeb2a4bdce06a407f905f90a250505050505050565b6121b46001600160a01b037f0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f1633308561315d565b6121c08283835f61309b565b5050565b6008546060908067ffffffffffffffff8111156121e3576121e3613ba4565b60405190808252806020026020018201604052801561227357816020015b6122606040518061014001604052805f6001600160a01b031681526020015f6001600160a01b031681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f8152602001606081525090565b8152602001906001900390816122015790505b5091505f5b818110156123fd5760088181548110612293576122936140d5565b5f9182526020918290206040805161014081018252600a90930290910180546001600160a01b039081168452600182015416938301939093526002830154908201526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e082015260088201546101008201526009820180549192916101208401919061232b906140e9565b80601f0160208091040260200160405190810160405280929190818152602001828054612357906140e9565b80156123a25780601f10612379576101008083540402835291602001916123a2565b820191905f5260205f20905b81548152906001019060200180831161238557829003601f168201915b5050505050815250508382815181106123bd576123bd6140d5565b60200260200101819052506123d1816134ac565b90508382815181106123e5576123e56140d5565b60209081029190910101516101000152600101612278565b505090565b61240a613402565b612412612bf1565b156124305760405163442400af60e01b815260040160405180910390fd5b80156124445761243f81612d58565b61244c565b61244c61254f565b5f60088581548110612460576124606140d5565b5f9182526020909120600a9091020180549091506001600160a01b03168015806124a257506001600160a01b0381165f908152600d602052604090205460ff16155b156124c0576040516302721e1f60e61b815260040160405180910390fd5b848260050154600a546124d3919061417e565b6124dd9190614135565b600a556005820185905583158015906124f95750600682015443105b156125135783431161250b578361250d565b435b60068301555b85816001600160a01b03167f9eca8f7bcfb868d72b4ed95b71c627c194ab6bcb9b83adb2280e8a0320bb847687604051611c9891815260200190565b6008545f5b818110156121c05761256581612057565b600101612554565b612575613402565b5f5b8251811015612051576001600160a01b0384165f90815260116020526040812084518492908690859081106125ae576125ae6140d5565b6020908102919091018101516001600160a01b031682528101919091526040015f20805460ff1916911515919091179055600101612577565b5f8181526009602090815260408083206001600160a01b03861684529091529020600201545b92915050565b61261b613402565b6126245f613581565b565b60015433906001600160a01b0316811461265e5760405163118cdaa760e01b81526001600160a01b0382166004820152602401610eb4565b61266781613581565b50565b6040516282b42960e81b815260040160405180910390fd5b61268a613402565b6001600160a01b0381166126b15760405163d92e233d60e01b815260040160405180910390fd5b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b6040516370a0823160e01b81523060048201525f907f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe846001600160a01b0316906370a0823190602401602060405180830381865afa158015612737573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061275b91906142ab565b90506127926001600160a01b037f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe841633308661315d565b6040516370a0823160e01b81523060048201525f9082906001600160a01b037f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe8416906370a0823190602401602060405180830381865afa1580156127f8573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061281c91906142ab565b612826919061417e565b9050612051818585600161309b565b61286a6001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21633308661315d565b5f6128748461359a565b9050600182600281111561288a5761288a6140c1565b0361289f5761289881612f46565b90506128c1565b60028260028111156128b3576128b36140c1565b03610cfa5761289881613053565b6120518185858561309b565b80516060908067ffffffffffffffff8111156128eb576128eb613ba4565b60405190808252806020026020018201604052801561291e57816020015b60608152602001906001900390816129095790505b506008549092505f5b82811015612b76575f858281518110612942576129426140d5565b602002602001015190508267ffffffffffffffff81111561296557612965613ba4565b60405190808252806020026020018201604052801561299e57816020015b61298b613960565b8152602001906001900390816129835790505b508583815181106129b1576129b16140d5565b60200260200101819052505f5b83811015612b6c575f8181526009602090815260408083206001600160a01b0386168452825291829020825160a0810184528154808252600183015493820193909352600282015493810193909352600381015460608401526004015460808301528751889086908110612a3457612a346140d5565b60200260200101518381518110612a4d57612a4d6140d5565b60200260200101515f60048110612a6657612a666140d5565b6020020181815250508060200151878581518110612a8657612a866140d5565b60200260200101518381518110612a9f57612a9f6140d5565b6020026020010151600160048110612ab957612ab96140d5565b602002015260408101518751889086908110612ad757612ad76140d5565b60200260200101518381518110612af057612af06140d5565b6020026020010151600260048110612b0a57612b0a6140d5565b6020020152612b198284613617565b878581518110612b2b57612b2b6140d5565b60200260200101518381518110612b4457612b446140d5565b6020026020010151600360048110612b5e57612b5e6140d5565b6020020152506001016129be565b5050600101612927565b505050919050565b5f612b898383613617565b9392505050565b61266a613402565b612ba0613402565b600280546001600160a01b0319166001600160a01b03838116918217909255600354604051919216907f67f679e13fe9dca16f3079221965ec41838cb8881cbc0f440bc13507c6b214c2905f90a350565b600b545f908015801590610d7d57508043610d7b565b806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c43573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c6791906142c2565b6001600160a01b0316336001600160a01b031614612c97576040516282b42960e81b815260040160405180910390fd5b806001600160a01b03166315ba56e56040518163ffffffff1660e01b81526004015f604051808303815f87803b158015612ccf575f80fd5b505af1158015612ce1573d5f803e3d5ffd5b5050505050565b612cf0613402565b600180546001600160a01b0383166001600160a01b03199091168117909155612d205f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b612d60613402565b612d68612bf1565b15612d865760405163442400af60e01b815260040160405180910390fd5b670de0b6b3a7640000811080612da45750683635c9adc5dea0000081115b15612dc2576040516376f18c4360e11b815260040160405180910390fd5b612dca61254f565b60075460408051918252602082018390527fb48e36a0869514773506a41441177faf21ebdda362731b7363ee174f3a007728910160405180910390a1600755565b80516060908067ffffffffffffffff811115612e2957612e29613ba4565b604051908082528060200260200182016040528015612e5c57816020015b6060815260200190600190039081612e475790505b506008549092505f5b82811015612b76575f858281518110612e8057612e806140d5565b602002602001015190508267ffffffffffffffff811115612ea357612ea3613ba4565b604051908082528060200260200182016040528015612ecc578160200160208202803683370190505b50858381518110612edf57612edf6140d5565b60200260200101819052505f5b83811015612f3c57612efe8183613617565b868481518110612f1057612f106140d5565b60200260200101518281518110612f2957612f296140d5565b6020908102919091010152600101612eec565b5050600101612e65565b5f6001600160a01b037f000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe8416637a28fb888163a1903eab85612f8e5f546001600160a01b031690565b6040516001600160e01b031960e085901b1681526001600160a01b03909116600482015260240160206040518083038185885af1158015612fd1573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190612ff691906142ab565b6040518263ffffffff1660e01b815260040161301491815260200190565b602060405180830381865afa15801561302f573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061260d91906142ab565b5f6001600160a01b037f000000000000000000000000308861a430be4cce5502d0a12724771fc6daf2161663561bddf88163f340fa0185612f8e5f546001600160a01b031690565b5f808260028111156130af576130af6140c1565b036130c4576130bd8561368e565b9050613108565b60018260028111156130d8576130d86140c1565b036130e6576130bd856136fb565b60028260028111156130fa576130fa6140c1565b03610cfa576130bd8561374a565b836131138285614148565b61311d919061415f565b9250612ce160045f846002811115613137576131376140c1565b6002811115613148576131486140c1565b81526020019081526020015f205482856131c4565b6040516001600160a01b0384811660248301528381166044830152606482018390526120519186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050613799565b6131cc612bf1565b156131ea5760405163442400af60e01b815260040160405180910390fd5b815f0361320a57604051635972996f60e11b815260040160405180910390fd5b8181111561322e576040516301bdd0f160e21b815260048101839052602401610eb4565b5f60088481548110613242576132426140d5565b5f91825260208083208784526009825260408085203386529092529220600a909102909101915061327285612057565b8054600482015460038301546007850154670de0b6b3a7640000906132979085614148565b6132a1919061415f565b6132ab9190614135565b6132b5919061417e565b60038301555f868152600560205260409020546132d3908590614135565b5f878152600560205260409020556132eb848661417e565b94508482600201546132fd9190614135565b60028301556004830154613312908690614135565b6004840155600654670de0b6b3a76400009061332e9086614148565b613338919061415f565b935083826001015461334a9190614135565b6001830155600383015461335f908590614135565b60038401558361336f8683614135565b6133799190614135565b80835560028401549091508490613391908790614135565b61339b9190614135565b60028401556007830154670de0b6b3a7640000906133b99083614148565b6133c3919061415f565b60048301556040805186815260208101869052879133917f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e9101611c98565b5f546001600160a01b031633146126245760405163118cdaa760e01b8152336004820152602401610eb4565b6040516001600160a01b03838116602483015260448201839052610d1f91859182169063a9059cbb90606401613192565b600b545f9080156134775761347483826137fa565b92505b838311156134a357613489848461417e565b61349b90670de0b6b3a7640000614148565b91505061260d565b5f91505061260d565b5f805f600884815481106134c2576134c26140d5565b905f5260205f2090600a0201905080600701549250806008015491505f8160020154905081600601546134f24390565b1180156134fe57508015155b1561357a575f61351383600601546120d44390565b90505f600a5484600501546007548461352c9190614148565b6135369190614148565b613540919061415f565b9050613554670de0b6b3a76400008261415f565b61355e9086614135565b94508561356b848361415f565b6135759190614135565b955050505b5050915091565b600180546001600160a01b03191690556126678161380f565b604051632e1a7d4d60e01b8152600481018290525f907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031690632e1a7d4d906024015f604051808303815f87803b1580156135fb575f80fd5b505af115801561360d573d5f803e3d5ffd5b5093949350505050565b5f8281526009602090815260408083206001600160a01b0385168452909152812081613642856134ac565b50905081600401548260030154670de0b6b3a764000083855f01546136679190614148565b613671919061415f565b61367b9190614135565b613685919061417e565b95945050505050565b604051636e553f6560e01b8152600481018290523060248201525f907f00000000000000000000000083f20f44975d03b1b09e64809b757c47f942beea6001600160a01b031690636e553f65906044015b6020604051808303815f875af115801561302f573d5f803e3d5ffd5b604051630ea598cb60e41b8152600481018290525f907f0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca06001600160a01b03169063ea598cb0906024016136df565b604051630ea598cb60e41b8152600481018290525f907f000000000000000000000000cd5fe23c85820f7b72d0926fc9b05b43e359b7ee6001600160a01b03169063ea598cb0906024016136df565b5f6137ad6001600160a01b0384168361385e565b905080515f141580156137d15750808060200190518101906137cf9190614191565b155b15610d1f57604051635274afe760e01b81526001600160a01b0384166004820152602401610eb4565b5f8183106138085781612b89565b5090919050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060612b8983835f845f80856001600160a01b0316848660405161388291906142dd565b5f6040518083038185875af1925050503d805f81146138bc576040519150601f19603f3d011682016040523d82523d5f602084013e6138c1565b606091505b50915091506138d18683836138db565b9695505050505050565b6060826138f0576138eb82613937565b612b89565b815115801561390757506001600160a01b0384163b155b1561393057604051639996b31560e01b81526001600160a01b0385166004820152602401610eb4565b5080612b89565b8051156139475780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b60405180608001604052806004906020820280368337509192915050565b5f805f60608486031215613990575f80fd5b505081359360208301359350604090920135919050565b5f602082840312156139b7575f80fd5b5035919050565b5f5b838110156139d85781810151838201526020016139c0565b50505f910152565b5f81518084526139f78160208601602086016139be565b601f01601f19169290920160200192915050565b60018060a01b038b16815260018060a01b038a1660208201528860408201528760608201528660808201528560a08201528460c08201528360e0820152826101008201526101406101208201525f613a676101408301846139e0565b9c9b505050505050505050505050565b5f8060408385031215613a88575f80fd5b50508035926020909101359150565b6001600160a01b0381168114612667575f80fd5b5f60208284031215613abb575f80fd5b8135612b8981613a97565b5f805f8060808587031215613ad9575f80fd5b843593506020850135613aeb81613a97565b92506040850135613afb81613a97565b9396929550929360600135925050565b5f8060408385031215613b1c575f80fd5b823591506020830135613b2e81613a97565b809150509250929050565b5f805f805f8060c08789031215613b4e575f80fd5b505084359660208601359650604086013595606081013595506080810135945060a0013592509050565b803560038110613b86575f80fd5b919050565b5f60208284031215613b9b575f80fd5b612b8982613b78565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613be157613be1613ba4565b604052919050565b5f805f805f60a08688031215613bfd575f80fd5b853594506020860135613c0f81613a97565b9350604086013567ffffffffffffffff811115613c2a575f80fd5b8601601f81018813613c3a575f80fd5b803567ffffffffffffffff811115613c5457613c54613ba4565b613c67601f8201601f1916602001613bb8565b818152896020838501011115613c7b575f80fd5b816020840160208301375f918101602001919091529598949750949560608101359550608001359392505050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b82811015613d8757868503603f19018452815180516001600160a01b031686526020810151613d0960208801826001600160a01b03169052565b5060408101516040870152606081015160608701526080810151608087015260a081015160a087015260c081015160c087015260e081015160e08701526101008101516101008701526101208101519050610140610120870152613d716101408701826139e0565b9550506020938401939190910190600101613ccf565b50929695505050505050565b5f805f8060808587031215613da6575f80fd5b5050823594602084013594506040840135936060013592509050565b5f82601f830112613dd1575f80fd5b813567ffffffffffffffff811115613deb57613deb613ba4565b8060051b613dfb60208201613bb8565b91825260208185018101929081019086841115613e16575f80fd5b6020860192505b838310156138d1578235613e3081613a97565b825260209283019290910190613e1d565b8015158114612667575f80fd5b5f805f60608486031215613e60575f80fd5b8335613e6b81613a97565b9250602084013567ffffffffffffffff811115613e86575f80fd5b613e9286828701613dc2565b9250506040840135613ea381613e41565b809150509250925092565b5f8060408385031215613ebf575f80fd5b8235613eca81613a97565b946020939093013593505050565b5f805f60608486031215613eea575f80fd5b8335925060208401359150613f0160408501613b78565b90509250925092565b5f60208284031215613f1a575f80fd5b813567ffffffffffffffff811115613f30575f80fd5b613f3c84828501613dc2565b949350505050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b82811015613d8757868503603f19018452815180518087526020918201918701905f5b81811015613fd2578351835f5b6004811015613fb9578251825260209283019290910190600101613f9a565b5050506020939093019260809290920191600101613f8d565b5090965050506020938401939190910190600101613f6a565b5f8060408385031215613ffc575f80fd5b823561400781613a97565b91506020830135613b2e81613a97565b5f8060408385031215614028575f80fd5b8235915061403860208401613b78565b90509250929050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b82811015613d8757868503603f19018452815180518087526020918201918701905f5b818110156140a857835183526020938401939092019160010161408a565b5090965050506020938401939190910190600101614067565b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b600181811c908216806140fd57607f821691505b60208210810361411b57634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561260d5761260d614121565b808202811582820484141761260d5761260d614121565b5f8261417957634e487b7160e01b5f52601260045260245ffd5b500490565b8181038181111561260d5761260d614121565b5f602082840312156141a1575f80fd5b8151612b8981613e41565b601f821115610d1f57805f5260205f20601f840160051c810160208510156141d15750805b601f840160051c820191505b81811015612ce1575f81556001016141dd565b815167ffffffffffffffff81111561420a5761420a613ba4565b61421e8161421884546140e9565b846141ac565b6020601f821160018114614250575f83156142395750848201515b5f19600385901b1c1916600184901b178455612ce1565b5f84815260208120601f198516915b8281101561427f578785015182556020948501946001909201910161425f565b508482101561429c57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f602082840312156142bb575f80fd5b5051919050565b5f602082840312156142d2575f80fd5b8151612b8981613a97565b5f82516142ee8184602087016139be565b919091019291505056fea26469706673582212202a9096c7b91493f04491379bf7799f31bb09e5510bcf8f08f751a226d98ac78964736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000083f20f44975d03b1b09e64809b757c47f942beea000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe840000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca000000000000000000000000035fa164735182de50811e8e2e824cfb9b6118ac2000000000000000000000000308861a430be4cce5502d0a12724771fc6daf216000000000000000000000000cd5fe23c85820f7b72d0926fc9b05b43e359b7ee
-----Decoded View---------------
Arg [0] : tokens_ (address[8]): 0x6B175474E89094C44Da98b954EedeAC495271d0F,0x83F20F44975D03b1b09e64809B757c47f942BEeA,0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2,0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84,0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0,0x35fA164735182de50811E8e2E824cFb9B6118ac2,0x308861A430be4cce5502d0A12724771Fc6DaF216,0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f
Arg [1] : 00000000000000000000000083f20f44975d03b1b09e64809b757c47f942beea
Arg [2] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [3] : 000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84
Arg [4] : 0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0
Arg [5] : 00000000000000000000000035fa164735182de50811e8e2e824cfb9b6118ac2
Arg [6] : 000000000000000000000000308861a430be4cce5502d0a12724771fc6daf216
Arg [7] : 000000000000000000000000cd5fe23c85820f7b72d0926fc9b05b43e359b7ee
Deployed Bytecode Sourcemap
46632:37010:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;50017:4:0;50003:18;:10;:18;49999:57;;46632:37010;49999:57;50068:36;50079:1;50082:21;50068:10;:36::i;:::-;46632:37010;;;;;63281:273;;;;;;;;;;-1:-1:-1;63281:273:0;;;;;:::i;:::-;;:::i;55259:95::-;;;;;;;;;;-1:-1:-1;55331:8:0;:15;55259:95;;;631:25:1;;;619:2;604:18;55259:95:0;;;;;;;;46227:23;;;;;;;;;;;;;;;;49248:29;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;940:32:1;;;922:51;;910:2;895:18;49248:29:0;776:203:1;55853:308:0;;;;;;;;;;;;;:::i;:::-;;;1149:14:1;;1142:22;1124:41;;1112:2;1097:18;55853:308:0;984:187:1;45894:26:0;;;;;;;;;;-1:-1:-1;45894:26:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;;;:::i;43271:312::-;;;;;;;;;;;;;:::i;46139:30::-;;;;;;;;;;;;;;;;57073:667;;;;;;;;;;-1:-1:-1;57073:667:0;;;;;:::i;:::-;;:::i;46294:42::-;;;;;;;;;;-1:-1:-1;46294:42:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;76610:1838;;;;;;;;;;-1:-1:-1;76610:1838:0;;;;;:::i;:::-;;:::i;56562:323::-;;;;;;;;;;-1:-1:-1;56562:323:0;;;;;:::i;:::-;;:::i;58403:365::-;;;;;;;;;;-1:-1:-1;58403:365:0;;;;;:::i;:::-;;:::i;50478:1337::-;;;;;;;;;;-1:-1:-1;50478:1337:0;;;;;:::i;:::-;;:::i;45598:50::-;;;;;;;;;;-1:-1:-1;45598:50:0;;;;;:::i;:::-;;;;;;;;;;;;;;42855:36;;;;;;;;;;-1:-1:-1;42855:36:0;;;;-1:-1:-1;;;;;42855:36:0;;;52288:1377;;;;;;;;;;-1:-1:-1;52288:1377:0;;;;;:::i;:::-;;:::i;49137:29::-;;;;;;;;;;;;;;;45829;;;;;;;;;;;;;;;;81426:102;;;;;;;;;;-1:-1:-1;81508:12:0;81426:102;;72633:1416;;;;;;;;;;-1:-1:-1;72633:1416:0;;;;;:::i;:::-;;:::i;70229:1801::-;;;;;;;;;;-1:-1:-1;70229:1801:0;;;;;:::i;:::-;;:::i;49210:31::-;;;;;;;;;;;;;;;64789:457;;;;;;;;;;-1:-1:-1;64789:457:0;;;;;:::i;:::-;;:::i;62080:1002::-;;;;;;;;;;-1:-1:-1;62080:1002:0;;;;;:::i;:::-;;:::i;42898:29::-;;;;;;;;;;-1:-1:-1;42898:29:0;;;;-1:-1:-1;;;;;42898:29:0;;;63714:290;;;;;;;;;;-1:-1:-1;63714:290:0;;;;;:::i;:::-;;:::i;81639:345::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;54073:1064::-;;;;;;;;;;-1:-1:-1;54073:1064:0;;;;;:::i;:::-;;:::i;61788:179::-;;;;;;;;;;;;;:::i;59529:248::-;;;;;;;;;;-1:-1:-1;59529:248:0;;;;;:::i;:::-;;:::i;72311:151::-;;;;;;;;;;-1:-1:-1;72311:151:0;;;;;:::i;:::-;;:::i;45754:32::-;;;;;;;;;;;;;;;;39854:103;;;;;;;;;;;;;:::i;49284:42::-;;;;;;;;;;;;;;;42322:235;;;;;;;;;;;;;:::i;45698:47::-;;;;;;;;;;-1:-1:-1;45698:47:0;;;;;:::i;:::-;;;;;;;;;;;;;;74341:1275;;;;;;:::i;:::-;;:::i;39179:87::-;;;;;;;;;;-1:-1:-1;39225:7:0;39252:6;-1:-1:-1;;;;;39252:6:0;39179:87;;56231:186;;;;;;;;;;-1:-1:-1;56231:186:0;;;;;:::i;:::-;;:::i;46422:41::-;;;;;;;;;;-1:-1:-1;46422:41:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;45978:64;;;;;;;;;;-1:-1:-1;45978:64:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11843:25:1;;;11899:2;11884:18;;11877:34;;;;11927:18;;;11920:34;;;;11985:2;11970:18;;11963:34;12028:3;12013:19;;12006:35;11830:3;11815:19;45978:64:0;11584:463:1;64166:462:0;;;;;;;;;;-1:-1:-1;64166:462:0;;;;;:::i;:::-;;:::i;66301:676::-;;;;;;;;;;-1:-1:-1;66301:676:0;;;;;:::i;:::-;;:::i;82146:790::-;;;;;;;;;;-1:-1:-1;82146:790:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;61578:137::-;;;;;;;;;;-1:-1:-1;61578:137:0;;;;;:::i;:::-;;:::i;80801:410::-;;;;;;:::i;:::-;;:::i;75901:368::-;;;;;;;;;;-1:-1:-1;75901:368:0;;;;;:::i;46472:88::-;;;;;;;;;;-1:-1:-1;46472:88:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;46345:37;;;;;;;;;;;;;;;;49173:30;;;;;;;;;;;;;;;49333;;;;;;;;;;;;;;;43027:178;;;;;;;;;;-1:-1:-1;43027:178:0;;;;;:::i;:::-;;:::i;55469:245::-;;;;;;;;;;;;;:::i;49101:29::-;;;;;;;;;;;;;;;41410:101;;;;;;;;;;-1:-1:-1;41490:13:0;;-1:-1:-1;;;;;41490:13:0;41410:101;;46391:24;;;;;;;;;;-1:-1:-1;46391:24:0;;;;-1:-1:-1;;;;;46391:24:0;;;65448:605;;;;;;:::i;:::-;;:::i;43647:199::-;;;;;;;;;;-1:-1:-1;43647:199:0;;;;;:::i;:::-;;:::i;41710:181::-;;;;;;;;;;-1:-1:-1;41710:181:0;;;;;:::i;:::-;;:::i;49066:28::-;;;;;;;;;;;;;;;57858:420;;;;;;;;;;-1:-1:-1;57858:420:0;;;;;:::i;:::-;;:::i;83106:533::-;;;;;;;;;;-1:-1:-1;83106:533:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;65448:605::-;65552:9;65565:1;65552:14;65548:65;;65590:11;;-1:-1:-1;;;65590:11:0;;;;;;;;;;;65548:65;65648:9;65691:21;65672:15;:40;;;;;;;;:::i;:::-;;65668:286;;65744:25;65756:12;65744:11;:25::i;:::-;65729:40;;65668:286;;;65810:20;65791:15;:39;;;;;;;;:::i;:::-;;65787:167;;65862:24;65873:12;65862:10;:24::i;65787:167::-;65926:16;;-1:-1:-1;;;65926:16:0;;;;;;;;;;;65787:167;65966:79;65990:12;66004:9;66015:12;66029:15;65966:23;:79::i;:::-;65537:516;65448:605;;:::o;63281:273::-;63371:125;63425:10;63458:4;63478:7;63371:8;63380:4;63371:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:22;-1:-1:-1;;;;;63371:22:0;;:125;;:39;:125::i;:::-;63509:37;63518:4;63524:7;63533:12;63509:8;:37::i;55853:308::-;55958:22;;55907:4;;55995:28;;;;;:74;;-1:-1:-1;56046:23:0;81508:12;56027:16;:42;55995:74;55991:163;;;56093:4;56086:11;;;55853:308;:::o;55991:163::-;56137:5;56130:12;;;55853:308;:::o;45894:26::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;45894:26:0;;;;-1:-1:-1;45894:26:0;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;43271:312::-;43339:21;;-1:-1:-1;;;;;43339:21:0;43325:10;:35;43321:113;;43384:38;;-1:-1:-1;;;43384:38:0;;43411:10;43384:38;;;922:51:1;895:18;;43384:38:0;;;;;;;;43321:113;43471:14;;43449:49;;43487:10;;-1:-1:-1;;;;;43471:14:0;;43449:49;;43471:14;;43449:49;43516:21;43509:28;;-1:-1:-1;;;;;;43509:28:0;;;;;;43548:14;:27;;;;;43565:10;43548:27;;;43271:312::o;57073:667::-;39065:13;:11;:13::i;:::-;57174:16:::1;:14;:16::i;:::-;57170:72;;;57214:16;;-1:-1:-1::0;;;57214:16:0::1;;;;;;;;;;;57170:72;57252:31;57298:14:::0;;57294:321:::1;;57352:9:::0;81508:12;57333:28:::1;57329:93;;;57389:17;;-1:-1:-1::0;;;57389:17:0::1;;;;;;;;;;;57329:93;57462:29;57474:17:::0;57462:9;:29:::1;:::i;:::-;57436:55;;57294:321;;;-1:-1:-1::0;57602:1:0::1;57294:321;57625:17;:15;:17::i;:::-;57653:8;:20:::0;;;;-1:-1:-1;57684:22:0::1;:48:::0;57073:667::o;76610:1838::-;76746:10;76736:21;;;;:9;:21;;;;;;;;-1:-1:-1;;;;;76736:30:0;;;;;;;;;;;;76731:91;;76790:20;;-1:-1:-1;;;76790:20:0;;;;;;;;;;;76731:91;76849:9;-1:-1:-1;;;;;76838:20:0;:7;-1:-1:-1;;;;;76838:20:0;;:50;;;-1:-1:-1;;;;;;76862:26:0;;76883:4;76862:26;76838:50;:74;;;-1:-1:-1;76892:20:0;;76838:74;76834:131;;;76936:17;;-1:-1:-1;;;76936:17:0;;;;;;;;;;;76834:131;76977:21;77001:8;77010:4;77001:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;77040:12;;77001:14;;-1:-1:-1;;;;;;77040:12:0;77028:93;;77091:18;;-1:-1:-1;;;77091:18:0;;;;;;;;;;;77028:93;77133:16;77144:4;77133:10;:16::i;:::-;77188:22;;;;77160:25;77251:14;;;:8;:14;;;;;;;;-1:-1:-1;;;;;77251:23:0;;;;;;;;;;77311:25;;;;;;;77374:15;;77423:13;;77612:19;;;;77574:22;;;;77251:23;;77311:25;;77374:15;;77423:13;;77554:4;77491:47;77188:22;77374:15;77491:47;:::i;:::-;:67;;;;:::i;:::-;:105;;;;:::i;:::-;:140;;;;:::i;:::-;77449:182;;-1:-1:-1;;77648:15:0;:36;77644:231;;77719:21;77701:39;;77644:231;;;77780:21;77762:15;:39;77758:117;;;77825:38;;-1:-1:-1;;;77825:38:0;;;;;631:25:1;;;604:18;;77825:38:0;485:177:1;77758:117:0;77912:39;77936:15;77912:21;:39;:::i;:::-;77887:8;:22;;:64;;;;78150:15;78117:6;:17;;;78081:6;:20;;;78061:4;78028:17;78000:12;:45;;;;:::i;:::-;:65;;;;:::i;:::-;:101;;;;:::i;:::-;:134;;;;:::i;:::-;:165;;;;:::i;:::-;77964:20;;;:201;78263:4;78200:47;78230:17;78200:14;:47;:::i;:::-;:67;;;;:::i;:::-;78178:19;;;:89;78361:4;78300:45;78328:17;78300:12;:45;:::i;:::-;:65;;;;:::i;:::-;78280:6;:17;;:85;;;;78418:4;78407:9;-1:-1:-1;;;;;78383:57:0;78398:7;-1:-1:-1;;;;;78383:57:0;;78424:15;78383:57;;;;631:25:1;;619:2;604:18;;485:177;78383:57:0;;;;;;;;76718:1730;;;;;;;76610:1838;;;;:::o;56562:323::-;39065:13;:11;:13::i;:::-;-1:-1:-1;;;;;56653:21:0;::::1;56649:74;;56698:13;;-1:-1:-1::0;;;56698:13:0::1;;;;;;;;;;;56649:74;56780:1;-1:-1:-1::0;;;;;56737:45:0::1;56745:8;56754:4;56745:14;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;:22:::0;-1:-1:-1;;;;;56745:22:0::1;56737:45:::0;56733:103:::1;;56806:18;;-1:-1:-1::0;;;56806:18:0::1;;;;;;;;;;;56733:103;56870:7;56846:8;56855:4;56846:14;;;;;;;;:::i;:::-;;;;;;;;;;;:21;;;:31;;;;;-1:-1:-1::0;;;;;56846:31:0::1;;;;;-1:-1:-1::0;;;;;56846:31:0::1;;;;;;56562:323:::0;;:::o;58403:365::-;39065:13;:11;:13::i;:::-;58516:4:::1;58495:18;:25;:55;;;;58545:5;58524:18;:26;58495:55;58491:111;;;58574:16;;-1:-1:-1::0;;;58574:16:0::1;;;;;;;;;;;58491:111;58616:16;:14;:16::i;:::-;58612:72;;;58656:16;;-1:-1:-1::0;;;58656:16:0::1;;;;;;;;;;;58612:72;58694:17;:15;:17::i;:::-;58722;:38:::0;58403:365::o;50478:1337::-;39065:13;:11;:13::i;:::-;50701:12:::1;::::0;::::1;;50697:72;;;50737:20;;-1:-1:-1::0;;;50737:20:0::1;;;;;;;;;;;50697:72;50803:4;50785:15;:22;:51;;;;50829:7;50811:15;:25;50785:51;50781:114;;;50860:23;;-1:-1:-1::0;;;50860:23:0::1;;;;;;;;;;;50781:114;50905:14;:32:::0;;;50975:4:::1;50954:25:::0;::::1;::::0;:55:::1;;;51004:5;50983:18;:26;50954:55;50950:111;;;51033:16;;-1:-1:-1::0;;;51033:16:0::1;;;;;;;;;;;50950:111;51071:17;:38:::0;;;-1:-1:-1;;;;;51133:3:0::1;51122:15:::0;::::1;;::::0;;;:10:::1;:15;::::0;;;;;;;:22;;-1:-1:-1;;51122:22:0;;::::1;51140:4;51122:22:::0;;::::1;::::0;;;51166:4:::1;51155:16:::0;::::1;::::0;;;;;:23;;;::::1;::::0;::::1;::::0;;51200:5:::1;51189:17:::0;::::1;::::0;;;;;:24;;;::::1;::::0;::::1;::::0;;51235:4:::1;51224:16:::0;;::::1;::::0;;;;;:23;;;::::1;::::0;::::1;::::0;;51260:12:::1;:19:::0;;;;::::1;;::::0;;;51341:61;;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;51341:61:0;;::::1;::::0;::::1;::::0;51345:15;;51362:4:::1;::::0;51341:61;51376:22;;51341:3:::1;:61::i;:::-;51309:8;:29;::::0;;;::::1;::::0;::::1;::::0;;;;;;;;-1:-1:-1;51309:29:0;:93;;;;51413:35;-1:-1:-1;;;51413:35:0;;-1:-1:-1;;;;;51433:4:0::1;18723:32:1::0;;51413:35:0::1;::::0;::::1;18705:51:1::0;-1:-1:-1;;18772:18:1;;;18765:34;51420:3:0::1;51413:19;::::0;::::1;::::0;18678:18:1;;51413:35:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;51514:67;51518:17;51537:6;51514:67;;;;;;;;;;;;;-1:-1:-1::0;;;51514:67:0::1;;::::0;51555:22:::1;51579:1;51514:3;:67::i;:::-;51480:8;:31;51489:21;51480:31:::0;;::::1;::::0;::::1;::::0;;;;;;;;-1:-1:-1;51480:31:0;:101;;;;51592:39;-1:-1:-1;;;51592:39:0;;-1:-1:-1;;;;;51614:6:0::1;18723:32:1::0;;51592:39:0::1;::::0;::::1;18705:51:1::0;-1:-1:-1;;18772:18:1;;;18765:34;51599:5:0::1;51592:21;::::0;::::1;::::0;18678:18:1;;51592:39:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;51695:64;51699:16;51717:5;51695:64;;;;;;;;;;;;;-1:-1:-1::0;;;51695:64:0::1;;::::0;51733:22:::1;51757:1;51695:3;:64::i;:::-;51662:8;:30;51671:20;51662:30:::0;;::::1;::::0;::::1;::::0;;;;;;;;-1:-1:-1;51662:30:0;:97;;;;51770:37;-1:-1:-1;;;51770:37:0;;-1:-1:-1;;;;;51791:5:0::1;18723:32:1::0;;51770:37:0::1;::::0;::::1;18705:51:1::0;-1:-1:-1;;18772:18:1;;;18765:34;51777:4:0::1;51770:20;::::0;::::1;::::0;18678:18:1;;51770:37:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;50478:1337:::0;;;;;;:::o;52288:1377::-;52447:7;39065:13;:11;:13::i;:::-;-1:-1:-1;;;;;52471:22:0;::::1;52467:75;;52517:13;;-1:-1:-1::0;;;52517:13:0::1;;;;;;;;;;;52467:75;-1:-1:-1::0;;;;;52556:20:0;::::1;;::::0;;;:10:::1;:20;::::0;;;;;::::1;;52552:72;;;52600:12;;-1:-1:-1::0;;;52600:12:0::1;;;;;;;;;;;52552:72;52638:16;:14;:16::i;:::-;52634:72;;;52678:16;;-1:-1:-1::0;;;52678:16:0::1;;;;;;;;;;;52634:72;52722:23:::0;;52718:143:::1;;52762:37;52780:18;52762:17;:37::i;:::-;52718:143;;;52832:17;:15;:17::i;:::-;52873:23;52931:15:::0;81508:12;52912:34:::1;:71;;52968:15;52912:71;;;81508:12:::0;52949:16:::1;52873:110;;53030:11;53012:15;;:29;;;;:::i;:::-;52994:15;:47;;;;53075:4;53052:10;:20;53063:8;-1:-1:-1::0;;;;;53052:20:0::1;-1:-1:-1::0;;;;;53052:20:0::1;;;;;;;;;;;;;:27;;;;;;;;;;;;;;;;;;53092:11;53106:8;:15;;;;53092:29;;53134:8;53162:412;;;;;;;;53206:8;-1:-1:-1::0;;;;;53162:412:0::1;;;;;53250:1;-1:-1:-1::0;;;;;53162:412:0::1;;;;;53279:1;53162:412;;;;53312:1;53162:412;;;;53347:1;53162:412;;;;53379:11;53162:412;;;;53426:15;53162:412;;;;53479:1;53162:412;;;;53513:1;53162:412;;;;53546:12;53162:412;;::::0;53134:451:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;53134:451:0::1;;;;;-1:-1:-1::0;;;;;53134:451:0::1;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;53134:451:0::1;;;;;-1:-1:-1::0;;;;;53134:451:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;53617:3;53607:8;-1:-1:-1::0;;;;;53603:31:0::1;;53622:11;53603:31;;;;631:25:1::0;;619:2;604:18;;485:177;53603:31:0::1;;;;;;;;53654:3:::0;52288:1377;-1:-1:-1;;;;;;;52288:1377:0:o;72633:1416::-;72714:23;:21;:23::i;:::-;72710:83;;;72761:20;;-1:-1:-1;;;72761:20:0;;;;;;;;;;;72710:83;72807:15;72826:1;72807:20;72803:76;;72851:16;;-1:-1:-1;;;72851:16:0;;;;;;;;;;;72803:76;72891:21;72915:8;72924:4;72915:14;;;;;;;;:::i;:::-;;;;;;;;;72964;;;:8;:14;;;;;;72979:10;72964:26;;;;;;;72915:14;;;;;;;;-1:-1:-1;73001:16:0;72973:4;73001:10;:16::i;:::-;73058:18;;;;73093:36;;;73089:219;;73164:17;73146:35;;73089:219;;;73221:17;73203:15;:35;73199:109;;;73262:34;;-1:-1:-1;;;73262:34:0;;;;;631:25:1;;;604:18;;73262:34:0;485:177:1;73199:109:0;73341:11;;73517:15;;;;73483:18;;;;73425:22;;;;73463:4;;73399:48;;73341:11;73399:48;:::i;:::-;:68;;;;:::i;:::-;:102;;;;:::i;:::-;:133;;;;:::i;:::-;73365:18;;;:167;73566:35;73586:15;73566:17;:35;:::i;:::-;73545:18;;;:56;73633:18;;;;:36;;73654:15;;73633:36;:::i;:::-;73612:18;;;:57;73695:28;73708:15;73695:10;:28;:::i;:::-;73736:24;;;73785:11;;;;73682:41;;-1:-1:-1;73785:29:0;;73799:15;;73785:29;:::i;:::-;73771:11;;;:43;73871:22;;;;73909:4;;73845:48;;:10;:48;:::i;:::-;:68;;;;:::i;:::-;73827:15;;;:86;73926:12;;:54;;-1:-1:-1;;;;;73926:12:0;73952:10;73964:15;73926:25;:54::i;:::-;73998:43;;631:25:1;;;74019:4:0;;74007:10;;73998:43;;619:2:1;604:18;73998:43:0;;;;;;;;72699:1350;;;;72633:1416;;:::o;70229:1801::-;70312:16;:14;:16::i;:::-;70308:72;;;70352:16;;-1:-1:-1;;;70352:16:0;;;;;;;;;;;70308:72;70396:12;70412:1;70396:17;70392:70;;70437:13;;-1:-1:-1;;;70437:13:0;;;;;;;;;;;70392:70;70474:26;70503:39;70525:10;70537:4;70503:21;:39::i;:::-;70474:68;;70572:18;70557:12;:33;70553:105;;;70614:32;;-1:-1:-1;;;70614:32:0;;;;;631:25:1;;;604:18;;70614:32:0;485:177:1;70553:105:0;70670:21;70694:8;70703:4;70694:14;;;;;;;;:::i;:::-;;;;;;;;;70743;;;:8;:14;;;;;;70758:10;70743:26;;;;;;;70694:14;;;;;;;;-1:-1:-1;70780:16:0;70752:4;70780:10;:16::i;:::-;70830:11;;71006:15;;;;70972:18;;;;70914:22;;;;70952:4;;70888:48;;70830:11;70888:48;:::i;:::-;:68;;;;:::i;:::-;:102;;;;:::i;:::-;:133;;;;:::i;:::-;70854:18;;;:167;71093:18;;;;:12;:18;;;;;;:33;;71114:12;;71093:33;:::i;:::-;71072:18;;;;:12;:18;;;;;:54;71242:18;;;;:33;;71263:12;;71242:33;:::i;:::-;71221:18;;;:54;71307:18;;;;:33;;71328:12;;71307:33;:::i;:::-;71286:18;;;:54;71428:17;;71386:24;;71448:4;;71413:32;;:12;:32;:::i;:::-;:39;;;;:::i;:::-;71386:66;;71503:16;71484:4;:16;;;:35;;;;:::i;:::-;71465:16;;;:54;71549:16;;;;:35;;71568:16;;71549:35;:::i;:::-;71530:16;;;:54;71737:12;71705:29;71718:16;71705:10;:29;:::i;:::-;:44;;;;:::i;:::-;71762:24;;;71811:11;;;;71692:57;;-1:-1:-1;71844:12:0;;71811:30;;71825:16;;71811:30;:::i;:::-;:45;;;;:::i;:::-;71797:11;;;:59;71913:22;;;;71951:4;;71887:48;;:10;:48;:::i;:::-;:68;;;;:::i;:::-;71869:15;;;:86;71973:49;;631:25:1;;;71999:4:0;;71987:10;;71973:49;;619:2:1;604:18;71973:49:0;;;;;;;70297:1733;;;;;70229:1801;;:::o;64789:457::-;64893:37;;-1:-1:-1;;;64893:37:0;;64924:4;64893:37;;;922:51:1;64869:21:0;;64900:4;-1:-1:-1;;;;;64893:22:0;;;;895:18:1;;64893:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64869:61;-1:-1:-1;64941:115:0;-1:-1:-1;;;;;64948:4:0;64941:29;64985:10;65018:4;65038:7;64941:29;:115::i;:::-;65090:37;;-1:-1:-1;;;65090:37:0;;65121:4;65090:37;;;922:51:1;65067:20:0;;65130:13;;-1:-1:-1;;;;;65097:4:0;65090:22;;;;895:18:1;;65090:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;;;;:::i;:::-;65067:76;;65156:82;65180:12;65194:7;65203:12;65217:20;65156:23;:82::i;:::-;64858:388;;64789:457;;:::o;62080:1002::-;62132:21;62156:8;62165:4;62156:14;;;;;;;;:::i;:::-;;;;;;;;;;;62132:38;;62205:4;:20;;;62185:16;81508:12;;81426:102;62185:16;:40;62181:79;;62242:7;62080:1002;:::o;62181:79::-;62289:11;;;;62337:14;;62384:15;;;;62414:13;;;:37;;-1:-1:-1;62431:20:0;;62414:37;:57;;;-1:-1:-1;62455:16:0;;62414:57;62410:150;;;81508:12;62488:4;:20;;:39;;;;62542:7;;;;62080:1002;:::o;62410:150::-;62570:23;62596:59;62616:4;:20;;;62638:16;81508:12;;81426:102;62638:16;62596:19;:59::i;:::-;62570:85;;62666:19;62790:15;;62763:11;62732:15;62701;:46;;;;:::i;:::-;:73;;;;:::i;:::-;:104;;;;:::i;:::-;62666:139;-1:-1:-1;62858:18:0;62872:4;62666:139;62858:18;:::i;:::-;62838:4;:17;;;:38;;;;:::i;:::-;62818:17;;;:58;62965:22;;;;62914:35;62941:8;62914:11;:35;:::i;:::-;:73;;;;:::i;:::-;62889:22;;;:98;81508:12;63000:20;;;:39;63057:17;;63069:4;;63057:17;;;;;62121:961;;;;;;62080:1002;:::o;63714:290::-;63793:114;-1:-1:-1;;;;;63800:3:0;63793:28;63836:10;63869:4;63889:7;63793:28;:114::i;:::-;63920:76;63944:7;63953;63962:12;63976:19;63920:23;:76::i;:::-;63714:290;;:::o;81639:345::-;81742:8;:15;81685:27;;81742:15;81780:22;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81780:22:0;;;;;;;;;;;;;;;;;81768:34;;81817:11;81813:164;81840:6;81834:3;:12;81813:164;;;81887:8;81896:3;81887:13;;;;;;;;:::i;:::-;;;;;;;;;;81870:30;;;;;;;;81887:13;;;;;;;81870:30;;-1:-1:-1;;;;;81870:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81887:13;81870:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:9;81880:3;81870:14;;;;;;;;:::i;:::-;;;;;;:30;;;;81949:16;81961:3;81949:11;:16::i;:::-;81915:50;;81918:9;81928:3;81918:14;;;;;;;;:::i;:::-;;;;;;;;;;;:27;;81915:50;81848:5;;81813:164;;;;81714:270;81639:345;:::o;54073:1064::-;39065:13;:11;:13::i;:::-;54208:16:::1;:14;:16::i;:::-;54204:72;;;54248:16;;-1:-1:-1::0;;;54248:16:0::1;;;;;;;;;;;54204:72;54292:23:::0;;54288:143:::1;;54332:37;54350:18;54332:17;:37::i;:::-;54288:143;;;54402:17;:15;:17::i;:::-;54443:21;54467:8;54476:4;54467:14;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;54518:12:::0;;54467:14;;-1:-1:-1;;;;;;54518:12:0::1;54546:21:::0;;;:45:::1;;-1:-1:-1::0;;;;;;54572:19:0;::::1;;::::0;;;:10:::1;:19;::::0;;;;;::::1;;54571:20;54546:45;54542:103;;;54615:18;;-1:-1:-1::0;;;54615:18:0::1;;;;;;;;;;;54542:103;54709:11;54691:4;:15;;;54673;;:33;;;;:::i;:::-;:47;;;;:::i;:::-;54655:15;:65:::0;54731:15:::1;::::0;::::1;:29:::0;;;54878:20;;;::::1;::::0;:63:::1;;-1:-1:-1::0;54921:20:0::1;::::0;::::1;::::0;81508:12;54902:39:::1;54878:63;54874:207;;;55017:15:::0;81508:12;54998:34:::1;:71;;55054:15;54998:71;;;81508:12:::0;55035:16:::1;54958:20;::::0;::::1;:111:::0;54874:207:::1;55111:4;55102:7;-1:-1:-1::0;;;;;55098:31:0::1;;55117:11;55098:31;;;;631:25:1::0;;619:2;604:18;;485:177;61788:179:0;61850:8;:15;61833:14;61876:84;61903:6;61897:3;:12;61876:84;;;61933:15;61944:3;61933:10;:15::i;:::-;61911:5;;61876:84;;59529:248;39065:13;:11;:13::i;:::-;59658:6:::1;59654:116;59674:6;:13;59670:1;:17;59654:116;;;-1:-1:-1::0;;;;;59709:21:0;::::1;;::::0;;;:9:::1;:21;::::0;;;;59731:9;;59744:14;;59709:21;59731:6;;59738:1;;59731:9;::::1;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;;;59709:32:0::1;::::0;;;::::1;::::0;;;;;;-1:-1:-1;59709:32:0;:49;;-1:-1:-1;;59709:49:0::1;::::0;::::1;;::::0;;;::::1;::::0;;-1:-1:-1;59689:3:0::1;59654:116;;72311:151:::0;72392:7;72419:14;;;:8;:14;;;;;;;;-1:-1:-1;;;;;72419:21:0;;;;;;;;;:35;;;72311:151;;;;;:::o;39854:103::-;39065:13;:11;:13::i;:::-;39919:30:::1;39946:1;39919:18;:30::i;:::-;39854:103::o:0;42322:235::-;41490:13;;37427:10;;-1:-1:-1;;;;;41490:13:0;42419:24;;42415:98;;42467:34;;-1:-1:-1;;;42467:34:0;;-1:-1:-1;;;;;940:32:1;;42467:34:0;;;922:51:1;895:18;;42467:34:0;776:203:1;42415:98:0;42523:26;42542:6;42523:18;:26::i;:::-;42364:193;42322:235::o;74341:1275::-;74465:14;;-1:-1:-1;;;74465:14:0;;;;;;;;;;;56231:186;39065:13;:11;:13::i;:::-;-1:-1:-1;;;;;56301:21:0;::::1;56297:74;;56346:13;;-1:-1:-1::0;;;56346:13:0::1;;;;;;;;;;;56297:74;56381:6;:28:::0;;-1:-1:-1;;;;;;56381:28:0::1;-1:-1:-1::0;;;;;56381:28:0;;;::::1;::::0;;;::::1;::::0;;56231:186::o;64166:462::-;64271:38;;-1:-1:-1;;;64271:38:0;;64303:4;64271:38;;;922:51:1;64247:21:0;;64278:5;-1:-1:-1;;;;;64271:23:0;;;;895:18:1;;64271:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64247:62;-1:-1:-1;64320:116:0;-1:-1:-1;;;;;64327:5:0;64320:30;64365:10;64398:4;64418:7;64320:30;:116::i;:::-;64470:38;;-1:-1:-1;;;64470:38:0;;64502:4;64470:38;;;922:51:1;64447:20:0;;64511:13;;-1:-1:-1;;;;;64477:5:0;64470:23;;;;895:18:1;;64470:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:54;;;;:::i;:::-;64447:77;;64537:83;64561:12;64575:7;64584:12;64598:21;64537:23;:83::i;66301:676::-;66413:115;-1:-1:-1;;;;;66420:4:0;66413:29;66457:10;66490:4;66510:7;66413:29;:115::i;:::-;66541:20;66564:19;66575:7;66564:10;:19::i;:::-;66541:42;-1:-1:-1;66617:21:0;66598:15;:40;;;;;;;;:::i;:::-;;66594:286;;66670:25;66682:12;66670:11;:25::i;:::-;66655:40;;66594:286;;;66736:20;66717:15;:39;;;;;;;;:::i;:::-;;66713:167;;66788:24;66799:12;66788:10;:24::i;66713:167::-;66892:77;66916:12;66930:7;66939:12;66953:15;66892:23;:77::i;82146:790::-;82287:13;;82224:31;;82287:13;82323:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;82380:8:0;:15;82311:40;;-1:-1:-1;82362:15:0;82406:523;82429:8;82425:1;:12;82406:523;;;82459:13;82475:6;82482:1;82475:9;;;;;;;;:::i;:::-;;;;;;;82459:25;;82531:7;82514:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;82499:9;82509:1;82499:12;;;;;;;;:::i;:::-;;;;;;:40;;;;82558:11;82554:364;82581:7;82575:3;:13;82554:364;;;82616:21;82640:13;;;:8;:13;;;;;;;;-1:-1:-1;;;;;82640:20:0;;;;;;;;;;82616:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82679:12;;:9;;82689:1;;82679:12;;;;;;:::i;:::-;;;;;;;82692:3;82679:17;;;;;;;;:::i;:::-;;;;;;;82697:1;82679:20;;;;;;;:::i;:::-;;;;:35;;;;;82756:5;:17;;;82733:9;82743:1;82733:12;;;;;;;;:::i;:::-;;;;;;;82746:3;82733:17;;;;;;;;:::i;:::-;;;;;;;82751:1;82733:20;;;;;;;:::i;:::-;;;;:40;82815:19;;;;82792:12;;:9;;82802:1;;82792:12;;;;;;:::i;:::-;;;;;;;82805:3;82792:17;;;;;;;;:::i;:::-;;;;;;;82810:1;82792:20;;;;;;;:::i;:::-;;;;:42;82876:26;82891:3;82896:5;82876:14;:26::i;:::-;82853:9;82863:1;82853:12;;;;;;;;:::i;:::-;;;;;;;82866:3;82853:17;;;;;;;;:::i;:::-;;;;;;;82871:1;82853:20;;;;;;;:::i;:::-;;;;:49;-1:-1:-1;82590:5:0;;82554:364;;;-1:-1:-1;;82439:3:0;;82406:523;;;;82257:679;;82146:790;;;:::o;61578:137::-;61653:7;61680:27;61695:4;61701:5;61680:14;:27::i;:::-;61673:34;61578:137;-1:-1:-1;;;61578:137:0:o;80801:410::-;39065:13;:11;:13::i;43027:178::-;39065:13;:11;:13::i;:::-;43101:21:::1;:29:::0;;-1:-1:-1;;;;;;43101:29:0::1;-1:-1:-1::0;;;;;43101:29:0;;::::1;::::0;;::::1;::::0;;;43175:14:::1;::::0;43146:51:::1;::::0;43101:29;;43175:14:::1;::::0;43146:51:::1;::::0;-1:-1:-1;;43146:51:0::1;43027:178:::0;:::o;55469:245::-;55553:8;;55516:4;;55576:14;;;;;:46;;-1:-1:-1;55613:9:0;81508:12;55594:16;81426:102;43647:199;43737:5;-1:-1:-1;;;;;43737:11:0;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;43723:27:0;:10;-1:-1:-1;;;;;43723:27:0;;43719:81;;43774:14;;-1:-1:-1;;;43774:14:0;;;;;;;;;;;43719:81;43810:5;-1:-1:-1;;;;;43810:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43647:199;:::o;41710:181::-;39065:13;:11;:13::i;:::-;41800::::1;:24:::0;;-1:-1:-1;;;;;41800:24:0;::::1;-1:-1:-1::0;;;;;;41800:24:0;;::::1;::::0;::::1;::::0;;;41865:7:::1;39225::::0;39252:6;-1:-1:-1;;;;;39252:6:0;;39179:87;41865:7:::1;-1:-1:-1::0;;;;;41840:43:0::1;;;;;;;;;;;41710:181:::0;:::o;57858:420::-;39065:13;:11;:13::i;:::-;57942:16:::1;:14;:16::i;:::-;57938:72;;;57982:16;;-1:-1:-1::0;;;57982:16:0::1;;;;;;;;;;;57938:72;58042:4;58024:15;:22;:51;;;;58068:7;58050:15;:25;58024:51;58020:114;;;58099:23;;-1:-1:-1::0;;;58099:23:0::1;;;;;;;;;;;58020:114;58144:17;:15;:17::i;:::-;58195:14;::::0;58177:50:::1;::::0;;22889:25:1;;;22945:2;22930:18;;22923:34;;;58177:50:0::1;::::0;22862:18:1;58177:50:0::1;;;;;;;58238:14;:32:::0;57858:420::o;83106:533::-;83239:13;;83180:27;;83239:13;83274:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;83328:8:0;:15;83263:36;;-1:-1:-1;83310:15:0;83354:278;83377:8;83373:1;:12;83354:278;;;83407:13;83423:6;83430:1;83423:9;;;;;;;;:::i;:::-;;;;;;;83407:25;;83475:7;83461:22;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;83461:22:0;;83447:8;83456:1;83447:11;;;;;;;;:::i;:::-;;;;;;:36;;;;83502:11;83498:123;83525:7;83519:3;:13;83498:123;;;83579:26;83594:3;83599:5;83579:14;:26::i;:::-;83560:8;83569:1;83560:11;;;;;;;;:::i;:::-;;;;;;;83572:3;83560:16;;;;;;;;:::i;:::-;;;;;;;;;;:45;83534:5;;83498:123;;;-1:-1:-1;;83387:3:0;;83354:278;;78925:196;78981:7;-1:-1:-1;;;;;79015:5:0;79008:34;;;79057:20;79085:7;79094;39225;39252:6;-1:-1:-1;;;;;39252:6:0;;39179:87;79094:7;79057:45;;-1:-1:-1;;;;;;79057:45:0;;;;;;;-1:-1:-1;;;;;940:32:1;;;79057:45:0;;;922:51:1;895:18;;79057:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79008:105;;;;;;;;;;;;;631:25:1;;619:2;604:18;;485:177;79008:105:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;79598:238::-;79653:7;-1:-1:-1;;;;;79699:17:0;79680:52;;;79747:45;79800:7;79809;39225;39252:6;-1:-1:-1;;;;;39252:6:0;;39179:87;67288:777;67437:20;;67474:15;:38;;;;;;;;:::i;:::-;;67470:392;;67544:19;67555:7;67544:10;:19::i;:::-;67529:34;;67470:392;;;67604:21;67585:15;:40;;;;;;;;:::i;:::-;;67581:281;;67657:23;67672:7;67657:14;:23::i;67581:281::-;67721:20;67702:15;:39;;;;;;;;:::i;:::-;;67698:164;;67773:21;67786:7;67773:12;:21::i;67698:164::-;67968:13;67938:27;67953:12;67938;:27;:::i;:::-;:43;;;;:::i;:::-;67923:58;;67994:63;68003:8;:25;68012:15;68003:25;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;68030:12;68044;67994:8;:63::i;14779:190::-;14907:53;;-1:-1:-1;;;;;23188:32:1;;;14907:53:0;;;23170:51:1;23257:32;;;23237:18;;;23230:60;23306:18;;;23299:34;;;14880:81:0;;14900:5;;14922:18;;;;;23143::1;;14907:53:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;14907:53:0;;;;;;;;;;;14880:19;:81::i;68276:1797::-;68378:16;:14;:16::i;:::-;68374:72;;;68418:16;;-1:-1:-1;;;68418:16:0;;;;;;;;;;;68374:72;68460:14;68478:1;68460:19;68456:75;;68503:16;;-1:-1:-1;;;68503:16:0;;;;;;;;;;;68456:75;68560:14;68545:12;:29;68541:97;;;68598:28;;-1:-1:-1;;;68598:28:0;;;;;631:25:1;;;604:18;;68598:28:0;485:177:1;68541:97:0;68650:21;68674:8;68683:4;68674:14;;;;;;;;:::i;:::-;;;;;;;;;68723;;;:8;:14;;;;;;68738:10;68723:26;;;;;;;68674:14;;;;;;;;-1:-1:-1;68760:16:0;68732:4;68760:10;:16::i;:::-;68810:11;;68986:15;;;;68952:18;;;;68894:22;;;;68932:4;;68868:48;;68810:11;68868:48;:::i;:::-;:68;;;;:::i;:::-;:102;;;;:::i;:::-;:133;;;;:::i;:::-;68834:18;;;:167;69073:18;;;;:12;:18;;;;;;:33;;69094:12;;69073:33;:::i;:::-;69052:18;;;;:12;:18;;;;;:54;69208:29;69225:12;69208:14;:29;:::i;:::-;69191:46;;69323:14;69302:4;:18;;;:35;;;;:::i;:::-;69281:18;;;:56;69369:18;;;;:35;;69390:14;;69369:35;:::i;:::-;69348:18;;;:56;69486:17;;69506:4;;69471:32;;:12;:32;:::i;:::-;:39;;;;:::i;:::-;69456:54;;69561:12;69542:4;:16;;;:31;;;;:::i;:::-;69523:16;;;:50;69603:16;;;;:31;;69622:12;;69603:31;:::i;:::-;69584:16;;;:50;69776:12;69746:27;69759:14;69746:10;:27;:::i;:::-;:42;;;;:::i;:::-;69801:24;;;69850:11;;;;69733:55;;-1:-1:-1;69881:12:0;;69850:28;;69864:14;;69850:28;:::i;:::-;:43;;;;:::i;:::-;69836:11;;;:57;69950:22;;;;69988:4;;69924:48;;:10;:48;:::i;:::-;:68;;;;:::i;:::-;69906:15;;;:86;70010:55;;;22889:25:1;;;22945:2;22930:18;;22923:34;;;70030:4:0;;70018:10;;70010:55;;22862:18:1;70010:55:0;22715:248:1;39344:166:0;39225:7;39252:6;-1:-1:-1;;;;;39252:6:0;37427:10;39404:23;39400:103;;39451:40;;-1:-1:-1;;;39451:40:0;;37427:10;39451:40;;;922:51:1;895:18;;39451:40:0;776:203:1;14372:162:0;14482:43;;-1:-1:-1;;;;;18723:32:1;;;14482:43:0;;;18705:51:1;18772:18;;;18765:34;;;14455:71:0;;14475:5;;14497:14;;;;;18678:18:1;;14482:43:0;18446:359:1;58944:345:0;59064:8;;59024:7;;59087:14;;59083:77;;59124:24;59133:3;59138:9;59124:8;:24::i;:::-;59118:30;;59083:77;59180:5;59174:3;:11;59170:112;;;59210:11;59216:5;59210:3;:11;:::i;:::-;59209:20;;59225:4;59209:20;:::i;:::-;59202:27;;;;;59170:112;59269:1;59262:8;;;;;60538:842;60596:25;60623:20;60656:21;60680:8;60689:4;60680:14;;;;;;;;:::i;:::-;;;;;;;;;;;60656:38;;60727:4;:22;;;60707:42;;60775:4;:17;;;60760:32;;60805:16;60824:4;:11;;;60805:30;;60869:4;:20;;;60850:16;81508:12;;81426:102;60850:16;:39;:56;;;;-1:-1:-1;60893:13:0;;;60850:56;60846:527;;;60923:23;60949:59;60969:4;:20;;;60991:16;81508:12;;81426:102;60949:59;60923:85;;61025:19;61168:15;;61133:4;:15;;;61099:14;;61064:15;:49;;;;:::i;:::-;:84;;;;:::i;:::-;:119;;;;:::i;:::-;61025:158;-1:-1:-1;61230:18:0;61244:4;61025:158;61230:18;:::i;:::-;61215:33;;:12;:33;:::i;:::-;61200:48;-1:-1:-1;61344:17:0;61285:39;61316:8;61285:11;:39;:::i;:::-;:76;;;;:::i;:::-;61265:96;;60908:465;;60846:527;60645:735;;60538:842;;;:::o;42081:156::-;42171:13;42164:20;;-1:-1:-1;;;;;;42164:20:0;;;42195:34;42220:8;42195:24;:34::i;78607:168::-;78713:29;;-1:-1:-1;;;78713:29:0;;;;;631:25:1;;;78662:7:0;;78719:4;-1:-1:-1;;;;;78713:20:0;;;;604:18:1;;78713:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;78760:7:0;;78607:168;-1:-1:-1;;;;78607:168:0:o;59975:358::-;60051:7;60095:14;;;:8;:14;;;;;;;;-1:-1:-1;;;;;60095:21:0;;;;;;;;;60051:7;60159:17;60104:4;60159:11;:17::i;:::-;60127:49;;;60310:4;:15;;;60276:4;:18;;;60256:4;60223:17;60196:4;:11;;;:44;;;;:::i;:::-;:64;;;;:::i;:::-;:98;;;;:::i;:::-;:129;;;;:::i;:::-;60189:136;59975:358;-1:-1:-1;;;;;59975:358:0:o;80310:165::-;80424:43;;-1:-1:-1;;;80424:43:0;;;;;23518:25:1;;;80461:4:0;23559:18:1;;;23552:60;80365:7:0;;80430:4;-1:-1:-1;;;;;80424:19:0;;;;23491:18:1;;80424:43:0;;;;;;;;;;;;;;;;;;;;;;;;79274:171;79408:29;;-1:-1:-1;;;79408:29:0;;;;;631:25:1;;;79333:7:0;;79416:6;-1:-1:-1;;;;;79408:20:0;;;;604:18:1;;79408:29:0;485:177:1;79991:166:0;80122:27;;-1:-1:-1;;;80122:27:0;;;;;631:25:1;;;80048:7:0;;80129:5;-1:-1:-1;;;;;80122:18:0;;;;604::1;;80122:27:0;485:177:1;17183:638:0;17607:23;17633:33;-1:-1:-1;;;;;17633:27:0;;17661:4;17633:27;:33::i;:::-;17607:59;;17681:10;:17;17702:1;17681:22;;:57;;;;;17719:10;17708:30;;;;;;;;;;;;:::i;:::-;17707:31;17681:57;17677:137;;;17762:40;;-1:-1:-1;;;17762:40:0;;-1:-1:-1;;;;;940:32:1;;17762:40:0;;;922:51:1;895:18;;17762:40:0;776:203:1;21434:106:0;21492:7;21523:1;21519;:5;:13;;21531:1;21519:13;;;-1:-1:-1;21527:1:0;;21434:106;-1:-1:-1;21434:106:0:o;40492:191::-;40566:16;40585:6;;-1:-1:-1;;;;;40602:17:0;;;-1:-1:-1;;;;;;40602:17:0;;;;;;40635:40;;40585:6;;;;;;;40635:40;;40566:16;40635:40;40555:128;40492:191;:::o;9687:153::-;9762:12;9794:38;9816:6;9824:4;9830:1;9762:12;10420;10434:23;10461:6;-1:-1:-1;;;;;10461:11:0;10480:5;10487:4;10461:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10419:73;;;;10510:55;10537:6;10545:7;10554:10;10510:26;:55::i;:::-;10503:62;10175:398;-1:-1:-1;;;;;;10175:398:0:o;11651:597::-;11799:12;11829:7;11824:417;;11853:19;11861:10;11853:7;:19::i;:::-;11824:417;;;12081:17;;:22;:49;;;;-1:-1:-1;;;;;;12107:18:0;;;:23;12081:49;12077:121;;;12158:24;;-1:-1:-1;;;12158:24:0;;-1:-1:-1;;;;;940:32:1;;12158:24:0;;;922:51:1;895:18;;12158:24:0;776:203:1;12077:121:0;-1:-1:-1;12219:10:0;12212:17;;12801:528;12934:17;;:21;12930:392;;13166:10;13160:17;13223:15;13210:10;13206:2;13202:19;13195:44;12930:392;13293:17;;-1:-1:-1;;;13293:17:0;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:466:1:-;91:6;99;107;160:2;148:9;139:7;135:23;131:32;128:52;;;176:1;173;166:12;128:52;-1:-1:-1;;221:23:1;;;341:2;326:18;;313:32;;-1:-1:-1;444:2:1;429:18;;;416:32;;14:466;-1:-1:-1;14:466:1:o;1176:226::-;1235:6;1288:2;1276:9;1267:7;1263:23;1259:32;1256:52;;;1304:1;1301;1294:12;1256:52;-1:-1:-1;1349:23:1;;1176:226;-1:-1:-1;1176:226:1:o;1407:250::-;1492:1;1502:113;1516:6;1513:1;1510:13;1502:113;;;1592:11;;;1586:18;1573:11;;;1566:39;1538:2;1531:10;1502:113;;;-1:-1:-1;;1649:1:1;1631:16;;1624:27;1407:250::o;1662:271::-;1704:3;1742:5;1736:12;1769:6;1764:3;1757:19;1785:76;1854:6;1847:4;1842:3;1838:14;1831:4;1824:5;1820:16;1785:76;:::i;:::-;1915:2;1894:15;-1:-1:-1;;1890:29:1;1881:39;;;;1922:4;1877:50;;1662:271;-1:-1:-1;;1662:271:1:o;1938:932::-;2381:1;2377;2372:3;2368:11;2364:19;2356:6;2352:32;2341:9;2334:51;2450:1;2446;2441:3;2437:11;2433:19;2425:6;2421:32;2416:2;2405:9;2401:18;2394:60;2490:6;2485:2;2474:9;2470:18;2463:34;2533:6;2528:2;2517:9;2513:18;2506:34;2577:6;2571:3;2560:9;2556:19;2549:35;2621:6;2615:3;2604:9;2600:19;2593:35;2665:6;2659:3;2648:9;2644:19;2637:35;2709:6;2703:3;2692:9;2688:19;2681:35;2753:6;2747:3;2736:9;2732:19;2725:35;2797:3;2791;2780:9;2776:19;2769:32;2315:4;2818:46;2859:3;2848:9;2844:19;2836:6;2818:46;:::i;:::-;2810:54;1938:932;-1:-1:-1;;;;;;;;;;;;1938:932:1:o;2875:346::-;2943:6;2951;3004:2;2992:9;2983:7;2979:23;2975:32;2972:52;;;3020:1;3017;3010:12;2972:52;-1:-1:-1;;3065:23:1;;;3185:2;3170:18;;;3157:32;;-1:-1:-1;2875:346:1:o;3226:131::-;-1:-1:-1;;;;;3301:31:1;;3291:42;;3281:70;;3347:1;3344;3337:12;3362:247;3421:6;3474:2;3462:9;3453:7;3449:23;3445:32;3442:52;;;3490:1;3487;3480:12;3442:52;3529:9;3516:23;3548:31;3573:5;3548:31;:::i;3614:629::-;3700:6;3708;3716;3724;3777:3;3765:9;3756:7;3752:23;3748:33;3745:53;;;3794:1;3791;3784:12;3745:53;3839:23;;;-1:-1:-1;3938:2:1;3923:18;;3910:32;3951:33;3910:32;3951:33;:::i;:::-;4003:7;-1:-1:-1;4062:2:1;4047:18;;4034:32;4075:33;4034:32;4075:33;:::i;:::-;3614:629;;;;-1:-1:-1;4127:7:1;;4207:2;4192:18;4179:32;;-1:-1:-1;;3614:629:1:o;4248:367::-;4316:6;4324;4377:2;4365:9;4356:7;4352:23;4348:32;4345:52;;;4393:1;4390;4383:12;4345:52;4438:23;;;-1:-1:-1;4537:2:1;4522:18;;4509:32;4550:33;4509:32;4550:33;:::i;:::-;4602:7;4592:17;;;4248:367;;;;;:::o;4620:829::-;4724:6;4732;4740;4748;4756;4764;4817:3;4805:9;4796:7;4792:23;4788:33;4785:53;;;4834:1;4831;4824:12;4785:53;-1:-1:-1;;4879:23:1;;;4999:2;4984:18;;4971:32;;-1:-1:-1;5102:2:1;5087:18;;5074:32;;5205:2;5190:18;;5177:32;;-1:-1:-1;5308:3:1;5293:19;;5280:33;;-1:-1:-1;5412:3:1;5397:19;5384:33;;-1:-1:-1;4620:829:1;-1:-1:-1;4620:829:1:o;5454:155::-;5534:20;;5583:1;5573:12;;5563:40;;5599:1;5596;5589:12;5563:40;5454:155;;;:::o;5614:217::-;5692:6;5745:2;5733:9;5724:7;5720:23;5716:32;5713:52;;;5761:1;5758;5751:12;5713:52;5784:41;5815:9;5784:41;:::i;5836:127::-;5897:10;5892:3;5888:20;5885:1;5878:31;5928:4;5925:1;5918:15;5952:4;5949:1;5942:15;5968:275;6039:2;6033:9;6104:2;6085:13;;-1:-1:-1;;6081:27:1;6069:40;;6139:18;6124:34;;6160:22;;;6121:62;6118:88;;;6186:18;;:::i;:::-;6222:2;6215:22;5968:275;;-1:-1:-1;5968:275:1:o;6248:1263::-;6353:6;6361;6369;6377;6385;6438:3;6426:9;6417:7;6413:23;6409:33;6406:53;;;6455:1;6452;6445:12;6406:53;6500:23;;;-1:-1:-1;6599:2:1;6584:18;;6571:32;6612:33;6571:32;6612:33;:::i;:::-;6664:7;-1:-1:-1;6722:2:1;6707:18;;6694:32;6749:18;6738:30;;6735:50;;;6781:1;6778;6771:12;6735:50;6804:22;;6857:4;6849:13;;6845:27;-1:-1:-1;6835:55:1;;6886:1;6883;6876:12;6835:55;6926:2;6913:16;6952:18;6944:6;6941:30;6938:56;;;6974:18;;:::i;:::-;7016:57;7063:2;7040:17;;-1:-1:-1;;7036:31:1;7069:2;7032:40;7016:57;:::i;:::-;7096:6;7089:5;7082:21;7144:7;7139:2;7130:6;7126:2;7122:15;7118:24;7115:37;7112:57;;;7165:1;7162;7155:12;7112:57;7220:6;7215:2;7211;7207:11;7202:2;7195:5;7191:14;7178:49;7272:1;7247:18;;;7267:2;7243:27;7236:38;;;;6248:1263;;;;-1:-1:-1;7251:5:1;;7371:2;7356:18;;7343:32;;-1:-1:-1;7474:3:1;7459:19;7446:33;;6248:1263;-1:-1:-1;;;6248:1263:1:o;7516:1552::-;7710:4;7758:2;7747:9;7743:18;7788:2;7777:9;7770:21;7811:6;7846;7840:13;7877:6;7869;7862:22;7915:2;7904:9;7900:18;7893:25;;7977:2;7967:6;7964:1;7960:14;7949:9;7945:30;7941:39;7927:53;;8015:2;8007:6;8003:15;8036:1;8046:993;8060:6;8057:1;8054:13;8046:993;;;8125:22;;;-1:-1:-1;;8121:36:1;8109:49;;8181:13;;8226:9;;-1:-1:-1;;;;;733:31:1;721:44;;8291:2;8287;8283:11;8277:18;8308:49;8353:2;8345:6;8341:15;8327:12;-1:-1:-1;;;;;733:31:1;721:44;;667:104;8308:49;;8408:2;8404;8400:11;8394:18;8389:2;8381:6;8377:15;8370:43;8466:4;8462:2;8458:13;8452:20;8445:4;8437:6;8433:17;8426:47;8526:4;8522:2;8518:13;8512:20;8505:4;8497:6;8493:17;8486:47;8586:4;8582:2;8578:13;8572:20;8565:4;8557:6;8553:17;8546:47;8646:4;8642:2;8638:13;8632:20;8625:4;8617:6;8613:17;8606:47;8706:4;8702:2;8698:13;8692:20;8685:4;8677:6;8673:17;8666:47;8768:6;8764:2;8760:15;8754:22;8745:6;8737;8733:19;8726:51;8826:6;8822:2;8818:15;8812:22;8790:44;;8875:6;8866;8858;8854:19;8847:35;8905:54;8951:6;8943;8939:19;8923:14;8905:54;:::i;:::-;8895:64;-1:-1:-1;;8994:2:1;9017:12;;;;8982:15;;;;;8082:1;8075:9;8046:993;;;-1:-1:-1;9056:6:1;;7516:1552;-1:-1:-1;;;;;;7516:1552:1:o;9073:587::-;9159:6;9167;9175;9183;9236:3;9224:9;9215:7;9211:23;9207:33;9204:53;;;9253:1;9250;9243:12;9204:53;-1:-1:-1;;9298:23:1;;;9418:2;9403:18;;9390:32;;-1:-1:-1;9521:2:1;9506:18;;9493:32;;9624:2;9609:18;9596:32;;-1:-1:-1;9073:587:1;-1:-1:-1;9073:587:1:o;9665:796::-;9719:5;9772:3;9765:4;9757:6;9753:17;9749:27;9739:55;;9790:1;9787;9780:12;9739:55;9830:6;9817:20;9860:18;9852:6;9849:30;9846:56;;;9882:18;;:::i;:::-;9928:6;9925:1;9921:14;9955:30;9979:4;9975:2;9971:13;9955:30;:::i;:::-;10021:19;;;10065:4;10097:15;;;10093:26;;;10056:14;;;;10131:15;;;10128:35;;;10159:1;10156;10149:12;10128:35;10195:4;10187:6;10183:17;10172:28;;10209:221;10225:6;10220:3;10217:15;10209:221;;;10307:3;10294:17;10324:31;10349:5;10324:31;:::i;:::-;10368:18;;10415:4;10242:14;;;;10406;;;;10209:221;;10466:118;10552:5;10545:13;10538:21;10531:5;10528:32;10518:60;;10574:1;10571;10564:12;10589:618;10688:6;10696;10704;10757:2;10745:9;10736:7;10732:23;10728:32;10725:52;;;10773:1;10770;10763:12;10725:52;10812:9;10799:23;10831:31;10856:5;10831:31;:::i;:::-;10881:5;-1:-1:-1;10937:2:1;10922:18;;10909:32;10964:18;10953:30;;10950:50;;;10996:1;10993;10986:12;10950:50;11019:61;11072:7;11063:6;11052:9;11048:22;11019:61;:::i;:::-;11009:71;;;11132:2;11121:9;11117:18;11104:32;11145:30;11167:7;11145:30;:::i;:::-;11194:7;11184:17;;;10589:618;;;;;:::o;11212:367::-;11280:6;11288;11341:2;11329:9;11320:7;11316:23;11312:32;11309:52;;;11357:1;11354;11347:12;11309:52;11396:9;11383:23;11415:31;11440:5;11415:31;:::i;:::-;11465:5;11543:2;11528:18;;;;11515:32;;-1:-1:-1;;;11212:367:1:o;12052:451::-;12148:6;12156;12164;12217:2;12205:9;12196:7;12192:23;12188:32;12185:52;;;12233:1;12230;12223:12;12185:52;12278:23;;;-1:-1:-1;12398:2:1;12383:18;;12370:32;;-1:-1:-1;12447:50:1;12493:2;12478:18;;12447:50;:::i;:::-;12437:60;;12052:451;;;;;:::o;12508:348::-;12592:6;12645:2;12633:9;12624:7;12620:23;12616:32;12613:52;;;12661:1;12658;12651:12;12613:52;12701:9;12688:23;12734:18;12726:6;12723:30;12720:50;;;12766:1;12763;12756:12;12720:50;12789:61;12842:7;12833:6;12822:9;12818:22;12789:61;:::i;:::-;12779:71;12508:348;-1:-1:-1;;;;12508:348:1:o;12861:1659::-;13099:4;13147:2;13136:9;13132:18;13177:2;13166:9;13159:21;13200:6;13235;13229:13;13266:6;13258;13251:22;13304:2;13293:9;13289:18;13282:25;;13366:2;13356:6;13353:1;13349:14;13338:9;13334:30;13330:39;13316:53;;13404:2;13396:6;13392:15;13425:1;13435:1056;13449:6;13446:1;13443:13;13435:1056;;;13514:22;;;-1:-1:-1;;13510:36:1;13498:49;;13570:13;;13644:9;;13666:24;;;13724:2;13756:11;;;;13712:15;;;13791:1;13805:578;13821:8;13816:3;13813:17;13805:578;;;13894:15;;13939:5;14038:1;14056:225;14072:4;14067:3;14064:13;14056:225;;;14153:15;;14139:30;;14210:2;14246:17;;;;14199:14;;;;14096:1;14087:11;14056:225;;;-1:-1:-1;;;14366:2:1;14352:17;;;;;14318:4;14307:16;;;;;13849:1;13840:11;13805:578;;;-1:-1:-1;14406:5:1;;-1:-1:-1;;;14446:2:1;14469:12;;;;14434:15;;;;;13471:1;13464:9;13435:1056;;14525:388;14593:6;14601;14654:2;14642:9;14633:7;14629:23;14625:32;14622:52;;;14670:1;14667;14660:12;14622:52;14709:9;14696:23;14728:31;14753:5;14728:31;:::i;:::-;14778:5;-1:-1:-1;14835:2:1;14820:18;;14807:32;14848:33;14807:32;14848:33;:::i;15145:331::-;15232:6;15240;15293:2;15281:9;15272:7;15268:23;15264:32;15261:52;;;15309:1;15306;15299:12;15261:52;15354:23;;;-1:-1:-1;15420:50:1;15466:2;15451:18;;15420:50;:::i;:::-;15410:60;;15145:331;;;;;:::o;15758:1244::-;15950:4;15998:2;15987:9;15983:18;16028:2;16017:9;16010:21;16051:6;16086;16080:13;16117:6;16109;16102:22;16155:2;16144:9;16140:18;16133:25;;16217:2;16207:6;16204:1;16200:14;16189:9;16185:30;16181:39;16167:53;;16255:2;16247:6;16243:15;16276:1;16286:687;16300:6;16297:1;16294:13;16286:687;;;16365:22;;;-1:-1:-1;;16361:36:1;16349:49;;16421:13;;16495:9;;16517:24;;;16575:2;16607:11;;;;16563:15;;;16642:1;16656:209;16672:8;16667:3;16664:17;16656:209;;;16749:15;;16735:30;;16802:2;16834:17;;;;16791:14;;;;16700:1;16691:11;16656:209;;;-1:-1:-1;16888:5:1;;-1:-1:-1;;;16928:2:1;16951:12;;;;16916:15;;;;;16322:1;16315:9;16286:687;;17007:127;17068:10;17063:3;17059:20;17056:1;17049:31;17099:4;17096:1;17089:15;17123:4;17120:1;17113:15;17139:127;17200:10;17195:3;17191:20;17188:1;17181:31;17231:4;17228:1;17221:15;17255:4;17252:1;17245:15;17271:380;17350:1;17346:12;;;;17393;;;17414:61;;17468:4;17460:6;17456:17;17446:27;;17414:61;17521:2;17513:6;17510:14;17490:18;17487:38;17484:161;;17567:10;17562:3;17558:20;17555:1;17548:31;17602:4;17599:1;17592:15;17630:4;17627:1;17620:15;17484:161;;17271:380;;;:::o;17656:127::-;17717:10;17712:3;17708:20;17705:1;17698:31;17748:4;17745:1;17738:15;17772:4;17769:1;17762:15;17788:125;17853:9;;;17874:10;;;17871:36;;;17887:18;;:::i;17918:168::-;17991:9;;;18022;;18039:15;;;18033:22;;18019:37;18009:71;;18060:18;;:::i;18091:217::-;18131:1;18157;18147:132;;18201:10;18196:3;18192:20;18189:1;18182:31;18236:4;18233:1;18226:15;18264:4;18261:1;18254:15;18147:132;-1:-1:-1;18293:9:1;;18091:217::o;18313:128::-;18380:9;;;18401:11;;;18398:37;;;18415:18;;:::i;18810:245::-;18877:6;18930:2;18918:9;18909:7;18905:23;18901:32;18898:52;;;18946:1;18943;18936:12;18898:52;18978:9;18972:16;18997:28;19019:5;18997:28;:::i;19186:518::-;19288:2;19283:3;19280:11;19277:421;;;19324:5;19321:1;19314:16;19368:4;19365:1;19355:18;19438:2;19426:10;19422:19;19419:1;19415:27;19409:4;19405:38;19474:4;19462:10;19459:20;19456:47;;;-1:-1:-1;19497:4:1;19456:47;19552:2;19547:3;19543:12;19540:1;19536:20;19530:4;19526:31;19516:41;;19607:81;19625:2;19618:5;19615:13;19607:81;;;19684:1;19670:16;;19651:1;19640:13;19607:81;;19880:1299;20006:3;20000:10;20033:18;20025:6;20022:30;20019:56;;;20055:18;;:::i;:::-;20084:97;20174:6;20134:38;20166:4;20160:11;20134:38;:::i;:::-;20128:4;20084:97;:::i;:::-;20230:4;20261:2;20250:14;;20278:1;20273:649;;;;20966:1;20983:6;20980:89;;;-1:-1:-1;21035:19:1;;;21029:26;20980:89;-1:-1:-1;;19837:1:1;19833:11;;;19829:24;19825:29;19815:40;19861:1;19857:11;;;19812:57;21082:81;;20243:930;;20273:649;19133:1;19126:14;;;19170:4;19157:18;;-1:-1:-1;;20309:20:1;;;20427:222;20441:7;20438:1;20435:14;20427:222;;;20523:19;;;20517:26;20502:42;;20630:4;20615:20;;;;20583:1;20571:14;;;;20457:12;20427:222;;;20431:3;20677:6;20668:7;20665:19;20662:201;;;20738:19;;;20732:26;-1:-1:-1;;20821:1:1;20817:14;;;20833:3;20813:24;20809:37;20805:42;20790:58;20775:74;;20662:201;-1:-1:-1;;;;20909:1:1;20893:14;;;20889:22;20876:36;;-1:-1:-1;19880:1299:1:o;21184:184::-;21254:6;21307:2;21295:9;21286:7;21282:23;21278:32;21275:52;;;21323:1;21320;21313:12;21275:52;-1:-1:-1;21346:16:1;;21184:184;-1:-1:-1;21184:184:1:o;22459:251::-;22529:6;22582:2;22570:9;22561:7;22557:23;22553:32;22550:52;;;22598:1;22595;22588:12;22550:52;22630:9;22624:16;22649:31;22674:5;22649:31;:::i;23623:287::-;23752:3;23790:6;23784:13;23806:66;23865:6;23860:3;23853:4;23845:6;23841:17;23806:66;:::i;:::-;23888:16;;;;;23623:287;-1:-1:-1;;23623:287:1:o
Swarm Source
ipfs://2a9096c7b91493f04491379bf7799f31bb09e5510bcf8f08f751a226d98ac789
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.