Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
Latest 25 from a total of 130 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Claim | 19309221 | 191 days ago | IN | 0 ETH | 0.00217184 | ||||
Claim | 19178994 | 209 days ago | IN | 0 ETH | 0.00320785 | ||||
Unstake And Clai... | 18139392 | 355 days ago | IN | 0 ETH | 0.00142808 | ||||
Unstake And Clai... | 18139204 | 355 days ago | IN | 0 ETH | 0.00185391 | ||||
Emergency Unstak... | 18090857 | 362 days ago | IN | 0 ETH | 0.00137304 | ||||
Emergency Unstak... | 17798303 | 402 days ago | IN | 0 ETH | 0.00172414 | ||||
Unstake And Clai... | 17460443 | 450 days ago | IN | 0 ETH | 0.00296196 | ||||
Unstake And Clai... | 17460159 | 450 days ago | IN | 0 ETH | 0.00242091 | ||||
Unstake And Clai... | 17460157 | 450 days ago | IN | 0 ETH | 0.00246486 | ||||
Unstake And Clai... | 17460151 | 450 days ago | IN | 0 ETH | 0.00300074 | ||||
Unstake And Clai... | 17460149 | 450 days ago | IN | 0 ETH | 0.00273432 | ||||
Unstake And Clai... | 17460146 | 450 days ago | IN | 0 ETH | 0.00275429 | ||||
Unstake And Clai... | 17460140 | 450 days ago | IN | 0 ETH | 0.0024891 | ||||
Stake | 17433236 | 454 days ago | IN | 0 ETH | 0.01253252 | ||||
Claim | 17418075 | 456 days ago | IN | 0 ETH | 0.00146434 | ||||
Unstake And Clai... | 17375497 | 462 days ago | IN | 0 ETH | 0.00545336 | ||||
Claim | 17375496 | 462 days ago | IN | 0 ETH | 0.00267723 | ||||
Unstake And Clai... | 17355350 | 465 days ago | IN | 0 ETH | 0.00677327 | ||||
Stake | 17354918 | 465 days ago | IN | 0 ETH | 0.00985528 | ||||
Extend Staking P... | 17352352 | 465 days ago | IN | 0 ETH | 0.00063892 | ||||
Claim | 17352140 | 465 days ago | IN | 0 ETH | 0.00169434 | ||||
Claim | 17352139 | 465 days ago | IN | 0 ETH | 0.00173885 | ||||
Claim | 17349485 | 466 days ago | IN | 0 ETH | 0.00173888 | ||||
Claim | 17345428 | 466 days ago | IN | 0 ETH | 0.00192015 | ||||
Unstake And Clai... | 17341597 | 467 days ago | IN | 0 ETH | 0.0056654 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
RibbitStaking
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-05-20 */ // File: @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) 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(errorMessage); } } } // File: @openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); } // File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File: @openzeppelin/contracts/security/ReentrancyGuard.sol // OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // File: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. 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 + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * 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 + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * 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 + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * 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 10, 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 + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/access/IAccessControl.sol // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; } // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/contracts/access/AccessControl.sol // OpenZeppelin Contracts (last updated v4.8.0) (access/AccessControl.sol) pragma solidity ^0.8.0; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(account), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } } // File: @openzeppelin/contracts/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); } // File: RibbitStaking.sol pragma solidity ^0.8.0; contract RibbitStaking is IERC721Receiver, AccessControl, ReentrancyGuard { using SafeERC20 for IERC20; bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE"); IERC20 public rewardToken; IERC721 public stakeToken; address public admin; uint256 public endTime; uint256 public rewardRate; uint256 public lastUpdateTime; uint256 private rewardsPerTokenStored; uint256 public totalStakedSupply; mapping(address => uint256) public userRewardPerTokenPaids; mapping(uint256 => StakeInfo) public stakeInfo; // token id => staking position info mapping(address => uint256[]) private tokensStaked; // user address => array of token ids staked mapping(uint256 => uint256) public tokenIdToIndex; // token id => index in tokensStaked array mapping(address => uint256) public userUnclaimedRewards; struct StakeInfo { uint256 amount; uint256 stakeTime; //time at which the NFT was staked address staker; } constructor(address _stakeToken, address _rewardToken, address _admin, uint256 _endTime, uint256 _rewardRate) { require(_stakeToken != address(0), "NFT contract address cannot be 0"); require(_rewardToken != address(0), "Reward token address cannot be 0"); require(_admin != address(0), "Admin address cannot be 0"); require(_rewardRate > 0, "Reward rate must be greater than 0"); stakeToken = IERC721(_stakeToken); rewardToken = IERC20(_rewardToken); admin = _admin; endTime = _endTime; rewardRate = _rewardRate; _setupRole(ADMIN_ROLE, _admin); } function initialize() public onlyAdmin { require(lastUpdateTime == 0, "Staking already initialized"); lastUpdateTime = block.timestamp; } //User functionality function stake(uint256[] calldata tokenIds) public nonReentrant { require(tokenIds.length != 0, "Staking: No tokenIds provided"); require(lastUpdateTime != 0, "Staking: Not yet initialized"); updateRewards(msg.sender); for (uint256 i = 0; i < tokenIds.length; i++) { require(stakeInfo[tokenIds[i]].staker == address(0), "Staking: Token already staked"); stakeToken.safeTransferFrom(msg.sender, address(this), tokenIds[i]); stakeInfo[tokenIds[i]] = StakeInfo( 1, block.timestamp, msg.sender ); tokensStaked[msg.sender].push(tokenIds[i]); tokenIdToIndex[tokenIds[i]] = tokensStaked[msg.sender].length - 1; } totalStakedSupply += tokenIds.length; } function _unstake(uint256[] calldata tokenIds) private { for (uint256 i = 0; i < tokenIds.length; i++) { require( stakeInfo[tokenIds[i]].staker == msg.sender, "Staking: Not the staker of the token" ); stakeToken.safeTransferFrom(address(this), msg.sender, tokenIds[i]); // Remove the token from the staked tokens array by swapping it with the last one and then deleting the last one uint256 lastIndex = tokensStaked[msg.sender].length - 1; uint256 lastTokenId = tokensStaked[msg.sender][lastIndex]; uint256 tokenIndex = tokenIdToIndex[tokenIds[i]]; tokensStaked[msg.sender][tokenIndex] = lastTokenId; tokenIdToIndex[lastTokenId] = tokenIndex; tokensStaked[msg.sender].pop(); delete tokenIdToIndex[tokenIds[i]]; delete stakeInfo[tokenIds[i]]; } totalStakedSupply -= tokenIds.length; } function unstakeAndClaim(uint256[] calldata tokenIds) public nonReentrant { require(tokenIds.length != 0, "Staking: No tokenIds provided"); updateRewards(msg.sender); _claim(); _unstake(tokenIds); } // forfeits rewards function emergencyUnstake(uint256[] calldata tokenIds) public nonReentrant { _unstake(tokenIds); } function claim() public nonReentrant { updateRewards(msg.sender); _claim(); } function _claim() private { uint256 reward = userUnclaimedRewards[msg.sender]; if (reward == 0) return; rewardToken.safeTransfer(msg.sender, userUnclaimedRewards[msg.sender]); userUnclaimedRewards[msg.sender] = 0; } function unclaimedRewards(address userAddress) public view returns(uint256) { if (userAddress == address(0)) return 0; uint256 _rewardsPerTokenStored = rewardsPerTokenStored; if (totalStakedSupply > 0) { _rewardsPerTokenStored = rewardsPerToken(); } uint256 validUserTokens = tokensStaked[userAddress].length; uint256 reward = (_rewardsPerTokenStored - userRewardPerTokenPaids[userAddress]) * validUserTokens; reward += userUnclaimedRewards[userAddress]; return reward; } function getStakedTokens(address account) public view returns (uint256[] memory) { return tokensStaked[account]; } //get staking position info for all the staked tokens by a user function getStakedTokensInfo(address account) public view returns (StakeInfo[] memory) { uint256[] memory userTokens = tokensStaked[account]; StakeInfo[] memory info = new StakeInfo[](userTokens.length); for (uint256 i = 0; i < userTokens.length; i++) { info[i] = stakeInfo[userTokens[i]]; } return info; } //Utils function updateRewards(address account) internal { if (totalStakedSupply > 0) { rewardsPerTokenStored = rewardsPerToken(); lastUpdateTime = lastTimeRewardApplicable(); } if (account == address(0)) return; uint256 validUserTokens = tokensStaked[account].length; uint256 earned = (rewardsPerTokenStored - userRewardPerTokenPaids[account]) * validUserTokens; userUnclaimedRewards[account] += earned; userRewardPerTokenPaids[account] = rewardsPerTokenStored; } function rewardsPerToken() public view returns (uint256) { if (totalStakedSupply == 0) return rewardsPerTokenStored; return rewardsPerTokenStored + (((lastTimeRewardApplicable() - lastUpdateTime) * rewardRate) / totalStakedSupply); } function lastTimeRewardApplicable() public view returns (uint256) { return block.timestamp < endTime ? block.timestamp : endTime; } //Admin utility modifier onlyAdmin() { require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin"); _; } function extendStakingPeriod(uint256 _newEndTime) external onlyAdmin { require(_newEndTime > 0, "Extension duration must be greater than 0"); endTime += _newEndTime; } //Misc function onERC721Received(address, address, uint256, bytes calldata) external pure returns (bytes4) { return IERC721Receiver.onERC721Received.selector; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_stakeToken","type":"address"},{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"address","name":"_admin","type":"address"},{"internalType":"uint256","name":"_endTime","type":"uint256"},{"internalType":"uint256","name":"_rewardRate","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"emergencyUnstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"endTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newEndTime","type":"uint256"}],"name":"extendStakingPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getStakedTokens","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getStakedTokensInfo","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"stakeTime","type":"uint256"},{"internalType":"address","name":"staker","type":"address"}],"internalType":"struct RibbitStaking.StakeInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakeInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"stakeTime","type":"uint256"},{"internalType":"address","name":"staker","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakeToken","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIdToIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakedSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"unclaimedRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"unstakeAndClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userRewardPerTokenPaids","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userUnclaimedRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162003df538038062003df5833981810160405281019062000037919062000506565b60018081905550600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603620000b0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000a790620005ef565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160362000122576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001199062000661565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160362000194576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200018b90620006d3565b60405180910390fd5b60008111620001da576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001d1906200076b565b60405180910390fd5b84600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160058190555080600681905550620002dd7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177584620002e860201b60201c565b50505050506200078d565b620002fa8282620002fe60201b60201c565b5050565b620003108282620003ef60201b60201c565b620003eb57600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550620003906200045960201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620004938262000466565b9050919050565b620004a58162000486565b8114620004b157600080fd5b50565b600081519050620004c5816200049a565b92915050565b6000819050919050565b620004e081620004cb565b8114620004ec57600080fd5b50565b6000815190506200050081620004d5565b92915050565b600080600080600060a0868803121562000525576200052462000461565b5b60006200053588828901620004b4565b95505060206200054888828901620004b4565b94505060406200055b88828901620004b4565b93505060606200056e88828901620004ef565b92505060806200058188828901620004ef565b9150509295509295909350565b600082825260208201905092915050565b7f4e465420636f6e747261637420616464726573732063616e6e6f742062652030600082015250565b6000620005d76020836200058e565b9150620005e4826200059f565b602082019050919050565b600060208201905081810360008301526200060a81620005c8565b9050919050565b7f52657761726420746f6b656e20616464726573732063616e6e6f742062652030600082015250565b6000620006496020836200058e565b9150620006568262000611565b602082019050919050565b600060208201905081810360008301526200067c816200063a565b9050919050565b7f41646d696e20616464726573732063616e6e6f74206265203000000000000000600082015250565b6000620006bb6019836200058e565b9150620006c88262000683565b602082019050919050565b60006020820190508181036000830152620006ee81620006ac565b9050919050565b7f5265776172642072617465206d7573742062652067726561746572207468616e60008201527f2030000000000000000000000000000000000000000000000000000000000000602082015250565b6000620007536022836200058e565b91506200076082620006f5565b604082019050919050565b60006020820190508181036000830152620007868162000744565b9050919050565b613658806200079d6000396000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c806375b238fc1161010f578063a2d01d9d116100a2578063d244a90d11610071578063d244a90d14610596578063d547741f146105c6578063f7c618c1146105e2578063f851a44014610600576101e5565b8063a2d01d9d14610522578063bcdc3cfc1461053e578063bf0e5b951461055c578063c8f33c9114610578576101e5565b80638129fc1c116100de5780638129fc1c1461049a57806391d14854146104a4578063949813b8146104d4578063a217fddf14610504576101e5565b806375b238fc1461041057806377643a661461042e5780637b0a47ee1461045e57806380faa57d1461047c576101e5565b806336568abe116101875780635ad873ff116101565780635ad873ff1461037657806363c28db11461039257806366f2787d146103c257806370641a36146103f2576101e5565b806336568abe146103005780634e5335721461031c5780634e71d92d1461034e57806351ed6a3014610358576101e5565b8063248a9ca3116101c3578063248a9ca31461026657806326ec0fbe146102965780632f2ff15d146102c65780633197cbb6146102e2576101e5565b806301ffc9a7146101ea5780630fbf0a931461021a578063150b7a0214610236575b600080fd5b61020460048036038101906101ff91906123bf565b61061e565b6040516102119190612407565b60405180910390f35b610234600480360381019061022f9190612487565b610698565b005b610250600480360381019061024b91906125be565b610aa0565b60405161025d9190612655565b60405180910390f35b610280600480360381019061027b91906126a6565b610ab5565b60405161028d91906126e2565b60405180910390f35b6102b060048036038101906102ab91906126fd565b610ad4565b6040516102bd9190612739565b60405180910390f35b6102e060048036038101906102db9190612754565b610aec565b005b6102ea610b0d565b6040516102f79190612739565b60405180910390f35b61031a60048036038101906103159190612754565b610b13565b005b610336600480360381019061033191906126fd565b610b96565b604051610345939291906127a3565b60405180910390f35b610356610be0565b005b610360610c03565b60405161036d9190612839565b60405180910390f35b610390600480360381019061038b9190612487565b610c29565b005b6103ac60048036038101906103a79190612854565b610c9e565b6040516103b9919061293f565b60405180910390f35b6103dc60048036038101906103d79190612854565b610d35565b6040516103e99190612739565b60405180910390f35b6103fa610d4d565b6040516104079190612739565b60405180910390f35b610418610da4565b60405161042591906126e2565b60405180910390f35b61044860048036038101906104439190612854565b610dc8565b6040516104559190612a61565b60405180910390f35b610466610f9f565b6040516104739190612739565b60405180910390f35b610484610fa5565b6040516104919190612739565b60405180910390f35b6104a2610fbf565b005b6104be60048036038101906104b99190612754565b611076565b6040516104cb9190612407565b60405180910390f35b6104ee60048036038101906104e99190612854565b6110e0565b6040516104fb9190612739565b60405180910390f35b61050c611235565b60405161051991906126e2565b60405180910390f35b61053c600480360381019061053791906126fd565b61123c565b005b610546611304565b6040516105539190612739565b60405180910390f35b61057660048036038101906105719190612487565b61130a565b005b610580611328565b60405161058d9190612739565b60405180910390f35b6105b060048036038101906105ab9190612854565b61132e565b6040516105bd9190612739565b60405180910390f35b6105e060048036038101906105db9190612754565b611346565b005b6105ea611367565b6040516105f79190612aa4565b60405180910390f35b61060861138d565b6040516106159190612abf565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806106915750610690826113b3565b5b9050919050565b6106a061141d565b600082829050036106e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106dd90612b37565b60405180910390fd5b60006007540361072b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072290612ba3565b60405180910390fd5b6107343361146c565b60005b82829050811015610a7757600073ffffffffffffffffffffffffffffffffffffffff16600b600085858581811061077157610770612bc3565b5b90506020020135815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610800576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f790612c3e565b60405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e333086868681811061085357610852612bc3565b5b905060200201356040518463ffffffff1660e01b815260040161087893929190612c5e565b600060405180830381600087803b15801561089257600080fd5b505af11580156108a6573d6000803e3d6000fd5b505050506040518060600160405280600181526020014281526020013373ffffffffffffffffffffffffffffffffffffffff16815250600b60008585858181106108f3576108f2612bc3565b5b905060200201358152602001908152602001600020600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208383838181106109b8576109b7612bc3565b5b9050602002013590806001815401808255809150506001900390600052602060002001600090919091909150556001600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050610a349190612cc4565b600d6000858585818110610a4b57610a4a612bc3565b5b905060200201358152602001908152602001600020819055508080610a6f90612cf8565b915050610737565b508181905060096000828254610a8d9190612d40565b92505081905550610a9c61160e565b5050565b600063150b7a0260e01b905095945050505050565b6000806000838152602001908152602001600020600101549050919050565b600d6020528060005260406000206000915090505481565b610af582610ab5565b610afe81611617565b610b08838361162b565b505050565b60055481565b610b1b61170b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7f90612de6565b60405180910390fd5b610b928282611713565b5050565b600b6020528060005260406000206000915090508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b610be861141d565b610bf13361146c565b610bf96117f4565b610c0161160e565b565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610c3161141d565b60008282905003610c77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6e90612b37565b60405180910390fd5b610c803361146c565b610c886117f4565b610c92828261191b565b610c9a61160e565b5050565b6060600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015610d2957602002820191906000526020600020905b815481526020019060010190808311610d15575b50505050509050919050565b600a6020528060005260406000206000915090505481565b60008060095403610d62576008549050610da1565b600954600654600754610d73610fa5565b610d7d9190612cc4565b610d879190612e06565b610d919190612e77565b600854610d9e9190612d40565b90505b90565b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177581565b60606000600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015610e5557602002820191906000526020600020905b815481526020019060010190808311610e41575b505050505090506000815167ffffffffffffffff811115610e7957610e78612ea8565b5b604051908082528060200260200182016040528015610eb257816020015b610e9f612326565b815260200190600190039081610e975790505b50905060005b8251811015610f9457600b6000848381518110610ed857610ed7612bc3565b5b6020026020010151815260200190815260200160002060405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050828281518110610f7657610f75612bc3565b5b60200260200101819052508080610f8c90612cf8565b915050610eb8565b508092505050919050565b60065481565b60006005544210610fb857600554610fba565b425b905090565b610fe97fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177533611076565b611028576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101f90612f23565b60405180910390fd5b60006007541461106d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106490612f8f565b60405180910390fd5b42600781905550565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361111e5760009050611230565b600060085490506000600954111561113b57611138610d4d565b90505b6000600c60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050600081600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054846111d09190612cc4565b6111da9190612e06565b9050600e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054816112279190612d40565b90508093505050505b919050565b6000801b81565b6112667fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177533611076565b6112a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129c90612f23565b60405180910390fd5b600081116112e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112df90613021565b60405180910390fd5b80600560008282546112fa9190612d40565b9250508190555050565b60095481565b61131261141d565b61131c828261191b565b61132461160e565b5050565b60075481565b600e6020528060005260406000206000915090505481565b61134f82610ab5565b61135881611617565b6113628383611713565b505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600260015403611462576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114599061308d565b60405180910390fd5b6002600181905550565b600060095411156114945761147f610d4d565b60088190555061148d610fa5565b6007819055505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16031561160b576000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050600081600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546008546115609190612cc4565b61156a9190612e06565b905080600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546115bb9190612d40565b92505081905550600854600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050505b50565b60018081905550565b6116288161162361170b565b611d1e565b50565b6116358282611076565b61170757600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506116ac61170b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600033905090565b61171d8282611076565b156117f057600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061179561170b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600081036118465750611919565b6118d233600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611da39092919063ffffffff16565b6000600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b565b60005b82829050811015611cfd573373ffffffffffffffffffffffffffffffffffffffff16600b600085858581811061195757611956612bc3565b5b90506020020135815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119dd9061311f565b60405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033868686818110611a3957611a38612bc3565b5b905060200201356040518463ffffffff1660e01b8152600401611a5e93929190612c5e565b600060405180830381600087803b158015611a7857600080fd5b505af1158015611a8c573d6000803e3d6000fd5b5050505060006001600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050611ae19190612cc4565b90506000600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110611b3657611b35612bc3565b5b906000526020600020015490506000600d6000878787818110611b5c57611b5b612bc3565b5b90506020020135815260200190815260200160002054905081600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110611bc657611bc5612bc3565b5b906000526020600020018190555080600d600084815260200190815260200160002081905550600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480611c3b57611c3a61313f565b5b60019003818190600052602060002001600090559055600d6000878787818110611c6857611c67612bc3565b5b90506020020135815260200190815260200160002060009055600b6000878787818110611c9857611c97612bc3565b5b90506020020135815260200190815260200160002060008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550505050508080611cf590612cf8565b91505061191e565b508181905060096000828254611d139190612cc4565b925050819055505050565b611d288282611076565b611d9f57611d3581611e29565b611d438360001c6020611e56565b604051602001611d54929190613277565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9691906132fb565b60405180910390fd5b5050565b611e248363a9059cbb60e01b8484604051602401611dc292919061331d565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612092565b505050565b6060611e4f8273ffffffffffffffffffffffffffffffffffffffff16601460ff16611e56565b9050919050565b606060006002836002611e699190612e06565b611e739190612d40565b67ffffffffffffffff811115611e8c57611e8b612ea8565b5b6040519080825280601f01601f191660200182016040528015611ebe5781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611ef657611ef5612bc3565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611f5a57611f59612bc3565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002611f9a9190612e06565b611fa49190612d40565b90505b6001811115612044577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110611fe657611fe5612bc3565b5b1a60f81b828281518110611ffd57611ffc612bc3565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c94508061203d90613346565b9050611fa7565b5060008414612088576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207f906133bb565b60405180910390fd5b8091505092915050565b60006120f4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121599092919063ffffffff16565b905060008151111561215457808060200190518101906121149190613407565b612153576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214a906134a6565b60405180910390fd5b5b505050565b60606121688484600085612171565b90509392505050565b6060824710156121b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121ad90613538565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516121df919061359f565b60006040518083038185875af1925050503d806000811461221c576040519150601f19603f3d011682016040523d82523d6000602084013e612221565b606091505b50915091506122328783838761223e565b92505050949350505050565b606083156122a057600083510361229857612258856122b3565b612297576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228e90613602565b60405180910390fd5b5b8290506122ab565b6122aa83836122d6565b5b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000825111156122e95781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231d91906132fb565b60405180910390fd5b60405180606001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61239c81612367565b81146123a757600080fd5b50565b6000813590506123b981612393565b92915050565b6000602082840312156123d5576123d461235d565b5b60006123e3848285016123aa565b91505092915050565b60008115159050919050565b612401816123ec565b82525050565b600060208201905061241c60008301846123f8565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261244757612446612422565b5b8235905067ffffffffffffffff81111561246457612463612427565b5b6020830191508360208202830111156124805761247f61242c565b5b9250929050565b6000806020838503121561249e5761249d61235d565b5b600083013567ffffffffffffffff8111156124bc576124bb612362565b5b6124c885828601612431565b92509250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006124ff826124d4565b9050919050565b61250f816124f4565b811461251a57600080fd5b50565b60008135905061252c81612506565b92915050565b6000819050919050565b61254581612532565b811461255057600080fd5b50565b6000813590506125628161253c565b92915050565b60008083601f84011261257e5761257d612422565b5b8235905067ffffffffffffffff81111561259b5761259a612427565b5b6020830191508360018202830111156125b7576125b661242c565b5b9250929050565b6000806000806000608086880312156125da576125d961235d565b5b60006125e88882890161251d565b95505060206125f98882890161251d565b945050604061260a88828901612553565b935050606086013567ffffffffffffffff81111561262b5761262a612362565b5b61263788828901612568565b92509250509295509295909350565b61264f81612367565b82525050565b600060208201905061266a6000830184612646565b92915050565b6000819050919050565b61268381612670565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b6000602082840312156126bc576126bb61235d565b5b60006126ca84828501612691565b91505092915050565b6126dc81612670565b82525050565b60006020820190506126f760008301846126d3565b92915050565b6000602082840312156127135761271261235d565b5b600061272184828501612553565b91505092915050565b61273381612532565b82525050565b600060208201905061274e600083018461272a565b92915050565b6000806040838503121561276b5761276a61235d565b5b600061277985828601612691565b925050602061278a8582860161251d565b9150509250929050565b61279d816124f4565b82525050565b60006060820190506127b8600083018661272a565b6127c5602083018561272a565b6127d26040830184612794565b949350505050565b6000819050919050565b60006127ff6127fa6127f5846124d4565b6127da565b6124d4565b9050919050565b6000612811826127e4565b9050919050565b600061282382612806565b9050919050565b61283381612818565b82525050565b600060208201905061284e600083018461282a565b92915050565b60006020828403121561286a5761286961235d565b5b60006128788482850161251d565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6128b681612532565b82525050565b60006128c883836128ad565b60208301905092915050565b6000602082019050919050565b60006128ec82612881565b6128f6818561288c565b93506129018361289d565b8060005b8381101561293257815161291988826128bc565b9750612924836128d4565b925050600181019050612905565b5085935050505092915050565b6000602082019050818103600083015261295981846128e1565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612996816124f4565b82525050565b6060820160008201516129b260008501826128ad565b5060208201516129c560208501826128ad565b5060408201516129d8604085018261298d565b50505050565b60006129ea838361299c565b60608301905092915050565b6000602082019050919050565b6000612a0e82612961565b612a18818561296c565b9350612a238361297d565b8060005b83811015612a54578151612a3b88826129de565b9750612a46836129f6565b925050600181019050612a27565b5085935050505092915050565b60006020820190508181036000830152612a7b8184612a03565b905092915050565b6000612a8e82612806565b9050919050565b612a9e81612a83565b82525050565b6000602082019050612ab96000830184612a95565b92915050565b6000602082019050612ad46000830184612794565b92915050565b600082825260208201905092915050565b7f5374616b696e673a204e6f20746f6b656e4964732070726f7669646564000000600082015250565b6000612b21601d83612ada565b9150612b2c82612aeb565b602082019050919050565b60006020820190508181036000830152612b5081612b14565b9050919050565b7f5374616b696e673a204e6f742079657420696e697469616c697a656400000000600082015250565b6000612b8d601c83612ada565b9150612b9882612b57565b602082019050919050565b60006020820190508181036000830152612bbc81612b80565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f5374616b696e673a20546f6b656e20616c7265616479207374616b6564000000600082015250565b6000612c28601d83612ada565b9150612c3382612bf2565b602082019050919050565b60006020820190508181036000830152612c5781612c1b565b9050919050565b6000606082019050612c736000830186612794565b612c806020830185612794565b612c8d604083018461272a565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612ccf82612532565b9150612cda83612532565b9250828203905081811115612cf257612cf1612c95565b5b92915050565b6000612d0382612532565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612d3557612d34612c95565b5b600182019050919050565b6000612d4b82612532565b9150612d5683612532565b9250828201905080821115612d6e57612d6d612c95565b5b92915050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6000612dd0602f83612ada565b9150612ddb82612d74565b604082019050919050565b60006020820190508181036000830152612dff81612dc3565b9050919050565b6000612e1182612532565b9150612e1c83612532565b9250828202612e2a81612532565b91508282048414831517612e4157612e40612c95565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612e8282612532565b9150612e8d83612532565b925082612e9d57612e9c612e48565b5b828204905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f43616c6c6572206973206e6f7420616e2061646d696e00000000000000000000600082015250565b6000612f0d601683612ada565b9150612f1882612ed7565b602082019050919050565b60006020820190508181036000830152612f3c81612f00565b9050919050565b7f5374616b696e6720616c726561647920696e697469616c697a65640000000000600082015250565b6000612f79601b83612ada565b9150612f8482612f43565b602082019050919050565b60006020820190508181036000830152612fa881612f6c565b9050919050565b7f457874656e73696f6e206475726174696f6e206d75737420626520677265617460008201527f6572207468616e20300000000000000000000000000000000000000000000000602082015250565b600061300b602983612ada565b915061301682612faf565b604082019050919050565b6000602082019050818103600083015261303a81612ffe565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000613077601f83612ada565b915061308282613041565b602082019050919050565b600060208201905081810360008301526130a68161306a565b9050919050565b7f5374616b696e673a204e6f7420746865207374616b6572206f6620746865207460008201527f6f6b656e00000000000000000000000000000000000000000000000000000000602082015250565b6000613109602483612ada565b9150613114826130ad565b604082019050919050565b60006020820190508181036000830152613138816130fc565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b60006131af60178361316e565b91506131ba82613179565b601782019050919050565b600081519050919050565b60005b838110156131ee5780820151818401526020810190506131d3565b60008484015250505050565b6000613205826131c5565b61320f818561316e565b935061321f8185602086016131d0565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b600061326160118361316e565b915061326c8261322b565b601182019050919050565b6000613282826131a2565b915061328e82856131fa565b915061329982613254565b91506132a582846131fa565b91508190509392505050565b6000601f19601f8301169050919050565b60006132cd826131c5565b6132d78185612ada565b93506132e78185602086016131d0565b6132f0816132b1565b840191505092915050565b6000602082019050818103600083015261331581846132c2565b905092915050565b60006040820190506133326000830185612794565b61333f602083018461272a565b9392505050565b600061335182612532565b91506000820361336457613363612c95565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006133a5602083612ada565b91506133b08261336f565b602082019050919050565b600060208201905081810360008301526133d481613398565b9050919050565b6133e4816123ec565b81146133ef57600080fd5b50565b600081519050613401816133db565b92915050565b60006020828403121561341d5761341c61235d565b5b600061342b848285016133f2565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000613490602a83612ada565b915061349b82613434565b604082019050919050565b600060208201905081810360008301526134bf81613483565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613522602683612ada565b915061352d826134c6565b604082019050919050565b6000602082019050818103600083015261355181613515565b9050919050565b600081519050919050565b600081905092915050565b600061357982613558565b6135838185613563565b93506135938185602086016131d0565b80840191505092915050565b60006135ab828461356e565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006135ec601d83612ada565b91506135f7826135b6565b602082019050919050565b6000602082019050818103600083015261361b816135df565b905091905056fea264697066735822122050362079720d7f4b5e416e90459e22e1c5009fbcb0cf24c3ba970f5e53d8784964736f6c63430008120033000000000000000000000000549d38f104ac46d856c1b2bf2a20d170efdb2a8d00000000000000000000000073648315fbe69f7bd36a917802e4f19314009def00000000000000000000000083343a12e98e0044bf5b0dcd11818961cb5e9fda00000000000000000000000000000000000000000000000000000000655d055d000000000000000000000000000000000000000000160d69019375812c1da800
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101e55760003560e01c806375b238fc1161010f578063a2d01d9d116100a2578063d244a90d11610071578063d244a90d14610596578063d547741f146105c6578063f7c618c1146105e2578063f851a44014610600576101e5565b8063a2d01d9d14610522578063bcdc3cfc1461053e578063bf0e5b951461055c578063c8f33c9114610578576101e5565b80638129fc1c116100de5780638129fc1c1461049a57806391d14854146104a4578063949813b8146104d4578063a217fddf14610504576101e5565b806375b238fc1461041057806377643a661461042e5780637b0a47ee1461045e57806380faa57d1461047c576101e5565b806336568abe116101875780635ad873ff116101565780635ad873ff1461037657806363c28db11461039257806366f2787d146103c257806370641a36146103f2576101e5565b806336568abe146103005780634e5335721461031c5780634e71d92d1461034e57806351ed6a3014610358576101e5565b8063248a9ca3116101c3578063248a9ca31461026657806326ec0fbe146102965780632f2ff15d146102c65780633197cbb6146102e2576101e5565b806301ffc9a7146101ea5780630fbf0a931461021a578063150b7a0214610236575b600080fd5b61020460048036038101906101ff91906123bf565b61061e565b6040516102119190612407565b60405180910390f35b610234600480360381019061022f9190612487565b610698565b005b610250600480360381019061024b91906125be565b610aa0565b60405161025d9190612655565b60405180910390f35b610280600480360381019061027b91906126a6565b610ab5565b60405161028d91906126e2565b60405180910390f35b6102b060048036038101906102ab91906126fd565b610ad4565b6040516102bd9190612739565b60405180910390f35b6102e060048036038101906102db9190612754565b610aec565b005b6102ea610b0d565b6040516102f79190612739565b60405180910390f35b61031a60048036038101906103159190612754565b610b13565b005b610336600480360381019061033191906126fd565b610b96565b604051610345939291906127a3565b60405180910390f35b610356610be0565b005b610360610c03565b60405161036d9190612839565b60405180910390f35b610390600480360381019061038b9190612487565b610c29565b005b6103ac60048036038101906103a79190612854565b610c9e565b6040516103b9919061293f565b60405180910390f35b6103dc60048036038101906103d79190612854565b610d35565b6040516103e99190612739565b60405180910390f35b6103fa610d4d565b6040516104079190612739565b60405180910390f35b610418610da4565b60405161042591906126e2565b60405180910390f35b61044860048036038101906104439190612854565b610dc8565b6040516104559190612a61565b60405180910390f35b610466610f9f565b6040516104739190612739565b60405180910390f35b610484610fa5565b6040516104919190612739565b60405180910390f35b6104a2610fbf565b005b6104be60048036038101906104b99190612754565b611076565b6040516104cb9190612407565b60405180910390f35b6104ee60048036038101906104e99190612854565b6110e0565b6040516104fb9190612739565b60405180910390f35b61050c611235565b60405161051991906126e2565b60405180910390f35b61053c600480360381019061053791906126fd565b61123c565b005b610546611304565b6040516105539190612739565b60405180910390f35b61057660048036038101906105719190612487565b61130a565b005b610580611328565b60405161058d9190612739565b60405180910390f35b6105b060048036038101906105ab9190612854565b61132e565b6040516105bd9190612739565b60405180910390f35b6105e060048036038101906105db9190612754565b611346565b005b6105ea611367565b6040516105f79190612aa4565b60405180910390f35b61060861138d565b6040516106159190612abf565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806106915750610690826113b3565b5b9050919050565b6106a061141d565b600082829050036106e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106dd90612b37565b60405180910390fd5b60006007540361072b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072290612ba3565b60405180910390fd5b6107343361146c565b60005b82829050811015610a7757600073ffffffffffffffffffffffffffffffffffffffff16600b600085858581811061077157610770612bc3565b5b90506020020135815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610800576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f790612c3e565b60405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e333086868681811061085357610852612bc3565b5b905060200201356040518463ffffffff1660e01b815260040161087893929190612c5e565b600060405180830381600087803b15801561089257600080fd5b505af11580156108a6573d6000803e3d6000fd5b505050506040518060600160405280600181526020014281526020013373ffffffffffffffffffffffffffffffffffffffff16815250600b60008585858181106108f3576108f2612bc3565b5b905060200201358152602001908152602001600020600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208383838181106109b8576109b7612bc3565b5b9050602002013590806001815401808255809150506001900390600052602060002001600090919091909150556001600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050610a349190612cc4565b600d6000858585818110610a4b57610a4a612bc3565b5b905060200201358152602001908152602001600020819055508080610a6f90612cf8565b915050610737565b508181905060096000828254610a8d9190612d40565b92505081905550610a9c61160e565b5050565b600063150b7a0260e01b905095945050505050565b6000806000838152602001908152602001600020600101549050919050565b600d6020528060005260406000206000915090505481565b610af582610ab5565b610afe81611617565b610b08838361162b565b505050565b60055481565b610b1b61170b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7f90612de6565b60405180910390fd5b610b928282611713565b5050565b600b6020528060005260406000206000915090508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b610be861141d565b610bf13361146c565b610bf96117f4565b610c0161160e565b565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610c3161141d565b60008282905003610c77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6e90612b37565b60405180910390fd5b610c803361146c565b610c886117f4565b610c92828261191b565b610c9a61160e565b5050565b6060600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015610d2957602002820191906000526020600020905b815481526020019060010190808311610d15575b50505050509050919050565b600a6020528060005260406000206000915090505481565b60008060095403610d62576008549050610da1565b600954600654600754610d73610fa5565b610d7d9190612cc4565b610d879190612e06565b610d919190612e77565b600854610d9e9190612d40565b90505b90565b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177581565b60606000600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015610e5557602002820191906000526020600020905b815481526020019060010190808311610e41575b505050505090506000815167ffffffffffffffff811115610e7957610e78612ea8565b5b604051908082528060200260200182016040528015610eb257816020015b610e9f612326565b815260200190600190039081610e975790505b50905060005b8251811015610f9457600b6000848381518110610ed857610ed7612bc3565b5b6020026020010151815260200190815260200160002060405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050828281518110610f7657610f75612bc3565b5b60200260200101819052508080610f8c90612cf8565b915050610eb8565b508092505050919050565b60065481565b60006005544210610fb857600554610fba565b425b905090565b610fe97fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177533611076565b611028576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101f90612f23565b60405180910390fd5b60006007541461106d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106490612f8f565b60405180910390fd5b42600781905550565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361111e5760009050611230565b600060085490506000600954111561113b57611138610d4d565b90505b6000600c60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050600081600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054846111d09190612cc4565b6111da9190612e06565b9050600e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054816112279190612d40565b90508093505050505b919050565b6000801b81565b6112667fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177533611076565b6112a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129c90612f23565b60405180910390fd5b600081116112e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112df90613021565b60405180910390fd5b80600560008282546112fa9190612d40565b9250508190555050565b60095481565b61131261141d565b61131c828261191b565b61132461160e565b5050565b60075481565b600e6020528060005260406000206000915090505481565b61134f82610ab5565b61135881611617565b6113628383611713565b505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600260015403611462576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114599061308d565b60405180910390fd5b6002600181905550565b600060095411156114945761147f610d4d565b60088190555061148d610fa5565b6007819055505b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16031561160b576000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050600081600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546008546115609190612cc4565b61156a9190612e06565b905080600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546115bb9190612d40565b92505081905550600854600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050505b50565b60018081905550565b6116288161162361170b565b611d1e565b50565b6116358282611076565b61170757600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506116ac61170b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600033905090565b61171d8282611076565b156117f057600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061179561170b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600081036118465750611919565b6118d233600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611da39092919063ffffffff16565b6000600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505b565b60005b82829050811015611cfd573373ffffffffffffffffffffffffffffffffffffffff16600b600085858581811061195757611956612bc3565b5b90506020020135815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146119e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119dd9061311f565b60405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e3033868686818110611a3957611a38612bc3565b5b905060200201356040518463ffffffff1660e01b8152600401611a5e93929190612c5e565b600060405180830381600087803b158015611a7857600080fd5b505af1158015611a8c573d6000803e3d6000fd5b5050505060006001600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050611ae19190612cc4565b90506000600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110611b3657611b35612bc3565b5b906000526020600020015490506000600d6000878787818110611b5c57611b5b612bc3565b5b90506020020135815260200190815260200160002054905081600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110611bc657611bc5612bc3565b5b906000526020600020018190555080600d600084815260200190815260200160002081905550600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480611c3b57611c3a61313f565b5b60019003818190600052602060002001600090559055600d6000878787818110611c6857611c67612bc3565b5b90506020020135815260200190815260200160002060009055600b6000878787818110611c9857611c97612bc3565b5b90506020020135815260200190815260200160002060008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550505050508080611cf590612cf8565b91505061191e565b508181905060096000828254611d139190612cc4565b925050819055505050565b611d288282611076565b611d9f57611d3581611e29565b611d438360001c6020611e56565b604051602001611d54929190613277565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9691906132fb565b60405180910390fd5b5050565b611e248363a9059cbb60e01b8484604051602401611dc292919061331d565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612092565b505050565b6060611e4f8273ffffffffffffffffffffffffffffffffffffffff16601460ff16611e56565b9050919050565b606060006002836002611e699190612e06565b611e739190612d40565b67ffffffffffffffff811115611e8c57611e8b612ea8565b5b6040519080825280601f01601f191660200182016040528015611ebe5781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611ef657611ef5612bc3565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611f5a57611f59612bc3565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002611f9a9190612e06565b611fa49190612d40565b90505b6001811115612044577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110611fe657611fe5612bc3565b5b1a60f81b828281518110611ffd57611ffc612bc3565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c94508061203d90613346565b9050611fa7565b5060008414612088576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207f906133bb565b60405180910390fd5b8091505092915050565b60006120f4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166121599092919063ffffffff16565b905060008151111561215457808060200190518101906121149190613407565b612153576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214a906134a6565b60405180910390fd5b5b505050565b60606121688484600085612171565b90509392505050565b6060824710156121b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121ad90613538565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516121df919061359f565b60006040518083038185875af1925050503d806000811461221c576040519150601f19603f3d011682016040523d82523d6000602084013e612221565b606091505b50915091506122328783838761223e565b92505050949350505050565b606083156122a057600083510361229857612258856122b3565b612297576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161228e90613602565b60405180910390fd5b5b8290506122ab565b6122aa83836122d6565b5b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000825111156122e95781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161231d91906132fb565b60405180910390fd5b60405180606001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61239c81612367565b81146123a757600080fd5b50565b6000813590506123b981612393565b92915050565b6000602082840312156123d5576123d461235d565b5b60006123e3848285016123aa565b91505092915050565b60008115159050919050565b612401816123ec565b82525050565b600060208201905061241c60008301846123f8565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261244757612446612422565b5b8235905067ffffffffffffffff81111561246457612463612427565b5b6020830191508360208202830111156124805761247f61242c565b5b9250929050565b6000806020838503121561249e5761249d61235d565b5b600083013567ffffffffffffffff8111156124bc576124bb612362565b5b6124c885828601612431565b92509250509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006124ff826124d4565b9050919050565b61250f816124f4565b811461251a57600080fd5b50565b60008135905061252c81612506565b92915050565b6000819050919050565b61254581612532565b811461255057600080fd5b50565b6000813590506125628161253c565b92915050565b60008083601f84011261257e5761257d612422565b5b8235905067ffffffffffffffff81111561259b5761259a612427565b5b6020830191508360018202830111156125b7576125b661242c565b5b9250929050565b6000806000806000608086880312156125da576125d961235d565b5b60006125e88882890161251d565b95505060206125f98882890161251d565b945050604061260a88828901612553565b935050606086013567ffffffffffffffff81111561262b5761262a612362565b5b61263788828901612568565b92509250509295509295909350565b61264f81612367565b82525050565b600060208201905061266a6000830184612646565b92915050565b6000819050919050565b61268381612670565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b6000602082840312156126bc576126bb61235d565b5b60006126ca84828501612691565b91505092915050565b6126dc81612670565b82525050565b60006020820190506126f760008301846126d3565b92915050565b6000602082840312156127135761271261235d565b5b600061272184828501612553565b91505092915050565b61273381612532565b82525050565b600060208201905061274e600083018461272a565b92915050565b6000806040838503121561276b5761276a61235d565b5b600061277985828601612691565b925050602061278a8582860161251d565b9150509250929050565b61279d816124f4565b82525050565b60006060820190506127b8600083018661272a565b6127c5602083018561272a565b6127d26040830184612794565b949350505050565b6000819050919050565b60006127ff6127fa6127f5846124d4565b6127da565b6124d4565b9050919050565b6000612811826127e4565b9050919050565b600061282382612806565b9050919050565b61283381612818565b82525050565b600060208201905061284e600083018461282a565b92915050565b60006020828403121561286a5761286961235d565b5b60006128788482850161251d565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6128b681612532565b82525050565b60006128c883836128ad565b60208301905092915050565b6000602082019050919050565b60006128ec82612881565b6128f6818561288c565b93506129018361289d565b8060005b8381101561293257815161291988826128bc565b9750612924836128d4565b925050600181019050612905565b5085935050505092915050565b6000602082019050818103600083015261295981846128e1565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612996816124f4565b82525050565b6060820160008201516129b260008501826128ad565b5060208201516129c560208501826128ad565b5060408201516129d8604085018261298d565b50505050565b60006129ea838361299c565b60608301905092915050565b6000602082019050919050565b6000612a0e82612961565b612a18818561296c565b9350612a238361297d565b8060005b83811015612a54578151612a3b88826129de565b9750612a46836129f6565b925050600181019050612a27565b5085935050505092915050565b60006020820190508181036000830152612a7b8184612a03565b905092915050565b6000612a8e82612806565b9050919050565b612a9e81612a83565b82525050565b6000602082019050612ab96000830184612a95565b92915050565b6000602082019050612ad46000830184612794565b92915050565b600082825260208201905092915050565b7f5374616b696e673a204e6f20746f6b656e4964732070726f7669646564000000600082015250565b6000612b21601d83612ada565b9150612b2c82612aeb565b602082019050919050565b60006020820190508181036000830152612b5081612b14565b9050919050565b7f5374616b696e673a204e6f742079657420696e697469616c697a656400000000600082015250565b6000612b8d601c83612ada565b9150612b9882612b57565b602082019050919050565b60006020820190508181036000830152612bbc81612b80565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f5374616b696e673a20546f6b656e20616c7265616479207374616b6564000000600082015250565b6000612c28601d83612ada565b9150612c3382612bf2565b602082019050919050565b60006020820190508181036000830152612c5781612c1b565b9050919050565b6000606082019050612c736000830186612794565b612c806020830185612794565b612c8d604083018461272a565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612ccf82612532565b9150612cda83612532565b9250828203905081811115612cf257612cf1612c95565b5b92915050565b6000612d0382612532565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612d3557612d34612c95565b5b600182019050919050565b6000612d4b82612532565b9150612d5683612532565b9250828201905080821115612d6e57612d6d612c95565b5b92915050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6000612dd0602f83612ada565b9150612ddb82612d74565b604082019050919050565b60006020820190508181036000830152612dff81612dc3565b9050919050565b6000612e1182612532565b9150612e1c83612532565b9250828202612e2a81612532565b91508282048414831517612e4157612e40612c95565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612e8282612532565b9150612e8d83612532565b925082612e9d57612e9c612e48565b5b828204905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f43616c6c6572206973206e6f7420616e2061646d696e00000000000000000000600082015250565b6000612f0d601683612ada565b9150612f1882612ed7565b602082019050919050565b60006020820190508181036000830152612f3c81612f00565b9050919050565b7f5374616b696e6720616c726561647920696e697469616c697a65640000000000600082015250565b6000612f79601b83612ada565b9150612f8482612f43565b602082019050919050565b60006020820190508181036000830152612fa881612f6c565b9050919050565b7f457874656e73696f6e206475726174696f6e206d75737420626520677265617460008201527f6572207468616e20300000000000000000000000000000000000000000000000602082015250565b600061300b602983612ada565b915061301682612faf565b604082019050919050565b6000602082019050818103600083015261303a81612ffe565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000613077601f83612ada565b915061308282613041565b602082019050919050565b600060208201905081810360008301526130a68161306a565b9050919050565b7f5374616b696e673a204e6f7420746865207374616b6572206f6620746865207460008201527f6f6b656e00000000000000000000000000000000000000000000000000000000602082015250565b6000613109602483612ada565b9150613114826130ad565b604082019050919050565b60006020820190508181036000830152613138816130fc565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b60006131af60178361316e565b91506131ba82613179565b601782019050919050565b600081519050919050565b60005b838110156131ee5780820151818401526020810190506131d3565b60008484015250505050565b6000613205826131c5565b61320f818561316e565b935061321f8185602086016131d0565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b600061326160118361316e565b915061326c8261322b565b601182019050919050565b6000613282826131a2565b915061328e82856131fa565b915061329982613254565b91506132a582846131fa565b91508190509392505050565b6000601f19601f8301169050919050565b60006132cd826131c5565b6132d78185612ada565b93506132e78185602086016131d0565b6132f0816132b1565b840191505092915050565b6000602082019050818103600083015261331581846132c2565b905092915050565b60006040820190506133326000830185612794565b61333f602083018461272a565b9392505050565b600061335182612532565b91506000820361336457613363612c95565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006133a5602083612ada565b91506133b08261336f565b602082019050919050565b600060208201905081810360008301526133d481613398565b9050919050565b6133e4816123ec565b81146133ef57600080fd5b50565b600081519050613401816133db565b92915050565b60006020828403121561341d5761341c61235d565b5b600061342b848285016133f2565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000613490602a83612ada565b915061349b82613434565b604082019050919050565b600060208201905081810360008301526134bf81613483565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613522602683612ada565b915061352d826134c6565b604082019050919050565b6000602082019050818103600083015261355181613515565b9050919050565b600081519050919050565b600081905092915050565b600061357982613558565b6135838185613563565b93506135938185602086016131d0565b80840191505092915050565b60006135ab828461356e565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006135ec601d83612ada565b91506135f7826135b6565b602082019050919050565b6000602082019050818103600083015261361b816135df565b905091905056fea264697066735822122050362079720d7f4b5e416e90459e22e1c5009fbcb0cf24c3ba970f5e53d8784964736f6c63430008120033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000549d38f104ac46d856c1b2bf2a20d170efdb2a8d00000000000000000000000073648315fbe69f7bd36a917802e4f19314009def00000000000000000000000083343a12e98e0044bf5b0dcd11818961cb5e9fda00000000000000000000000000000000000000000000000000000000655d055d000000000000000000000000000000000000000000160d69019375812c1da800
-----Decoded View---------------
Arg [0] : _stakeToken (address): 0x549d38F104AC46d856C1b2bF2A20D170EfdB2a8D
Arg [1] : _rewardToken (address): 0x73648315fbE69f7bd36a917802E4F19314009def
Arg [2] : _admin (address): 0x83343A12e98E0044bF5b0DcD11818961CB5E9FdA
Arg [3] : _endTime (uint256): 1700595037
Arg [4] : _rewardRate (uint256): 26659695817490500000000000
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000549d38f104ac46d856c1b2bf2a20d170efdb2a8d
Arg [1] : 00000000000000000000000073648315fbe69f7bd36a917802e4f19314009def
Arg [2] : 00000000000000000000000083343a12e98e0044bf5b0dcd11818961cb5e9fda
Arg [3] : 00000000000000000000000000000000000000000000000000000000655d055d
Arg [4] : 000000000000000000000000000000000000000000160d69019375812c1da800
Deployed Bytecode Sourcemap
57678:7198:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46832:204;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59552:849;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64706:167;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48655:131;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58395:49;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49096:147;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57956:22;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;50240:218;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58203:46;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;61824:100;;;:::i;:::-;;57895:25;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61432:239;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;62773:128;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58138:58;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63930:258;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57794:60;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62978:369;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57985:25;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64196:145;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59358:160;;;:::i;:::-;;47128:147;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62198:567;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46233:49;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64496:190;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58097:32;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61704:112;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58017:29;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58494:55;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49536:149;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57863:25;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57927:20;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46832:204;46917:4;46956:32;46941:47;;;:11;:47;;;;:87;;;;46992:36;47016:11;46992:23;:36::i;:::-;46941:87;46934:94;;46832:204;;;:::o;59552:849::-;21521:21;:19;:21::i;:::-;59654:1:::1;59635:8;;:15;;:20:::0;59627:62:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;59726:1;59708:14;;:19:::0;59700:60:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;59781:25;59795:10;59781:13;:25::i;:::-;59824:9;59819:528;59843:8;;:15;;59839:1;:19;59819:528;;;59929:1;59888:43;;:9;:22;59898:8;;59907:1;59898:11;;;;;;;:::i;:::-;;;;;;;;59888:22;;;;;;;;;;;:29;;;;;;;;;;;;:43;;;59880:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;59982:10;;;;;;;;;;;:27;;;60010:10;60030:4;60037:8;;60046:1;60037:11;;;;;;;:::i;:::-;;;;;;;;59982:67;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;60091:107;;;;;;;;60119:1;60091:107;;;;60139:15;60091:107;;;;60173:10;60091:107;;;;::::0;60066:9:::1;:22;60076:8;;60085:1;60076:11;;;;;;;:::i;:::-;;;;;;;;60066:22;;;;;;;;;;;:132;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60213:12;:24;60226:10;60213:24;;;;;;;;;;;;;;;60243:8;;60252:1;60243:11;;;;;;;:::i;:::-;;;;;;;;60213:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60334:1;60300:12;:24;60313:10;60300:24;;;;;;;;;;;;;;;:31;;;;:35;;;;:::i;:::-;60270:14;:27;60285:8;;60294:1;60285:11;;;;;;;:::i;:::-;;;;;;;;60270:27;;;;;;;;;;;:65;;;;59860:3;;;;;:::i;:::-;;;;59819:528;;;;60378:8;;:15;;60357:17;;:36;;;;;;;:::i;:::-;;;;;;;;21565:20:::0;:18;:20::i;:::-;59552:849;;:::o;64706:167::-;64798:6;64824:41;;;64817:48;;64706:167;;;;;;;:::o;48655:131::-;48729:7;48756:6;:12;48763:4;48756:12;;;;;;;;;;;:22;;;48749:29;;48655:131;;;:::o;58395:49::-;;;;;;;;;;;;;;;;;:::o;49096:147::-;49179:18;49192:4;49179:12;:18::i;:::-;46724:16;46735:4;46724:10;:16::i;:::-;49210:25:::1;49221:4;49227:7;49210:10;:25::i;:::-;49096:147:::0;;;:::o;57956:22::-;;;;:::o;50240:218::-;50347:12;:10;:12::i;:::-;50336:23;;:7;:23;;;50328:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;50424:26;50436:4;50442:7;50424:11;:26::i;:::-;50240:218;;:::o;58203:46::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;61824:100::-;21521:21;:19;:21::i;:::-;61872:25:::1;61886:10;61872:13;:25::i;:::-;61908:8;:6;:8::i;:::-;21565:20:::0;:18;:20::i;:::-;61824:100::o;57895:25::-;;;;;;;;;;;;;:::o;61432:239::-;21521:21;:19;:21::i;:::-;61544:1:::1;61525:8;;:15;;:20:::0;61517:62:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;61590:25;61604:10;61590:13;:25::i;:::-;61626:8;:6;:8::i;:::-;61645:18;61654:8;;61645;:18::i;:::-;21565:20:::0;:18;:20::i;:::-;61432:239;;:::o;62773:128::-;62836:16;62872:12;:21;62885:7;62872:21;;;;;;;;;;;;;;;62865:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62773:128;;;:::o;58138:58::-;;;;;;;;;;;;;;;;;:::o;63930:258::-;63978:7;64023:1;64002:17;;:22;63998:56;;64033:21;;64026:28;;;;63998:56;64162:17;;64148:10;;64130:14;;64101:26;:24;:26::i;:::-;:43;;;;:::i;:::-;64100:58;;;;:::i;:::-;64099:80;;;;:::i;:::-;64074:21;;:106;;;;:::i;:::-;64067:113;;63930:258;;:::o;57794:60::-;57831:23;57794:60;:::o;62978:369::-;63045:18;63076:27;63106:12;:21;63119:7;63106:21;;;;;;;;;;;;;;;63076:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63138:23;63180:10;:17;63164:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;63138:60;;63214:9;63209:109;63233:10;:17;63229:1;:21;63209:109;;;63282:9;:24;63292:10;63303:1;63292:13;;;;;;;;:::i;:::-;;;;;;;;63282:24;;;;;;;;;;;63272:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:4;63277:1;63272:7;;;;;;;;:::i;:::-;;;;;;;:34;;;;63252:3;;;;;:::i;:::-;;;;63209:109;;;;63335:4;63328:11;;;;62978:369;;;:::o;57985:25::-;;;;:::o;64196:145::-;64253:7;64298;;64280:15;:25;:53;;64326:7;;64280:53;;;64308:15;64280:53;64273:60;;64196:145;:::o;59358:160::-;64410:31;57831:23;64430:10;64410:7;:31::i;:::-;64402:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;59434:1:::1;59416:14;;:19;59408:59;;;;;;;;;;;;:::i;:::-;;;;;;;;;59495:15;59478:14;:32;;;;59358:160::o:0;47128:147::-;47214:4;47238:6;:12;47245:4;47238:12;;;;;;;;;;;:20;;:29;47259:7;47238:29;;;;;;;;;;;;;;;;;;;;;;;;;47231:36;;47128:147;;;;:::o;62198:567::-;62265:7;62312:1;62289:25;;:11;:25;;;62285:39;;62323:1;62316:8;;;;62285:39;62335:30;62368:21;;62335:54;;62426:1;62406:17;;:21;62402:96;;;62469:17;:15;:17::i;:::-;62444:42;;62402:96;62510:23;62536:12;:25;62549:11;62536:25;;;;;;;;;;;;;;;:32;;;;62510:58;;62579:14;62662:15;62622:23;:36;62646:11;62622:36;;;;;;;;;;;;;;;;62597:22;:61;;;;:::i;:::-;62596:81;;;;:::i;:::-;62579:98;;62698:20;:33;62719:11;62698:33;;;;;;;;;;;;;;;;62688:43;;;;;:::i;:::-;;;62751:6;62744:13;;;;;62198:567;;;;:::o;46233:49::-;46278:4;46233:49;;;:::o;64496:190::-;64410:31;57831:23;64430:10;64410:7;:31::i;:::-;64402:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;64598:1:::1;64584:11;:15;64576:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;64667:11;64656:7;;:22;;;;;;;:::i;:::-;;;;;;;;64496:190:::0;:::o;58097:32::-;;;;:::o;61704:112::-;21521:21;:19;:21::i;:::-;61790:18:::1;61799:8;;61790;:18::i;:::-;21565:20:::0;:18;:20::i;:::-;61704:112;;:::o;58017:29::-;;;;:::o;58494:55::-;;;;;;;;;;;;;;;;;:::o;49536:149::-;49620:18;49633:4;49620:12;:18::i;:::-;46724:16;46735:4;46724:10;:16::i;:::-;49651:26:::1;49663:4;49669:7;49651:11;:26::i;:::-;49536:149:::0;;;:::o;57863:25::-;;;;;;;;;;;;;:::o;57927:20::-;;;;;;;;;;;;;:::o;44091:157::-;44176:4;44215:25;44200:40;;;:11;:40;;;;44193:47;;44091:157;;;:::o;21601:293::-;21003:1;21735:7;;:19;21727:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;21003:1;21868:7;:18;;;;21601:293::o;63368:554::-;63452:1;63432:17;;:21;63428:153;;;63494:17;:15;:17::i;:::-;63470:21;:41;;;;63543:26;:24;:26::i;:::-;63526:14;:43;;;;63428:153;63614:1;63595:21;;:7;:21;;;63591:34;63618:7;63591:34;63637:23;63663:12;:21;63676:7;63663:21;;;;;;;;;;;;;;;:28;;;;63637:54;;63704:14;63782:15;63746:23;:32;63770:7;63746:32;;;;;;;;;;;;;;;;63722:21;;:56;;;;:::i;:::-;63721:76;;;;:::i;:::-;63704:93;;63841:6;63808:20;:29;63829:7;63808:29;;;;;;;;;;;;;;;;:39;;;;;;;:::i;:::-;;;;;;;;63893:21;;63858:23;:32;63882:7;63858:32;;;;;;;;;;;;;;;:56;;;;63417:505;;63368:554;;:::o;21902:213::-;20959:1;22085:7;:22;;;;21902:213::o;47579:105::-;47646:30;47657:4;47663:12;:10;:12::i;:::-;47646:10;:30::i;:::-;47579:105;:::o;51837:238::-;51921:22;51929:4;51935:7;51921;:22::i;:::-;51916:152;;51992:4;51960:6;:12;51967:4;51960:12;;;;;;;;;;;:20;;:29;51981:7;51960:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;52043:12;:10;:12::i;:::-;52016:40;;52034:7;52016:40;;52028:4;52016:40;;;;;;;;;;51916:152;51837:238;;:::o;38000:98::-;38053:7;38080:10;38073:17;;38000:98;:::o;52255:239::-;52339:22;52347:4;52353:7;52339;:22::i;:::-;52335:152;;;52410:5;52378:6;:12;52385:4;52378:12;;;;;;;;;;;:20;;:29;52399:7;52378:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;52462:12;:10;:12::i;:::-;52435:40;;52453:7;52435:40;;52447:4;52435:40;;;;;;;;;;52335:152;52255:239;;:::o;61932:258::-;61969:14;61986:20;:32;62007:10;61986:32;;;;;;;;;;;;;;;;61969:49;;62043:1;62033:6;:11;62029:24;;62046:7;;;62029:24;62065:70;62090:10;62102:20;:32;62123:10;62102:32;;;;;;;;;;;;;;;;62065:11;;;;;;;;;;;:24;;;;:70;;;;;:::i;:::-;62181:1;62146:20;:32;62167:10;62146:32;;;;;;;;;;;;;;;:36;;;;61958:232;61932:258;:::o;60409:1015::-;60482:9;60477:893;60501:8;;:15;;60497:1;:19;60477:893;;;60597:10;60564:43;;:9;:22;60574:8;;60583:1;60574:11;;;;;;;:::i;:::-;;;;;;;;60564:22;;;;;;;;;;;:29;;;;;;;;;;;;:43;;;60538:141;;;;;;;;;;;;:::i;:::-;;;;;;;;;60696:10;;;;;;;;;;;:27;;;60732:4;60739:10;60751:8;;60760:1;60751:11;;;;;;;:::i;:::-;;;;;;;;60696:67;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60906:17;60960:1;60926:12;:24;60939:10;60926:24;;;;;;;;;;;;;;;:31;;;;:35;;;;:::i;:::-;60906:55;;60976:19;60998:12;:24;61011:10;60998:24;;;;;;;;;;;;;;;61023:9;60998:35;;;;;;;;:::i;:::-;;;;;;;;;;60976:57;;61050:18;61071:14;:27;61086:8;;61095:1;61086:11;;;;;;;:::i;:::-;;;;;;;;61071:27;;;;;;;;;;;;61050:48;;61152:11;61113:12;:24;61126:10;61113:24;;;;;;;;;;;;;;;61138:10;61113:36;;;;;;;;:::i;:::-;;;;;;;;;:50;;;;61208:10;61178:14;:27;61193:11;61178:27;;;;;;;;;;;:40;;;;61235:12;:24;61248:10;61235:24;;;;;;;;;;;;;;;:30;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;61287:14;:27;61302:8;;61311:1;61302:11;;;;;;;:::i;:::-;;;;;;;;61287:27;;;;;;;;;;;61280:34;;;61336:9;:22;61346:8;;61355:1;61346:11;;;;;;;:::i;:::-;;;;;;;;61336:22;;;;;;;;;;;;61329:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60523:847;;;60518:3;;;;;:::i;:::-;;;;60477:893;;;;61401:8;;:15;;61380:17;;:36;;;;;;;:::i;:::-;;;;;;;;60409:1015;;:::o;47974:492::-;48063:22;48071:4;48077:7;48063;:22::i;:::-;48058:401;;48251:28;48271:7;48251:19;:28::i;:::-;48352:38;48380:4;48372:13;;48387:2;48352:19;:38::i;:::-;48156:257;;;;;;;;;:::i;:::-;;;;;;;;;;;;;48102:345;;;;;;;;;;;:::i;:::-;;;;;;;;48058:401;47974:492;;:::o;15386:211::-;15503:86;15523:5;15553:23;;;15578:2;15582:5;15530:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15503:19;:86::i;:::-;15386:211;;;:::o;37163:151::-;37221:13;37254:52;37282:4;37266:22;;35318:2;37254:52;;:11;:52::i;:::-;37247:59;;37163:151;;;:::o;36559:447::-;36634:13;36660:19;36705:1;36696:6;36692:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;36682:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36660:47;;36718:15;:6;36725:1;36718:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;36744;:6;36751:1;36744:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;36775:9;36800:1;36791:6;36787:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;36775:26;;36770:131;36807:1;36803;:5;36770:131;;;36842:8;36859:3;36851:5;:11;36842:21;;;;;;;:::i;:::-;;;;;36830:6;36837:1;36830:9;;;;;;;;:::i;:::-;;;;;:33;;;;;;;;;;;36888:1;36878:11;;;;;36810:3;;;;:::i;:::-;;;36770:131;;;;36928:1;36919:5;:10;36911:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;36991:6;36977:21;;;36559:447;;;;:::o;18453:716::-;18877:23;18903:69;18931:4;18903:69;;;;;;;;;;;;;;;;;18911:5;18903:27;;;;:69;;;;;:::i;:::-;18877:95;;19007:1;18987:10;:17;:21;18983:179;;;19084:10;19073:30;;;;;;;;;;;;:::i;:::-;19065:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;18983:179;18523:646;18453:716;;:::o;3990:229::-;4127:12;4159:52;4181:6;4189:4;4195:1;4198:12;4159:21;:52::i;:::-;4152:59;;3990:229;;;;;:::o;5110:455::-;5280:12;5338:5;5313:21;:30;;5305:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;5398:12;5412:23;5439:6;:11;;5458:5;5465:4;5439:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5397:73;;;;5488:69;5515:6;5523:7;5532:10;5544:12;5488:26;:69::i;:::-;5481:76;;;;5110:455;;;;;;:::o;7683:644::-;7868:12;7897:7;7893:427;;;7946:1;7925:10;:17;:22;7921:290;;8143:18;8154:6;8143:10;:18::i;:::-;8135:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;7921:290;8232:10;8225:17;;;;7893:427;8275:33;8283:10;8295:12;8275:7;:33::i;:::-;7683:644;;;;;;;:::o;1233:326::-;1293:4;1550:1;1528:7;:19;;;:23;1521:30;;1233:326;;;:::o;8869:552::-;9050:1;9030:10;:17;:21;9026:388;;;9262:10;9256:17;9319:15;9306:10;9302:2;9298:19;9291:44;9026:388;9389:12;9382:20;;;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;88:117:1:-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:117::-;1627:1;1624;1617:12;1641:117;1750:1;1747;1740:12;1764:117;1873:1;1870;1863:12;1904:568;1977:8;1987:6;2037:3;2030:4;2022:6;2018:17;2014:27;2004:122;;2045:79;;:::i;:::-;2004:122;2158:6;2145:20;2135:30;;2188:18;2180:6;2177:30;2174:117;;;2210:79;;:::i;:::-;2174:117;2324:4;2316:6;2312:17;2300:29;;2378:3;2370:4;2362:6;2358:17;2348:8;2344:32;2341:41;2338:128;;;2385:79;;:::i;:::-;2338:128;1904:568;;;;;:::o;2478:559::-;2564:6;2572;2621:2;2609:9;2600:7;2596:23;2592:32;2589:119;;;2627:79;;:::i;:::-;2589:119;2775:1;2764:9;2760:17;2747:31;2805:18;2797:6;2794:30;2791:117;;;2827:79;;:::i;:::-;2791:117;2940:80;3012:7;3003:6;2992:9;2988:22;2940:80;:::i;:::-;2922:98;;;;2718:312;2478:559;;;;;:::o;3043:126::-;3080:7;3120:42;3113:5;3109:54;3098:65;;3043:126;;;:::o;3175:96::-;3212:7;3241:24;3259:5;3241:24;:::i;:::-;3230:35;;3175:96;;;:::o;3277:122::-;3350:24;3368:5;3350:24;:::i;:::-;3343:5;3340:35;3330:63;;3389:1;3386;3379:12;3330:63;3277:122;:::o;3405:139::-;3451:5;3489:6;3476:20;3467:29;;3505:33;3532:5;3505:33;:::i;:::-;3405:139;;;;:::o;3550:77::-;3587:7;3616:5;3605:16;;3550:77;;;:::o;3633:122::-;3706:24;3724:5;3706:24;:::i;:::-;3699:5;3696:35;3686:63;;3745:1;3742;3735:12;3686:63;3633:122;:::o;3761:139::-;3807:5;3845:6;3832:20;3823:29;;3861:33;3888:5;3861:33;:::i;:::-;3761:139;;;;:::o;3919:552::-;3976:8;3986:6;4036:3;4029:4;4021:6;4017:17;4013:27;4003:122;;4044:79;;:::i;:::-;4003:122;4157:6;4144:20;4134:30;;4187:18;4179:6;4176:30;4173:117;;;4209:79;;:::i;:::-;4173:117;4323:4;4315:6;4311:17;4299:29;;4377:3;4369:4;4361:6;4357:17;4347:8;4343:32;4340:41;4337:128;;;4384:79;;:::i;:::-;4337:128;3919:552;;;;;:::o;4477:963::-;4574:6;4582;4590;4598;4606;4655:3;4643:9;4634:7;4630:23;4626:33;4623:120;;;4662:79;;:::i;:::-;4623:120;4782:1;4807:53;4852:7;4843:6;4832:9;4828:22;4807:53;:::i;:::-;4797:63;;4753:117;4909:2;4935:53;4980:7;4971:6;4960:9;4956:22;4935:53;:::i;:::-;4925:63;;4880:118;5037:2;5063:53;5108:7;5099:6;5088:9;5084:22;5063:53;:::i;:::-;5053:63;;5008:118;5193:2;5182:9;5178:18;5165:32;5224:18;5216:6;5213:30;5210:117;;;5246:79;;:::i;:::-;5210:117;5359:64;5415:7;5406:6;5395:9;5391:22;5359:64;:::i;:::-;5341:82;;;;5136:297;4477:963;;;;;;;;:::o;5446:115::-;5531:23;5548:5;5531:23;:::i;:::-;5526:3;5519:36;5446:115;;:::o;5567:218::-;5658:4;5696:2;5685:9;5681:18;5673:26;;5709:69;5775:1;5764:9;5760:17;5751:6;5709:69;:::i;:::-;5567:218;;;;:::o;5791:77::-;5828:7;5857:5;5846:16;;5791:77;;;:::o;5874:122::-;5947:24;5965:5;5947:24;:::i;:::-;5940:5;5937:35;5927:63;;5986:1;5983;5976:12;5927:63;5874:122;:::o;6002:139::-;6048:5;6086:6;6073:20;6064:29;;6102:33;6129:5;6102:33;:::i;:::-;6002:139;;;;:::o;6147:329::-;6206:6;6255:2;6243:9;6234:7;6230:23;6226:32;6223:119;;;6261:79;;:::i;:::-;6223:119;6381:1;6406:53;6451:7;6442:6;6431:9;6427:22;6406:53;:::i;:::-;6396:63;;6352:117;6147:329;;;;:::o;6482:118::-;6569:24;6587:5;6569:24;:::i;:::-;6564:3;6557:37;6482:118;;:::o;6606:222::-;6699:4;6737:2;6726:9;6722:18;6714:26;;6750:71;6818:1;6807:9;6803:17;6794:6;6750:71;:::i;:::-;6606:222;;;;:::o;6834:329::-;6893:6;6942:2;6930:9;6921:7;6917:23;6913:32;6910:119;;;6948:79;;:::i;:::-;6910:119;7068:1;7093:53;7138:7;7129:6;7118:9;7114:22;7093:53;:::i;:::-;7083:63;;7039:117;6834:329;;;;:::o;7169:118::-;7256:24;7274:5;7256:24;:::i;:::-;7251:3;7244:37;7169:118;;:::o;7293:222::-;7386:4;7424:2;7413:9;7409:18;7401:26;;7437:71;7505:1;7494:9;7490:17;7481:6;7437:71;:::i;:::-;7293:222;;;;:::o;7521:474::-;7589:6;7597;7646:2;7634:9;7625:7;7621:23;7617:32;7614:119;;;7652:79;;:::i;:::-;7614:119;7772:1;7797:53;7842:7;7833:6;7822:9;7818:22;7797:53;:::i;:::-;7787:63;;7743:117;7899:2;7925:53;7970:7;7961:6;7950:9;7946:22;7925:53;:::i;:::-;7915:63;;7870:118;7521:474;;;;;:::o;8001:118::-;8088:24;8106:5;8088:24;:::i;:::-;8083:3;8076:37;8001:118;;:::o;8125:442::-;8274:4;8312:2;8301:9;8297:18;8289:26;;8325:71;8393:1;8382:9;8378:17;8369:6;8325:71;:::i;:::-;8406:72;8474:2;8463:9;8459:18;8450:6;8406:72;:::i;:::-;8488;8556:2;8545:9;8541:18;8532:6;8488:72;:::i;:::-;8125:442;;;;;;:::o;8573:60::-;8601:3;8622:5;8615:12;;8573:60;;;:::o;8639:142::-;8689:9;8722:53;8740:34;8749:24;8767:5;8749:24;:::i;:::-;8740:34;:::i;:::-;8722:53;:::i;:::-;8709:66;;8639:142;;;:::o;8787:126::-;8837:9;8870:37;8901:5;8870:37;:::i;:::-;8857:50;;8787:126;;;:::o;8919:142::-;8985:9;9018:37;9049:5;9018:37;:::i;:::-;9005:50;;8919:142;;;:::o;9067:163::-;9170:53;9217:5;9170:53;:::i;:::-;9165:3;9158:66;9067:163;;:::o;9236:254::-;9345:4;9383:2;9372:9;9368:18;9360:26;;9396:87;9480:1;9469:9;9465:17;9456:6;9396:87;:::i;:::-;9236:254;;;;:::o;9496:329::-;9555:6;9604:2;9592:9;9583:7;9579:23;9575:32;9572:119;;;9610:79;;:::i;:::-;9572:119;9730:1;9755:53;9800:7;9791:6;9780:9;9776:22;9755:53;:::i;:::-;9745:63;;9701:117;9496:329;;;;:::o;9831:114::-;9898:6;9932:5;9926:12;9916:22;;9831:114;;;:::o;9951:184::-;10050:11;10084:6;10079:3;10072:19;10124:4;10119:3;10115:14;10100:29;;9951:184;;;;:::o;10141:132::-;10208:4;10231:3;10223:11;;10261:4;10256:3;10252:14;10244:22;;10141:132;;;:::o;10279:108::-;10356:24;10374:5;10356:24;:::i;:::-;10351:3;10344:37;10279:108;;:::o;10393:179::-;10462:10;10483:46;10525:3;10517:6;10483:46;:::i;:::-;10561:4;10556:3;10552:14;10538:28;;10393:179;;;;:::o;10578:113::-;10648:4;10680;10675:3;10671:14;10663:22;;10578:113;;;:::o;10727:732::-;10846:3;10875:54;10923:5;10875:54;:::i;:::-;10945:86;11024:6;11019:3;10945:86;:::i;:::-;10938:93;;11055:56;11105:5;11055:56;:::i;:::-;11134:7;11165:1;11150:284;11175:6;11172:1;11169:13;11150:284;;;11251:6;11245:13;11278:63;11337:3;11322:13;11278:63;:::i;:::-;11271:70;;11364:60;11417:6;11364:60;:::i;:::-;11354:70;;11210:224;11197:1;11194;11190:9;11185:14;;11150:284;;;11154:14;11450:3;11443:10;;10851:608;;;10727:732;;;;:::o;11465:373::-;11608:4;11646:2;11635:9;11631:18;11623:26;;11695:9;11689:4;11685:20;11681:1;11670:9;11666:17;11659:47;11723:108;11826:4;11817:6;11723:108;:::i;:::-;11715:116;;11465:373;;;;:::o;11844:141::-;11938:6;11972:5;11966:12;11956:22;;11844:141;;;:::o;11991:211::-;12117:11;12151:6;12146:3;12139:19;12191:4;12186:3;12182:14;12167:29;;11991:211;;;;:::o;12208:159::-;12302:4;12325:3;12317:11;;12355:4;12350:3;12346:14;12338:22;;12208:159;;;:::o;12373:108::-;12450:24;12468:5;12450:24;:::i;:::-;12445:3;12438:37;12373:108;;:::o;12559:684::-;12700:4;12695:3;12691:14;12789:4;12782:5;12778:16;12772:23;12808:63;12865:4;12860:3;12856:14;12842:12;12808:63;:::i;:::-;12715:166;12968:4;12961:5;12957:16;12951:23;12987:63;13044:4;13039:3;13035:14;13021:12;12987:63;:::i;:::-;12891:169;13144:4;13137:5;13133:16;13127:23;13163:63;13220:4;13215:3;13211:14;13197:12;13163:63;:::i;:::-;13070:166;12669:574;12559:684;;:::o;13249:287::-;13372:10;13393:100;13489:3;13481:6;13393:100;:::i;:::-;13525:4;13520:3;13516:14;13502:28;;13249:287;;;;:::o;13542:140::-;13639:4;13671;13666:3;13662:14;13654:22;;13542:140;;;:::o;13764:948::-;13937:3;13966:81;14041:5;13966:81;:::i;:::-;14063:113;14169:6;14164:3;14063:113;:::i;:::-;14056:120;;14200:83;14277:5;14200:83;:::i;:::-;14306:7;14337:1;14322:365;14347:6;14344:1;14341:13;14322:365;;;14423:6;14417:13;14450:117;14563:3;14548:13;14450:117;:::i;:::-;14443:124;;14590:87;14670:6;14590:87;:::i;:::-;14580:97;;14382:305;14369:1;14366;14362:9;14357:14;;14322:365;;;14326:14;14703:3;14696:10;;13942:770;;;13764:948;;;;:::o;14718:481::-;14915:4;14953:2;14942:9;14938:18;14930:26;;15002:9;14996:4;14992:20;14988:1;14977:9;14973:17;14966:47;15030:162;15187:4;15178:6;15030:162;:::i;:::-;15022:170;;14718:481;;;;:::o;15205:140::-;15269:9;15302:37;15333:5;15302:37;:::i;:::-;15289:50;;15205:140;;;:::o;15351:159::-;15452:51;15497:5;15452:51;:::i;:::-;15447:3;15440:64;15351:159;;:::o;15516:250::-;15623:4;15661:2;15650:9;15646:18;15638:26;;15674:85;15756:1;15745:9;15741:17;15732:6;15674:85;:::i;:::-;15516:250;;;;:::o;15772:222::-;15865:4;15903:2;15892:9;15888:18;15880:26;;15916:71;15984:1;15973:9;15969:17;15960:6;15916:71;:::i;:::-;15772:222;;;;:::o;16000:169::-;16084:11;16118:6;16113:3;16106:19;16158:4;16153:3;16149:14;16134:29;;16000:169;;;;:::o;16175:179::-;16315:31;16311:1;16303:6;16299:14;16292:55;16175:179;:::o;16360:366::-;16502:3;16523:67;16587:2;16582:3;16523:67;:::i;:::-;16516:74;;16599:93;16688:3;16599:93;:::i;:::-;16717:2;16712:3;16708:12;16701:19;;16360:366;;;:::o;16732:419::-;16898:4;16936:2;16925:9;16921:18;16913:26;;16985:9;16979:4;16975:20;16971:1;16960:9;16956:17;16949:47;17013:131;17139:4;17013:131;:::i;:::-;17005:139;;16732:419;;;:::o;17157:178::-;17297:30;17293:1;17285:6;17281:14;17274:54;17157:178;:::o;17341:366::-;17483:3;17504:67;17568:2;17563:3;17504:67;:::i;:::-;17497:74;;17580:93;17669:3;17580:93;:::i;:::-;17698:2;17693:3;17689:12;17682:19;;17341:366;;;:::o;17713:419::-;17879:4;17917:2;17906:9;17902:18;17894:26;;17966:9;17960:4;17956:20;17952:1;17941:9;17937:17;17930:47;17994:131;18120:4;17994:131;:::i;:::-;17986:139;;17713:419;;;:::o;18138:180::-;18186:77;18183:1;18176:88;18283:4;18280:1;18273:15;18307:4;18304:1;18297:15;18324:179;18464:31;18460:1;18452:6;18448:14;18441:55;18324:179;:::o;18509:366::-;18651:3;18672:67;18736:2;18731:3;18672:67;:::i;:::-;18665:74;;18748:93;18837:3;18748:93;:::i;:::-;18866:2;18861:3;18857:12;18850:19;;18509:366;;;:::o;18881:419::-;19047:4;19085:2;19074:9;19070:18;19062:26;;19134:9;19128:4;19124:20;19120:1;19109:9;19105:17;19098:47;19162:131;19288:4;19162:131;:::i;:::-;19154:139;;18881:419;;;:::o;19306:442::-;19455:4;19493:2;19482:9;19478:18;19470:26;;19506:71;19574:1;19563:9;19559:17;19550:6;19506:71;:::i;:::-;19587:72;19655:2;19644:9;19640:18;19631:6;19587:72;:::i;:::-;19669;19737:2;19726:9;19722:18;19713:6;19669:72;:::i;:::-;19306:442;;;;;;:::o;19754:180::-;19802:77;19799:1;19792:88;19899:4;19896:1;19889:15;19923:4;19920:1;19913:15;19940:194;19980:4;20000:20;20018:1;20000:20;:::i;:::-;19995:25;;20034:20;20052:1;20034:20;:::i;:::-;20029:25;;20078:1;20075;20071:9;20063:17;;20102:1;20096:4;20093:11;20090:37;;;20107:18;;:::i;:::-;20090:37;19940:194;;;;:::o;20140:233::-;20179:3;20202:24;20220:5;20202:24;:::i;:::-;20193:33;;20248:66;20241:5;20238:77;20235:103;;20318:18;;:::i;:::-;20235:103;20365:1;20358:5;20354:13;20347:20;;20140:233;;;:::o;20379:191::-;20419:3;20438:20;20456:1;20438:20;:::i;:::-;20433:25;;20472:20;20490:1;20472:20;:::i;:::-;20467:25;;20515:1;20512;20508:9;20501:16;;20536:3;20533:1;20530:10;20527:36;;;20543:18;;:::i;:::-;20527:36;20379:191;;;;:::o;20576:234::-;20716:34;20712:1;20704:6;20700:14;20693:58;20785:17;20780:2;20772:6;20768:15;20761:42;20576:234;:::o;20816:366::-;20958:3;20979:67;21043:2;21038:3;20979:67;:::i;:::-;20972:74;;21055:93;21144:3;21055:93;:::i;:::-;21173:2;21168:3;21164:12;21157:19;;20816:366;;;:::o;21188:419::-;21354:4;21392:2;21381:9;21377:18;21369:26;;21441:9;21435:4;21431:20;21427:1;21416:9;21412:17;21405:47;21469:131;21595:4;21469:131;:::i;:::-;21461:139;;21188:419;;;:::o;21613:410::-;21653:7;21676:20;21694:1;21676:20;:::i;:::-;21671:25;;21710:20;21728:1;21710:20;:::i;:::-;21705:25;;21765:1;21762;21758:9;21787:30;21805:11;21787:30;:::i;:::-;21776:41;;21966:1;21957:7;21953:15;21950:1;21947:22;21927:1;21920:9;21900:83;21877:139;;21996:18;;:::i;:::-;21877:139;21661:362;21613:410;;;;:::o;22029:180::-;22077:77;22074:1;22067:88;22174:4;22171:1;22164:15;22198:4;22195:1;22188:15;22215:185;22255:1;22272:20;22290:1;22272:20;:::i;:::-;22267:25;;22306:20;22324:1;22306:20;:::i;:::-;22301:25;;22345:1;22335:35;;22350:18;;:::i;:::-;22335:35;22392:1;22389;22385:9;22380:14;;22215:185;;;;:::o;22406:180::-;22454:77;22451:1;22444:88;22551:4;22548:1;22541:15;22575:4;22572:1;22565:15;22592:172;22732:24;22728:1;22720:6;22716:14;22709:48;22592:172;:::o;22770:366::-;22912:3;22933:67;22997:2;22992:3;22933:67;:::i;:::-;22926:74;;23009:93;23098:3;23009:93;:::i;:::-;23127:2;23122:3;23118:12;23111:19;;22770:366;;;:::o;23142:419::-;23308:4;23346:2;23335:9;23331:18;23323:26;;23395:9;23389:4;23385:20;23381:1;23370:9;23366:17;23359:47;23423:131;23549:4;23423:131;:::i;:::-;23415:139;;23142:419;;;:::o;23567:177::-;23707:29;23703:1;23695:6;23691:14;23684:53;23567:177;:::o;23750:366::-;23892:3;23913:67;23977:2;23972:3;23913:67;:::i;:::-;23906:74;;23989:93;24078:3;23989:93;:::i;:::-;24107:2;24102:3;24098:12;24091:19;;23750:366;;;:::o;24122:419::-;24288:4;24326:2;24315:9;24311:18;24303:26;;24375:9;24369:4;24365:20;24361:1;24350:9;24346:17;24339:47;24403:131;24529:4;24403:131;:::i;:::-;24395:139;;24122:419;;;:::o;24547:228::-;24687:34;24683:1;24675:6;24671:14;24664:58;24756:11;24751:2;24743:6;24739:15;24732:36;24547:228;:::o;24781:366::-;24923:3;24944:67;25008:2;25003:3;24944:67;:::i;:::-;24937:74;;25020:93;25109:3;25020:93;:::i;:::-;25138:2;25133:3;25129:12;25122:19;;24781:366;;;:::o;25153:419::-;25319:4;25357:2;25346:9;25342:18;25334:26;;25406:9;25400:4;25396:20;25392:1;25381:9;25377:17;25370:47;25434:131;25560:4;25434:131;:::i;:::-;25426:139;;25153:419;;;:::o;25578:181::-;25718:33;25714:1;25706:6;25702:14;25695:57;25578:181;:::o;25765:366::-;25907:3;25928:67;25992:2;25987:3;25928:67;:::i;:::-;25921:74;;26004:93;26093:3;26004:93;:::i;:::-;26122:2;26117:3;26113:12;26106:19;;25765:366;;;:::o;26137:419::-;26303:4;26341:2;26330:9;26326:18;26318:26;;26390:9;26384:4;26380:20;26376:1;26365:9;26361:17;26354:47;26418:131;26544:4;26418:131;:::i;:::-;26410:139;;26137:419;;;:::o;26562:223::-;26702:34;26698:1;26690:6;26686:14;26679:58;26771:6;26766:2;26758:6;26754:15;26747:31;26562:223;:::o;26791:366::-;26933:3;26954:67;27018:2;27013:3;26954:67;:::i;:::-;26947:74;;27030:93;27119:3;27030:93;:::i;:::-;27148:2;27143:3;27139:12;27132:19;;26791:366;;;:::o;27163:419::-;27329:4;27367:2;27356:9;27352:18;27344:26;;27416:9;27410:4;27406:20;27402:1;27391:9;27387:17;27380:47;27444:131;27570:4;27444:131;:::i;:::-;27436:139;;27163:419;;;:::o;27588:180::-;27636:77;27633:1;27626:88;27733:4;27730:1;27723:15;27757:4;27754:1;27747:15;27774:148;27876:11;27913:3;27898:18;;27774:148;;;;:::o;27928:173::-;28068:25;28064:1;28056:6;28052:14;28045:49;27928:173;:::o;28107:402::-;28267:3;28288:85;28370:2;28365:3;28288:85;:::i;:::-;28281:92;;28382:93;28471:3;28382:93;:::i;:::-;28500:2;28495:3;28491:12;28484:19;;28107:402;;;:::o;28515:99::-;28567:6;28601:5;28595:12;28585:22;;28515:99;;;:::o;28620:246::-;28701:1;28711:113;28725:6;28722:1;28719:13;28711:113;;;28810:1;28805:3;28801:11;28795:18;28791:1;28786:3;28782:11;28775:39;28747:2;28744:1;28740:10;28735:15;;28711:113;;;28858:1;28849:6;28844:3;28840:16;28833:27;28682:184;28620:246;;;:::o;28872:390::-;28978:3;29006:39;29039:5;29006:39;:::i;:::-;29061:89;29143:6;29138:3;29061:89;:::i;:::-;29054:96;;29159:65;29217:6;29212:3;29205:4;29198:5;29194:16;29159:65;:::i;:::-;29249:6;29244:3;29240:16;29233:23;;28982:280;28872:390;;;;:::o;29268:167::-;29408:19;29404:1;29396:6;29392:14;29385:43;29268:167;:::o;29441:402::-;29601:3;29622:85;29704:2;29699:3;29622:85;:::i;:::-;29615:92;;29716:93;29805:3;29716:93;:::i;:::-;29834:2;29829:3;29825:12;29818:19;;29441:402;;;:::o;29849:967::-;30231:3;30253:148;30397:3;30253:148;:::i;:::-;30246:155;;30418:95;30509:3;30500:6;30418:95;:::i;:::-;30411:102;;30530:148;30674:3;30530:148;:::i;:::-;30523:155;;30695:95;30786:3;30777:6;30695:95;:::i;:::-;30688:102;;30807:3;30800:10;;29849:967;;;;;:::o;30822:102::-;30863:6;30914:2;30910:7;30905:2;30898:5;30894:14;30890:28;30880:38;;30822:102;;;:::o;30930:377::-;31018:3;31046:39;31079:5;31046:39;:::i;:::-;31101:71;31165:6;31160:3;31101:71;:::i;:::-;31094:78;;31181:65;31239:6;31234:3;31227:4;31220:5;31216:16;31181:65;:::i;:::-;31271:29;31293:6;31271:29;:::i;:::-;31266:3;31262:39;31255:46;;31022:285;30930:377;;;;:::o;31313:313::-;31426:4;31464:2;31453:9;31449:18;31441:26;;31513:9;31507:4;31503:20;31499:1;31488:9;31484:17;31477:47;31541:78;31614:4;31605:6;31541:78;:::i;:::-;31533:86;;31313:313;;;;:::o;31632:332::-;31753:4;31791:2;31780:9;31776:18;31768:26;;31804:71;31872:1;31861:9;31857:17;31848:6;31804:71;:::i;:::-;31885:72;31953:2;31942:9;31938:18;31929:6;31885:72;:::i;:::-;31632:332;;;;;:::o;31970:171::-;32009:3;32032:24;32050:5;32032:24;:::i;:::-;32023:33;;32078:4;32071:5;32068:15;32065:41;;32086:18;;:::i;:::-;32065:41;32133:1;32126:5;32122:13;32115:20;;31970:171;;;:::o;32147:182::-;32287:34;32283:1;32275:6;32271:14;32264:58;32147:182;:::o;32335:366::-;32477:3;32498:67;32562:2;32557:3;32498:67;:::i;:::-;32491:74;;32574:93;32663:3;32574:93;:::i;:::-;32692:2;32687:3;32683:12;32676:19;;32335:366;;;:::o;32707:419::-;32873:4;32911:2;32900:9;32896:18;32888:26;;32960:9;32954:4;32950:20;32946:1;32935:9;32931:17;32924:47;32988:131;33114:4;32988:131;:::i;:::-;32980:139;;32707:419;;;:::o;33132:116::-;33202:21;33217:5;33202:21;:::i;:::-;33195:5;33192:32;33182:60;;33238:1;33235;33228:12;33182:60;33132:116;:::o;33254:137::-;33308:5;33339:6;33333:13;33324:22;;33355:30;33379:5;33355:30;:::i;:::-;33254:137;;;;:::o;33397:345::-;33464:6;33513:2;33501:9;33492:7;33488:23;33484:32;33481:119;;;33519:79;;:::i;:::-;33481:119;33639:1;33664:61;33717:7;33708:6;33697:9;33693:22;33664:61;:::i;:::-;33654:71;;33610:125;33397:345;;;;:::o;33748:229::-;33888:34;33884:1;33876:6;33872:14;33865:58;33957:12;33952:2;33944:6;33940:15;33933:37;33748:229;:::o;33983:366::-;34125:3;34146:67;34210:2;34205:3;34146:67;:::i;:::-;34139:74;;34222:93;34311:3;34222:93;:::i;:::-;34340:2;34335:3;34331:12;34324:19;;33983:366;;;:::o;34355:419::-;34521:4;34559:2;34548:9;34544:18;34536:26;;34608:9;34602:4;34598:20;34594:1;34583:9;34579:17;34572:47;34636:131;34762:4;34636:131;:::i;:::-;34628:139;;34355:419;;;:::o;34780:225::-;34920:34;34916:1;34908:6;34904:14;34897:58;34989:8;34984:2;34976:6;34972:15;34965:33;34780:225;:::o;35011:366::-;35153:3;35174:67;35238:2;35233:3;35174:67;:::i;:::-;35167:74;;35250:93;35339:3;35250:93;:::i;:::-;35368:2;35363:3;35359:12;35352:19;;35011:366;;;:::o;35383:419::-;35549:4;35587:2;35576:9;35572:18;35564:26;;35636:9;35630:4;35626:20;35622:1;35611:9;35607:17;35600:47;35664:131;35790:4;35664:131;:::i;:::-;35656:139;;35383:419;;;:::o;35808:98::-;35859:6;35893:5;35887:12;35877:22;;35808:98;;;:::o;35912:147::-;36013:11;36050:3;36035:18;;35912:147;;;;:::o;36065:386::-;36169:3;36197:38;36229:5;36197:38;:::i;:::-;36251:88;36332:6;36327:3;36251:88;:::i;:::-;36244:95;;36348:65;36406:6;36401:3;36394:4;36387:5;36383:16;36348:65;:::i;:::-;36438:6;36433:3;36429:16;36422:23;;36173:278;36065:386;;;;:::o;36457:271::-;36587:3;36609:93;36698:3;36689:6;36609:93;:::i;:::-;36602:100;;36719:3;36712:10;;36457:271;;;;:::o;36734:179::-;36874:31;36870:1;36862:6;36858:14;36851:55;36734:179;:::o;36919:366::-;37061:3;37082:67;37146:2;37141:3;37082:67;:::i;:::-;37075:74;;37158:93;37247:3;37158:93;:::i;:::-;37276:2;37271:3;37267:12;37260:19;;36919:366;;;:::o;37291:419::-;37457:4;37495:2;37484:9;37480:18;37472:26;;37544:9;37538:4;37534:20;37530:1;37519:9;37515:17;37508:47;37572:131;37698:4;37572:131;:::i;:::-;37564:139;;37291:419;;;:::o
Swarm Source
ipfs://50362079720d7f4b5e416e90459e22e1c5009fbcb0cf24c3ba970f5e53d87849
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.