Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 1,168 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Transfer | 4961013 | 797 days ago | IN | 0 GLMR | 0.04789049 | ||||
| Transfer | 4961003 | 797 days ago | IN | 0 GLMR | 0.04537011 | ||||
| Transfer | 4961001 | 797 days ago | IN | 0 GLMR | 0.037404 | ||||
| Transfer | 4960998 | 797 days ago | IN | 0 GLMR | 0.03739441 | ||||
| Transfer | 4960996 | 797 days ago | IN | 0 GLMR | 0.03739441 | ||||
| Transfer | 4960994 | 797 days ago | IN | 0 GLMR | 0.03739441 | ||||
| Transfer | 4960992 | 797 days ago | IN | 0 GLMR | 0.03739441 | ||||
| Transfer | 4960990 | 797 days ago | IN | 0 GLMR | 0.03739441 | ||||
| Transfer | 4960987 | 797 days ago | IN | 0 GLMR | 0.06367111 | ||||
| Transfer | 4532840 | 857 days ago | IN | 0 GLMR | 0.05831865 | ||||
| Transfer | 4134977 | 913 days ago | IN | 0 GLMR | 0.05449113 | ||||
| Transfer | 4134828 | 913 days ago | IN | 0 GLMR | 0.02751028 | ||||
| Transfer | 4134816 | 913 days ago | IN | 0 GLMR | 0.06671122 | ||||
| Transfer | 4030175 | 928 days ago | IN | 0 GLMR | 0.04912506 | ||||
| Transfer | 4001786 | 932 days ago | IN | 0 GLMR | 0.01668177 | ||||
| Transfer | 4001776 | 932 days ago | IN | 0 GLMR | 0.01668249 | ||||
| Transfer | 4001744 | 932 days ago | IN | 0 GLMR | 0.03873512 | ||||
| Transfer | 4001674 | 932 days ago | IN | 0 GLMR | 0.04379241 | ||||
| Transfer | 4001584 | 932 days ago | IN | 0 GLMR | 0.02310512 | ||||
| Transfer | 3997610 | 933 days ago | IN | 0 GLMR | 0.09276288 | ||||
| Transfer | 3987535 | 934 days ago | IN | 0 GLMR | 0.05591438 | ||||
| Transfer | 3986678 | 934 days ago | IN | 0 GLMR | 0.05559004 | ||||
| Transfer | 3986206 | 934 days ago | IN | 0 GLMR | 0.04959428 | ||||
| Transfer | 3944176 | 940 days ago | IN | 14 GLMR | 0.00290336 | ||||
| Transfer | 3944167 | 940 days ago | IN | 14.77 GLMR | 0.00269452 |
View more zero value Internal Transactions in Advanced View mode
Cross-Chain Transactions
Loading...
Loading
Contract Name:
AbleSaver
Compiler Version
v0.8.7+commit.e28d00a7
Contract Source Code (Solidity)
/**
*Submitted for verification at moonbeam.moonscan.io on 2023-04-16
*/
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
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);
(bool success, ) = recipient.call{value: amount}("");
require(success);
}
/**
* @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);
}
}
}
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);
}
}
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);
}
}
}
library Counters {
struct Counter {
// This variable should never be directly accessed by users of the library: interactions must be restricted to
// the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
// this feature: see https://github.com/ethereum/solidity/issues/4637
uint256 _value; // default: 0
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
unchecked {
counter._value += 1;
}
}
function decrement(Counter storage counter) internal {
uint256 value = counter._value;
require(value > 0);
unchecked {
counter._value = value - 1;
}
}
function reset(Counter storage counter) internal {
counter._value = 0;
}
}
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(
address owner,
address spender
) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
interface IERC721 is IERC165 {
event Transfer(
address indexed from,
address indexed to,
uint256 indexed tokenId
);
event Approval(
address indexed owner,
address indexed approved,
uint256 indexed tokenId
);
event ApprovalForAll(
address indexed owner,
address indexed operator,
bool approved
);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool _approved) external;
function getApproved(
uint256 tokenId
) external view returns (address operator);
function isApprovedForAll(
address owner,
address operator
) external view returns (bool);
}
interface IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
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);
}
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(
bytes4 interfaceId
) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to owner address
mapping(uint256 => address) private _owners;
// Mapping owner address to token count
mapping(address => uint256) private _balances;
// Mapping from token ID to approved address
mapping(uint256 => address) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
// Sinergy NFT
mapping(address => uint256[]) public get_my_nfts;
mapping(address => uint256) public favourite_nft;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function updateFromAble() public {}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(
bytes4 interfaceId
) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721-balanceOf}.
*/
function balanceOf(
address owner
) public view virtual override returns (uint256) {
require(owner != address(0));
return _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(
uint256 tokenId
) public view virtual override returns (address) {
address owner = _ownerOf(tokenId);
require(owner != address(0));
return owner;
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(
uint256 tokenId
) public view virtual override returns (string memory) {
_requireMinted(tokenId);
string memory baseURI = _baseURI();
return
bytes(baseURI).length > 0
? string(abi.encodePacked(baseURI, tokenId.toString()))
: "";
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overridden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return "";
}
/**
* @dev See {IERC721-approve}.
*/
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner);
require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()));
_approve(to, tokenId);
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(
uint256 tokenId
) public view virtual override returns (address) {
_requireMinted(tokenId);
return _tokenApprovals[tokenId];
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(
address operator,
bool approved
) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(
address owner,
address operator
) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId));
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory data
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId));
_safeTransfer(from, to, tokenId, data);
}
/**
* @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.
*
* `data` is additional data, it has no specified format and it is sent in call to `to`.
*
* This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory data
) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, data));
}
/**
* @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
*/
function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
return _owners[tokenId];
}
/**
* @dev Returns whether `tokenId` exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted (`_mint`),
* and stop existing when they are burned (`_burn`).
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _ownerOf(tokenId) != address(0);
}
/**
* @dev Returns whether `spender` is allowed to manage `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _isApprovedOrOwner(
address spender,
uint256 tokenId
) internal view virtual returns (bool) {
address owner = ERC721.ownerOf(tokenId);
return (spender == owner ||
isApprovedForAll(owner, spender) ||
getApproved(tokenId) == spender);
}
/**
* @dev Safely mints `tokenId` and transfers it to `to`.
*
* Requirements:
*
* - `tokenId` must not exist.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeMint(
address to,
uint256 tokenId,
bytes memory data
) internal virtual {
_mint(to, tokenId);
require(_checkOnERC721Received(address(0), to, tokenId, data));
}
/**
* @dev Mints `tokenId` and transfers it to `to`.
*
* WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
*
* Requirements:
*
* - `tokenId` must not exist.
* - `to` cannot be the zero address.
*
* Emits a {Transfer} event.
*/
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0));
require(!_exists(tokenId));
_beforeTokenTransfer(address(0), to, tokenId);
// Check that tokenId was not minted by `_beforeTokenTransfer` hook
require(!_exists(tokenId));
unchecked {
// Will not overflow unless all 2**256 token ids are minted to the same owner.
// Given that tokens are minted one by one, it is impossible in practice that
// this ever happens. Might change if we allow batch minting.
// The ERC fails to describe this case.
_balances[to] += 1;
}
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
_afterTokenTransfer(address(0), to, tokenId);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
* This is an internal function that does not check if the sender is authorized to operate on the token.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
// Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
owner = ERC721.ownerOf(tokenId);
// Clear approvals
delete _tokenApprovals[tokenId];
unchecked {
// Cannot overflow, as that would require more tokens to be burned/transferred
// out than the owner initially received through minting and transferring in.
_balances[owner] -= 1;
}
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
_afterTokenTransfer(owner, address(0), tokenId);
}
function add_nft_before_transfer(uint256 tokenId, address wallet) private {
get_my_nfts[wallet].push(tokenId);
if (favourite_nft[wallet] == 0)
{
favourite_nft[wallet] = tokenId;
}
}
function delete_nft_before_transfer(
uint256 tokenId,
address wallet
) private {
uint256 i = 0;
while (get_my_nfts[wallet][i] != tokenId) i++;
for (i; i < (_balances[wallet] - 1); i++) {
get_my_nfts[wallet][i] = get_my_nfts[wallet][i + 1];
}
get_my_nfts[wallet].pop();
if (favourite_nft[wallet] == tokenId)
{
favourite_nft[wallet] = get_my_nfts[wallet][0];
}
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721.ownerOf(tokenId) == from);
require(to != address(0));
_beforeTokenTransfer(from, to, tokenId);
// Check that tokenId was not transferred by `_beforeTokenTransfer` hook
require(ERC721.ownerOf(tokenId) == from);
// Clear approvals from the previous owner
delete _tokenApprovals[tokenId];
unchecked {
// `_balances[from]` cannot overflow for the same reason as described in `_burn`:
// `from`'s balance is the number of token held, which is at least one before the current
// transfer.
// `_balances[to]` could overflow in the conditions described in `_mint`. That would require
// all 2**256 token ids to be minted, which in practice is impossible.
delete_nft_before_transfer(tokenId, from);
_balances[from] -= 1;
add_nft_before_transfer(tokenId, to);
_balances[to] += 1;
}
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
_afterTokenTransfer(from, to, tokenId);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits an {Approval} event.
*/
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits an {ApprovalForAll} event.
*/
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator);
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Reverts if the `tokenId` has not been minted yet.
*/
function _requireMinted(uint256 tokenId) internal view virtual {
require(_exists(tokenId));
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param data bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory data
) private returns (bool) {
if (to.isContract()) {
try
IERC721Receiver(to).onERC721Received(
_msgSender(),
from,
tokenId,
data
)
returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert();
} else {
/// @solidity memory-safe-assembly
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
/**
* @dev Hook that is called before any (single) token transfer. This includes minting and burning.
* See {_beforeConsecutiveTokenTransfer}.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, ``from``'s `tokenId` will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
/**
* @dev Hook that is called after any (single) transfer of tokens. This includes minting and burning.
* See {_afterConsecutiveTokenTransfer}.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
/**
* @dev Hook that is called before consecutive token transfers.
* Calling conditions are similar to {_beforeTokenTransfer}.
*
* The default implementation include balances updates that extensions such as {ERC721Consecutive} cannot perform
* directly.
*/
function _beforeConsecutiveTokenTransfer(
address from,
address to,
uint256 /*first*/,
uint96 size
) internal virtual {
if (from != address(0)) {
_balances[from] -= size;
}
if (to != address(0)) {
_balances[to] += size;
}
}
/**
* @dev Hook that is called after consecutive token transfers.
* Calling conditions are similar to {_afterTokenTransfer}.
*/
function _afterConsecutiveTokenTransfer(
address /*from*/,
address /*to*/,
uint256 /*first*/,
uint96 /*size*/
) internal virtual {}
}
abstract contract ERC721URIStorage is ERC721 {
using Strings for uint256;
// Optional mapping for token URIs
mapping(uint256 => string) private _tokenURIs;
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(
uint256 tokenId
) public view virtual override returns (string memory) {
_requireMinted(tokenId);
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = _baseURI();
// If there is no base URI, return the token URI.
if (bytes(base).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(base, _tokenURI));
}
return super.tokenURI(tokenId);
}
/**
* @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _setTokenURI(
uint256 tokenId,
string memory _tokenURI
) internal virtual {
require(_exists(tokenId));
_tokenURIs[tokenId] = _tokenURI;
}
/**
* @dev See {ERC721-_burn}. This override additionally checks to see if a
* token-specific URI was set for the token, and if so, it deletes the token URI from
* the storage mapping.
*/
function _burn(uint256 tokenId) internal virtual override {
super._burn(tokenId);
if (bytes(_tokenURIs[tokenId]).length != 0) {
delete _tokenURIs[tokenId];
}
}
}
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender());
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0));
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
contract SinergySale {
// Constants
uint256 public constant TIME_OF_CYCLE = 6 minutes;
uint256 public MAX_AMOUNT_SELL_TOKEN = 90 ether;
uint256 public MIN_AMOUNT_SELL_TOKEN = 9 ether;
uint256 public TOKEN_PRICE = 3;
uint256 public LIMIT_POST_BY_CYCLE = 1;
// Global Variables
uint256 public TOTAL_TOKENS_SOLD;
mapping(uint256 => uint256) public tokens_sold_by_cycle;
// ERC20 Contracts
ERC20 public ABLE;
ERC20 public TOKEN;
ERC20 public BUSD;
// ERC721 Contract
Sinergy public SinergyContract =
Sinergy(0x508c132EE7cBb4A666E661634F85B59158eaDB4B);
// Wallets
address payable public communityWallet =
payable(0xc8895f6f85D870589C42fd6d531c855bddD27B0f);
address public dev_wallet = 0x9060723c22dE586c2fA5eFa07A7743F6f4a935f5;
// Sell List
uint256[] public sell_list;
mapping(uint256 => bool) public is_in_sell_list;
mapping(address => uint256) public timestamp_last_post_sell;
mapping(address => uint256) public amount_of_post_of;
// Driven List
uint256[] public driven_list;
mapping(uint256 => bool) public is_in_driven_list;
mapping(address => uint256) public turns_in_driven_list_of;
// Turn of pick
uint256 public turn; // 0 y 1 => Driven List ||| 2 => Sell List
// Amount on Sell
uint256 public total_selling_amount;
mapping(uint256 => uint256) public selling_amount_of;
mapping(address => uint256) public post_count_of;
// User Data
mapping(address => uint256) public amount_sold_of;
// Events
event SellList(uint256 indexed nft_id, bool comeIn, bool driven);
event SellToken(
uint256 indexed nft_id,
address indexed buyer,
address indexed seller,
uint256 amount
);
event SwapList(uint256 indexed nft_id);
event BackToQueue(uint256 indexed nft_id, uint256 posAnt, uint256 posAct);
// Constructor
constructor(ERC20 _able, ERC20 _busd, ERC20 _token) {
ABLE = _able;
TOKEN = _token;
BUSD = _busd;
}
// Public Methods
function sell(uint256 _amount, uint256 _tokenID) public {
require(
_amount >= MIN_AMOUNT_SELL_TOKEN,
"The amount to sell have to be more or equal than 9 and less or equal than 90."
);
require(
(selling_amount_of[_tokenID] + _amount) <= MAX_AMOUNT_SELL_TOKEN,
"The amount to sell have to be more or equal than 9 and less or equal than 90."
);
require(
SinergyContract.ownerOf(_tokenID) == msg.sender,
"You are not the owner of this NFT."
);
require(
!is_selling(_tokenID),
"You are already selling tokens on SinergySell"
);
require(
TOKEN.transferFrom(msg.sender, address(this), _amount),
"Transfer fails."
);
require(
block.timestamp > timestamp_last_post_sell[msg.sender],
"You have to wait to post another sell."
);
selling_amount_of[_tokenID] += _amount;
total_selling_amount += _amount;
timestamp_last_post_sell[msg.sender] = block.timestamp + TIME_OF_CYCLE;
if (can_be_in_driven_list(msg.sender)) {
set_nft_to_driven_list(_tokenID);
turns_in_driven_list_of[msg.sender]++;
} else {
set_nft_to_sell_list(_tokenID);
}
}
function buy(uint256 _amount, bool incrementBDD) public {
require(_amount <= total_selling_amount);
// Transferimos los BUSD a este contrato
BUSD.transferFrom(msg.sender, address(this), _amount * TOKEN_PRICE);
// El 33% que va para el vendedor de los tokens, se envian directamente a la billetera del vendedor.
// Esto se hace en la funcion sell_able_from_list
// Transferimos 33% para el Admin
BUSD.transfer(communityWallet, ((_amount * TOKEN_PRICE) / 3));
// Transferimos 33% para Able, para que lo otorgue en el regalo diario de Able.
BUSD.transfer(address(ABLE), ((_amount * TOKEN_PRICE) / 3));
// Transferimos los TOKEN al usuario
TOKEN.transfer(msg.sender, _amount);
// Buscamos los vendedores
uint256 nfts_to_remove_sell;
uint256 nfts_to_remove_driven;
(nfts_to_remove_sell, nfts_to_remove_driven) = find_sellers(
_amount,
msg.sender
);
// Eliminamos de la lista, los vendedores que vendieron el total de su capital.
for (uint256 i = 0; i < nfts_to_remove_sell; i++) {
remove_first_nft_from_sell_list();
}
for (uint256 i = 0; i < nfts_to_remove_driven; i++) {
remove_first_nft_from_driven_list();
}
// Aumentamos el BDD de esta billetera en ABLE
if (incrementBDD)
ABLE.incrementDonationBalance(_amount * TOKEN_PRICE, msg.sender);
// Aumentamos la cantidad de tokens vendidos.
TOTAL_TOKENS_SOLD += _amount;
tokens_sold_by_cycle[ABLE.cycle()] += _amount;
}
function quit_sell(uint256 tokenID) public {
require(is_selling(tokenID));
require(SinergyContract.ownerOf(tokenID) == msg.sender);
require(selling_amount_of[tokenID] > 0);
require(total_selling_amount >= selling_amount_of[tokenID]);
require(TOKEN.transfer(msg.sender, selling_amount_of[tokenID]));
// Descontamos el monto que se saca de la venta
total_selling_amount -= selling_amount_of[tokenID];
selling_amount_of[tokenID] = 0;
// Sacamos al NFT de la Lista de Venta TOKEN
if (is_in_sell_list[tokenID]) {
remove_nft_from_sell_list(get_index_of_nft_from_sell_list(tokenID));
} else {
remove_nft_from_driven_list(
get_index_of_nft_from_driven_list(tokenID)
);
}
}
// Check Methods
function check_sell_list() public {
// Chequeamos si algun NFT de la Lista de Venta de Able esta descalificado.
for (uint256 i = 0; i < sell_list.length; i++) {
uint256 nft_id = sell_list[i];
if (!SinergyContract.nft_was_qualified(nft_id)) {
// Traemos todos los NFTs que habia detras una posicion mas adelante
for (uint256 j = i; j < sell_list.length - 1; j++) {
sell_list[j] = sell_list[j + 1];
}
// Posicionamos al NFT sancionado en el ultimo lugar de la cola
sell_list[sell_list.length - 1] = nft_id;
emit BackToQueue(nft_id, i, sell_list.length - 1);
}
}
}
function check_driven_list() public {
// Chequeamos si algun NFT de la Lista de Venta de Able esta descalificado.
for (uint256 i = 0; i < driven_list.length; i++) {
uint256 nft_id = driven_list[i];
if (!SinergyContract.nft_was_qualified(nft_id)) {
// Traemos todos los NFTs que habia detras una posicion mas adelante
for (uint256 j = i; j < driven_list.length - 1; j++) {
driven_list[j] = sell_list[j + 1];
}
// Posicionamos al NFT sancionado en el ultimo lugar de la cola
driven_list[driven_list.length - 1] = nft_id;
emit BackToQueue(nft_id, i, driven_list.length - 1);
}
}
}
// Get Methods
function get_sell_list_length() public view returns (uint256) {
return sell_list.length;
}
function get_driven_list_length() public view returns (uint256) {
return driven_list.length;
}
// Communication
function try_to_swap(uint256 _tokenID) public {
require(
msg.sender == address(SinergyContract),
"Only SinergyContract can call to this function."
);
if (
is_selling(_tokenID) &&
is_in_sell_list[_tokenID] &&
(get_index_of_nft_from_sell_list(_tokenID) > driven_list.length)
) {
remove_nft_from_sell_list(
get_index_of_nft_from_sell_list(_tokenID)
);
set_nft_to_driven_list(_tokenID);
emit SwapList(_tokenID);
}
}
function set_sinergy(address _sinergyContract) public {
require(
msg.sender == dev_wallet,
"You are not qualified to call this function."
);
SinergyContract = Sinergy(_sinergyContract);
}
function set_limit_post_by_cycle(uint256 new_limit) public {
require(
msg.sender == communityWallet || msg.sender == dev_wallet,
"You are not qualified to call this function."
);
LIMIT_POST_BY_CYCLE = new_limit;
}
function set_values_of_sale(
uint256 max_amount,
uint256 min_amount,
uint256 price
) public {
/*
Ninguno de los parametros tienen que estar en WEI.
Tienen que estar directamente en Ether.
*/
require(
msg.sender == dev_wallet || msg.sender == communityWallet,
"You are not qualified to call this function"
);
MAX_AMOUNT_SELL_TOKEN = max_amount * 1 ether;
MIN_AMOUNT_SELL_TOKEN = min_amount * 1 ether;
TOKEN_PRICE = price;
}
// Helpers
function is_selling(uint256 _tokenID) public view returns (bool) {
return is_in_sell_list[_tokenID] || is_in_driven_list[_tokenID];
}
// Sell Helpers
function is_sell_turn() public view returns (bool) {
return (turn == 2);
}
function sell_list_is_empty() public view returns (bool) {
return sell_list.length == 0;
}
function can_use_sell() public view returns (bool) {
return (!sell_list_is_empty() &&
(is_sell_turn() || driven_list_is_empty()));
}
// Driven Helpers
function can_be_in_driven_list(address wallet) public view returns (bool) {
return
ABLE.winSaverReward(wallet) &&
ABLE.winsSaverRewardOf(wallet) > turns_in_driven_list_of[wallet];
}
function is_driven_turn() public view returns (bool) {
return turn == 0 || turn == 1;
}
function driven_list_is_empty() public view returns (bool) {
return driven_list.length == 0;
}
function can_use_driven() public view returns (bool) {
return (!driven_list_is_empty() &&
(is_driven_turn() || sell_list_is_empty()));
}
// Private Methods
function set_nft_to_sell_list(uint256 _tokenID) private {
sell_list.push(_tokenID);
is_in_sell_list[_tokenID] = true;
emit SellList(_tokenID, true, false);
}
function set_nft_to_driven_list(uint256 _tokenID) private {
driven_list.push(_tokenID);
is_in_driven_list[_tokenID] = true;
emit SellList(_tokenID, true, true);
}
function remove_first_nft_from_sell_list() private {
require(sell_list.length > 0);
uint256 nft_id = sell_list[0];
for (uint256 i = 0; i < sell_list.length - 1; i++) {
sell_list[i] = sell_list[i + 1];
}
sell_list.pop();
is_in_sell_list[nft_id] = false;
emit SellList(nft_id, false, false);
}
function remove_first_nft_from_driven_list() private {
require(driven_list.length > 0);
uint256 nft_id = driven_list[0];
for (uint256 i = 0; i < driven_list.length - 1; i++) {
driven_list[i] = driven_list[i + 1];
}
driven_list.pop();
is_in_driven_list[nft_id] = false;
emit SellList(nft_id, false, true);
}
function remove_nft_from_sell_list(uint256 idx) private {
require(sell_list.length > idx);
uint256 nft_id = sell_list[idx];
for (uint256 i = idx; i < sell_list.length - 1; i++) {
sell_list[i] = sell_list[i + 1];
}
sell_list.pop();
is_in_sell_list[nft_id] = false;
emit SellList(nft_id, false, false);
}
function remove_nft_from_driven_list(uint256 idx) private {
require(driven_list.length > idx);
uint256 nft_id = driven_list[idx];
for (uint256 i = idx; i < driven_list.length - 1; i++) {
driven_list[i] = driven_list[i + 1];
}
driven_list.pop();
is_in_driven_list[nft_id] = false;
emit SellList(nft_id, false, true);
}
function can_sell(address wallet) private returns (bool) {
if (block.timestamp > timestamp_last_post_sell[wallet]) {
post_count_of[wallet] = 0;
return true;
}
if (post_count_of[wallet] < LIMIT_POST_BY_CYCLE) {
post_count_of[wallet]++;
return true;
}
return false;
}
function get_index_of_nft_from_sell_list(
uint256 tokenID
) private view returns (uint256) {
for (uint256 i = 0; i < sell_list.length; i++) {
if (sell_list[i] == tokenID) {
return i;
}
}
return sell_list.length + 1;
}
function get_index_of_nft_from_driven_list(
uint256 tokenID
) private view returns (uint256) {
for (uint256 i = 0; i < driven_list.length; i++) {
if (driven_list[i] == tokenID) {
return i;
}
}
return driven_list.length + 1;
}
function sell_able_from_list(
uint256 _amount,
uint256 _tokenID,
address buyer
) private {
address owner = SinergyContract.ownerOf(_tokenID);
selling_amount_of[_tokenID] -= _amount;
total_selling_amount -= _amount;
// 33% van directo al usuario
BUSD.transfer(owner, ((_amount * TOKEN_PRICE) / 3));
amount_sold_of[owner] += ((_amount * TOKEN_PRICE) / 3);
emit SellToken(_tokenID, buyer, owner, _amount);
}
// Turn Helper
function increment_turn() private {
if (turn == 2) {
turn = 0;
} else {
turn++;
}
}
function find_sellers(
uint256 _amount,
address buyer
) private returns (uint256, uint256) {
bool sell_all = false;
uint256 nft_id;
uint256 idx_sell = 0;
uint256 nfts_to_remove_sell;
uint256 idx_driven = 0;
uint256 nfts_to_remove_driven;
while (!sell_all) {
// Driven List
while (
can_use_driven() && idx_driven < driven_list.length && !sell_all
) {
nft_id = driven_list[idx_driven];
if (_amount <= selling_amount_of[nft_id]) {
// Este NFT me da lo que necesito.
if (_amount == selling_amount_of[nft_id]) {
nfts_to_remove_driven++;
}
sell_able_from_list(_amount, nft_id, buyer);
sell_all = true;
} else {
// Este NFT me ayuda a alcanzar lo que necesito. No me es suficiente lo que me da.
_amount -= selling_amount_of[nft_id];
sell_able_from_list(
selling_amount_of[nft_id],
nft_id,
buyer
);
nfts_to_remove_driven++;
}
idx_driven++;
increment_turn();
}
// Sell List
while (can_use_sell() && idx_sell < sell_list.length && !sell_all) {
nft_id = sell_list[idx_sell];
if (_amount <= selling_amount_of[nft_id]) {
// Este NFT me da lo que necesito.
if (_amount == selling_amount_of[nft_id]) {
nfts_to_remove_sell++;
}
sell_able_from_list(_amount, nft_id, buyer);
sell_all = true;
} else {
// Este NFT me ayuda a alcanzar lo que necesito. No me es suficiente lo que me da.
_amount -= selling_amount_of[nft_id];
sell_able_from_list(
selling_amount_of[nft_id],
nft_id,
buyer
);
nfts_to_remove_sell++;
}
idx_sell++;
increment_turn();
}
}
return (nfts_to_remove_sell, nfts_to_remove_driven);
}
}
contract SinergyMigration is ERC721, ERC721URIStorage, Ownable {
// Constants
uint256 public constant PRICE = 36 ether;
uint256 public constant REWARD = 3 ether;
uint256 public constant TO_DEVELOPMENT = 3 ether;
// NFT GENESIS
string constant NFT_GENESIS_NAME = "GENESIS";
string constant NFT_GENESIS_INSCRIPTION = "GENESIS INSCRIPTION";
string constant NFT_GENESIS_VALUE_PROPOSAL = "GENESIS VALUE PROPOSAL";
string constant NFT_GENESIS_IMAGE_URL =
"https://res.cloudinary.com/saver-community/image/upload/v1666380501/jvjbls4lg5mtxsxhlhnf.png";
// Migration
Sinergy ContractMigration =
Sinergy(0xEa063b5A744616a161272a013a626A1cBD80Ee1B);
// ERC20's
ERC20 CDA = ERC20(0x8e3153a724aF487Fd11fB4C4cDA508984dEDf3c4);
ERC20 ABLE = ERC20(0xd9B9c7A1B42f1ad78D9C3Dd5C7F0381277ddc9Bb);
ERC20 BUSD = ERC20(0xB856De7DAFf71A0d7eAFD4CC22A7db6F762179de);
// Able Sale
SinergySale public ABLE_SALE =
SinergySale(0xD8c101aA6b225135b437E3B87988457B23Adb2f0);
SinergySale public TRIPLE_SALE =
SinergySale(0xD8c101aA6b225135b437E3B87988457B23Adb2f0);
// Address
address public communityWallet = 0xc8895f6f85D870589C42fd6d531c855bddD27B0f;
address public constant developmentWallet =
0x9060723c22dE586c2fA5eFa07A7743F6f4a935f5;
uint256 public oneDay = 12 minutes;
uint256 public timeToNextReward;
// Counters
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
// Migration
mapping(address => bool) public isRecover;
mapping(uint256 => bool) public nftRecover;
mapping(uint256 => bool) public first_level_references_recover;
mapping(uint256 => bool) public second_level_references_recover;
mapping(uint256 => bool) public third_level_references_recover;
mapping(uint256 => bool) public four_level_references_recover;
mapping(uint256 => bool) public five_level_references_recover;
mapping(uint256 => bool) public six_level_references_recover;
mapping(uint256 => bool) public seven_level_references_recover;
mapping(uint256 => bool) public eight_level_references_recover;
mapping(uint256 => bool) public nine_level_references_recover;
uint256 public starting_nft_id;
uint256[] public recovered_nfts;
uint256 public recovered_nfts_amount;
// Constructor
constructor(uint256 initial_tokenID) ERC721("Saver Sinergy", "Sinergy") {
while (_tokenIds.current() < initial_tokenID) {
_tokenIds.increment();
}
timeToNextReward = block.timestamp + oneDay;
starting_nft_id = initial_tokenID;
}
// NFT's
uint256 public nfts_qualified;
mapping(address => bool) public is_qualified;
// mapping(address => uint256) public favourite_nft;
// mapping(address => uint256[]) public get_my_nfts;
mapping(uint256 => string) public get_nft_name;
mapping(uint256 => string) public get_nft_inscription;
mapping(uint256 => string) public get_nft_value_proposal;
mapping(uint256 => uint256) public get_nft_timestamp_created;
mapping(uint256 => string) public get_nft_image_url;
// mapping(string => uint256[]) public get_nfts_by_keyword; // me queda implementarlo en el crear nft
// References
// Esto sabemos que va (Cantidad de NFTs que estan conectados conmigo en el NIVEL x)
mapping(uint256 => uint256) public get_first_level_amount_reference;
mapping(uint256 => uint256) public get_second_level_amount_reference;
mapping(uint256 => uint256) public get_third_level_amount_reference;
mapping(uint256 => uint256) public get_four_level_amount_reference;
mapping(uint256 => uint256) public get_five_level_amount_reference;
mapping(uint256 => uint256) public get_six_level_amount_reference;
mapping(uint256 => uint256) public get_seven_level_amount_reference;
mapping(uint256 => uint256) public get_eight_level_amount_reference;
mapping(uint256 => uint256) public get_nine_level_amount_reference;
mapping(uint256 => uint256) public get_total_amount_references; // Cantidad de NFTs que estan conectados conmigo en total.
// Esto puede fallar (NFT ID de cada uno que esta conectado con nosotros en el NIVEL x)
mapping(uint256 => uint256[]) public get_first_level_references;
mapping(uint256 => uint256[]) public get_second_level_references;
mapping(uint256 => uint256[]) public get_third_level_references;
mapping(uint256 => uint256[]) public get_four_level_references;
mapping(uint256 => uint256[]) public get_five_level_references;
mapping(uint256 => uint256[]) public get_six_level_references;
mapping(uint256 => uint256[]) public get_seven_level_references;
mapping(uint256 => uint256[]) public get_eight_level_references;
mapping(uint256 => uint256[]) public get_nine_level_references;
// NFT al que me conecte
mapping(uint256 => uint256) public get_nft_reference;
// Rewards
mapping(uint256 => uint256) public get_nft_balance_to_claim;
mapping(uint256 => uint256) public get_nft_rewards_claimed;
// Passive Rewards
uint256 public passiveRewardID;
mapping(uint256 => uint256) public passiveReward;
mapping(uint256 => uint256) public passiveRewardClaimed;
mapping(address => uint256) public timestampToClaimPassiveReward;
// Constancy Rewards (usa el ID de las pasivas)
mapping(uint256 => uint256) public constancyReward;
mapping(uint256 => uint256) public constancyRewardClaimed;
mapping(address => uint256) public timestampToClaimConstancyReward;
// Resources
uint256 public resourcesAmount;
// Stadistics
mapping(address => uint256) public total_stablecoin_earned;
mapping(address => uint256) public total_lost_income;
mapping(address => uint256) public actual_lost_income;
// Auxs
mapping(address => uint256) public amount_nfts_considered;
// Public Functions
// Migration
function migrate() public {
require(!isRecover[msg.sender]);
if (msg.sender == communityWallet) {
create_genesis_nfts();
isRecover[communityWallet] = true;
return;
}
uint256 amountNFTs = ContractMigration.balanceOf(msg.sender);
uint256[] storage nfts = get_my_nfts[msg.sender];
uint256[] storage new_nfts_recovered = recovered_nfts;
uint256 nftID;
for (uint256 i = 0; i < amountNFTs; i++) {
nftID = ContractMigration.get_my_nfts(msg.sender, i);
nfts.push(nftID);
new_nfts_recovered.push(nftID);
recovered_nfts_amount++;
recoverNFT(nftID);
_safeMint(msg.sender, nftID);
}
favourite_nft[msg.sender] = ContractMigration.favourite_nft(msg.sender);
get_my_nfts[msg.sender] = nfts;
recovered_nfts = new_nfts_recovered;
isRecover[msg.sender] = true;
}
function recoverNFT(uint256 nftID) private {
// NFT Basic Info
get_nft_name[nftID] = ContractMigration.get_nft_name(nftID);
get_nft_inscription[nftID] = ContractMigration.get_nft_inscription(
nftID
);
get_nft_value_proposal[nftID] = ContractMigration
.get_nft_value_proposal(nftID);
get_nft_timestamp_created[nftID] = ContractMigration
.get_nft_timestamp_created(nftID);
get_nft_image_url[nftID] = ContractMigration.get_nft_image_url(nftID);
get_nft_reference[nftID] = ContractMigration.get_nft_reference(nftID);
// References
get_first_level_amount_reference[nftID] = ContractMigration
.get_first_level_amount_reference(nftID);
get_second_level_amount_reference[nftID] = ContractMigration
.get_second_level_amount_reference(nftID);
get_third_level_amount_reference[nftID] = ContractMigration
.get_third_level_amount_reference(nftID);
get_four_level_amount_reference[nftID] = ContractMigration
.get_four_level_amount_reference(nftID);
get_five_level_amount_reference[nftID] = ContractMigration
.get_five_level_amount_reference(nftID);
get_six_level_amount_reference[nftID] = ContractMigration
.get_six_level_amount_reference(nftID);
get_seven_level_amount_reference[nftID] = ContractMigration
.get_seven_level_amount_reference(nftID);
get_eight_level_amount_reference[nftID] = ContractMigration
.get_eight_level_amount_reference(nftID);
get_nine_level_amount_reference[nftID] = ContractMigration
.get_nine_level_amount_reference(nftID);
get_total_amount_references[nftID] = ContractMigration
.get_total_amount_references(nftID);
nftRecover[nftID] = true;
}
function recoverFirstLevelReferences(uint256 nftID) public {
require(
msg.sender == ownerOf(nftID) &&
!first_level_references_recover[nftID]
);
uint256[] storage nfts = get_first_level_references[nftID];
// uint256 amount = ContractMigration.get_first_level_amount_reference(nftID);
for (
uint256 i = 0;
i < ContractMigration.get_first_level_amount_reference(nftID);
i++
) {
nfts.push(ContractMigration.get_first_level_references(nftID, i));
}
get_first_level_references[nftID] = nfts;
first_level_references_recover[nftID] = true;
}
function recoverSecondLevelReferences(uint256 nftID) public {
require(
msg.sender == ownerOf(nftID) &&
!second_level_references_recover[nftID]
);
uint256[] storage nfts = get_second_level_references[nftID];
// uint256 amount = ContractMigration.get_second_level_amount_reference(nftID);
for (
uint256 i = 0;
i < ContractMigration.get_second_level_amount_reference(nftID);
i++
) {
nfts.push(ContractMigration.get_second_level_references(nftID, i));
}
get_second_level_references[nftID] = nfts;
second_level_references_recover[nftID] = true;
}
function recoverThirdLevelReferences(uint256 nftID) public {
require(
msg.sender == ownerOf(nftID) &&
!third_level_references_recover[nftID]
);
uint256[] storage nfts = get_third_level_references[nftID];
// uint256 amount = ContractMigration.get_third_level_amount_reference(nftID);
for (
uint256 i = 0;
i < ContractMigration.get_third_level_amount_reference(nftID);
i++
) {
nfts.push(ContractMigration.get_third_level_references(nftID, i));
}
get_third_level_references[nftID] = nfts;
third_level_references_recover[nftID] = true;
}
function recoverFourLevelReferences(uint256 nftID) public {
require(
msg.sender == ownerOf(nftID) &&
!four_level_references_recover[nftID]
);
uint256[] storage nfts = get_four_level_references[nftID];
// uint256 amount = ContractMigration.get_four_level_amount_reference(nftID);
for (
uint256 i = 0;
i < ContractMigration.get_four_level_amount_reference(nftID);
i++
) {
nfts.push(ContractMigration.get_four_level_references(nftID, i));
}
get_four_level_references[nftID] = nfts;
four_level_references_recover[nftID] = true;
}
function recoverFiveLevelReferences(uint256 nftID) public {
require(
msg.sender == ownerOf(nftID) &&
!five_level_references_recover[nftID]
);
uint256[] storage nfts = get_five_level_references[nftID];
// uint256 amount = ContractMigration.get_five_level_amount_reference(nftID);
for (
uint256 i = 0;
i < ContractMigration.get_five_level_amount_reference(nftID);
i++
) {
nfts.push(ContractMigration.get_five_level_references(nftID, i));
}
get_five_level_references[nftID] = nfts;
five_level_references_recover[nftID] = true;
}
function recoverSixLevelReferences(uint256 nftID) public {
require(
msg.sender == ownerOf(nftID) && !six_level_references_recover[nftID]
);
uint256[] storage nfts = get_six_level_references[nftID];
// uint256 amount = ContractMigration.get_six_level_amount_reference(nftID);
for (
uint256 i = 0;
i < ContractMigration.get_six_level_amount_reference(nftID);
i++
) {
nfts.push(ContractMigration.get_six_level_references(nftID, i));
}
get_six_level_references[nftID] = nfts;
six_level_references_recover[nftID] = true;
}
function recoverSevenLevelReferences(uint256 nftID) public {
require(
msg.sender == ownerOf(nftID) &&
!seven_level_references_recover[nftID]
);
uint256[] storage nfts = get_seven_level_references[nftID];
// uint256 amount = ContractMigration.get_seven_level_amount_reference(nftID);
for (
uint256 i = 0;
i < ContractMigration.get_seven_level_amount_reference(nftID);
i++
) {
nfts.push(ContractMigration.get_seven_level_references(nftID, i));
}
get_seven_level_references[nftID] = nfts;
seven_level_references_recover[nftID] = true;
}
function recoverEightLevelReferences(uint256 nftID) public {
require(
msg.sender == ownerOf(nftID) &&
!eight_level_references_recover[nftID]
);
uint256[] storage nfts = get_eight_level_references[nftID];
// uint256 amount = ContractMigration.get_eight_level_amount_reference(nftID);
for (
uint256 i = 0;
i < ContractMigration.get_eight_level_amount_reference(nftID);
i++
) {
nfts.push(ContractMigration.get_eight_level_references(nftID, i));
}
get_eight_level_references[nftID] = nfts;
eight_level_references_recover[nftID] = true;
}
function recoverNineLevelReferences(uint256 nftID) public {
require(
msg.sender == ownerOf(nftID) &&
!nine_level_references_recover[nftID]
);
uint256[] storage nfts = get_nine_level_references[nftID];
// uint256 amount = ContractMigration.get_nine_level_amount_reference(nftID);
for (
uint256 i = 0;
i < ContractMigration.get_nine_level_amount_reference(nftID);
i++
) {
nfts.push(ContractMigration.get_nine_level_references(nftID, i));
}
get_nine_level_references[nftID] = nfts;
nine_level_references_recover[nftID] = true;
}
// NFT
function createNFT(
string memory _name,
string memory _inscription,
string memory _valueProposal,
string memory _uri,
string memory _imageURL,
uint256 _ref,
uint256 _timestamp
) public {
// Get Reference
uint256 _reference = favourite_nft[ABLE.lastDonationFrom()];
if (_ref != 0) {
_reference = _ref;
}
if (_reference == 0) {
_reference = 8;
}
require(_reference < _tokenIds.current());
BUSD.transferFrom(msg.sender, address(this), PRICE);
update_qualified_nfts(msg.sender);
ABLE_SALE.try_to_swap(favourite_nft[msg.sender]);
// Mint NFT
uint256 tokenID = _tokenIds.current();
_tokenIds.increment();
_safeMint(msg.sender, tokenID);
// Set URI
_setTokenURI(tokenID, _uri);
// Add information to the NFT
get_nft_name[tokenID] = _name;
get_nft_inscription[tokenID] = _inscription;
get_nft_value_proposal[tokenID] = _valueProposal;
get_nft_reference[tokenID] = _reference;
get_nft_image_url[tokenID] = _imageURL;
get_nft_timestamp_created[tokenID] = _timestamp;
if (favourite_nft[msg.sender] == 0) {
favourite_nft[msg.sender] = tokenID;
}
uint256[] storage myNFTS = get_my_nfts[msg.sender];
myNFTS.push(tokenID);
get_my_nfts[msg.sender] = myNFTS;
// Increase the resources amount
resourcesAmount += TO_DEVELOPMENT;
// Increase Passive Rewards
passiveReward[passiveRewardID] += 6 ether;
// Distribute BUSD's in 9 generations
distribute(tokenID, _reference, true);
update(msg.sender);
// Emit event
// emit Mint(tokenID, block.timestamp, _name, _valueProposal, msg.sender);
}
function modifyNFT(
string memory _name,
string memory _inscription,
string memory _valueProposal,
uint256 _tokenID
) public {
require(msg.sender == ownerOf(_tokenID));
BUSD.transferFrom(msg.sender, address(this), PRICE);
// Modify the NFT
get_nft_name[_tokenID] = _name;
get_nft_inscription[_tokenID] = _inscription;
get_nft_value_proposal[_tokenID] = _valueProposal;
// Increase the resources amount
resourcesAmount += TO_DEVELOPMENT;
// Increase Passive Rewards
passiveReward[passiveRewardID] += 6 ether;
// Distribute BUSD in 9 generations
distribute(_tokenID, get_nft_reference[_tokenID], false);
update(msg.sender);
}
// Rewards
function claimReward(uint256 _tokenID) public {
require(
msg.sender == ownerOf(_tokenID) &&
get_nft_balance_to_claim[_tokenID] > 0
);
BUSD.transfer(msg.sender, get_nft_balance_to_claim[_tokenID]);
// // Emit events
// emit Reward(
// _tokenID,
// get_nft_balance_to_claim[_tokenID],
// msg.sender,
// block.timestamp
// );
get_nft_rewards_claimed[_tokenID] += get_nft_balance_to_claim[_tokenID];
get_nft_balance_to_claim[_tokenID] = 0;
update(msg.sender);
}
function viewAmountToClaimPassiveReward(
address wallet
) public view returns (uint256) {
if (passiveRewardID == 0 || nfts_qualified == 0) return 0;
if (nfts_qualified < balanceOf(wallet)) return 0;
uint256 amount_raised = passiveReward[passiveRewardID - 1];
uint256 amount_claimed = passiveRewardClaimed[passiveRewardID - 1];
uint256 amount_to_claim = ((balanceOf(wallet) * amount_raised) /
nfts_qualified);
if (amount_to_claim > (amount_raised - amount_claimed)) {
return (amount_raised - amount_claimed);
}
return amount_to_claim;
}
function viewAmountToClaimConstancyReward(
address wallet
) public view returns (uint256) {
// Formula:
// Veces que gane el Premio Able * Cantidad recaudada / Veces que ganaron el Premio Able
uint256 totalWinsSaverReward = ABLE.totalWinsSaverReward();
uint256 winsSaverRewardOf = ABLE.winsSaverRewardOf(wallet);
if (passiveRewardID == 0 || totalWinsSaverReward == 0) return 0;
if (totalWinsSaverReward < winsSaverRewardOf) return 0;
uint256 amount_raised = constancyReward[passiveRewardID - 1];
uint256 amount_claimed = constancyRewardClaimed[passiveRewardID - 1];
uint256 amount_to_claim = ((winsSaverRewardOf * amount_raised) /
totalWinsSaverReward);
if (amount_to_claim > (amount_raised - amount_claimed)) {
return (amount_raised - amount_claimed);
}
return amount_to_claim;
}
function claimPassiveReward() public {
require(
passiveRewardID > 0 &&
block.timestamp > timestampToClaimPassiveReward[msg.sender] &&
ABLE.canReclaim(msg.sender)
);
uint256 amount = viewAmountToClaimPassiveReward(msg.sender);
BUSD.transfer(msg.sender, amount);
passiveRewardClaimed[passiveRewardID - 1] += amount;
timestampToClaimPassiveReward[msg.sender] = block.timestamp + oneDay;
update(msg.sender);
// Emit events
// emit PassiveReward(amount, msg.sender, block.timestamp);
}
function claimConstancyReward() public {
require(
passiveRewardID > 0 &&
block.timestamp > timestampToClaimConstancyReward[msg.sender] &&
ABLE.canReclaim(msg.sender) &&
ABLE.winSaverReward(msg.sender) &&
ABLE.totalWinsSaverReward() >= 2
);
uint256 amount = viewAmountToClaimConstancyReward(msg.sender);
BUSD.transfer(msg.sender, amount);
constancyRewardClaimed[passiveRewardID - 1] += amount;
timestampToClaimConstancyReward[msg.sender] = block.timestamp + oneDay;
update(msg.sender);
// Emit Event
}
function claimResources() public {
require(msg.sender == developmentWallet);
BUSD.transfer(msg.sender, resourcesAmount);
// Emit events
// emit Resources(block.timestamp, resourcesAmount);
resourcesAmount = 0;
update(msg.sender);
}
// Read functions
function getAmountOfNftMinted() public view returns (uint256) {
return _tokenIds.current();
}
// Set Functions
function setAbleAddress(address _ableAddress) public {
require(msg.sender == developmentWallet);
ABLE = ERC20(_ableAddress);
}
function setFavouriteNFT(uint256 id) public {
require(_tokenIds.current() > id);
favourite_nft[msg.sender] = id;
update(msg.sender);
}
function changeCommunityWallet(address newAddress) public {
require(msg.sender == communityWallet);
communityWallet = newAddress;
}
// Booleans
function nft_was_qualified(uint256 tokenID) public view returns (bool) {
return
ABLE.canReclaim(ownerOf(tokenID)) ||
ABLE.qualifiedHistory(ownerOf(tokenID), ABLE.cycle() - 1);
}
// Update Functions
function update_qualified_nfts(address wallet) private {
if (is_qualified[wallet]) {
nfts_qualified -= amount_nfts_considered[wallet];
amount_nfts_considered[wallet] = 0;
is_qualified[wallet] = false;
}
if (ABLE.canReclaim(wallet)) {
nfts_qualified += balanceOf(wallet);
amount_nfts_considered[wallet] = balanceOf(wallet);
is_qualified[wallet] = true;
}
}
function update_timestamp() private {
if (block.timestamp > timeToNextReward) {
if (
passiveRewardID > 0 &&
passiveReward[passiveRewardID - 1] >
passiveRewardClaimed[passiveRewardID - 1]
) {
passiveReward[passiveRewardID] += (passiveReward[
passiveRewardID - 1
] - passiveRewardClaimed[passiveRewardID - 1]);
}
if (
passiveRewardID > 0 &&
constancyReward[passiveRewardID - 1] >
constancyRewardClaimed[passiveRewardID - 1]
) {
constancyReward[passiveRewardID] += (constancyReward[
passiveRewardID - 1
] - constancyRewardClaimed[passiveRewardID - 1]);
}
passiveRewardID++;
timeToNextReward = block.timestamp + oneDay;
}
}
function update(address wallet) public {
ABLE.updateFromSinergy(wallet);
update_timestamp();
update_qualified_nfts(wallet);
}
function updateFromAble(address wallet) public {
update_timestamp();
update_qualified_nfts(wallet);
}
function getAbleBalance(address wallet) public view returns (uint256) {
return ABLE.balanceOf(wallet);
}
// SaleToken Public Functions
function set_able_sale(SinergySale ableSale) public {
require(msg.sender == developmentWallet);
ABLE_SALE = ableSale;
}
function set_triple_sale(SinergySale tripleSale) public {
require(msg.sender == developmentWallet);
TRIPLE_SALE = tripleSale;
}
function set_passive_rewards(uint256 amount) public {
require(
msg.sender == address(ABLE_SALE) ||
msg.sender == address(TRIPLE_SALE)
);
passiveReward[passiveRewardID] += amount;
}
function set_active_rewards(uint256 tokenID, uint256 amount) public {
require(
msg.sender == address(ABLE_SALE) ||
msg.sender == address(TRIPLE_SALE)
);
get_nft_balance_to_claim[tokenID] += amount;
}
function set_constancy_reward(uint256 amount) public {
require(
msg.sender == address(ABLE_SALE) ||
msg.sender == address(TRIPLE_SALE)
);
constancyReward[passiveRewardID] += amount;
}
// Private Functions
// Distribute 9 generations
function distribute(
uint256 tokenID,
uint256 _reference,
bool created
) private {
address owner;
uint256 i = 0;
while (i < 9) {
if (created) setReferences(i, tokenID, _reference);
owner = ownerOf(_reference);
if (ABLE.canReclaim(owner)) {
get_nft_balance_to_claim[_reference] += REWARD;
total_stablecoin_earned[owner] += REWARD;
} else {
passiveReward[passiveRewardID] += REWARD;
total_lost_income[owner] += REWARD;
actual_lost_income[owner] = REWARD;
}
_reference = get_nft_reference[_reference];
i++;
}
}
function create_genesis_nfts() private {
// Crear 8 NFTs para la billetera destinada a Desarrollo y Mantenimiento
// Estos NFTs deben estar vinculados entre si
uint256[] storage myNFTS = get_my_nfts[communityWallet];
uint256[] storage new_nfts_recovered = recovered_nfts;
for (uint256 i = 0; i < 9; i++) {
_safeMint(communityWallet, i);
recoverNFT(i);
myNFTS.push(i);
new_nfts_recovered.push(i);
recovered_nfts_amount++;
_setTokenURI(
i,
"ipfs://QmRi1DvgDu6zAJwpbURGNBBQTM82ZCNZAyTkEArbKZKm1U/0.json"
);
}
get_my_nfts[communityWallet] = myNFTS;
recovered_nfts = new_nfts_recovered;
}
function setReferences(uint256 i, uint256 tokenID, uint256 ref) private {
if (i == 0) {
get_first_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
uint256[] storage nftIDs = get_first_level_references[ref];
nftIDs.push(tokenID);
get_first_level_references[ref] = nftIDs;
return;
}
if (i == 1) {
get_second_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
uint256[] storage nftIDs = get_second_level_references[ref];
nftIDs.push(tokenID);
get_second_level_references[ref] = nftIDs;
return;
}
if (i == 2) {
get_third_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
uint256[] storage nftIDs = get_third_level_references[ref];
nftIDs.push(tokenID);
get_third_level_references[ref] = nftIDs;
return;
}
if (i == 3) {
get_four_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
uint256[] storage nftIDs = get_four_level_references[ref];
nftIDs.push(tokenID);
get_four_level_references[ref] = nftIDs;
return;
}
if (i == 4) {
get_five_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
uint256[] storage nftIDs = get_five_level_references[ref];
nftIDs.push(tokenID);
get_five_level_references[ref] = nftIDs;
return;
}
if (i == 5) {
get_six_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
uint256[] storage nftIDs = get_six_level_references[ref];
nftIDs.push(tokenID);
get_six_level_references[ref] = nftIDs;
return;
}
if (i == 6) {
get_seven_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
uint256[] storage nftIDs = get_seven_level_references[ref];
nftIDs.push(tokenID);
get_seven_level_references[ref] = nftIDs;
return;
}
if (i == 7) {
get_eight_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
uint256[] storage nftIDs = get_eight_level_references[ref];
nftIDs.push(tokenID);
get_eight_level_references[ref] = nftIDs;
return;
}
if (i == 8) {
get_nine_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
uint256[] storage nftIDs = get_nine_level_references[ref];
nftIDs.push(tokenID);
get_nine_level_references[ref] = nftIDs;
return;
}
}
// The following functions are overrides required by Solidity.
function _burn(
uint256 tokenId
) internal override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}
function tokenURI(
uint256 tokenId
) public view override(ERC721, ERC721URIStorage) returns (string memory) {
return super.tokenURI(tokenId);
}
}
contract Sinergy is ERC721, ERC721URIStorage, Ownable {
// Constants
uint256 public constant PRICE = 36 ether;
uint256 public constant ABLE_PRICE = 12 ether;
uint256 public constant REWARD = 3 ether;
uint256 public constant TO_DEVELOPMENT = 3 ether;
// NFT GENESIS
string constant NFT_GENESIS_NAME = "GENESIS";
string constant NFT_GENESIS_INSCRIPTION = "GENESIS INSCRIPTION";
string constant NFT_GENESIS_VALUE_PROPOSAL = "GENESIS VALUE PROPOSAL";
string constant NFT_GENESIS_IMAGE_URL =
"https://res.cloudinary.com/saver-community/image/upload/v1666380501/jvjbls4lg5mtxsxhlhnf.png";
// Migration
SinergyMigration ContractMigration =
SinergyMigration(0xEa063b5A744616a161272a013a626A1cBD80Ee1B);
Migration public MigrationContract =
Migration(0xfd26B8BE868C0E16A5a54E8D586B0C6D7d6892fA);
// ERC20's
ERC20 public ABLE = ERC20(0x68627b19b01C497749328e160e17a168D7719956);
ERC20 public BUSD = ERC20(0xB856De7DAFf71A0d7eAFD4CC22A7db6F762179de);
// Able Sale
SinergySale public ABLE_SALE =
SinergySale(0x7fa46675165F0d0Ab1A3bd3FD96AA3eD59167B52);
// Passive Rewards
Reward public BUSD_PassiveReward =
Reward(0x4F19668690b3501fa2404039436d4f1C14079dB8);
Reward public ABLE_PassiveReward =
Reward(0x72e29bC0cF7E6f2A3FC99890069E857b736F6dE9);
// Constancy Rewards (usa el ID de las pasivas)
Reward public BUSD_ConstancyReward =
Reward(0x2B06dD06Cf7cdAB0f8cC39a6F79FD88b20cb2C5D);
Reward public ABLE_ConstancyReward =
Reward(0xc32AfBC61e4A2Be096cBe27Fa1072EA7f25Aa79d);
// Address
address public communityWallet = 0xc8895f6f85D870589C42fd6d531c855bddD27B0f;
address public constant developmentWallet =
0x9060723c22dE586c2fA5eFa07A7743F6f4a935f5;
uint256 public oneDay = 6 minutes;
uint256 public timeToNextReward;
// Counters
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
uint256 public starting_nft_id;
uint256 initial_tokenID = 1159;
// Constructor
constructor() ERC721("Offer Sinergy", "Sinergy") {
while (_tokenIds.current() < initial_tokenID) {
_tokenIds.increment();
}
// Mint NFT
uint256 tokenID = _tokenIds.current();
_tokenIds.increment();
_safeMint(developmentWallet, tokenID);
get_nft_name[tokenID] = NFT_GENESIS_NAME;
get_nft_inscription[tokenID] = NFT_GENESIS_INSCRIPTION;
get_nft_value_proposal[tokenID] = NFT_GENESIS_VALUE_PROPOSAL;
get_nft_image_url[tokenID] = NFT_GENESIS_IMAGE_URL;
get_nft_timestamp_created[tokenID] = block.timestamp;
favourite_nft[developmentWallet] = tokenID;
_setTokenURI(
tokenID,
"ipfs://QmRi1DvgDu6zAJwpbURGNBBQTM82ZCNZAyTkEArbKZKm1U/273.json"
);
get_my_nfts[developmentWallet].push(tokenID);
timeToNextReward = block.timestamp + oneDay;
starting_nft_id = initial_tokenID;
total_holders++;
is_holder[developmentWallet] = true;
}
// NFT's
uint256 public nfts_qualified;
mapping(address => bool) public is_qualified;
mapping(uint256 => string) public get_nft_name;
mapping(uint256 => string) public get_nft_inscription;
mapping(uint256 => string) public get_nft_value_proposal;
mapping(uint256 => uint256) public get_nft_timestamp_created;
mapping(uint256 => string) public get_nft_image_url;
// References
// Esto sabemos que va (Cantidad de NFTs que estan conectados conmigo en el NIVEL x)
mapping(uint256 => uint256) public get_first_level_amount_reference;
mapping(uint256 => uint256) public get_second_level_amount_reference;
mapping(uint256 => uint256) public get_third_level_amount_reference;
mapping(uint256 => uint256) public get_four_level_amount_reference;
mapping(uint256 => uint256) public get_five_level_amount_reference;
mapping(uint256 => uint256) public get_six_level_amount_reference;
mapping(uint256 => uint256) public get_seven_level_amount_reference;
mapping(uint256 => uint256) public get_eight_level_amount_reference;
mapping(uint256 => uint256) public get_nine_level_amount_reference;
mapping(uint256 => uint256) public get_total_amount_references; // Cantidad de NFTs que estan conectados conmigo en total.
// Esto puede fallar (NFT ID de cada uno que esta conectado con nosotros en el NIVEL x)
mapping(uint256 => uint256[]) public get_first_level_references;
mapping(uint256 => uint256[]) public get_second_level_references;
mapping(uint256 => uint256[]) public get_third_level_references;
mapping(uint256 => uint256[]) public get_four_level_references;
mapping(uint256 => uint256[]) public get_five_level_references;
mapping(uint256 => uint256[]) public get_six_level_references;
mapping(uint256 => uint256[]) public get_seven_level_references;
mapping(uint256 => uint256[]) public get_eight_level_references;
mapping(uint256 => uint256[]) public get_nine_level_references;
// NFT al que me conecte
mapping(uint256 => uint256) public get_nft_reference;
// Rewards
mapping(uint256 => uint256) public nft_affiliate_rewards_earned;
// Resources
uint256 public total_raided_for_admin;
// Stadistics
uint256 public total_stablecoin_distributed;
mapping(address => uint256) public total_stablecoin_earned;
mapping(address => uint256) public total_lost_income;
mapping(address => uint256) public actual_lost_income;
mapping(uint256 => uint256) public nfts_created_by_cycle;
// Holders
mapping(address => bool) public is_holder;
uint256 public total_holders;
// Auxs
mapping(address => uint256) public amount_nfts_considered;
// Events
event Mint(
uint256 id,
uint256 date,
string indexed name,
string indexed valueProposal,
address indexed wallet
);
event AffiliateRewardEvent(
uint256 tokenID,
uint256 amount,
address indexed wallet,
uint256 indexed date
);
event ChangeFavourite(
address indexed wallet,
uint256 previousFavourite,
uint256 actualFavourite
);
// Public Functions
// Migration
function set_migration_contract(Migration _migrationContract) public {
if (msg.sender != developmentWallet) return;
MigrationContract = _migrationContract;
}
function handleRecover(address wallet, uint256 tokenId) public {
if (msg.sender != address(MigrationContract)) return;
recoverNFT(tokenId);
get_my_nfts[wallet].push(tokenId);
_safeMint(wallet, tokenId);
if (favourite_nft[wallet] == 0) {
favourite_nft[wallet] = tokenId;
}
}
function recoverNFT(uint256 nftID) private {
// NFT Basic Info
get_nft_name[nftID] = ContractMigration.get_nft_name(nftID);
get_nft_inscription[nftID] = ContractMigration.get_nft_inscription(
nftID
);
get_nft_value_proposal[nftID] = ContractMigration
.get_nft_value_proposal(nftID);
get_nft_timestamp_created[nftID] = ContractMigration
.get_nft_timestamp_created(nftID);
get_nft_image_url[nftID] = ContractMigration.get_nft_image_url(nftID);
get_nft_reference[nftID] = ContractMigration.get_nft_reference(nftID);
// References
get_first_level_amount_reference[nftID] = ContractMigration
.get_first_level_amount_reference(nftID);
get_second_level_amount_reference[nftID] = ContractMigration
.get_second_level_amount_reference(nftID);
get_third_level_amount_reference[nftID] = ContractMigration
.get_third_level_amount_reference(nftID);
get_four_level_amount_reference[nftID] = ContractMigration
.get_four_level_amount_reference(nftID);
get_five_level_amount_reference[nftID] = ContractMigration
.get_five_level_amount_reference(nftID);
get_six_level_amount_reference[nftID] = ContractMigration
.get_six_level_amount_reference(nftID);
get_seven_level_amount_reference[nftID] = ContractMigration
.get_seven_level_amount_reference(nftID);
get_eight_level_amount_reference[nftID] = ContractMigration
.get_eight_level_amount_reference(nftID);
get_nine_level_amount_reference[nftID] = ContractMigration
.get_nine_level_amount_reference(nftID);
get_total_amount_references[nftID] = ContractMigration
.get_total_amount_references(nftID);
}
function handlerRecoverFirstLevel(uint256 tokenId, uint256 index) public {
if (msg.sender != address(MigrationContract)) return;
get_first_level_references[tokenId].push(
ContractMigration.get_first_level_references(tokenId, index)
);
}
function handlerRecoverSecondLevel(uint256 tokenId, uint256 index) public {
if (msg.sender != address(MigrationContract)) return;
get_second_level_references[tokenId].push(
ContractMigration.get_second_level_references(tokenId, index)
);
}
function handlerRecoverThirdLevel(uint256 tokenId, uint256 index) public {
if (msg.sender != address(MigrationContract)) return;
get_third_level_references[tokenId].push(
ContractMigration.get_third_level_references(tokenId, index)
);
}
function handlerRecoverFourLevel(uint256 tokenId, uint256 index) public {
if (msg.sender != address(MigrationContract)) return;
get_four_level_references[tokenId].push(
ContractMigration.get_four_level_references(tokenId, index)
);
}
function handlerRecoverFiveLevel(uint256 tokenId, uint256 index) public {
if (msg.sender != address(MigrationContract)) return;
get_five_level_references[tokenId].push(
ContractMigration.get_five_level_references(tokenId, index)
);
}
function handlerRecoverSixLevel(uint256 tokenId, uint256 index) public {
if (msg.sender != address(MigrationContract)) return;
get_six_level_references[tokenId].push(
ContractMigration.get_six_level_references(tokenId, index)
);
}
function handlerRecoverSevenLevel(uint256 tokenId, uint256 index) public {
if (msg.sender != address(MigrationContract)) return;
get_seven_level_references[tokenId].push(
ContractMigration.get_seven_level_references(tokenId, index)
);
}
function handlerRecoverEightLevel(uint256 tokenId, uint256 index) public {
if (msg.sender != address(MigrationContract)) return;
get_eight_level_references[tokenId].push(
ContractMigration.get_eight_level_references(tokenId, index)
);
}
function handlerRecoverNineLevel(uint256 tokenId, uint256 index) public {
if (msg.sender != address(MigrationContract)) return;
get_nine_level_references[tokenId].push(
ContractMigration.get_nine_level_references(tokenId, index)
);
}
// NFT
function createNFT(
string memory _name,
string memory _inscription,
string memory _valueProposal,
string memory _uri,
string memory _imageURL,
uint256 _ref,
uint256 _timestamp
) public {
// Get Reference
uint256 _reference = favourite_nft[ABLE.lastDonationFrom()];
if (_ref != 0) {
_reference = _ref;
}
if (_reference == 0) {
_reference = 8;
}
require(_reference < _tokenIds.current());
BUSD.transferFrom(msg.sender, address(this), PRICE);
ABLE.transferFrom(msg.sender, address(this), ABLE_PRICE);
// Transferimos 3 BUSD para el admin
BUSD.transfer(communityWallet, TO_DEVELOPMENT);
update_qualified_nfts(msg.sender);
ABLE_SALE.try_to_swap(favourite_nft[msg.sender]);
// Mint NFT
uint256 tokenID = _tokenIds.current();
_tokenIds.increment();
_safeMint(msg.sender, tokenID);
// Set URI
_setTokenURI(tokenID, _uri);
// Add information to the NFT
get_nft_name[tokenID] = _name;
get_nft_inscription[tokenID] = _inscription;
get_nft_value_proposal[tokenID] = _valueProposal;
get_nft_reference[tokenID] = _reference;
get_nft_image_url[tokenID] = _imageURL;
get_nft_timestamp_created[tokenID] = _timestamp;
if (favourite_nft[msg.sender] == 0) {
favourite_nft[msg.sender] = tokenID;
}
// uint256[] storage myNFTS = get_my_nfts[msg.sender];
get_my_nfts[msg.sender].push(tokenID);
// get_my_nfts[msg.sender] = myNFTS;
// Increase the resources amount
total_raided_for_admin += TO_DEVELOPMENT;
// Increase Rewards
ABLE_PassiveReward.set_reward(6 ether);
ABLE.transfer(address(ABLE_PassiveReward), 6 ether);
BUSD_PassiveReward.set_reward(3 ether);
BUSD.transfer(address(BUSD_PassiveReward), 3 ether);
ABLE_ConstancyReward.set_reward(6 ether);
ABLE.transfer(address(ABLE_ConstancyReward), 6 ether);
BUSD_ConstancyReward.set_reward(3 ether);
BUSD.transfer(address(BUSD_ConstancyReward), 3 ether);
// Distribute BUSD's in 9 generations
distribute(tokenID, _reference, true);
update(msg.sender);
// Aumentamos la cantidad de NFTs creados en este ciclo
nfts_created_by_cycle[ABLE.cycle()]++;
// Holders
if (!is_holder[msg.sender]) {
is_holder[msg.sender] = true;
total_holders++;
}
// Emit event
emit Mint(tokenID, block.timestamp, _name, _valueProposal, msg.sender);
}
function modifyNFT(
string memory _name,
string memory _inscription,
string memory _valueProposal,
uint256 _tokenID
) public {
require(msg.sender == ownerOf(_tokenID));
BUSD.transferFrom(msg.sender, address(this), PRICE);
ABLE.transferFrom(msg.sender, address(this), ABLE_PRICE);
// Transferimos 3 BUSD para el admin
BUSD.transfer(communityWallet, TO_DEVELOPMENT);
// Modify the NFT
get_nft_name[_tokenID] = _name;
get_nft_inscription[_tokenID] = _inscription;
get_nft_value_proposal[_tokenID] = _valueProposal;
// Increase the resources amount
total_raided_for_admin += TO_DEVELOPMENT;
// Increase Rewards
BUSD_PassiveReward.set_reward(3 ether);
BUSD.transfer(address(BUSD_PassiveReward), 3 ether);
ABLE_PassiveReward.set_reward(6 ether);
ABLE.transfer(address(ABLE_PassiveReward), 6 ether);
ABLE_ConstancyReward.set_reward(6 ether);
ABLE.transfer(address(ABLE_ConstancyReward), 6 ether);
BUSD_ConstancyReward.set_reward(3 ether);
BUSD.transfer(address(ABLE_ConstancyReward), 3 ether);
// Distribute BUSD in 9 generations
distribute(_tokenID, get_nft_reference[_tokenID], false);
update(msg.sender);
}
// Read functions
function getAmountOfNftMinted() public view returns (uint256) {
return _tokenIds.current();
}
// Set Functions
function setAbleAddress(address _ableAddress) public {
require(msg.sender == developmentWallet);
ABLE = ERC20(_ableAddress);
}
function setRewards(
Reward busd_passive,
Reward busd_constancy,
Reward able_passive,
Reward able_constancy
) public {
require(msg.sender == developmentWallet);
BUSD_PassiveReward = busd_passive;
BUSD_ConstancyReward = busd_constancy;
ABLE_PassiveReward = able_passive;
ABLE_ConstancyReward = able_constancy;
}
function setFavouriteNFT(address wallet, uint256 id) public {
require(id <= _tokenIds.current());
require(msg.sender == ownerOf(id) || msg.sender == address(MigrationContract), "Wallet not qualified to setFavouriteNFT");
uint256 previousFavourite = favourite_nft[wallet];
favourite_nft[wallet] = id;
emit ChangeFavourite(msg.sender, previousFavourite, id);
}
function changeCommunityWallet(address newAddress) public {
require(msg.sender == communityWallet);
communityWallet = newAddress;
}
// Booleans
function nft_was_qualified(uint256 tokenID) public view returns (bool) {
return
ABLE.canReclaim(ownerOf(tokenID)) ||
ABLE.qualifiedHistory(ownerOf(tokenID), ABLE.cycle() - 1);
}
// Update Functions
function update_qualified_nfts(address wallet) private {
if (is_qualified[wallet]) {
nfts_qualified -= amount_nfts_considered[wallet];
amount_nfts_considered[wallet] = 0;
is_qualified[wallet] = false;
}
if (ABLE.canReclaim(wallet)) {
nfts_qualified += balanceOf(wallet);
amount_nfts_considered[wallet] = balanceOf(wallet);
is_qualified[wallet] = true;
}
}
function update_timestamp() private {
if (block.timestamp > timeToNextReward) {
BUSD_PassiveReward.update();
ABLE_PassiveReward.update();
BUSD_ConstancyReward.update();
ABLE_ConstancyReward.update();
timeToNextReward = block.timestamp + oneDay;
}
}
function update(address wallet) public {
ABLE.updateFromSinergy(wallet);
update_timestamp();
update_qualified_nfts(wallet);
}
function updateFromAble(address wallet) public {
update_timestamp();
update_qualified_nfts(wallet);
}
function getAbleBalance(address wallet) public view returns (uint256) {
return ABLE.balanceOf(wallet);
}
// SaleToken Public Functions
function set_able_sale(SinergySale ableSale) public {
require(msg.sender == developmentWallet);
ABLE_SALE = ableSale;
}
// Private Functions
// Distribute 9 generations
function distribute(
uint256 tokenID,
uint256 _reference,
bool created
) private {
address owner;
uint256 i = 0;
while (i < 9) {
if (created) setReferences(i, tokenID, _reference);
owner = ownerOf(_reference);
total_stablecoin_earned[owner] += REWARD;
nft_affiliate_rewards_earned[_reference] += REWARD;
total_stablecoin_distributed += REWARD;
BUSD.transfer(owner, REWARD);
// Emit events
emit AffiliateRewardEvent(
_reference,
REWARD,
owner,
block.timestamp
);
_reference = get_nft_reference[_reference];
i++;
}
}
function create_genesis_nfts() public {
if (msg.sender != address(MigrationContract)) return;
// Crear 8 NFTs para la billetera destinada a Desarrollo y Mantenimiento
// Estos NFTs deben estar vinculados entre si
uint256 affiliate_rewards;
for (uint256 i = 0; i < 9; i++) {
_safeMint(communityWallet, i);
recoverNFT(i);
affiliate_rewards += ContractMigration.get_nft_balance_to_claim(i);
get_my_nfts[communityWallet].push(i);
_setTokenURI(
i,
"ipfs://QmRi1DvgDu6zAJwpbURGNBBQTM82ZCNZAyTkEArbKZKm1U/0.json"
);
}
}
function setReferences(uint256 i, uint256 tokenID, uint256 ref) private {
if (i == 0) {
get_first_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
// uint256[] storage nftIDs = get_first_level_references[ref];
get_first_level_references[ref].push(tokenID);
// get_first_level_references[ref] = nftIDs;
return;
}
if (i == 1) {
get_second_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
// uint256[] storage nftIDs = get_second_level_references[ref];
get_second_level_references[ref].push(tokenID);
// get_second_level_references[ref] = nftIDs;
return;
}
if (i == 2) {
get_third_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
// uint256[] storage nftIDs = get_third_level_references[ref];
get_third_level_references[ref].push(tokenID);
// get_third_level_references[ref] = nftIDs;
return;
}
if (i == 3) {
get_four_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
// uint256[] storage nftIDs = get_four_level_references[ref];
get_four_level_references[ref].push(tokenID);
// get_four_level_references[ref] = nftIDs;
return;
}
if (i == 4) {
get_five_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
// uint256[] storage nftIDs = get_five_level_references[ref];
get_five_level_references[ref].push(tokenID);
// get_five_level_references[ref] = nftIDs;
return;
}
if (i == 5) {
get_six_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
// uint256[] storage nftIDs = get_six_level_references[ref];
get_six_level_references[ref].push(tokenID);
// get_six_level_references[ref] = nftIDs;
return;
}
if (i == 6) {
get_seven_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
// uint256[] storage nftIDs = get_seven_level_references[ref];
get_seven_level_references[ref].push(tokenID);
// get_seven_level_references[ref] = nftIDs;
return;
}
if (i == 7) {
get_eight_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
// uint256[] storage nftIDs = get_eight_level_references[ref];
get_eight_level_references[ref].push(tokenID);
// get_eight_level_references[ref] = nftIDs;
return;
}
if (i == 8) {
get_nine_level_amount_reference[ref]++;
get_total_amount_references[ref]++;
// uint256[] storage nftIDs = get_nine_level_references[ref];
get_nine_level_references[ref].push(tokenID);
// get_nine_level_references[ref] = nftIDs;
return;
}
}
// The following functions are overrides required by Solidity.
function _burn(
uint256 tokenId
) internal override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}
function tokenURI(
uint256 tokenId
) public view override(ERC721, ERC721URIStorage) returns (string memory) {
return super.tokenURI(tokenId);
}
}
contract Migration {
// Constants
uint256 public constant AMOUNT_LIMIT_TO_MIGRATE = 21;
// Contracts
SinergyMigration ContractMigration =
SinergyMigration(0xEa063b5A744616a161272a013a626A1cBD80Ee1B);
Sinergy Contract = Sinergy(0x508c132EE7cBb4A666E661634F85B59158eaDB4B);
// ERC20
ERC20 public ABLE = ERC20(0x68627b19b01C497749328e160e17a168D7719956);
// Addresses
address public communityWallet = 0xc8895f6f85D870589C42fd6d531c855bddD27B0f;
address public constant developmentWallet =
0x9060723c22dE586c2fA5eFa07A7743F6f4a935f5;
// Migration
mapping(address => bool) public isRecover;
mapping(uint256 => bool) public nftRecover;
mapping(uint256 => bool) public first_level_references_recover;
mapping(uint256 => uint256) public first_level_references_recover_amount;
mapping(uint256 => bool) public second_level_references_recover;
mapping(uint256 => uint256) public second_level_references_recover_amount;
mapping(uint256 => bool) public third_level_references_recover;
mapping(uint256 => uint256) public third_level_references_recover_amount;
mapping(uint256 => bool) public four_level_references_recover;
mapping(uint256 => uint256) public four_level_references_recover_amount;
mapping(uint256 => bool) public five_level_references_recover;
mapping(uint256 => uint256) public five_level_references_recover_amount;
mapping(uint256 => bool) public six_level_references_recover;
mapping(uint256 => uint256) public six_level_references_recover_amount;
mapping(uint256 => bool) public seven_level_references_recover;
mapping(uint256 => uint256) public seven_level_references_recover_amount;
mapping(uint256 => bool) public eight_level_references_recover;
mapping(uint256 => uint256) public eight_level_references_recover_amount;
mapping(uint256 => bool) public nine_level_references_recover;
mapping(uint256 => uint256) public nine_level_references_recover_amount;
mapping(address => uint256) public nfts_migrated;
uint256 public starting_nft_id;
uint256[] public recovered_nfts;
uint256 public recovered_nfts_amount;
constructor() {
isRecover[developmentWallet] = true;
}
// Main recover
function migrate() public {
if (msg.sender == communityWallet && !isRecover[communityWallet]) {
Contract.create_genesis_nfts();
isRecover[communityWallet] = true;
handle_recover_nfts_amount_for_admin();
return;
}
if (!isRecover[msg.sender]) {
uint256 affiliate_rewards;
uint256 amount = ContractMigration.balanceOf(msg.sender);
uint256 migrated;
uint256 nftID;
while (
migrated < AMOUNT_LIMIT_TO_MIGRATE &&
nfts_migrated[msg.sender] < amount
) {
nftID = ContractMigration.get_my_nfts(
msg.sender,
nfts_migrated[msg.sender]
);
recovered_nfts.push(nftID);
Contract.handleRecover(msg.sender, nftID);
nftRecover[nftID] = true;
recovered_nfts_amount++;
affiliate_rewards += ContractMigration.get_nft_balance_to_claim(
nftID
);
nfts_migrated[msg.sender]++;
migrated++;
}
if (nfts_migrated[msg.sender] == amount) {
ABLE.transfer(msg.sender, affiliate_rewards);
isRecover[msg.sender] = true;
}
}
}
// Recover by level
function recoverFirstLevelReferences(uint256 nftID) public {
require(
msg.sender == Contract.ownerOf(nftID) &&
!first_level_references_recover[nftID]
);
uint256 migrated;
uint256 amount = ContractMigration.get_first_level_amount_reference(
nftID
);
while (
migrated < AMOUNT_LIMIT_TO_MIGRATE &&
first_level_references_recover_amount[nftID] < amount
) {
Contract.handlerRecoverFirstLevel(
nftID,
first_level_references_recover_amount[nftID]
);
migrated++;
first_level_references_recover_amount[nftID]++;
}
if (first_level_references_recover_amount[nftID] == amount) {
first_level_references_recover[nftID] = true;
}
}
function recoverSecondLevelReferences(uint256 nftID) public {
require(
msg.sender == Contract.ownerOf(nftID) &&
!second_level_references_recover[nftID]
);
uint256 migrated;
uint256 amount = ContractMigration.get_second_level_amount_reference(
nftID
);
while (
migrated < AMOUNT_LIMIT_TO_MIGRATE &&
second_level_references_recover_amount[nftID] < amount
) {
Contract.handlerRecoverSecondLevel(
nftID,
second_level_references_recover_amount[nftID]
);
migrated++;
second_level_references_recover_amount[nftID]++;
}
if (second_level_references_recover_amount[nftID] == amount) {
second_level_references_recover[nftID] = true;
}
}
function recoverThirdLevelReferences(uint256 nftID) public {
require(
msg.sender == Contract.ownerOf(nftID) &&
!third_level_references_recover[nftID]
);
uint256 migrated;
uint256 amount = ContractMigration.get_third_level_amount_reference(
nftID
);
while (
migrated < AMOUNT_LIMIT_TO_MIGRATE &&
third_level_references_recover_amount[nftID] < amount
) {
Contract.handlerRecoverThirdLevel(
nftID,
third_level_references_recover_amount[nftID]
);
migrated++;
third_level_references_recover_amount[nftID]++;
}
if (third_level_references_recover_amount[nftID] == amount) {
third_level_references_recover[nftID] = true;
}
}
function recoverFourLevelReferences(uint256 nftID) public {
require(
msg.sender == Contract.ownerOf(nftID) &&
!four_level_references_recover[nftID]
);
uint256 migrated;
uint256 amount = ContractMigration.get_four_level_amount_reference(
nftID
);
while (
migrated < AMOUNT_LIMIT_TO_MIGRATE &&
four_level_references_recover_amount[nftID] < amount
) {
Contract.handlerRecoverFourLevel(
nftID,
four_level_references_recover_amount[nftID]
);
migrated++;
four_level_references_recover_amount[nftID]++;
}
if (four_level_references_recover_amount[nftID] == amount) {
four_level_references_recover[nftID] = true;
}
}
function recoverFiveLevelReferences(uint256 nftID) public {
require(
msg.sender == Contract.ownerOf(nftID) &&
!five_level_references_recover[nftID]
);
uint256 migrated;
uint256 amount = ContractMigration.get_five_level_amount_reference(
nftID
);
while (
migrated < AMOUNT_LIMIT_TO_MIGRATE &&
five_level_references_recover_amount[nftID] < amount
) {
Contract.handlerRecoverFiveLevel(
nftID,
five_level_references_recover_amount[nftID]
);
migrated++;
five_level_references_recover_amount[nftID]++;
}
if (five_level_references_recover_amount[nftID] == amount) {
five_level_references_recover[nftID] = true;
}
}
function recoverSixLevelReferences(uint256 nftID) public {
require(
msg.sender == Contract.ownerOf(nftID) &&
!six_level_references_recover[nftID]
);
uint256 migrated;
uint256 amount = ContractMigration.get_six_level_amount_reference(
nftID
);
while (
migrated < AMOUNT_LIMIT_TO_MIGRATE &&
six_level_references_recover_amount[nftID] < amount
) {
Contract.handlerRecoverSixLevel(
nftID,
six_level_references_recover_amount[nftID]
);
migrated++;
six_level_references_recover_amount[nftID]++;
}
if (six_level_references_recover_amount[nftID] == amount) {
six_level_references_recover[nftID] = true;
}
}
function recoverSevenLevelReferences(uint256 nftID) public {
require(
msg.sender == Contract.ownerOf(nftID) &&
!seven_level_references_recover[nftID]
);
uint256 migrated;
uint256 amount = ContractMigration.get_seven_level_amount_reference(
nftID
);
while (
migrated < AMOUNT_LIMIT_TO_MIGRATE &&
seven_level_references_recover_amount[nftID] < amount
) {
Contract.handlerRecoverSevenLevel(
nftID,
seven_level_references_recover_amount[nftID]
);
migrated++;
seven_level_references_recover_amount[nftID]++;
}
if (seven_level_references_recover_amount[nftID] == amount) {
seven_level_references_recover[nftID] = true;
}
}
function recoverEightLevelReferences(uint256 nftID) public {
require(
msg.sender == Contract.ownerOf(nftID) &&
!eight_level_references_recover[nftID]
);
uint256 migrated;
uint256 amount = ContractMigration.get_eight_level_amount_reference(
nftID
);
while (
migrated < AMOUNT_LIMIT_TO_MIGRATE &&
eight_level_references_recover_amount[nftID] < amount
) {
Contract.handlerRecoverEightLevel(
nftID,
eight_level_references_recover_amount[nftID]
);
migrated++;
eight_level_references_recover_amount[nftID]++;
}
if (eight_level_references_recover_amount[nftID] == amount) {
eight_level_references_recover[nftID] = true;
}
}
function recoverNineLevelReferences(uint256 nftID) public {
require(
msg.sender == Contract.ownerOf(nftID) &&
!nine_level_references_recover[nftID]
);
uint256 migrated;
uint256 amount = ContractMigration.get_nine_level_amount_reference(
nftID
);
while (
migrated < AMOUNT_LIMIT_TO_MIGRATE &&
nine_level_references_recover_amount[nftID] < amount
) {
Contract.handlerRecoverNineLevel(
nftID,
nine_level_references_recover_amount[nftID]
);
migrated++;
nine_level_references_recover_amount[nftID]++;
}
if (nine_level_references_recover_amount[nftID] == amount) {
nine_level_references_recover[nftID] = true;
}
}
// Helpers
function handle_recover_nfts_amount_for_admin() private {
for (uint8 i = 0; i < 9; i++) {
recovered_nfts.push(i);
recovered_nfts_amount++;
}
}
// Set Contracts
function set_sinergy(Sinergy _sinergyAddress) public {
if (msg.sender != developmentWallet) return;
Contract = Sinergy(_sinergyAddress);
}
function set_able(ERC20 _able) public {
if (msg.sender != developmentWallet) return;
ABLE = ERC20(_able);
}
}
contract Reward {
// Contracts
ERC20 public ABLE = ERC20(0x68627b19b01C497749328e160e17a168D7719956);
ERC20 public TOKEN = ERC20(0x68627b19b01C497749328e160e17a168D7719956);
SinergySale public ABLE_SALE =
SinergySale(0xD42058180A985DEe1b52aEAEa5573D069D87Dc94);
Sinergy public SinergyContract =
Sinergy(0x508c132EE7cBb4A666E661634F85B59158eaDB4B);
// Wallets
address public developmentWallet =
0x9060723c22dE586c2fA5eFa07A7743F6f4a935f5;
// Attributes
uint256 public TIME = 6 minutes;
uint256 public reward_id;
uint256 public AMOUNT_USERS_NEED_TO_CLAIM = 3;
mapping(uint256 => uint256) public reward;
mapping(uint256 => uint256) public reward_claimed;
mapping(address => uint256) public timestamp_to_claim_reward;
event RewardClaimed(uint256 amount, address indexed wallet);
function set_reward(uint256 amount) public {
require(can_call(msg.sender));
reward[reward_id] += amount;
}
function claim_reward(bool passive) public {
require(
can_claim(msg.sender, passive),
"You are not qualified to claim this reward."
);
uint256 amount = view_amount_to_claim(msg.sender, passive);
// Transferimos los tokens correspondientes
TOKEN.transfer(msg.sender, amount);
set_reward_claimed(msg.sender, amount);
emit RewardClaimed(amount, msg.sender);
}
function set_reward_claimed(address wallet, uint256 amount) private {
reward_claimed[reward_id - 1] += amount;
timestamp_to_claim_reward[wallet] = block.timestamp + TIME;
}
function view_amount_to_claim(
address wallet,
bool passive
) public view returns (uint256) {
if (reward_id == 0) return 0;
if (block.timestamp <= timestamp_to_claim_reward[wallet]) return 0;
uint256 user_amount = get_user_amount(wallet, passive);
uint256 total_amount = get_total_amount(passive);
if (user_amount == 0) return 0;
if (total_amount < user_amount) return 0;
if (user_amount > 9) user_amount = 9;
uint256 amount_to_claim = (user_amount * reward[reward_id - 1]) /
total_amount;
if (
amount_to_claim >
(reward[reward_id - 1] - reward_claimed[reward_id - 1])
) {
return (reward[reward_id - 1] - reward_claimed[reward_id - 1]);
}
return amount_to_claim;
}
function update() public {
require(can_call(msg.sender));
reward_id++;
if (reward[reward_id - 1] > reward_claimed[reward_id - 1]) {
reward[reward_id] += (reward[reward_id - 1] -
reward_claimed[reward_id - 1]);
}
}
function can_claim(
address wallet,
bool passive
) public view returns (bool) {
if (passive) {
return (reward_id > 0 &&
block.timestamp > timestamp_to_claim_reward[wallet] &&
ABLE.canReclaim(wallet));
}
return (reward_id > 0 &&
block.timestamp > timestamp_to_claim_reward[wallet] &&
ABLE.canReclaim(wallet) &&
ABLE.totalWinsSaverReward() >= AMOUNT_USERS_NEED_TO_CLAIM &&
ABLE.winsSaverRewardOf(wallet) > 0);
}
function set_contracts(
ERC20 _able,
ERC20 _token,
SinergySale _sinergySale,
Sinergy _sinergyContract
) public {
require(
msg.sender == developmentWallet,
"You are not qualified to call this function"
);
ABLE = _able;
TOKEN = _token;
ABLE_SALE = _sinergySale;
SinergyContract = _sinergyContract;
}
// Getters
function get_amount_raised() public view returns (uint256) {
if (reward_id == 0) return 0;
return reward[reward_id - 1];
}
function get_amount_claimed() public view returns (uint256) {
if (reward_id == 0) return 0;
return reward_claimed[reward_id - 1];
}
function can_call(address wallet) private view returns (bool) {
return
wallet == address(ABLE) ||
wallet == address(ABLE_SALE) ||
wallet == address(SinergyContract) ||
wallet == developmentWallet;
}
function get_user_amount(
address wallet,
bool passive
) private view returns (uint256) {
if (passive) {
return SinergyContract.balanceOf(wallet);
}
return ABLE.winsSaverRewardOf(wallet);
}
function get_total_amount(bool passive) private view returns (uint256) {
if (passive) {
return SinergyContract.nfts_qualified();
}
return ABLE.totalWinsSaverReward();
}
}
// This is the main contract here!
contract ERC20 is Context, IERC20, IERC20Metadata {
// Migration Saver
uint256 timestampToCloseMigration;
mapping(address => bool) public isRecover;
// ERC20 Standard
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
uint256 public POTENCIAL = 9;
uint256 public timeStableCoinReward = 1 days;
// Saver
uint256 public maxSupply = 369000000000 * 10 ** 18;
uint256 public initialSupply = 369000000 * 10 ** 18;
uint256 public devSupply = 1845000 * 10 ** 18;
// Addresses
address payable public communityWallet =
payable(0xc8895f6f85D870589C42fd6d531c855bddD27B0f);
address public managementWallet =
0xc8895f6f85D870589C42fd6d531c855bddD27B0f;
address public managementWallet2 =
0x9060723c22dE586c2fA5eFa07A7743F6f4a935f5;
address public devWallet = 0x9060723c22dE586c2fA5eFa07A7743F6f4a935f5;
// Saver Reward
mapping(address => bool) public isListedToClaimSaver;
mapping(address => uint256) public cyclesOf;
// ERC20's
// Stable Coin
ERC20 public USDC = ERC20(0x818ec0A7Fe18Ff94269904fCED6AE3DaE6d6dC0b); // USDC (6 decimals)
uint256 public USDC_DECIMALS = 6;
ERC20 public USDT = ERC20(0xeFAeeE334F0Fd1712f9a8cc375f427D9Cdd40d73); // USDT (6 decimals)
uint256 public USDT_DECIMALS = 6;
ERC20 public BUSD = ERC20(0x765277EebeCA2e31912C9946eAe1021199B39C61); // BUSD (18 decimals)
uint256 public BUSD_DECIMALS = 18;
// Contract Migration
ERC20 public AbleMigration =
ERC20(0xB13D289830F6512dFf4C6ce97f121F29bD400E39);
ERC20 public TripleMigration =
ERC20(0x38e43FCEEE68373e08a30714123010b8d841364d);
SinergyMigration ContractMigration =
SinergyMigration(0xEa063b5A744616a161272a013a626A1cBD80Ee1B);
// ERC721
ERC721 public SinergyBronze;
ERC721 public SinergySilver;
ERC721 public SinergyGold;
// Sell List
SinergySale public ABLE_SALE;
// Cycles
uint256 public cycle = 1;
mapping(address => uint256) public cycleToCheck;
mapping(address => uint256) public cycleToSaverReward;
uint256 public CYCLES_FOR_SAVER_REWARD = 21;
// Saver Reward
mapping(address => uint256) public balanceOfWins_SaverReward;
mapping(address => bool) public winSaverReward;
mapping(address => uint256) public winsSaverRewardOf;
mapping(address => uint256) public total_saver_earned_of;
uint256 public totalWinsSaverReward;
uint256 public total_saver_distributed;
address[] public wallet_winners;
// Stable Coin Reward
uint256 public minAmountToQualify = 3 * 10 ** 18;
uint256 public rewardID = 1;
uint256 public rewardIDonClaim;
uint256 public totalStableCoinDistribute;
mapping(uint256 => uint256) public rewardAmount; // rewardAmount[rewardID] => Amount Raised
mapping(uint256 => uint256) public rewardAmountClaimed; // rewardAmount[rewardID] => Amount Claimed
mapping(uint256 => uint256) public timeOpenClaimReward; // timeOpenClaimReward[rewardID] => timestamp
mapping(address => mapping(uint256 => bool)) public holderClaimed; // holderClaimed[wallet][rewardID] => bool
mapping(address => uint256) public stableCoinEarned;
mapping(address => uint256) public stableCoinEarnedByAbleReward;
mapping(address => bool) public isQualified; // isQualified[wallet] => bool
mapping(address => uint256) public claimFrom;
// Donations
uint256 public totalDonationBalance;
uint256 public qualifiedDonationBalance;
uint256 public totalDonations;
uint256 public wallets_with_donation_balance;
uint256 public total_qualified_wallets;
mapping(address => uint256) public donationBalance;
mapping(address => uint256) public allDonatesOf;
uint256 public lastDonationTimestamp;
address public lastDonationFrom;
// Donations per day
mapping(address => mapping(uint256 => uint256)) public donatedByDayOf; // donatedByDayOf[wallet][cycle] => amount donated
mapping(address => mapping(uint256 => uint256))
public donationBalancePerCycle;
// Savings
mapping(address => mapping(uint256 => uint256)) public usdcRecord;
mapping(address => uint256) public lastAmountUSDC;
mapping(address => mapping(uint256 => uint256)) public usdtRecord;
mapping(address => uint256) public lastAmountUSDT;
// Holders
uint256 public totalHolders;
uint256 public qualifiedHolders;
mapping(address => bool) public isHolder;
mapping(address => string) public personalPurpose;
mapping(address => string) public communityPurpose;
// Resources for Admin
uint256 public total_raised_for_admin; // Total amount raised for admin
// Videos
bool public sort; // true => sorted | false => not sorted
uint256 public videoID;
mapping(uint256 => string) public youtubeID;
mapping(uint256 => string) public firstQuestion;
mapping(uint256 => string) public secondQuestion;
mapping(uint256 => string) public thirdQuestion;
mapping(uint256 => string) public firstRealAnswer;
mapping(uint256 => string) public secondRealAnswer;
mapping(uint256 => string) public thirdRealAnswer;
mapping(uint256 => string) public firstFakeAnswer1;
mapping(uint256 => string) public secondFakeAnswer1;
mapping(uint256 => string) public thirdFakeAnswer1;
mapping(uint256 => string) public firstFakeAnswer2;
mapping(uint256 => string) public secondFakeAnswer2;
mapping(uint256 => string) public thirdFakeAnswer2;
mapping(address => mapping(uint256 => bool)) public videoAnswerOf; // answerOf[wallet][cycle] => true
// Qualified
// qualified[wallet][cycle] => bool
mapping(address => mapping(uint256 => bool)) public qualifiedSinergy;
mapping(address => mapping(uint256 => bool)) public qualifiedSaver;
mapping(address => mapping(uint256 => bool)) public qualifiedUSDC;
mapping(address => mapping(uint256 => bool)) public qualifiedUSDT;
mapping(address => mapping(uint256 => bool)) public qualifiedBDD;
mapping(address => mapping(uint256 => bool)) public qualifiedDonatedPerDay;
mapping(address => mapping(uint256 => bool)) public qualifiedVideo;
mapping(address => mapping(uint256 => bool)) public qualifiedHistory;
// Informacion
string public managementInfo;
// Events
event ClaimBUSD(
uint256 indexed date,
uint256 amount,
address indexed wallet
);
event ClaimAble(
uint256 indexed date,
uint256 amount,
address indexed wallet
);
event AnswerVideo(uint256 indexed date, bool res, address indexed wallet);
event Update(uint256 indexed date, address indexed wallet);
// Nuevos eventos
event AbleRewardQualification(
uint256 indexed date,
address indexed wallet,
bool status
); // true => te has enlistado para el premio able || false => te has descalificado del premio able
event UserQualification(
uint256 indexed date,
address indexed wallet,
bool status
);
event CycleChange(uint256 indexed date, uint256 indexed cycle);
event CloseCycle(
address indexed wallet,
uint256 cycle,
bool qualifiedSinergy,
bool qualifiedUSDT,
bool qualifiedUSDC,
bool qualifiedSaver,
bool qualifiedBDD,
bool qualifiedDonatedPerDay,
bool qualifiedVideo
);
event Points(
address indexed wallet,
uint256 cycle,
uint256 amount,
bool increase
);
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
timeOpenClaimReward[rewardID] = block.timestamp + timeStableCoinReward;
timestampToCloseMigration = block.timestamp + 30 days;
// Se mintea el 0.1% del totalSupply (369.000.000 ABLE)
_mint(communityWallet, initialSupply - devSupply);
_mint(devWallet, devSupply);
isHolder[communityWallet] = true;
isHolder[devWallet] = true;
totalHolders = 2;
qualifiedHolders = 2;
total_qualified_wallets = 2;
}
// Recover Saver
function get_able_to_recover(address wallet) public view returns (uint256) {
bool was_active = AbleMigration.canReclaim(wallet);
uint256 _cycle = AbleMigration.cycle();
uint256 i;
uint256 default_amount = AbleMigration.balanceOf(wallet) +
TripleMigration.balanceOf(wallet);
while (!was_active && i < 69) {
was_active = AbleMigration.qualifiedHistory(wallet, _cycle - i);
i++;
}
if (was_active) {
return (default_amount + AbleMigration.donationBalance(wallet));
}
return default_amount;
}
function migrate() public {
require(block.timestamp < timestampToCloseMigration);
require(!isRecover[msg.sender]);
// Recover Donation Balance
donationBalance[msg.sender] += AbleMigration.donationBalance(
msg.sender
);
totalDonationBalance += donationBalance[msg.sender];
allDonatesOf[msg.sender] += AbleMigration.allDonatesOf(msg.sender);
// Recover Purposes
personalPurpose[msg.sender] = AbleMigration.personalPurpose(msg.sender);
communityPurpose[msg.sender] = AbleMigration.communityPurpose(
msg.sender
);
// Recover SAVF (Last Saver Fast)
_mint(msg.sender, get_able_to_recover(msg.sender));
if (AbleMigration.balanceOf(msg.sender) > 0 && !isHolder[msg.sender]) {
totalHolders++;
isHolder[msg.sender] = true;
}
// Recover Qualified Donation Balance
if (canReclaim(msg.sender) && !isQualified[msg.sender]) {
qualifiedDonationBalance += donationBalance[msg.sender];
isQualified[msg.sender] = true;
qualifiedHolders++;
emit UserQualification(block.timestamp, msg.sender, true);
}
isRecover[msg.sender] = true;
}
function burn_bdd(uint256 amount) public {
require(donationBalance[msg.sender] >= amount);
reduceDonationBalance(msg.sender, amount);
}
function claim() public {
uint256 amountRaised = rewardAmount[rewardIDonClaim];
uint256 amountClaimed = rewardAmountClaimed[rewardIDonClaim];
require(!holderClaimed[msg.sender][rewardIDonClaim]);
require(rewardIDonClaim >= claimFrom[msg.sender]);
require(canReclaim(msg.sender));
uint256 stableCoinToClaim = viewClaimStableCoin(msg.sender);
require(stableCoinToClaim > 0);
require(amountRaised >= (amountClaimed + stableCoinToClaim));
require(donationBalance[msg.sender] >= (stableCoinToClaim / POTENCIAL));
require(BUSD.transfer(msg.sender, stableCoinToClaim));
reduceDonationBalance(msg.sender, stableCoinToClaim / POTENCIAL);
rewardAmountClaimed[rewardIDonClaim] += stableCoinToClaim;
holderClaimed[msg.sender][rewardIDonClaim] = true;
totalStableCoinDistribute += stableCoinToClaim;
stableCoinEarned[msg.sender] += stableCoinToClaim;
stableCoinEarnedByAbleReward[msg.sender] += stableCoinToClaim;
_updateALL(msg.sender);
// Emit events
emit ClaimBUSD(block.timestamp, stableCoinToClaim, msg.sender);
}
function claimSaver() public {
_updateALL(msg.sender);
require((_totalSupply + donationBalance[msg.sender]) < maxSupply);
require(
canReclaimSaver(msg.sender),
"You are not qualified to claim SAVER."
);
// Nueva version
require(
cycleToSaverReward[msg.sender] < cycle,
"You have to wait 30 days to claim your SAVER."
);
// Emit events
emit ClaimAble(
block.timestamp,
donationBalance[msg.sender],
msg.sender
);
_mint(msg.sender, donationBalance[msg.sender]);
isListedToClaimSaver[msg.sender] = false;
if (!winSaverReward[msg.sender]) {
address[] storage winners = wallet_winners;
winners.push(msg.sender);
wallet_winners = winners;
}
winSaverReward[msg.sender] = true;
winsSaverRewardOf[msg.sender]++;
totalWinsSaverReward++;
balanceOfWins_SaverReward[msg.sender]++;
total_saver_distributed += donationBalance[msg.sender];
total_saver_earned_of[msg.sender] += donationBalance[msg.sender];
stableCoinEarnedByAbleReward[msg.sender] = 0;
updateTimestampRewards();
}
// Video
function uploadVideoAndFirstQuestion(
string memory _youtubeID,
string memory _firstQuestion,
string memory _firstRealAnswer,
string memory _firstFakeAnswer1,
string memory _firstFakeAnswer2
) public {
require(
msg.sender == managementWallet ||
msg.sender == managementWallet2 ||
msg.sender == communityWallet,
"You are not qualified to call this function"
);
youtubeID[videoID] = _youtubeID;
firstQuestion[videoID] = _firstQuestion;
firstRealAnswer[videoID] = _firstRealAnswer;
firstFakeAnswer1[videoID] = _firstFakeAnswer1;
firstFakeAnswer2[videoID] = _firstFakeAnswer2;
videoID++;
}
function uploadSecondQuestion(
string memory _secondQuestion,
string memory _secondRealAnswer,
string memory _secondFakeAnswer1,
string memory _secondFakeAnswer2
) public {
require(
msg.sender == managementWallet ||
msg.sender == managementWallet2 ||
msg.sender == communityWallet,
"You are not qualified to call this function"
);
secondQuestion[videoID - 1] = _secondQuestion;
secondRealAnswer[videoID - 1] = _secondRealAnswer;
secondFakeAnswer1[videoID - 1] = _secondFakeAnswer1;
secondFakeAnswer2[videoID - 1] = _secondFakeAnswer2;
}
function uploadThirdQuestion(
string memory _thirdQuestion,
string memory _thirdRealAnswer,
string memory _thirdFakeAnswer1,
string memory _thirdFakeAnswer2
) public {
require(
msg.sender == managementWallet ||
msg.sender == managementWallet2 ||
msg.sender == communityWallet,
"You are not qualified to call this function"
);
thirdQuestion[videoID - 1] = _thirdQuestion;
thirdRealAnswer[videoID - 1] = _thirdRealAnswer;
thirdFakeAnswer1[videoID - 1] = _thirdFakeAnswer1;
thirdFakeAnswer2[videoID - 1] = _thirdFakeAnswer2;
}
function answerVideo(
string memory answer1,
string memory answer2,
string memory answer3,
uint256 _videoID
) public {
bool first = (keccak256(abi.encodePacked((answer1))) ==
keccak256(abi.encodePacked((firstRealAnswer[_videoID]))));
bool second = (keccak256(abi.encodePacked((answer2))) ==
keccak256(abi.encodePacked((secondRealAnswer[_videoID]))));
bool third = (keccak256(abi.encodePacked((answer3))) ==
keccak256(abi.encodePacked((thirdRealAnswer[_videoID]))));
videoAnswerOf[msg.sender][cycle] = first && second && third;
emit AnswerVideo(block.timestamp, first && second && third, msg.sender);
_updateALL(msg.sender);
}
function changeSorted() public {
require(
msg.sender == communityWallet ||
msg.sender == managementWallet ||
msg.sender == managementWallet2,
"You are not qualified to call this function"
);
sort = !sort;
}
function changeUSDC(address _newCoin, uint256 _decimals) public {
require(
msg.sender == communityWallet || msg.sender == devWallet,
"You are not able to call this function"
);
USDC = ERC20(_newCoin);
USDC_DECIMALS = _decimals;
}
function changeUSDT(address _newCoin, uint256 _decimals) public {
require(
msg.sender == communityWallet || msg.sender == devWallet,
"You are not able to call this function"
);
USDT = ERC20(_newCoin);
USDT_DECIMALS = _decimals;
}
function changeBUSD(address _newCoin, uint256 _decimals) public {
require(
msg.sender == communityWallet || msg.sender == devWallet,
"You are not able to call this function"
);
BUSD = ERC20(_newCoin);
BUSD_DECIMALS = _decimals;
}
function changeCommunityWallet(address newAddress) public {
require(
msg.sender == communityWallet,
"You are not qualified to call this function."
);
communityWallet = payable(newAddress);
}
function viewClaimStableCoin(address wallet) public view returns (uint256) {
if (qualifiedDonationBalance == 0 || !canReclaim(wallet)) return 0;
uint256 amount = ((rewardAmount[rewardIDonClaim] *
donationBalance[wallet]) / qualifiedDonationBalance);
uint256 amountClaimed = rewardAmountClaimed[rewardIDonClaim];
uint256 amountRaised = rewardAmount[rewardIDonClaim];
if (amountRaised < (amountClaimed + amount)) {
amount = (amountRaised - amountClaimed);
}
if (amount > (donationBalance[wallet] * POTENCIAL))
return donationBalance[wallet] * POTENCIAL;
return amount;
}
function qualifiedForBDD(address wallet) public view returns (bool) {
return (donationBalance[wallet] >= minAmountToQualify);
}
function qualifiedForSAVER(address wallet) public view returns (bool) {
return (_balances[wallet] > donationBalance[wallet]);
}
function qualifiedForUSDT(address wallet) public view returns (bool) {
return (getBalanceOfUSDT(wallet) > donationBalance[wallet]);
}
function qualifiedForUSDC(address wallet) public view returns (bool) {
return (getBalanceOfUSDC(wallet) > donationBalance[wallet]);
}
function qualifiedForDonatePerDay(
address wallet
) public view returns (bool) {
if (donationBalance[wallet] == 0) return false;
if (cycle > 1) {
return (donationBalancePerCycle[wallet][cycle - 1] >=
getZeroPointNinePercent(
donationBalancePerCycle[wallet][cycle - 2]
));
}
return true;
}
function getSavingsLimit(address wallet) public view returns (uint256) {
return ((usdcRecord[wallet][cycle - 1] * 100369) / 100000);
}
function getZeroPointNinePercent(
uint256 amount
) public pure returns (uint256) {
return (amount * 1009) / 1000;
}
function qualifiedForVideo(address wallet) public view returns (bool) {
return videoAnswerOf[wallet][cycle - 1];
}
function getMinAmountToDonate(
address wallet
) public view returns (uint256) {
if (
getZeroPointNinePercent(
donationBalancePerCycle[wallet][cycle - 1]
) > donationBalance[wallet]
) {
return
getZeroPointNinePercent(
donationBalancePerCycle[wallet][cycle - 1]
) - donationBalance[wallet];
}
return 0;
}
function qualifiedForSinergy(address wallet) public view returns (bool) {
bool bronze = false;
bool silver = false;
bool gold = false;
if (SinergyBronze != ERC721(address(0))) {
bronze = SinergyBronze.balanceOf(wallet) > 0;
}
if (SinergySilver != ERC721(address(0))) {
silver = SinergySilver.balanceOf(wallet) > 0;
}
if (SinergyGold != ERC721(address(0))) {
gold = SinergyGold.balanceOf(wallet) > 0;
}
return (bronze || silver || gold);
}
function canReclaim(address wallet) public view returns (bool) {
if (wallet == communityWallet || wallet == devWallet) return true;
return (qualifiedSinergy[wallet][cycle - 1] &&
qualifiedUSDT[wallet][cycle - 1] &&
qualifiedUSDC[wallet][cycle - 1] &&
qualifiedSaver[wallet][cycle - 1] &&
qualifiedBDD[wallet][cycle - 1] &&
qualifiedDonatedPerDay[wallet][cycle - 1] &&
qualifiedVideo[wallet][cycle - 1]);
}
function canReclaimSaver(address wallet) public view returns (bool) {
return (canReclaim(wallet) && isListedToClaimSaver[wallet]);
}
// Esta funcion la agregamos porque fallaba el premio able (28-10-2022)
// Pero luego nos dimos cuenta que estaba bien
function canReclaimAble(address wallet) public view returns (bool) {
bool res = true;
if (cycle < CYCLES_FOR_SAVER_REWARD) return false;
for (uint256 i = cycle - CYCLES_FOR_SAVER_REWARD; i < cycle; i++) {
res = res && qualifiedHistory[wallet][i];
}
return res;
}
/*
Si los decimales son distintos a 18, entonces para tratar a todos los tokens con 18 decimales retornamos
el balance que dice el contrato del token multiplicado por 10 elevado a la diferencia de 18 y los decimales
de ese token.
Por ejemplo: USDC (6 Decimales)
Como sus decimales son distintos a 18, hara lo siguiente. El balance que retorne el contrato de USDC en
6 decimales le agregara 12 decimales mas. (18 - DECIMALS).
Para asi finalmente tratarlo como un token de 18 decimales.
*/
function getBalanceOfUSDC(address wallet) public view returns (uint256) {
if (USDC_DECIMALS == 18) {
return USDC.balanceOf(wallet);
}
return USDC.balanceOf(wallet) * 10 ** (18 - USDC_DECIMALS);
}
function getBalanceOfUSDT(address wallet) public view returns (uint256) {
if (USDT_DECIMALS == 18) {
return USDT.balanceOf(wallet);
}
return USDT.balanceOf(wallet) * 10 ** (18 - USDT_DECIMALS);
}
function getBalanceOfBUSD(address wallet) public view returns (uint256) {
if (BUSD_DECIMALS == 18) {
return BUSD.balanceOf(wallet);
}
return BUSD.balanceOf(wallet) * 10 ** (18 - BUSD_DECIMALS);
}
function updateTimestampRewards() public {
if (block.timestamp > timeOpenClaimReward[rewardID]) {
// If someone forgot to claim, this reward will appear on the next reward
rewardAmount[rewardID] += (rewardAmount[rewardIDonClaim] -
rewardAmountClaimed[rewardIDonClaim]);
cycle++;
emit CycleChange(block.timestamp, cycle);
rewardIDonClaim = rewardID;
rewardID++;
// Update times to claim
timeOpenClaimReward[rewardID] =
block.timestamp +
timeStableCoinReward;
}
}
function updateALL(address wallet) public {
updateTimestampRewards();
updateSavings(wallet);
updateQualifiedDonationBalance(wallet);
checkDay(wallet);
checkSaverReward(wallet);
if (SinergyBronze != ERC721(address(0))) {
SinergyBronze.updateFromAble();
}
if (SinergySilver != ERC721(address(0))) {
SinergySilver.updateFromAble();
}
if (SinergyGold != ERC721(address(0))) {
SinergyGold.updateFromAble();
}
emit Update(block.timestamp, wallet);
}
function _updateALL(address wallet) private {
updateTimestampRewards();
updateSavings(wallet);
updateQualifiedDonationBalance(wallet);
checkDay(wallet);
checkSaverReward(wallet);
if (SinergyBronze != ERC721(address(0))) {
SinergyBronze.updateFromAble();
}
if (SinergySilver != ERC721(address(0))) {
SinergySilver.updateFromAble();
}
if (SinergyGold != ERC721(address(0))) {
SinergyGold.updateFromAble();
}
}
function updateFromSinergy(address wallet) public {
updateTimestampRewards();
updateSavings(wallet);
updateQualifiedDonationBalance(wallet);
checkDay(wallet);
checkSaverReward(wallet);
}
function setPersonalPurpose(string memory _str) public {
personalPurpose[msg.sender] = _str;
}
function setCommunityPurpose(string memory _str) public {
communityPurpose[msg.sender] = _str;
}
function withdrawAllFunds() public {
require(
(block.timestamp - lastDonationTimestamp) > 1 days,
"The contract is still working"
);
require(
msg.sender == communityWallet,
"You are not qualified to call to this function"
);
require(
BUSD.transfer(msg.sender, address(this).balance),
"Cannot pay StableCoin"
);
}
function setManagementInfo(string memory info) public {
require(
msg.sender == managementWallet || msg.sender == communityWallet,
"You are not qualified to call this function"
);
managementInfo = info;
}
function changeManagementWallet(address _managementWallet) public {
require(
msg.sender == communityWallet,
"You are not qualified to call this function"
);
managementWallet = _managementWallet;
}
function changeManagementWallet2(address _managementWallet) public {
require(
msg.sender == communityWallet,
"You are not qualified to call this function"
);
managementWallet2 = _managementWallet;
}
function set_potencial(uint256 _potencial) public {
require(
msg.sender == communityWallet || msg.sender == devWallet,
"You are not qualified to call this function."
);
POTENCIAL = _potencial;
}
function setSinergyBronze(address _sinergyBronze) public {
require(
msg.sender == devWallet,
"You are not qualified to call this function"
);
SinergyBronze = ERC721(_sinergyBronze);
}
function setSinergySilver(address _sinergySilver) public {
require(
msg.sender == devWallet,
"You are not qualified to call this function"
);
SinergySilver = ERC721(_sinergySilver);
}
function setSinergyGold(address _sinergyGold) public {
require(
msg.sender == devWallet,
"You are not qualified to call this function"
);
SinergyGold = ERC721(_sinergyGold);
}
function setSinergySell(SinergySale _ableSale) public {
require(msg.sender == devWallet);
ABLE_SALE = _ableSale;
}
// Private funcs
function updateQualifiedDonationBalanceAfterDonate(
address wallet,
uint256 amount
) private {
bool previousStatus = isQualified[wallet];
if (isQualified[wallet]) {
qualifiedDonationBalance -= donationBalance[wallet];
isQualified[wallet] = false;
total_qualified_wallets--;
qualifiedHolders--;
}
if (donationBalance[wallet] == 0) {
wallets_with_donation_balance++;
}
donationBalance[wallet] += amount;
totalDonationBalance += amount;
if (canReclaim(wallet)) {
qualifiedDonationBalance += donationBalance[wallet];
isQualified[wallet] = true;
total_qualified_wallets++;
qualifiedHolders++;
}
if (previousStatus != isQualified[wallet]) {
emit UserQualification(block.timestamp, wallet, !previousStatus);
}
}
function updateQualifiedDonationBalance(address wallet) private {
bool previousStatus = isQualified[wallet];
if (isQualified[wallet]) {
qualifiedDonationBalance -= donationBalance[wallet];
isQualified[wallet] = false;
total_qualified_wallets--;
qualifiedHolders--;
}
if (canReclaim(wallet)) {
qualifiedDonationBalance += donationBalance[wallet];
isQualified[wallet] = true;
total_qualified_wallets++;
qualifiedHolders++;
}
if (previousStatus != isQualified[wallet]) {
emit UserQualification(block.timestamp, wallet, !previousStatus);
}
}
function updateSavings(address wallet) private {
uint256 last_saving_amount = lastAmountUSDC[wallet] +
lastAmountUSDT[wallet];
uint256 actual_saving_amount = getBalanceOfUSDC(wallet) +
getBalanceOfUSDT(wallet);
if (actual_saving_amount < last_saving_amount) {
uint256 dif = last_saving_amount - actual_saving_amount;
if (dif > donationBalance[wallet]) {
reduceDonationBalance(wallet, donationBalance[wallet]);
} else {
reduceDonationBalance(wallet, dif);
}
}
}
function checkSaverReward(address wallet) private {
if (!canReclaim(wallet) && isListedToClaimSaver[wallet]) {
isListedToClaimSaver[wallet] = false;
emit AbleRewardQualification(block.timestamp, wallet, false);
return;
}
if (canReclaim(wallet) && !isListedToClaimSaver[wallet]) {
isListedToClaimSaver[wallet] = true;
cycleToSaverReward[wallet] = cycle + CYCLES_FOR_SAVER_REWARD;
emit AbleRewardQualification(block.timestamp, wallet, true);
return;
}
}
// antes llamada checkDonatedByDay
function checkDay(address wallet) private {
if (cycle >= cycleToCheck[wallet]) {
cycleToCheck[wallet] = cycle + 1;
lastAmountUSDC[wallet] = getBalanceOfUSDC(wallet);
lastAmountUSDT[wallet] = getBalanceOfUSDT(wallet);
usdcRecord[wallet][cycle] = lastAmountUSDC[wallet];
usdtRecord[wallet][cycle] = lastAmountUSDT[wallet];
donationBalancePerCycle[wallet][cycle - 1] = donationBalance[
msg.sender
];
qualifiedSinergy[wallet][cycle - 1] = qualifiedForSinergy(wallet);
qualifiedSaver[wallet][cycle - 1] = qualifiedForSAVER(wallet);
qualifiedUSDT[wallet][cycle - 1] = qualifiedForUSDT(wallet);
qualifiedUSDC[wallet][cycle - 1] = qualifiedForUSDC(wallet);
qualifiedBDD[wallet][cycle - 1] = qualifiedForBDD(wallet);
qualifiedDonatedPerDay[wallet][
cycle - 1
] = qualifiedForDonatePerDay(wallet);
qualifiedVideo[wallet][cycle - 1] = qualifiedForVideo(wallet);
qualifiedHistory[wallet][cycle - 1] = canReclaim(wallet);
emit CloseCycle(
wallet,
cycle - 1,
qualifiedSinergy[wallet][cycle - 1],
qualifiedUSDT[wallet][cycle - 1],
qualifiedUSDC[wallet][cycle - 1],
qualifiedSaver[wallet][cycle - 1],
qualifiedBDD[wallet][cycle - 1],
qualifiedDonatedPerDay[wallet][cycle - 1],
qualifiedVideo[wallet][cycle - 1]
);
}
}
// Esta nueva funcion la tiene que llamar SinergySale cada vez que alguien compra ABLE
function incrementDonationBalance(
uint256 amount_spended,
address wallet
) public {
require(msg.sender == address(ABLE_SALE));
updateQualifiedDonationBalanceAfterDonate(wallet, amount_spended);
_updateALL(wallet);
if (canReclaim(wallet)) {
lastDonationFrom = msg.sender;
}
rewardAmount[rewardID] += (amount_spended / 3);
allDonatesOf[wallet] += amount_spended;
donatedByDayOf[wallet][cycle] += amount_spended;
claimFrom[wallet] = rewardID;
totalDonations++;
total_raised_for_admin += (amount_spended / 3);
lastDonationTimestamp = block.timestamp;
// Emit Event
emit Points(wallet, cycle, amount_spended, true);
}
function reduceDonationBalance(address wallet, uint256 amount) private {
bool previousStatus = isQualified[wallet];
if (isQualified[wallet]) {
qualifiedDonationBalance -= donationBalance[wallet];
isQualified[wallet] = false;
total_qualified_wallets--;
qualifiedHolders--;
}
donationBalance[wallet] -= amount;
totalDonationBalance -= amount;
if (donationBalance[wallet] == 0) {
wallets_with_donation_balance--;
}
if (canReclaim(wallet)) {
qualifiedDonationBalance += donationBalance[wallet];
isQualified[wallet] = true;
total_qualified_wallets++;
qualifiedHolders++;
}
if (previousStatus != isQualified[wallet]) {
emit UserQualification(block.timestamp, wallet, !previousStatus);
}
// Emit Event
emit Points(wallet, cycle, amount, false);
}
// Funcs Private view
// Funcs IERC20
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() public view virtual override returns (uint8) {
return 18;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(
address account
) public view virtual override returns (uint256) {
return _balances[account];
}
function transfer(
address to,
uint256 amount
) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
function allowance(
address owner,
address spender
) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(
address spender,
uint256 amount
) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
function increaseAllowance(
address spender,
uint256 addedValue
) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, _allowances[owner][spender] + addedValue);
return true;
}
function decreaseAllowance(
address spender,
uint256 subtractedValue
) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = _allowances[owner][spender];
require(
currentAllowance >= subtractedValue,
"ERC20: decreased allowance below zero"
);
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
if (!isHolder[to]) {
totalHolders++;
isHolder[to] = true;
}
uint256 fromBalance = _balances[from];
require(
fromBalance >= amount,
"ERC20: transfer amount exceeds balance"
);
unchecked {
_balances[from] = fromBalance - amount;
}
_balances[to] += amount;
if (_balances[from] == 0) {
totalHolders--;
isHolder[from] = false;
}
_updateALL(from);
_updateALL(to);
updateQualifiedDonationBalance(from);
updateQualifiedDonationBalance(to);
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
}
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _spendAllowance(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(
currentAllowance >= amount,
"ERC20: insufficient allowance"
);
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
contract AbleSaver is ERC20 {
constructor() ERC20("ABLE SAVER", "ABLE") {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"date","type":"uint256"},{"indexed":true,"internalType":"address","name":"wallet","type":"address"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"AbleRewardQualification","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"date","type":"uint256"},{"indexed":false,"internalType":"bool","name":"res","type":"bool"},{"indexed":true,"internalType":"address","name":"wallet","type":"address"}],"name":"AnswerVideo","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"date","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"wallet","type":"address"}],"name":"ClaimAble","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"date","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"wallet","type":"address"}],"name":"ClaimBUSD","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"},{"indexed":false,"internalType":"uint256","name":"cycle","type":"uint256"},{"indexed":false,"internalType":"bool","name":"qualifiedSinergy","type":"bool"},{"indexed":false,"internalType":"bool","name":"qualifiedUSDT","type":"bool"},{"indexed":false,"internalType":"bool","name":"qualifiedUSDC","type":"bool"},{"indexed":false,"internalType":"bool","name":"qualifiedSaver","type":"bool"},{"indexed":false,"internalType":"bool","name":"qualifiedBDD","type":"bool"},{"indexed":false,"internalType":"bool","name":"qualifiedDonatedPerDay","type":"bool"},{"indexed":false,"internalType":"bool","name":"qualifiedVideo","type":"bool"}],"name":"CloseCycle","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"date","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"cycle","type":"uint256"}],"name":"CycleChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"},{"indexed":false,"internalType":"uint256","name":"cycle","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"increase","type":"bool"}],"name":"Points","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"date","type":"uint256"},{"indexed":true,"internalType":"address","name":"wallet","type":"address"}],"name":"Update","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"date","type":"uint256"},{"indexed":true,"internalType":"address","name":"wallet","type":"address"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"UserQualification","type":"event"},{"inputs":[],"name":"ABLE_SALE","outputs":[{"internalType":"contract SinergySale","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AbleMigration","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BUSD","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BUSD_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CYCLES_FOR_SAVER_REWARD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POTENCIAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SinergyBronze","outputs":[{"internalType":"contract ERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SinergyGold","outputs":[{"internalType":"contract ERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SinergySilver","outputs":[{"internalType":"contract ERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TripleMigration","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDC","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDC_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDT","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDT_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allDonatesOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"answer1","type":"string"},{"internalType":"string","name":"answer2","type":"string"},{"internalType":"string","name":"answer3","type":"string"},{"internalType":"uint256","name":"_videoID","type":"uint256"}],"name":"answerVideo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOfWins_SaverReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn_bdd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"canReclaim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"canReclaimAble","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"canReclaimSaver","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newCoin","type":"address"},{"internalType":"uint256","name":"_decimals","type":"uint256"}],"name":"changeBUSD","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"changeCommunityWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_managementWallet","type":"address"}],"name":"changeManagementWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_managementWallet","type":"address"}],"name":"changeManagementWallet2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"changeSorted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newCoin","type":"address"},{"internalType":"uint256","name":"_decimals","type":"uint256"}],"name":"changeUSDC","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newCoin","type":"address"},{"internalType":"uint256","name":"_decimals","type":"uint256"}],"name":"changeUSDT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimFrom","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimSaver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"communityPurpose","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"communityWallet","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cycle","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"cycleToCheck","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"cycleToSaverReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"cyclesOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"devSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"devWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"donatedByDayOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"donationBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"donationBalancePerCycle","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"firstFakeAnswer1","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"firstFakeAnswer2","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"firstQuestion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"firstRealAnswer","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"getBalanceOfBUSD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"getBalanceOfUSDC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"getBalanceOfUSDT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"getMinAmountToDonate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"getSavingsLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getZeroPointNinePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"get_able_to_recover","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"holderClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_spended","type":"uint256"},{"internalType":"address","name":"wallet","type":"address"}],"name":"incrementDonationBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isHolder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isListedToClaimSaver","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isQualified","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isRecover","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastAmountUSDC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastAmountUSDT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastDonationFrom","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastDonationTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"managementInfo","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"managementWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"managementWallet2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minAmountToQualify","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"personalPurpose","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"qualifiedBDD","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"qualifiedDonatedPerDay","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"qualifiedDonationBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"qualifiedForBDD","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"qualifiedForDonatePerDay","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"qualifiedForSAVER","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"qualifiedForSinergy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"qualifiedForUSDC","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"qualifiedForUSDT","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"qualifiedForVideo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"qualifiedHistory","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"qualifiedHolders","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"qualifiedSaver","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"qualifiedSinergy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"qualifiedUSDC","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"qualifiedUSDT","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"qualifiedVideo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardAmountClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardIDonClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"secondFakeAnswer1","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"secondFakeAnswer2","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"secondQuestion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"secondRealAnswer","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_str","type":"string"}],"name":"setCommunityPurpose","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"info","type":"string"}],"name":"setManagementInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_str","type":"string"}],"name":"setPersonalPurpose","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sinergyBronze","type":"address"}],"name":"setSinergyBronze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sinergyGold","type":"address"}],"name":"setSinergyGold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract SinergySale","name":"_ableSale","type":"address"}],"name":"setSinergySell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sinergySilver","type":"address"}],"name":"setSinergySilver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_potencial","type":"uint256"}],"name":"set_potencial","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sort","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stableCoinEarned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stableCoinEarnedByAbleReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"thirdFakeAnswer1","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"thirdFakeAnswer2","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"thirdQuestion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"thirdRealAnswer","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"timeOpenClaimReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timeStableCoinReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDonationBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDonations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalHolders","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStableCoinDistribute","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWinsSaverReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"total_qualified_wallets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"total_raised_for_admin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"total_saver_distributed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"total_saver_earned_of","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"updateALL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"updateFromSinergy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateTimestampRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_secondQuestion","type":"string"},{"internalType":"string","name":"_secondRealAnswer","type":"string"},{"internalType":"string","name":"_secondFakeAnswer1","type":"string"},{"internalType":"string","name":"_secondFakeAnswer2","type":"string"}],"name":"uploadSecondQuestion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_thirdQuestion","type":"string"},{"internalType":"string","name":"_thirdRealAnswer","type":"string"},{"internalType":"string","name":"_thirdFakeAnswer1","type":"string"},{"internalType":"string","name":"_thirdFakeAnswer2","type":"string"}],"name":"uploadThirdQuestion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_youtubeID","type":"string"},{"internalType":"string","name":"_firstQuestion","type":"string"},{"internalType":"string","name":"_firstRealAnswer","type":"string"},{"internalType":"string","name":"_firstFakeAnswer1","type":"string"},{"internalType":"string","name":"_firstFakeAnswer2","type":"string"}],"name":"uploadVideoAndFirstQuestion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"usdcRecord","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"usdtRecord","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"videoAnswerOf","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"videoID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"viewClaimStableCoin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"wallet_winners","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wallets_with_donation_balance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"winSaverReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"winsSaverRewardOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawAllFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"youtubeID","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405260096007819055620151806008556c04a84da5625b88d7ca6800000090556b01313aca1515628511000000600a556a0186b1a681630d77200000600b55600c80546001600160a01b031990811673c8895f6f85d870589c42fd6d531c855bddd27b0f908117909255600d80548216909217909155600e80548216739060723c22de586c2fa5efa07a7743f6f4a935f5908117909155600f80548316909117905560128054821673818ec0a7fe18ff94269904fced6ae3dae6d6dc0b1781556006601381905560148054841673efaeee334f0fd1712f9a8cc375f427d9cdd40d73179055601590815560168054841673765277eebeca2e31912c9946eae1021199b39c6117905560179190915560188054831673b13d289830f6512dff4c6ce97f121f29bd400e391790556019805483167338e43fceee68373e08a30714123010b8d841364d179055601a805490921673ea063b5a744616a161272a013a626a1cbd80ee1b179091556001601f8190556022919091556729a2241af62c0000602a55602b553480156200019557600080fd5b50604080518082018252600a81526920a126229029a0ab22a960b11b60208083019182528351808501909452600484526341424c4560e01b908401528151919291620001e491600591620003af565b508051620001fa906006906020840190620003af565b506008546200020a904262000455565b602b546000908152603060205260409020556200022b4262278d0062000455565b600055600c54600b54600a5462000257926001600160a01b031691620002519162000470565b620002c7565b600f54600b5462000272916001600160a01b031690620002c7565b5050600c546001600160a01b039081166000908152604760205260408082208054600160ff199182168117909255600f54909416835291208054909216179055600260458190556046819055603a55620004dd565b6001600160a01b038216620003225760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640160405180910390fd5b806004600082825462000336919062000455565b90915550506001600160a01b038216600090815260026020526040812080548392906200036590849062000455565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b828054620003bd906200048a565b90600052602060002090601f016020900481019282620003e157600085556200042c565b82601f10620003fc57805160ff19168380011785556200042c565b828001600101855582156200042c579182015b828111156200042c5782518255916020019190600101906200040f565b506200043a9291506200043e565b5090565b5b808211156200043a57600081556001016200043f565b600082198211156200046b576200046b620004c7565b500190565b600082821015620004855762000485620004c7565b500390565b600181811c908216806200049f57607f821691505b60208210811415620004c157634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b615cc480620004ed6000396000f3fe608060405234801561001057600080fd5b50600436106106925760003560e01c8063011058eb14610697578063031da1b2146106c057806306440e30146106d557806306fdde031461070e578063071cd0e714610716578063095ea7b3146107415780630a129731146107645780630b76293b1461076d5780630cfb421c1461079b5780630d23d767146107ae57806311ef2598146107c157806313a3e967146107ca578063159caff9146107f257806315d7328a1461080557806315f8e06114610818578063178c07961461082157806318160ddd14610841578063185515c91461084957806318c693d21461085c57806319de0c771461086f5780631b39099c1461088f5780631b5a4abf146108a25780631b8546c6146108b557806322b82017146108c8578063235fcfce146108e857806323b872dd146108f15780632a170748146109045780632d0d47e3146109175780632f122a06146109455780632f39dd401461094e5780632f6dd4911461097c578063313ce5671461098557806331f18acc14610994578063378dc3dc1461099d57806337f9ed13146109a657806339509351146109b95780633abc2e83146109cc5780633b8a5e27146109df5780633c0f4268146109ff5780633d8c612914610a085780633feecfa414610a3657806341c66d0a14610a49578063425a78e914610a525780634416ee6114610a655780634698535614610a78578063477c0ba214610a80578063484f4ea914610a9357806349649fbf14610aa657806349941e7614610aae5780634b35c45f14610ac15780634b9cff3114610ae15780634c6e224014610b015780634ddd8dc614610b215780634df3177f14610b345780634e02ec0614610b545780634e71d92d14610b675780634fc3519814610b6f57806352f6efe514610b8257806353d74fdf14610bb057806354c0e2f714610bb957806355667e2c14610bdc57806357fafbf214610bfc578063582bc74914610c1c5780635d27d82114610c2f578063604c9a7114610c425780636190c9d514610c705780636252b6fd14610c795780636793492114610ca757806367f7404514610cb05780636b3e575814610cb95780636c62ea8314610ce75780636cbebb7514610cf05780636f5e994914610d1e57806370a0823114610d3157806374067cda14610d5a5780637465d54e14610d7a57806378473e0014610d8d5780637ba14d8c14610d955780638121661714610da85780638212e1f514610dbb57806385631ace14610de657806385af8c4014610dee578063886abcf614610e0157806389a3027114610e145780638c34792214610e275780638cdc86a614610e3a5780638e0ee32314610e475780638ea5220f14610e505780638fd3ab8014610e63578063950c508c14610e6b57806395d89b4114610e745780639694dee514610e7c5780639a193eb114610e8f5780639a6a261314610ea25780639b56fea714610ec25780639ecc473e14610ed55780639ed4166314610ee8578063a0464f0a14610efb578063a1df307314610f04578063a3592c3614610f17578063a421d66814610f2a578063a457c2d714610f4d578063a4610abd14610f60578063a75c24f314610f73578063a846b13114610f96578063a9059cbb14610f9e578063acc00b8014610fb1578063ae580d3814610fba578063af2996ad14610fcd578063afce26f214610fe0578063b098edb014610ff3578063b1ea103314611013578063b389bae514611026578063b594351f14611039578063b7c03fc114611042578063b7fb02ca14611055578063bd1bb2af14611083578063c1419def14611096578063c3bf04561461109f578063c54e44eb146110bf578063c7574839146110d2578063c8b6c6ff146110e5578063cd41eef0146110f8578063cdef8b2914611117578063cdf5b2261461112a578063cfbff44614611133578063d2a2f08514611146578063d4d7b19a14611159578063d5abeb011461117c578063d963905714611185578063d992de6a146111a5578063da9a1d24146111c8578063da9d7929146111db578063dce61464146111ee578063dd62ed3e14611201578063de2ed89314611214578063dfdd78251461121d578063e185e17614611226578063e4c7ab9c14611246578063e4cf9e1614611259578063e6efcb371461126c578063e771f1e01461127f578063eb08e4f614611292578063eb41ce2e146112a5578063ef2cfd1a146112b8578063f2129a23146112c1578063fd89390e146112d4578063fdf6c443146112e7578063feb69248146112fa578063ffd733a71461130d575b600080fd5b6106aa6106a5366004615722565b611320565b6040516106b7919061585e565b60405180910390f35b6106d36106ce36600461541f565b6113ba565b005b6107006106e336600461541f565b603f60209081526000928352604080842090915290825290205481565b6040519081526020016106b7565b6106aa611428565b61070061072436600461541f565b604160209081526000928352604080842090915290825290205481565b61075461074f36600461541f565b6114ba565b60405190151581526020016106b7565b61070060465481565b61075461077b36600461541f565b606060209081526000928352604080842090915290825290205460ff1681565b6106aa6107a9366004615722565b6114d4565b6107546107bc366004615381565b6114ed565b61070060395481565b6107006107d836600461541f565b604060208181526000938452818420905290825290205481565b6106aa610800366004615722565b611515565b6106d3610813366004615516565b61152e565b61070060175481565b61083461082f366004615722565b611660565b6040516106b79190615831565b600454610700565b610700610857366004615381565b61168a565b6106d361086a366004615722565b611798565b61070061087d366004615381565b60256020526000908152604090205481565b600d54610834906001600160a01b031681565b6106d36108b03660046155c2565b6117c1565b6106d36108c3366004615381565b6118e0565b6107006108d6366004615381565b60426020526000908152604090205481565b61070060275481565b6107546108ff3660046153de565b611ab3565b600e54610834906001600160a01b031681565b61075461092536600461541f565b605f60209081526000928352604080842090915290825290205460ff1681565b61070060075481565b61075461095c36600461541f565b605e60209081526000928352604080842090915290825290205460ff1681565b610700602c5481565b604051601281526020016106b7565b61070060365481565b610700600a5481565b6106d36109b4366004615381565b611ad7565b6107546109c736600461541f565b611b03565b6106d36109da366004615516565b611b42565b6107006109ed366004615381565b603b6020526000908152604090205481565b610700603a5481565b610754610a1636600461541f565b605b60209081526000928352604080842090915290825290205460ff1681565b601954610834906001600160a01b031681565b610700600b5481565b610700610a60366004615381565b611c4c565b610754610a73366004615381565b611d7c565b6106d3611dbf565b610754610a8e366004615381565b612089565b601654610834906001600160a01b031681565b6106d361226b565b6106aa610abc366004615722565b612403565b610700610acf366004615381565b60266020526000908152604090205481565b610700610aef366004615381565b60236020526000908152604090205481565b610700610b0f366004615722565b60306020526000908152604090205481565b610754610b2f366004615381565b61241c565b610700610b42366004615381565b60216020526000908152604090205481565b610700610b62366004615722565b6124a1565b6106d36124bc565b6106d3610b7d366004615381565b61271d565b610754610b9036600461541f565b606160209081526000928352604080842090915290825290205460ff1681565b61070060455481565b610754610bc7366004615381565b60106020526000908152604090205460ff1681565b610700610bea366004615381565b60116020526000908152604090205481565b610700610c0a366004615722565b602e6020526000908152604090205481565b6106aa610c2a366004615722565b612769565b601b54610834906001600160a01b031681565b610754610c5036600461541f565b605d60209081526000928352604080842090915290825290205460ff1681565b610700601f5481565b610754610c8736600461541f565b606260209081526000928352604080842090915290825290205460ff1681565b610700604a5481565b61070060085481565b610754610cc736600461541f565b603160209081526000928352604080842090915290825290205460ff1681565b610700602b5481565b610754610cfe36600461541f565b605a60209081526000928352604080842090915290825290205460ff1681565b6106d3610d2c366004615722565b612782565b610700610d3f366004615381565b6001600160a01b031660009081526002602052604090205490565b610700610d68366004615381565b60356020526000908152604090205481565b6106d3610d88366004615754565b6127c6565b6106d361293d565b610754610da3366004615381565b612a22565b6106d3610db6366004615381565b612c28565b610700610dc936600461541f565b604360209081526000928352604080842090915290825290205481565b6106aa612c61565b610754610dfc366004615381565b612c6e565b610700610e0f366004615381565b612c97565b601254610834906001600160a01b031681565b6106aa610e35366004615722565b613003565b604b546107549060ff1681565b610700602a5481565b600f54610834906001600160a01b031681565b6106d361301c565b61070060375481565b6106aa6134b3565b601e54610834906001600160a01b031681565b6106aa610e9d366004615722565b6134c2565b610700610eb0366004615381565b60326020526000908152604090205481565b610754610ed0366004615381565b6134db565b610700610ee3366004615381565b61350c565b610700610ef6366004615381565b613558565b610700602d5481565b6106d3610f12366004615381565b6135de565b610700610f25366004615381565b61362a565b610754610f38366004615381565b60346020526000908152604090205460ff1681565b610754610f5b36600461541f565b6136c5565b6106d3610f6e36600461546d565b613757565b610754610f81366004615381565b60016020526000908152604090205460ff1681565b6106d36137ad565b610754610fac36600461541f565b613815565b610700604c5481565b6106d3610fc836600461541f565b613823565b6106aa610fdb366004615381565b613888565b610754610fee366004615381565b6138a1565b610700611001366004615381565b60446020526000908152604090205481565b603e54610834906001600160a01b031681565b6106aa611034366004615381565b6138c3565b610700603d5481565b6106aa611050366004615722565b6138dc565b61075461106336600461541f565b605c60209081526000928352604080842090915290825290205460ff1681565b6106aa611091366004615722565b6138f5565b61070060135481565b6107006110ad366004615722565b602f6020526000908152604090205481565b601454610834906001600160a01b031681565b600c54610834906001600160a01b031681565b6106aa6110f3366004615722565b61390e565b610700611106366004615381565b602080526000908152604090205481565b6106d3611125366004615381565b613927565b61070060285481565b6106d361114136600461541f565b613973565b6106aa611154366004615722565b6139d8565b610754611167366004615381565b60476020526000908152604090205460ff1681565b61070060095481565b610700611193366004615381565b603c6020526000908152604090205481565b6107546111b3366004615381565b60246020526000908152604090205460ff1681565b6106aa6111d6366004615722565b6139f1565b6107546111e9366004615381565b613a0a565b601c54610834906001600160a01b031681565b61070061120f3660046153a5565b613a2c565b61070060385481565b61070060225481565b610700611234366004615381565b60336020526000908152604090205481565b6106d3611254366004615693565b613a57565b610700611267366004615381565b613c07565b6106d361127a366004615381565b613c8d565b6106aa61128d366004615722565b613cd9565b6107546112a0366004615381565b613cf2565b6106d36112b3366004615381565b613d98565b61070060155481565b6106d36112cf36600461546d565b613de4565b601854610834906001600160a01b031681565b601d54610834906001600160a01b031681565b6106d3611308366004615381565b613e04565b6106d361131b36600461546d565b613e50565b604e602052600090815260409020805461133990615b57565b80601f016020809104026020016040519081016040528092919081815260200182805461136590615b57565b80156113b25780601f10611387576101008083540402835291602001916113b2565b820191906000526020600020905b81548152906001019060200180831161139557829003601f168201915b505050505081565b600c546001600160a01b03163314806113dd5750600f546001600160a01b031633145b6114025760405162461bcd60e51b81526004016113f9906158cb565b60405180910390fd5b601680546001600160a01b0319166001600160a01b039390931692909217909155601755565b60606005805461143790615b57565b80601f016020809104026020016040519081016040528092919081815260200182805461146390615b57565b80156114b05780601f10611485576101008083540402835291602001916114b0565b820191906000526020600020905b81548152906001019060200180831161149357829003601f168201915b5050505050905090565b6000336114c8818585613e70565b60019150505b92915050565b604d602052600090815260409020805461133990615b57565b6001600160a01b03166000908152603b60209081526040808320546002909252909120541190565b6056602052600090815260409020805461133990615b57565b600d546001600160a01b03163314806115515750600e546001600160a01b031633145b806115665750600c546001600160a01b031633145b6115825760405162461bcd60e51b81526004016113f990615911565b83604f60006001604c546115969190615afd565b815260200190815260200160002090805190602001906115b7929190615252565b5082605260006001604c546115cc9190615afd565b815260200190815260200160002090805190602001906115ed929190615252565b5081605560006001604c546116029190615afd565b81526020019081526020016000209080519060200190611623929190615252565b5080605860006001604c546116389190615afd565b81526020019081526020016000209080519060200190611659929190615252565b5050505050565b6029818154811061167057600080fd5b6000918252602090912001546001600160a01b0316905081565b6000603754600014806116a357506116a182612a22565b155b156116b057506000919050565b6037546001600160a01b0383166000908152603b6020908152604080832054602c548452602e9092528220549192916116e99190615ade565b6116f391906159d1565b602c546000908152602f6020908152604080832054602e909252909120549192509061171f83836159b9565b811015611733576117308282615afd565b92505b6007546001600160a01b0386166000908152603b60205260409020546117599190615ade565b83111561178f576007546001600160a01b0386166000908152603b60205260409020546117869190615ade565b95945050505050565b50909392505050565b336000908152603b60205260409020548111156117b457600080fd5b6117be3382613f8c565b50565b600d546001600160a01b03163314806117e45750600e546001600160a01b031633145b806117f95750600c546001600160a01b031633145b6118155760405162461bcd60e51b81526004016113f990615911565b604c546000908152604d60209081526040909120865161183792880190615252565b50604c546000908152604e60209081526040909120855161185a92870190615252565b50604c546000908152605160209081526040909120845161187d92860190615252565b50604c54600090815260546020908152604090912083516118a092850190615252565b50604c54600090815260576020908152604090912082516118c392840190615252565b50604c80549060006118d483615b92565b91905055505050505050565b6118e861293d565b6118f1816141bd565b6118fa8161427e565b611903816143fe565b61190c816149e1565b601b546001600160a01b03161561198657601b60009054906101000a90046001600160a01b03166001600160a01b031663c8aaf64b6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561196d57600080fd5b505af1158015611981573d6000803e3d6000fd5b505050505b601c546001600160a01b031615611a0057601c60009054906101000a90046001600160a01b03166001600160a01b031663c8aaf64b6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156119e757600080fd5b505af11580156119fb573d6000803e3d6000fd5b505050505b601d546001600160a01b031615611a7a57601d60009054906101000a90046001600160a01b03166001600160a01b031663c8aaf64b6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611a6157600080fd5b505af1158015611a75573d6000803e3d6000fd5b505050505b6040516001600160a01b0382169042907f2e943002f66a261aa0e546cf9618bd716755c99d8a3930e2fdae512c6d201be990600090a350565b600033611ac1858285614aff565b611acc858585614b73565b506001949350505050565b611adf61293d565b611ae8816141bd565b611af18161427e565b611afa816143fe565b6117be816149e1565b3360008181526003602090815260408083206001600160a01b03871684529091528120549091906114c89082908690611b3d9087906159b9565b613e70565b600d546001600160a01b0316331480611b655750600e546001600160a01b031633145b80611b7a5750600c546001600160a01b031633145b611b965760405162461bcd60e51b81526004016113f990615911565b83605060006001604c54611baa9190615afd565b81526020019081526020016000209080519060200190611bcb929190615252565b5082605360006001604c54611be09190615afd565b81526020019081526020016000209080519060200190611c01929190615252565b5081605660006001604c54611c169190615afd565b81526020019081526020016000209080519060200190611c37929190615252565b5080605960006001604c546116389190615afd565b600060155460121415611cd9576014546040516370a0823160e01b81526001600160a01b03909116906370a0823190611c89908590600401615831565b60206040518083038186803b158015611ca157600080fd5b505afa158015611cb5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ce919061573b565b601554611ce7906012615afd565b611cf290600a615a36565b6014546040516370a0823160e01b81526001600160a01b03909116906370a0823190611d22908690600401615831565b60206040518083038186803b158015611d3a57600080fd5b505afa158015611d4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d72919061573b565b6114ce9190615ade565b6001600160a01b0381166000908152605a60205260408120601f548290611da590600190615afd565b815260208101919091526040016000205460ff1692915050565b611dc833614dfd565b600954336000908152603b6020526040902054600454611de891906159b9565b10611df257600080fd5b611dfb336134db565b611e555760405162461bcd60e51b815260206004820152602560248201527f596f7520617265206e6f74207175616c696669656420746f20636c61696d205360448201526420ab22a91760d91b60648201526084016113f9565b601f543360009081526021602052604090205410611ecb5760405162461bcd60e51b815260206004820152602d60248201527f596f75206861766520746f2077616974203330206461797320746f20636c616960448201526c36903cb7bab91029a0ab22a91760991b60648201526084016113f9565b336000818152603b60205260409081902054905142917fbeebf42e6a78a38fc5266af6bcb706ca29678ff16f93ce85f9207ded9632407d91611f0f91815260200190565b60405180910390a3336000818152603b6020526040902054611f319190614f92565b336000908152601060209081526040808320805460ff19169055602490915290205460ff16611fad576029805460018101825560008290527fcb7c14ce178f56e2e8d86ab33ebc0ae081ba8556a00cd122038841867181caac0180546001600160a01b031916331790558054611faa90829081906152d6565b50505b336000908152602460209081526040808320805460ff1916600117905560259091528120805491611fdd83615b92565b909155505060278054906000611ff283615b92565b909155505033600090815260236020526040812080549161201283615b92565b9091555050336000908152603b6020526040812054602880549192909161203a9084906159b9565b9091555050336000908152603b60209081526040808320546026909252822080549192909161206a9084906159b9565b90915550503360009081526033602052604081205561208761293d565b565b601b546000908190819081906001600160a01b03161561212857601b546040516370a0823160e01b81526000916001600160a01b0316906370a08231906120d4908990600401615831565b60206040518083038186803b1580156120ec57600080fd5b505afa158015612100573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612124919061573b565b1192505b601c546001600160a01b0316156121be57601c546040516370a0823160e01b81526000916001600160a01b0316906370a082319061216a908990600401615831565b60206040518083038186803b15801561218257600080fd5b505afa158015612196573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ba919061573b565b1191505b601d546001600160a01b03161561225457601d546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612200908990600401615831565b60206040518083038186803b15801561221857600080fd5b505afa15801561222c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612250919061573b565b1190505b828061225d5750815b806117865750949350505050565b62015180603d544261227d9190615afd565b116122ca5760405162461bcd60e51b815260206004820152601d60248201527f54686520636f6e7472616374206973207374696c6c20776f726b696e6700000060448201526064016113f9565b600c546001600160a01b0316331461233b5760405162461bcd60e51b815260206004820152602e60248201527f596f7520617265206e6f74207175616c696669656420746f2063616c6c20746f60448201526d103a3434b990333ab731ba34b7b760911b60648201526084016113f9565b60165460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061236d9033904790600401615845565b602060405180830381600087803b15801561238757600080fd5b505af115801561239b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123bf919061544b565b6120875760405162461bcd60e51b815260206004820152601560248201527421b0b73737ba103830bc9029ba30b13632a1b7b4b760591b60448201526064016113f9565b6055602052600090815260409020805461133990615b57565b602254601f5460009160019110156124375750600092915050565b6000602254601f546124499190615afd565b90505b601f5481101561249a5781801561248657506001600160a01b038416600090815260626020908152604080832084845290915290205460ff165b91508061249281615b92565b91505061244c565b5092915050565b60006103e86124b2836103f1615ade565b6114ce91906159d1565b602c546000818152602e6020908152604080832054602f83528184205433855260318452828520958552949092529091205490919060ff16156124fe57600080fd5b33600090815260356020526040902054602c54101561251c57600080fd5b61252533612a22565b61252e57600080fd5b60006125393361168a565b90506000811161254857600080fd5b61255281836159b9565b83101561255e57600080fd5b60075461256b90826159d1565b336000908152603b6020526040902054101561258657600080fd5b60165460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906125b89033908590600401615845565b602060405180830381600087803b1580156125d257600080fd5b505af11580156125e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260a919061544b565b61261357600080fd5b61262a336007548361262591906159d1565b613f8c565b602c546000908152602f60205260408120805483929061264b9084906159b9565b9091555050336000908152603160209081526040808320602c5484529091528120805460ff19166001179055602d80548392906126899084906159b9565b909155505033600090815260326020526040812080548392906126ad9084906159b9565b909155505033600090815260336020526040812080548392906126d19084906159b9565b909155506126e0905033614dfd565b604051818152339042907f7f61f8c57ad5757ff357174bf30c28673a0dd1f02a173b1a308dd68c59ba0693906020015b60405180910390a3505050565b600f546001600160a01b031633146127475760405162461bcd60e51b81526004016113f990615911565b601b80546001600160a01b0319166001600160a01b0392909216919091179055565b6054602052600090815260409020805461133990615b57565b600c546001600160a01b03163314806127a55750600f546001600160a01b031633145b6127c15760405162461bcd60e51b81526004016113f990615891565b600755565b601e546001600160a01b031633146127dd57600080fd5b6127e7818361505f565b6127f081614dfd565b6127f981612a22565b1561281157603e80546001600160a01b031916331790555b61281c6003836159d1565b602b546000908152602e60205260408120805490919061283d9084906159b9565b90915550506001600160a01b0381166000908152603c60205260408120805484929061286a9084906159b9565b90915550506001600160a01b0381166000908152603f60209081526040808320601f548452909152812080548492906128a49084906159b9565b9091555050602b546001600160a01b03821660009081526035602052604081209190915560388054916128d683615b92565b909155506128e790506003836159d1565b604a60008282546128f891906159b9565b909155505042603d55601f546040516001600160a01b03831691600080516020615c6f833981519152916129319190869060019061594a565b60405180910390a25050565b602b5460009081526030602052604090205442111561208757602c546000908152602f6020908152604080832054602e9092529091205461297e9190615afd565b602b546000908152602e60205260408120805490919061299f9084906159b9565b9091555050601f80549060006129b483615b92565b9091555050601f5460405142907f8a5aeed79336e8e02c0bd5f6827b1b5d1e48973bd23b29202673f0788c832d6590600090a3602b8054602c8190559060006129fc83615b92565b9091555050600854612a0e90426159b9565b602b54600090815260306020526040902055565b600c546000906001600160a01b0383811691161480612a4e5750600f546001600160a01b038381169116145b15612a5b57506001919050565b6001600160a01b0382166000908152605b60205260408120601f54909190612a8590600190615afd565b815260208101919091526040016000205460ff168015612adf57506001600160a01b0382166000908152605e60205260408120601f54909190612aca90600190615afd565b815260208101919091526040016000205460ff165b8015612b2557506001600160a01b0382166000908152605d60205260408120601f54909190612b1090600190615afd565b815260208101919091526040016000205460ff165b8015612b6b57506001600160a01b0382166000908152605c60205260408120601f54909190612b5690600190615afd565b815260208101919091526040016000205460ff165b8015612bb157506001600160a01b0382166000908152605f60205260408120601f54909190612b9c90600190615afd565b815260208101919091526040016000205460ff165b8015612bf757506001600160a01b0382166000908152606060205260408120601f54909190612be290600190615afd565b815260208101919091526040016000205460ff165b80156114ce57506001600160a01b0382166000908152606160205260408120601f54909190611da590600190615afd565b600f546001600160a01b03163314612c3f57600080fd5b601e80546001600160a01b0319166001600160a01b0392909216919091179055565b6063805461133990615b57565b6001600160a01b0381166000908152603b6020526040812054612c9083611c4c565b1192915050565b601854604051631ee8536360e21b815260009182916001600160a01b0390911690637ba14d8c90612ccc908690600401615831565b60206040518083038186803b158015612ce457600080fd5b505afa158015612cf8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d1c919061544b565b90506000601860009054906101000a90046001600160a01b03166001600160a01b0316636190c9d56040518163ffffffff1660e01b815260040160206040518083038186803b158015612d6e57600080fd5b505afa158015612d82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612da6919061573b565b6019546040516370a0823160e01b815291925060009182916001600160a01b0316906370a0823190612ddc908990600401615831565b60206040518083038186803b158015612df457600080fd5b505afa158015612e08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e2c919061573b565b6018546040516370a0823160e01b81526001600160a01b03909116906370a0823190612e5c908a90600401615831565b60206040518083038186803b158015612e7457600080fd5b505afa158015612e88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eac919061573b565b612eb691906159b9565b90505b83158015612ec75750604582105b15612f69576018546001600160a01b0316636252b6fd87612ee88587615afd565b6040518363ffffffff1660e01b8152600401612f05929190615845565b60206040518083038186803b158015612f1d57600080fd5b505afa158015612f31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f55919061544b565b935081612f6181615b92565b925050612eb9565b831561178657601854604051633b8a5e2760e01b81526001600160a01b0390911690633b8a5e2790612f9f908990600401615831565b60206040518083038186803b158015612fb757600080fd5b505afa158015612fcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fef919061573b565b612ff990826159b9565b9695505050505050565b6050602052600090815260409020805461133990615b57565b600054421061302a57600080fd5b3360009081526001602052604090205460ff161561304757600080fd5b601854604051633b8a5e2760e01b81526001600160a01b0390911690633b8a5e2790613077903390600401615831565b60206040518083038186803b15801561308f57600080fd5b505afa1580156130a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130c7919061573b565b336000908152603b6020526040812080549091906130e69084906159b9565b9091555050336000908152603b6020526040812054603680549192909161310e9084906159b9565b909155505060185460405163d963905760e01b81526001600160a01b039091169063d963905790613143903390600401615831565b60206040518083038186803b15801561315b57600080fd5b505afa15801561316f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613193919061573b565b336000908152603c6020526040812080549091906131b29084906159b9565b909155505060185460405163b389bae560e01b81526001600160a01b039091169063b389bae5906131e7903390600401615831565b60006040518083038186803b1580156131ff57600080fd5b505afa158015613213573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261323b91908101906154a9565b336000908152604860209081526040909120825161325f9391929190910190615252565b5060185460405163af2996ad60e01b81526001600160a01b039091169063af2996ad90613290903390600401615831565b60006040518083038186803b1580156132a857600080fd5b505afa1580156132bc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526132e491908101906154a9565b33600090815260496020908152604090912082516133089391929190910190615252565b5061331b3361331633612c97565b614f92565b6018546040516370a0823160e01b81526000916001600160a01b0316906370a082319061334c903390600401615831565b60206040518083038186803b15801561336457600080fd5b505afa158015613378573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061339c919061573b565b1180156133b957503360009081526047602052604090205460ff16155b156133ee57604580549060006133ce83615b92565b9091555050336000908152604760205260409020805460ff191660011790555b6133f733612a22565b801561341357503360009081526034602052604090205460ff16155b1561349457336000908152603b6020526040812054603780549192909161343b9084906159b9565b9091555050336000908152603460205260408120805460ff19166001179055604680549161346883615b92565b90915550506040516001815233904290600080516020615c0f8339815191529060200160405180910390a35b336000908152600160208190526040909120805460ff19169091179055565b60606006805461143790615b57565b604f602052600090815260409020805461133990615b57565b60006134e682612a22565b80156114ce5750506001600160a01b031660009081526010602052604090205460ff1690565b6001600160a01b0381166000908152604160205260408120601f54620186a09190839061353b90600190615afd565b815260200190815260200160002054620188116124b29190615ade565b600060175460121415613595576016546040516370a0823160e01b81526001600160a01b03909116906370a0823190611c89908590600401615831565b6017546135a3906012615afd565b6135ae90600a615a36565b6016546040516370a0823160e01b81526001600160a01b03909116906370a0823190611d22908690600401615831565b600c546001600160a01b031633146136085760405162461bcd60e51b81526004016113f990615891565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0381166000908152603b6020908152604080832054918190528220601f546136769190849061366290600190615afd565b8152602001908152602001600020546124a1565b11156136bd576001600160a01b0382166000908152603b6020908152604080832054918190528220601f5491926136b39261366290600190615afd565b6114ce9190615afd565b506000919050565b3360008181526003602090815260408083206001600160a01b03871684529091528120549091908381101561374a5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016113f9565b611acc8286868403613e70565b600d546001600160a01b031633148061377a5750600c546001600160a01b031633145b6137965760405162461bcd60e51b81526004016113f990615911565b80516137a9906063906020840190615252565b5050565b600c546001600160a01b03163314806137d05750600d546001600160a01b031633145b806137e55750600e546001600160a01b031633145b6138015760405162461bcd60e51b81526004016113f990615911565b604b805460ff19811660ff90911615179055565b6000336114c8818585614b73565b600c546001600160a01b03163314806138465750600f546001600160a01b031633145b6138625760405162461bcd60e51b81526004016113f9906158cb565b601280546001600160a01b0319166001600160a01b039390931692909217909155601355565b6049602052600090815260409020805461133990615b57565b6001600160a01b0381166000908152603b6020526040812054612c9083613c07565b6048602052600090815260409020805461133990615b57565b6057602052600090815260409020805461133990615b57565b6059602052600090815260409020805461133990615b57565b6058602052600090815260409020805461133990615b57565b600c546001600160a01b031633146139515760405162461bcd60e51b81526004016113f990615911565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b600c546001600160a01b03163314806139965750600f546001600160a01b031633145b6139b25760405162461bcd60e51b81526004016113f9906158cb565b601480546001600160a01b0319166001600160a01b039390931692909217909155601555565b6052602052600090815260409020805461133990615b57565b6053602052600090815260409020805461133990615b57565b602a546001600160a01b039091166000908152603b6020526040902054101590565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b60008181526051602090815260408083209051613a749201615795565b6040516020818303038152906040528051906020012085604051602001613a9b9190615779565b60408051601f198184030181528282528051602091820120600087815260528352928320941494509092613ad192909101615795565b6040516020818303038152906040528051906020012085604051602001613af89190615779565b60408051601f198184030181528282528051602091820120600088815260538352928320941494509092613b2e92909101615795565b6040516020818303038152906040528051906020012085604051602001613b559190615779565b60405160208183030381529060405280519060200120149050828015613b785750815b8015613b815750805b336000818152605a60209081526040808320601f5484529091529020805460ff191692151592909217909155427f8c523ebdf6485477f33992ad2a94e5245e6777dc6feb33a26a26dbb8f919165a858015613bd95750845b8015613be25750835b604051901515815260200160405180910390a3613bfe33614dfd565b50505050505050565b600060135460121415613c44576012546040516370a0823160e01b81526001600160a01b03909116906370a0823190611c89908590600401615831565b601354613c52906012615afd565b613c5d90600a615a36565b6012546040516370a0823160e01b81526001600160a01b03909116906370a0823190611d22908690600401615831565b600f546001600160a01b03163314613cb75760405162461bcd60e51b81526004016113f990615911565b601d80546001600160a01b0319166001600160a01b0392909216919091179055565b6051602052600090815260409020805461133990615b57565b6001600160a01b0381166000908152603b6020526040812054613d1757506000919050565b6001601f541115613d90576001600160a01b0382166000908152604060208190528120601f54613d4e929061366290600290615afd565b6001600160a01b0383166000908152604060208190528120601f54909190613d7890600190615afd565b81526020019081526020016000205410159050919050565b506001919050565b600c546001600160a01b03163314613dc25760405162461bcd60e51b81526004016113f990615911565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b33600090815260496020908152604090912082516137a992840190615252565b600f546001600160a01b03163314613e2e5760405162461bcd60e51b81526004016113f990615911565b601c80546001600160a01b0319166001600160a01b0392909216919091179055565b33600090815260486020908152604090912082516137a992840190615252565b6001600160a01b038316613ed25760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016113f9565b6001600160a01b038216613f335760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016113f9565b6001600160a01b0383811660008181526003602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101612710565b6001600160a01b03821660009081526034602052604090205460ff168015614028576001600160a01b0383166000908152603b60205260408120546037805491929091613fda908490615afd565b90915550506001600160a01b0383166000908152603460205260408120805460ff19169055603a80549161400d83615b40565b90915550506046805490600061402283615b40565b91905055505b6001600160a01b0383166000908152603b602052604081208054849290614050908490615afd565b9250508190555081603660008282546140699190615afd565b90915550506001600160a01b0383166000908152603b60205260409020546140a1576039805490600061409b83615b40565b91905055505b6140aa83612a22565b1561412c576001600160a01b0383166000908152603b602052604081205460378054919290916140db9084906159b9565b90915550506001600160a01b0383166000908152603460205260408120805460ff19166001179055603a80549161411183615b92565b90915550506046805490600061412683615b92565b91905055505b6001600160a01b03831660009081526034602052604090205460ff1615158115151461418257604051811581526001600160a01b038416904290600080516020615c0f8339815191529060200160405180910390a35b826001600160a01b0316600080516020615c6f833981519152601f548460006040516141b09392919061594a565b60405180910390a2505050565b6001600160a01b03811660009081526044602090815260408083205460429092528220546141eb91906159b9565b905060006141f883611c4c565b61420184613c07565b61420b91906159b9565b9050818110156142795760006142218284615afd565b6001600160a01b0385166000908152603b602052604090205490915081111561426d576001600160a01b0384166000908152603b6020526040902054614268908590613f8c565b614277565b6142778482613f8c565b505b505050565b6001600160a01b03811660009081526034602052604090205460ff16801561431a576001600160a01b0382166000908152603b602052604081205460378054919290916142cc908490615afd565b90915550506001600160a01b0382166000908152603460205260408120805460ff19169055603a8054916142ff83615b40565b90915550506046805490600061431483615b40565b91905055505b61432382612a22565b156143a5576001600160a01b0382166000908152603b602052604081205460378054919290916143549084906159b9565b90915550506001600160a01b0382166000908152603460205260408120805460ff19166001179055603a80549161438a83615b92565b90915550506046805490600061439f83615b92565b91905055505b6001600160a01b03821660009081526034602052604090205460ff161515811515146137a957604051811581526001600160a01b038316904290600080516020615c0f8339815191529060200160405180910390a35050565b6001600160a01b0381166000908152602080526040902054601f54106117be57601f5461442c9060016159b9565b6001600160a01b038216600090815260208052604090205561444d81613c07565b6001600160a01b03821660009081526042602052604090205561446f81611c4c565b6001600160a01b0382166000818152604460209081526040808320948555604282528083205460418352818420601f805486529084528285209190915584845294546043835281842086548552835281842055338352603b82528083205493835290819052812092549192916144e790600190615afd565b815260208101919091526040016000205561450181612089565b6001600160a01b0382166000908152605b60205260408120601f5490919061452b90600190615afd565b81526020810191909152604001600020805460ff1916911515919091179055614553816114ed565b6001600160a01b0382166000908152605c60205260408120601f5490919061457d90600190615afd565b81526020810191909152604001600020805460ff19169115159190911790556145a581612c6e565b6001600160a01b0382166000908152605e60205260408120601f549091906145cf90600190615afd565b81526020810191909152604001600020805460ff19169115159190911790556145f7816138a1565b6001600160a01b0382166000908152605d60205260408120601f5490919061462190600190615afd565b81526020810191909152604001600020805460ff191691151591909117905561464981613a0a565b6001600160a01b0382166000908152605f60205260408120601f5490919061467390600190615afd565b81526020810191909152604001600020805460ff191691151591909117905561469b81613cf2565b6001600160a01b0382166000908152606060205260408120601f549091906146c590600190615afd565b81526020810191909152604001600020805460ff19169115159190911790556146ed81611d7c565b6001600160a01b0382166000908152606160205260408120601f5490919061471790600190615afd565b81526020810191909152604001600020805460ff191691151591909117905561473f81612a22565b6001600160a01b0382166000908152606260205260408120601f5490919061476990600190615afd565b815260200190815260200160002060006101000a81548160ff021916908315150217905550806001600160a01b03167f527e2cac87a0f06e1102c21d4d5c884fe456c3fe85a12c5450f69505009d2c1b6001601f546147c89190615afd565b6001600160a01b0384166000908152605b60205260408120601f549091906147f290600190615afd565b815260208082019290925260409081016000908120546001600160a01b0388168252605e909352908120601f5460ff9093169290919061483490600190615afd565b815260208082019290925260409081016000908120546001600160a01b0389168252605d909352908120601f5460ff9093169290919061487690600190615afd565b815260208082019290925260409081016000908120546001600160a01b038a168252605c909352908120601f5460ff909316929091906148b890600190615afd565b815260208082019290925260409081016000908120546001600160a01b038b168252605f909352908120601f5460ff909316929091906148fa90600190615afd565b815260208082019290925260409081016000908120546001600160a01b038c1682526060909352908120601f5460ff9093169290919061493c90600190615afd565b815260208082019290925260409081016000908120546001600160a01b038d1682526061909352908120601f5460ff9093169290919061497e90600190615afd565b81526020808201929092526040908101600020548151998a529715159189019190915294151594870194909452911515606086015215156080850152151560a0840152151560c083015260ff16151560e08201526101000160405180910390a250565b6149ea81612a22565b158015614a0f57506001600160a01b03811660009081526010602052604090205460ff165b15614a5a576001600160a01b0381166000818152601060209081526040808320805460ff19169055519182524291600080516020615c2f83398151915291015b60405180910390a350565b614a6381612a22565b8015614a8857506001600160a01b03811660009081526010602052604090205460ff16155b156117be576001600160a01b0381166000908152601060205260409020805460ff19166001179055602254601f54614ac091906159b9565b6001600160a01b03821660008181526021602090815260409182902093909355516001815290914291600080516020615c2f8339815191529101614a4f565b6000614b0b8484613a2c565b905060001981146142775781811015614b665760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016113f9565b6142778484848403613e70565b6001600160a01b038316614bd75760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016113f9565b6001600160a01b038216614c395760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016113f9565b6001600160a01b03821660009081526047602052604090205460ff16614c925760458054906000614c6983615b92565b90915550506001600160a01b0382166000908152604760205260409020805460ff191660011790555b6001600160a01b03831660009081526002602052604090205481811015614d0a5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016113f9565b6001600160a01b03808516600090815260026020526040808220858503905591851681529081208054849290614d419084906159b9565b90915550506001600160a01b038416600090815260026020526040902054614d995760458054906000614d7383615b40565b90915550506001600160a01b0384166000908152604760205260409020805460ff191690555b614da284614dfd565b614dab83614dfd565b614db48461427e565b614dbd8361427e565b826001600160a01b0316846001600160a01b0316600080516020615c4f83398151915284604051614df091815260200190565b60405180910390a3614277565b614e0561293d565b614e0e816141bd565b614e178161427e565b614e20816143fe565b614e29816149e1565b601b546001600160a01b031615614ea357601b60009054906101000a90046001600160a01b03166001600160a01b031663c8aaf64b6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015614e8a57600080fd5b505af1158015614e9e573d6000803e3d6000fd5b505050505b601c546001600160a01b031615614f1d57601c60009054906101000a90046001600160a01b03166001600160a01b031663c8aaf64b6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015614f0457600080fd5b505af1158015614f18573d6000803e3d6000fd5b505050505b601d546001600160a01b0316156117be57601d60009054906101000a90046001600160a01b03166001600160a01b031663c8aaf64b6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015614f7e57600080fd5b505af1158015611659573d6000803e3d6000fd5b6001600160a01b038216614fe85760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016113f9565b8060046000828254614ffa91906159b9565b90915550506001600160a01b038216600090815260026020526040812080548392906150279084906159b9565b90915550506040518181526001600160a01b03831690600090600080516020615c4f8339815191529060200160405180910390a35050565b6001600160a01b03821660009081526034602052604090205460ff1680156150fb576001600160a01b0383166000908152603b602052604081205460378054919290916150ad908490615afd565b90915550506001600160a01b0383166000908152603460205260408120805460ff19169055603a8054916150e083615b40565b9091555050604680549060006150f583615b40565b91905055505b6001600160a01b0383166000908152603b602052604090205461512e576039805490600061512883615b92565b91905055505b6001600160a01b0383166000908152603b6020526040812080548492906151569084906159b9565b92505081905550816036600082825461516f91906159b9565b9091555061517e905083612a22565b15615200576001600160a01b0383166000908152603b602052604081205460378054919290916151af9084906159b9565b90915550506001600160a01b0383166000908152603460205260408120805460ff19166001179055603a8054916151e583615b92565b9091555050604680549060006151fa83615b92565b91905055505b6001600160a01b03831660009081526034602052604090205460ff1615158115151461427957604051811581526001600160a01b038416904290600080516020615c0f83398151915290602001612710565b82805461525e90615b57565b90600052602060002090601f01602090048101928261528057600085556152c6565b82601f1061529957805160ff19168380011785556152c6565b828001600101855582156152c6579182015b828111156152c65782518255916020019190600101906152ab565b506152d2929150615316565b5090565b8280548282559060005260206000209081019282156152c65760005260206000209182015b828111156152c65782548255916001019190600101906152fb565b5b808211156152d25760008155600101615317565b600082601f83011261533c57600080fd5b813561534f61534a82615992565b615962565b81815284602083860101111561536457600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561539357600080fd5b813561539e81615bd9565b9392505050565b600080604083850312156153b857600080fd5b82356153c381615bd9565b915060208301356153d381615bd9565b809150509250929050565b6000806000606084860312156153f357600080fd5b83356153fe81615bd9565b9250602084013561540e81615bd9565b929592945050506040919091013590565b6000806040838503121561543257600080fd5b823561543d81615bd9565b946020939093013593505050565b60006020828403121561545d57600080fd5b8151801515811461539e57600080fd5b60006020828403121561547f57600080fd5b81356001600160401b0381111561549557600080fd5b6154a18482850161532b565b949350505050565b6000602082840312156154bb57600080fd5b81516001600160401b038111156154d157600080fd5b8201601f810184136154e257600080fd5b80516154f061534a82615992565b81815285602083850101111561550557600080fd5b611786826020830160208601615b14565b6000806000806080858703121561552c57600080fd5b84356001600160401b038082111561554357600080fd5b61554f8883890161532b565b9550602087013591508082111561556557600080fd5b6155718883890161532b565b9450604087013591508082111561558757600080fd5b6155938883890161532b565b935060608701359150808211156155a957600080fd5b506155b68782880161532b565b91505092959194509250565b600080600080600060a086880312156155da57600080fd5b85356001600160401b03808211156155f157600080fd5b6155fd89838a0161532b565b9650602088013591508082111561561357600080fd5b61561f89838a0161532b565b9550604088013591508082111561563557600080fd5b61564189838a0161532b565b9450606088013591508082111561565757600080fd5b61566389838a0161532b565b9350608088013591508082111561567957600080fd5b506156868882890161532b565b9150509295509295909350565b600080600080608085870312156156a957600080fd5b84356001600160401b03808211156156c057600080fd5b6156cc8883890161532b565b955060208701359150808211156156e257600080fd5b6156ee8883890161532b565b9450604087013591508082111561570457600080fd5b506157118782880161532b565b949793965093946060013593505050565b60006020828403121561573457600080fd5b5035919050565b60006020828403121561574d57600080fd5b5051919050565b6000806040838503121561576757600080fd5b8235915060208301356153d381615bd9565b6000825161578b818460208701615b14565b9190910192915050565b600080835481600182811c9150808316806157b157607f831692505b60208084108214156157d157634e487b7160e01b86526022600452602486fd5b8180156157e557600181146157f657615823565b60ff19861689528489019650615823565b60008a81526020902060005b8681101561581b5781548b820152908501908301615802565b505084890196505b509498975050505050505050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b602081526000825180602084015261587d816040850160208701615b14565b601f01601f19169190910160400192915050565b6020808252602c90820152600080516020615bef83398151915260408201526b34b990333ab731ba34b7b71760a11b606082015260800190565b60208082526026908201527f596f7520617265206e6f742061626c6520746f2063616c6c20746869732066756040820152653731ba34b7b760d11b606082015260800190565b6020808252602b90820152600080516020615bef83398151915260408201526a34b990333ab731ba34b7b760a91b606082015260800190565b92835260208301919091521515604082015260600190565b604051601f8201601f191681016001600160401b038111828210171561598a5761598a615bc3565b604052919050565b60006001600160401b038211156159ab576159ab615bc3565b50601f01601f191660200190565b600082198211156159cc576159cc615bad565b500190565b6000826159ee57634e487b7160e01b600052601260045260246000fd5b500490565b600181815b80851115615a2e578160001904821115615a1457615a14615bad565b80851615615a2157918102915b93841c93908002906159f8565b509250929050565b600061539e8383600082615a4c575060016114ce565b81615a59575060006114ce565b8160018114615a6f5760028114615a7957615a95565b60019150506114ce565b60ff841115615a8a57615a8a615bad565b50506001821b6114ce565b5060208310610133831016604e8410600b8410161715615ab8575081810a6114ce565b615ac283836159f3565b8060001904821115615ad657615ad6615bad565b029392505050565b6000816000190483118215151615615af857615af8615bad565b500290565b600082821015615b0f57615b0f615bad565b500390565b60005b83811015615b2f578181015183820152602001615b17565b838111156142775750506000910152565b600081615b4f57615b4f615bad565b506000190190565b600181811c90821680615b6b57607f821691505b60208210811415615b8c57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415615ba657615ba6615bad565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146117be57600080fdfe596f7520617265206e6f74207175616c696669656420746f2063616c6c20746806450a68843513e906a6efb7847c7647be951acc890120744c8e1ec91014f8ca7ee0265bf5adc943b87293232f34cef62f3f2c4b91156c24f460349766250ae9ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efc327d4bbc6ddb4c022b1e87bcadd36113256d88be3b6c55ca717b474a56881a3a2646970667358221220a24787eff837165ab19b4835bf6fe9ce149d7345e543adf4c68fbbcbf8db069a64736f6c63430008070033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106106925760003560e01c8063011058eb14610697578063031da1b2146106c057806306440e30146106d557806306fdde031461070e578063071cd0e714610716578063095ea7b3146107415780630a129731146107645780630b76293b1461076d5780630cfb421c1461079b5780630d23d767146107ae57806311ef2598146107c157806313a3e967146107ca578063159caff9146107f257806315d7328a1461080557806315f8e06114610818578063178c07961461082157806318160ddd14610841578063185515c91461084957806318c693d21461085c57806319de0c771461086f5780631b39099c1461088f5780631b5a4abf146108a25780631b8546c6146108b557806322b82017146108c8578063235fcfce146108e857806323b872dd146108f15780632a170748146109045780632d0d47e3146109175780632f122a06146109455780632f39dd401461094e5780632f6dd4911461097c578063313ce5671461098557806331f18acc14610994578063378dc3dc1461099d57806337f9ed13146109a657806339509351146109b95780633abc2e83146109cc5780633b8a5e27146109df5780633c0f4268146109ff5780633d8c612914610a085780633feecfa414610a3657806341c66d0a14610a49578063425a78e914610a525780634416ee6114610a655780634698535614610a78578063477c0ba214610a80578063484f4ea914610a9357806349649fbf14610aa657806349941e7614610aae5780634b35c45f14610ac15780634b9cff3114610ae15780634c6e224014610b015780634ddd8dc614610b215780634df3177f14610b345780634e02ec0614610b545780634e71d92d14610b675780634fc3519814610b6f57806352f6efe514610b8257806353d74fdf14610bb057806354c0e2f714610bb957806355667e2c14610bdc57806357fafbf214610bfc578063582bc74914610c1c5780635d27d82114610c2f578063604c9a7114610c425780636190c9d514610c705780636252b6fd14610c795780636793492114610ca757806367f7404514610cb05780636b3e575814610cb95780636c62ea8314610ce75780636cbebb7514610cf05780636f5e994914610d1e57806370a0823114610d3157806374067cda14610d5a5780637465d54e14610d7a57806378473e0014610d8d5780637ba14d8c14610d955780638121661714610da85780638212e1f514610dbb57806385631ace14610de657806385af8c4014610dee578063886abcf614610e0157806389a3027114610e145780638c34792214610e275780638cdc86a614610e3a5780638e0ee32314610e475780638ea5220f14610e505780638fd3ab8014610e63578063950c508c14610e6b57806395d89b4114610e745780639694dee514610e7c5780639a193eb114610e8f5780639a6a261314610ea25780639b56fea714610ec25780639ecc473e14610ed55780639ed4166314610ee8578063a0464f0a14610efb578063a1df307314610f04578063a3592c3614610f17578063a421d66814610f2a578063a457c2d714610f4d578063a4610abd14610f60578063a75c24f314610f73578063a846b13114610f96578063a9059cbb14610f9e578063acc00b8014610fb1578063ae580d3814610fba578063af2996ad14610fcd578063afce26f214610fe0578063b098edb014610ff3578063b1ea103314611013578063b389bae514611026578063b594351f14611039578063b7c03fc114611042578063b7fb02ca14611055578063bd1bb2af14611083578063c1419def14611096578063c3bf04561461109f578063c54e44eb146110bf578063c7574839146110d2578063c8b6c6ff146110e5578063cd41eef0146110f8578063cdef8b2914611117578063cdf5b2261461112a578063cfbff44614611133578063d2a2f08514611146578063d4d7b19a14611159578063d5abeb011461117c578063d963905714611185578063d992de6a146111a5578063da9a1d24146111c8578063da9d7929146111db578063dce61464146111ee578063dd62ed3e14611201578063de2ed89314611214578063dfdd78251461121d578063e185e17614611226578063e4c7ab9c14611246578063e4cf9e1614611259578063e6efcb371461126c578063e771f1e01461127f578063eb08e4f614611292578063eb41ce2e146112a5578063ef2cfd1a146112b8578063f2129a23146112c1578063fd89390e146112d4578063fdf6c443146112e7578063feb69248146112fa578063ffd733a71461130d575b600080fd5b6106aa6106a5366004615722565b611320565b6040516106b7919061585e565b60405180910390f35b6106d36106ce36600461541f565b6113ba565b005b6107006106e336600461541f565b603f60209081526000928352604080842090915290825290205481565b6040519081526020016106b7565b6106aa611428565b61070061072436600461541f565b604160209081526000928352604080842090915290825290205481565b61075461074f36600461541f565b6114ba565b60405190151581526020016106b7565b61070060465481565b61075461077b36600461541f565b606060209081526000928352604080842090915290825290205460ff1681565b6106aa6107a9366004615722565b6114d4565b6107546107bc366004615381565b6114ed565b61070060395481565b6107006107d836600461541f565b604060208181526000938452818420905290825290205481565b6106aa610800366004615722565b611515565b6106d3610813366004615516565b61152e565b61070060175481565b61083461082f366004615722565b611660565b6040516106b79190615831565b600454610700565b610700610857366004615381565b61168a565b6106d361086a366004615722565b611798565b61070061087d366004615381565b60256020526000908152604090205481565b600d54610834906001600160a01b031681565b6106d36108b03660046155c2565b6117c1565b6106d36108c3366004615381565b6118e0565b6107006108d6366004615381565b60426020526000908152604090205481565b61070060275481565b6107546108ff3660046153de565b611ab3565b600e54610834906001600160a01b031681565b61075461092536600461541f565b605f60209081526000928352604080842090915290825290205460ff1681565b61070060075481565b61075461095c36600461541f565b605e60209081526000928352604080842090915290825290205460ff1681565b610700602c5481565b604051601281526020016106b7565b61070060365481565b610700600a5481565b6106d36109b4366004615381565b611ad7565b6107546109c736600461541f565b611b03565b6106d36109da366004615516565b611b42565b6107006109ed366004615381565b603b6020526000908152604090205481565b610700603a5481565b610754610a1636600461541f565b605b60209081526000928352604080842090915290825290205460ff1681565b601954610834906001600160a01b031681565b610700600b5481565b610700610a60366004615381565b611c4c565b610754610a73366004615381565b611d7c565b6106d3611dbf565b610754610a8e366004615381565b612089565b601654610834906001600160a01b031681565b6106d361226b565b6106aa610abc366004615722565b612403565b610700610acf366004615381565b60266020526000908152604090205481565b610700610aef366004615381565b60236020526000908152604090205481565b610700610b0f366004615722565b60306020526000908152604090205481565b610754610b2f366004615381565b61241c565b610700610b42366004615381565b60216020526000908152604090205481565b610700610b62366004615722565b6124a1565b6106d36124bc565b6106d3610b7d366004615381565b61271d565b610754610b9036600461541f565b606160209081526000928352604080842090915290825290205460ff1681565b61070060455481565b610754610bc7366004615381565b60106020526000908152604090205460ff1681565b610700610bea366004615381565b60116020526000908152604090205481565b610700610c0a366004615722565b602e6020526000908152604090205481565b6106aa610c2a366004615722565b612769565b601b54610834906001600160a01b031681565b610754610c5036600461541f565b605d60209081526000928352604080842090915290825290205460ff1681565b610700601f5481565b610754610c8736600461541f565b606260209081526000928352604080842090915290825290205460ff1681565b610700604a5481565b61070060085481565b610754610cc736600461541f565b603160209081526000928352604080842090915290825290205460ff1681565b610700602b5481565b610754610cfe36600461541f565b605a60209081526000928352604080842090915290825290205460ff1681565b6106d3610d2c366004615722565b612782565b610700610d3f366004615381565b6001600160a01b031660009081526002602052604090205490565b610700610d68366004615381565b60356020526000908152604090205481565b6106d3610d88366004615754565b6127c6565b6106d361293d565b610754610da3366004615381565b612a22565b6106d3610db6366004615381565b612c28565b610700610dc936600461541f565b604360209081526000928352604080842090915290825290205481565b6106aa612c61565b610754610dfc366004615381565b612c6e565b610700610e0f366004615381565b612c97565b601254610834906001600160a01b031681565b6106aa610e35366004615722565b613003565b604b546107549060ff1681565b610700602a5481565b600f54610834906001600160a01b031681565b6106d361301c565b61070060375481565b6106aa6134b3565b601e54610834906001600160a01b031681565b6106aa610e9d366004615722565b6134c2565b610700610eb0366004615381565b60326020526000908152604090205481565b610754610ed0366004615381565b6134db565b610700610ee3366004615381565b61350c565b610700610ef6366004615381565b613558565b610700602d5481565b6106d3610f12366004615381565b6135de565b610700610f25366004615381565b61362a565b610754610f38366004615381565b60346020526000908152604090205460ff1681565b610754610f5b36600461541f565b6136c5565b6106d3610f6e36600461546d565b613757565b610754610f81366004615381565b60016020526000908152604090205460ff1681565b6106d36137ad565b610754610fac36600461541f565b613815565b610700604c5481565b6106d3610fc836600461541f565b613823565b6106aa610fdb366004615381565b613888565b610754610fee366004615381565b6138a1565b610700611001366004615381565b60446020526000908152604090205481565b603e54610834906001600160a01b031681565b6106aa611034366004615381565b6138c3565b610700603d5481565b6106aa611050366004615722565b6138dc565b61075461106336600461541f565b605c60209081526000928352604080842090915290825290205460ff1681565b6106aa611091366004615722565b6138f5565b61070060135481565b6107006110ad366004615722565b602f6020526000908152604090205481565b601454610834906001600160a01b031681565b600c54610834906001600160a01b031681565b6106aa6110f3366004615722565b61390e565b610700611106366004615381565b602080526000908152604090205481565b6106d3611125366004615381565b613927565b61070060285481565b6106d361114136600461541f565b613973565b6106aa611154366004615722565b6139d8565b610754611167366004615381565b60476020526000908152604090205460ff1681565b61070060095481565b610700611193366004615381565b603c6020526000908152604090205481565b6107546111b3366004615381565b60246020526000908152604090205460ff1681565b6106aa6111d6366004615722565b6139f1565b6107546111e9366004615381565b613a0a565b601c54610834906001600160a01b031681565b61070061120f3660046153a5565b613a2c565b61070060385481565b61070060225481565b610700611234366004615381565b60336020526000908152604090205481565b6106d3611254366004615693565b613a57565b610700611267366004615381565b613c07565b6106d361127a366004615381565b613c8d565b6106aa61128d366004615722565b613cd9565b6107546112a0366004615381565b613cf2565b6106d36112b3366004615381565b613d98565b61070060155481565b6106d36112cf36600461546d565b613de4565b601854610834906001600160a01b031681565b601d54610834906001600160a01b031681565b6106d3611308366004615381565b613e04565b6106d361131b36600461546d565b613e50565b604e602052600090815260409020805461133990615b57565b80601f016020809104026020016040519081016040528092919081815260200182805461136590615b57565b80156113b25780601f10611387576101008083540402835291602001916113b2565b820191906000526020600020905b81548152906001019060200180831161139557829003601f168201915b505050505081565b600c546001600160a01b03163314806113dd5750600f546001600160a01b031633145b6114025760405162461bcd60e51b81526004016113f9906158cb565b60405180910390fd5b601680546001600160a01b0319166001600160a01b039390931692909217909155601755565b60606005805461143790615b57565b80601f016020809104026020016040519081016040528092919081815260200182805461146390615b57565b80156114b05780601f10611485576101008083540402835291602001916114b0565b820191906000526020600020905b81548152906001019060200180831161149357829003601f168201915b5050505050905090565b6000336114c8818585613e70565b60019150505b92915050565b604d602052600090815260409020805461133990615b57565b6001600160a01b03166000908152603b60209081526040808320546002909252909120541190565b6056602052600090815260409020805461133990615b57565b600d546001600160a01b03163314806115515750600e546001600160a01b031633145b806115665750600c546001600160a01b031633145b6115825760405162461bcd60e51b81526004016113f990615911565b83604f60006001604c546115969190615afd565b815260200190815260200160002090805190602001906115b7929190615252565b5082605260006001604c546115cc9190615afd565b815260200190815260200160002090805190602001906115ed929190615252565b5081605560006001604c546116029190615afd565b81526020019081526020016000209080519060200190611623929190615252565b5080605860006001604c546116389190615afd565b81526020019081526020016000209080519060200190611659929190615252565b5050505050565b6029818154811061167057600080fd5b6000918252602090912001546001600160a01b0316905081565b6000603754600014806116a357506116a182612a22565b155b156116b057506000919050565b6037546001600160a01b0383166000908152603b6020908152604080832054602c548452602e9092528220549192916116e99190615ade565b6116f391906159d1565b602c546000908152602f6020908152604080832054602e909252909120549192509061171f83836159b9565b811015611733576117308282615afd565b92505b6007546001600160a01b0386166000908152603b60205260409020546117599190615ade565b83111561178f576007546001600160a01b0386166000908152603b60205260409020546117869190615ade565b95945050505050565b50909392505050565b336000908152603b60205260409020548111156117b457600080fd5b6117be3382613f8c565b50565b600d546001600160a01b03163314806117e45750600e546001600160a01b031633145b806117f95750600c546001600160a01b031633145b6118155760405162461bcd60e51b81526004016113f990615911565b604c546000908152604d60209081526040909120865161183792880190615252565b50604c546000908152604e60209081526040909120855161185a92870190615252565b50604c546000908152605160209081526040909120845161187d92860190615252565b50604c54600090815260546020908152604090912083516118a092850190615252565b50604c54600090815260576020908152604090912082516118c392840190615252565b50604c80549060006118d483615b92565b91905055505050505050565b6118e861293d565b6118f1816141bd565b6118fa8161427e565b611903816143fe565b61190c816149e1565b601b546001600160a01b03161561198657601b60009054906101000a90046001600160a01b03166001600160a01b031663c8aaf64b6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561196d57600080fd5b505af1158015611981573d6000803e3d6000fd5b505050505b601c546001600160a01b031615611a0057601c60009054906101000a90046001600160a01b03166001600160a01b031663c8aaf64b6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156119e757600080fd5b505af11580156119fb573d6000803e3d6000fd5b505050505b601d546001600160a01b031615611a7a57601d60009054906101000a90046001600160a01b03166001600160a01b031663c8aaf64b6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611a6157600080fd5b505af1158015611a75573d6000803e3d6000fd5b505050505b6040516001600160a01b0382169042907f2e943002f66a261aa0e546cf9618bd716755c99d8a3930e2fdae512c6d201be990600090a350565b600033611ac1858285614aff565b611acc858585614b73565b506001949350505050565b611adf61293d565b611ae8816141bd565b611af18161427e565b611afa816143fe565b6117be816149e1565b3360008181526003602090815260408083206001600160a01b03871684529091528120549091906114c89082908690611b3d9087906159b9565b613e70565b600d546001600160a01b0316331480611b655750600e546001600160a01b031633145b80611b7a5750600c546001600160a01b031633145b611b965760405162461bcd60e51b81526004016113f990615911565b83605060006001604c54611baa9190615afd565b81526020019081526020016000209080519060200190611bcb929190615252565b5082605360006001604c54611be09190615afd565b81526020019081526020016000209080519060200190611c01929190615252565b5081605660006001604c54611c169190615afd565b81526020019081526020016000209080519060200190611c37929190615252565b5080605960006001604c546116389190615afd565b600060155460121415611cd9576014546040516370a0823160e01b81526001600160a01b03909116906370a0823190611c89908590600401615831565b60206040518083038186803b158015611ca157600080fd5b505afa158015611cb5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ce919061573b565b601554611ce7906012615afd565b611cf290600a615a36565b6014546040516370a0823160e01b81526001600160a01b03909116906370a0823190611d22908690600401615831565b60206040518083038186803b158015611d3a57600080fd5b505afa158015611d4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d72919061573b565b6114ce9190615ade565b6001600160a01b0381166000908152605a60205260408120601f548290611da590600190615afd565b815260208101919091526040016000205460ff1692915050565b611dc833614dfd565b600954336000908152603b6020526040902054600454611de891906159b9565b10611df257600080fd5b611dfb336134db565b611e555760405162461bcd60e51b815260206004820152602560248201527f596f7520617265206e6f74207175616c696669656420746f20636c61696d205360448201526420ab22a91760d91b60648201526084016113f9565b601f543360009081526021602052604090205410611ecb5760405162461bcd60e51b815260206004820152602d60248201527f596f75206861766520746f2077616974203330206461797320746f20636c616960448201526c36903cb7bab91029a0ab22a91760991b60648201526084016113f9565b336000818152603b60205260409081902054905142917fbeebf42e6a78a38fc5266af6bcb706ca29678ff16f93ce85f9207ded9632407d91611f0f91815260200190565b60405180910390a3336000818152603b6020526040902054611f319190614f92565b336000908152601060209081526040808320805460ff19169055602490915290205460ff16611fad576029805460018101825560008290527fcb7c14ce178f56e2e8d86ab33ebc0ae081ba8556a00cd122038841867181caac0180546001600160a01b031916331790558054611faa90829081906152d6565b50505b336000908152602460209081526040808320805460ff1916600117905560259091528120805491611fdd83615b92565b909155505060278054906000611ff283615b92565b909155505033600090815260236020526040812080549161201283615b92565b9091555050336000908152603b6020526040812054602880549192909161203a9084906159b9565b9091555050336000908152603b60209081526040808320546026909252822080549192909161206a9084906159b9565b90915550503360009081526033602052604081205561208761293d565b565b601b546000908190819081906001600160a01b03161561212857601b546040516370a0823160e01b81526000916001600160a01b0316906370a08231906120d4908990600401615831565b60206040518083038186803b1580156120ec57600080fd5b505afa158015612100573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612124919061573b565b1192505b601c546001600160a01b0316156121be57601c546040516370a0823160e01b81526000916001600160a01b0316906370a082319061216a908990600401615831565b60206040518083038186803b15801561218257600080fd5b505afa158015612196573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ba919061573b565b1191505b601d546001600160a01b03161561225457601d546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612200908990600401615831565b60206040518083038186803b15801561221857600080fd5b505afa15801561222c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612250919061573b565b1190505b828061225d5750815b806117865750949350505050565b62015180603d544261227d9190615afd565b116122ca5760405162461bcd60e51b815260206004820152601d60248201527f54686520636f6e7472616374206973207374696c6c20776f726b696e6700000060448201526064016113f9565b600c546001600160a01b0316331461233b5760405162461bcd60e51b815260206004820152602e60248201527f596f7520617265206e6f74207175616c696669656420746f2063616c6c20746f60448201526d103a3434b990333ab731ba34b7b760911b60648201526084016113f9565b60165460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061236d9033904790600401615845565b602060405180830381600087803b15801561238757600080fd5b505af115801561239b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123bf919061544b565b6120875760405162461bcd60e51b815260206004820152601560248201527421b0b73737ba103830bc9029ba30b13632a1b7b4b760591b60448201526064016113f9565b6055602052600090815260409020805461133990615b57565b602254601f5460009160019110156124375750600092915050565b6000602254601f546124499190615afd565b90505b601f5481101561249a5781801561248657506001600160a01b038416600090815260626020908152604080832084845290915290205460ff165b91508061249281615b92565b91505061244c565b5092915050565b60006103e86124b2836103f1615ade565b6114ce91906159d1565b602c546000818152602e6020908152604080832054602f83528184205433855260318452828520958552949092529091205490919060ff16156124fe57600080fd5b33600090815260356020526040902054602c54101561251c57600080fd5b61252533612a22565b61252e57600080fd5b60006125393361168a565b90506000811161254857600080fd5b61255281836159b9565b83101561255e57600080fd5b60075461256b90826159d1565b336000908152603b6020526040902054101561258657600080fd5b60165460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906125b89033908590600401615845565b602060405180830381600087803b1580156125d257600080fd5b505af11580156125e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260a919061544b565b61261357600080fd5b61262a336007548361262591906159d1565b613f8c565b602c546000908152602f60205260408120805483929061264b9084906159b9565b9091555050336000908152603160209081526040808320602c5484529091528120805460ff19166001179055602d80548392906126899084906159b9565b909155505033600090815260326020526040812080548392906126ad9084906159b9565b909155505033600090815260336020526040812080548392906126d19084906159b9565b909155506126e0905033614dfd565b604051818152339042907f7f61f8c57ad5757ff357174bf30c28673a0dd1f02a173b1a308dd68c59ba0693906020015b60405180910390a3505050565b600f546001600160a01b031633146127475760405162461bcd60e51b81526004016113f990615911565b601b80546001600160a01b0319166001600160a01b0392909216919091179055565b6054602052600090815260409020805461133990615b57565b600c546001600160a01b03163314806127a55750600f546001600160a01b031633145b6127c15760405162461bcd60e51b81526004016113f990615891565b600755565b601e546001600160a01b031633146127dd57600080fd5b6127e7818361505f565b6127f081614dfd565b6127f981612a22565b1561281157603e80546001600160a01b031916331790555b61281c6003836159d1565b602b546000908152602e60205260408120805490919061283d9084906159b9565b90915550506001600160a01b0381166000908152603c60205260408120805484929061286a9084906159b9565b90915550506001600160a01b0381166000908152603f60209081526040808320601f548452909152812080548492906128a49084906159b9565b9091555050602b546001600160a01b03821660009081526035602052604081209190915560388054916128d683615b92565b909155506128e790506003836159d1565b604a60008282546128f891906159b9565b909155505042603d55601f546040516001600160a01b03831691600080516020615c6f833981519152916129319190869060019061594a565b60405180910390a25050565b602b5460009081526030602052604090205442111561208757602c546000908152602f6020908152604080832054602e9092529091205461297e9190615afd565b602b546000908152602e60205260408120805490919061299f9084906159b9565b9091555050601f80549060006129b483615b92565b9091555050601f5460405142907f8a5aeed79336e8e02c0bd5f6827b1b5d1e48973bd23b29202673f0788c832d6590600090a3602b8054602c8190559060006129fc83615b92565b9091555050600854612a0e90426159b9565b602b54600090815260306020526040902055565b600c546000906001600160a01b0383811691161480612a4e5750600f546001600160a01b038381169116145b15612a5b57506001919050565b6001600160a01b0382166000908152605b60205260408120601f54909190612a8590600190615afd565b815260208101919091526040016000205460ff168015612adf57506001600160a01b0382166000908152605e60205260408120601f54909190612aca90600190615afd565b815260208101919091526040016000205460ff165b8015612b2557506001600160a01b0382166000908152605d60205260408120601f54909190612b1090600190615afd565b815260208101919091526040016000205460ff165b8015612b6b57506001600160a01b0382166000908152605c60205260408120601f54909190612b5690600190615afd565b815260208101919091526040016000205460ff165b8015612bb157506001600160a01b0382166000908152605f60205260408120601f54909190612b9c90600190615afd565b815260208101919091526040016000205460ff165b8015612bf757506001600160a01b0382166000908152606060205260408120601f54909190612be290600190615afd565b815260208101919091526040016000205460ff165b80156114ce57506001600160a01b0382166000908152606160205260408120601f54909190611da590600190615afd565b600f546001600160a01b03163314612c3f57600080fd5b601e80546001600160a01b0319166001600160a01b0392909216919091179055565b6063805461133990615b57565b6001600160a01b0381166000908152603b6020526040812054612c9083611c4c565b1192915050565b601854604051631ee8536360e21b815260009182916001600160a01b0390911690637ba14d8c90612ccc908690600401615831565b60206040518083038186803b158015612ce457600080fd5b505afa158015612cf8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d1c919061544b565b90506000601860009054906101000a90046001600160a01b03166001600160a01b0316636190c9d56040518163ffffffff1660e01b815260040160206040518083038186803b158015612d6e57600080fd5b505afa158015612d82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612da6919061573b565b6019546040516370a0823160e01b815291925060009182916001600160a01b0316906370a0823190612ddc908990600401615831565b60206040518083038186803b158015612df457600080fd5b505afa158015612e08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e2c919061573b565b6018546040516370a0823160e01b81526001600160a01b03909116906370a0823190612e5c908a90600401615831565b60206040518083038186803b158015612e7457600080fd5b505afa158015612e88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eac919061573b565b612eb691906159b9565b90505b83158015612ec75750604582105b15612f69576018546001600160a01b0316636252b6fd87612ee88587615afd565b6040518363ffffffff1660e01b8152600401612f05929190615845565b60206040518083038186803b158015612f1d57600080fd5b505afa158015612f31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f55919061544b565b935081612f6181615b92565b925050612eb9565b831561178657601854604051633b8a5e2760e01b81526001600160a01b0390911690633b8a5e2790612f9f908990600401615831565b60206040518083038186803b158015612fb757600080fd5b505afa158015612fcb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fef919061573b565b612ff990826159b9565b9695505050505050565b6050602052600090815260409020805461133990615b57565b600054421061302a57600080fd5b3360009081526001602052604090205460ff161561304757600080fd5b601854604051633b8a5e2760e01b81526001600160a01b0390911690633b8a5e2790613077903390600401615831565b60206040518083038186803b15801561308f57600080fd5b505afa1580156130a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130c7919061573b565b336000908152603b6020526040812080549091906130e69084906159b9565b9091555050336000908152603b6020526040812054603680549192909161310e9084906159b9565b909155505060185460405163d963905760e01b81526001600160a01b039091169063d963905790613143903390600401615831565b60206040518083038186803b15801561315b57600080fd5b505afa15801561316f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613193919061573b565b336000908152603c6020526040812080549091906131b29084906159b9565b909155505060185460405163b389bae560e01b81526001600160a01b039091169063b389bae5906131e7903390600401615831565b60006040518083038186803b1580156131ff57600080fd5b505afa158015613213573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261323b91908101906154a9565b336000908152604860209081526040909120825161325f9391929190910190615252565b5060185460405163af2996ad60e01b81526001600160a01b039091169063af2996ad90613290903390600401615831565b60006040518083038186803b1580156132a857600080fd5b505afa1580156132bc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526132e491908101906154a9565b33600090815260496020908152604090912082516133089391929190910190615252565b5061331b3361331633612c97565b614f92565b6018546040516370a0823160e01b81526000916001600160a01b0316906370a082319061334c903390600401615831565b60206040518083038186803b15801561336457600080fd5b505afa158015613378573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061339c919061573b565b1180156133b957503360009081526047602052604090205460ff16155b156133ee57604580549060006133ce83615b92565b9091555050336000908152604760205260409020805460ff191660011790555b6133f733612a22565b801561341357503360009081526034602052604090205460ff16155b1561349457336000908152603b6020526040812054603780549192909161343b9084906159b9565b9091555050336000908152603460205260408120805460ff19166001179055604680549161346883615b92565b90915550506040516001815233904290600080516020615c0f8339815191529060200160405180910390a35b336000908152600160208190526040909120805460ff19169091179055565b60606006805461143790615b57565b604f602052600090815260409020805461133990615b57565b60006134e682612a22565b80156114ce5750506001600160a01b031660009081526010602052604090205460ff1690565b6001600160a01b0381166000908152604160205260408120601f54620186a09190839061353b90600190615afd565b815260200190815260200160002054620188116124b29190615ade565b600060175460121415613595576016546040516370a0823160e01b81526001600160a01b03909116906370a0823190611c89908590600401615831565b6017546135a3906012615afd565b6135ae90600a615a36565b6016546040516370a0823160e01b81526001600160a01b03909116906370a0823190611d22908690600401615831565b600c546001600160a01b031633146136085760405162461bcd60e51b81526004016113f990615891565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0381166000908152603b6020908152604080832054918190528220601f546136769190849061366290600190615afd565b8152602001908152602001600020546124a1565b11156136bd576001600160a01b0382166000908152603b6020908152604080832054918190528220601f5491926136b39261366290600190615afd565b6114ce9190615afd565b506000919050565b3360008181526003602090815260408083206001600160a01b03871684529091528120549091908381101561374a5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016113f9565b611acc8286868403613e70565b600d546001600160a01b031633148061377a5750600c546001600160a01b031633145b6137965760405162461bcd60e51b81526004016113f990615911565b80516137a9906063906020840190615252565b5050565b600c546001600160a01b03163314806137d05750600d546001600160a01b031633145b806137e55750600e546001600160a01b031633145b6138015760405162461bcd60e51b81526004016113f990615911565b604b805460ff19811660ff90911615179055565b6000336114c8818585614b73565b600c546001600160a01b03163314806138465750600f546001600160a01b031633145b6138625760405162461bcd60e51b81526004016113f9906158cb565b601280546001600160a01b0319166001600160a01b039390931692909217909155601355565b6049602052600090815260409020805461133990615b57565b6001600160a01b0381166000908152603b6020526040812054612c9083613c07565b6048602052600090815260409020805461133990615b57565b6057602052600090815260409020805461133990615b57565b6059602052600090815260409020805461133990615b57565b6058602052600090815260409020805461133990615b57565b600c546001600160a01b031633146139515760405162461bcd60e51b81526004016113f990615911565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b600c546001600160a01b03163314806139965750600f546001600160a01b031633145b6139b25760405162461bcd60e51b81526004016113f9906158cb565b601480546001600160a01b0319166001600160a01b039390931692909217909155601555565b6052602052600090815260409020805461133990615b57565b6053602052600090815260409020805461133990615b57565b602a546001600160a01b039091166000908152603b6020526040902054101590565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b60008181526051602090815260408083209051613a749201615795565b6040516020818303038152906040528051906020012085604051602001613a9b9190615779565b60408051601f198184030181528282528051602091820120600087815260528352928320941494509092613ad192909101615795565b6040516020818303038152906040528051906020012085604051602001613af89190615779565b60408051601f198184030181528282528051602091820120600088815260538352928320941494509092613b2e92909101615795565b6040516020818303038152906040528051906020012085604051602001613b559190615779565b60405160208183030381529060405280519060200120149050828015613b785750815b8015613b815750805b336000818152605a60209081526040808320601f5484529091529020805460ff191692151592909217909155427f8c523ebdf6485477f33992ad2a94e5245e6777dc6feb33a26a26dbb8f919165a858015613bd95750845b8015613be25750835b604051901515815260200160405180910390a3613bfe33614dfd565b50505050505050565b600060135460121415613c44576012546040516370a0823160e01b81526001600160a01b03909116906370a0823190611c89908590600401615831565b601354613c52906012615afd565b613c5d90600a615a36565b6012546040516370a0823160e01b81526001600160a01b03909116906370a0823190611d22908690600401615831565b600f546001600160a01b03163314613cb75760405162461bcd60e51b81526004016113f990615911565b601d80546001600160a01b0319166001600160a01b0392909216919091179055565b6051602052600090815260409020805461133990615b57565b6001600160a01b0381166000908152603b6020526040812054613d1757506000919050565b6001601f541115613d90576001600160a01b0382166000908152604060208190528120601f54613d4e929061366290600290615afd565b6001600160a01b0383166000908152604060208190528120601f54909190613d7890600190615afd565b81526020019081526020016000205410159050919050565b506001919050565b600c546001600160a01b03163314613dc25760405162461bcd60e51b81526004016113f990615911565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b33600090815260496020908152604090912082516137a992840190615252565b600f546001600160a01b03163314613e2e5760405162461bcd60e51b81526004016113f990615911565b601c80546001600160a01b0319166001600160a01b0392909216919091179055565b33600090815260486020908152604090912082516137a992840190615252565b6001600160a01b038316613ed25760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016113f9565b6001600160a01b038216613f335760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016113f9565b6001600160a01b0383811660008181526003602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101612710565b6001600160a01b03821660009081526034602052604090205460ff168015614028576001600160a01b0383166000908152603b60205260408120546037805491929091613fda908490615afd565b90915550506001600160a01b0383166000908152603460205260408120805460ff19169055603a80549161400d83615b40565b90915550506046805490600061402283615b40565b91905055505b6001600160a01b0383166000908152603b602052604081208054849290614050908490615afd565b9250508190555081603660008282546140699190615afd565b90915550506001600160a01b0383166000908152603b60205260409020546140a1576039805490600061409b83615b40565b91905055505b6140aa83612a22565b1561412c576001600160a01b0383166000908152603b602052604081205460378054919290916140db9084906159b9565b90915550506001600160a01b0383166000908152603460205260408120805460ff19166001179055603a80549161411183615b92565b90915550506046805490600061412683615b92565b91905055505b6001600160a01b03831660009081526034602052604090205460ff1615158115151461418257604051811581526001600160a01b038416904290600080516020615c0f8339815191529060200160405180910390a35b826001600160a01b0316600080516020615c6f833981519152601f548460006040516141b09392919061594a565b60405180910390a2505050565b6001600160a01b03811660009081526044602090815260408083205460429092528220546141eb91906159b9565b905060006141f883611c4c565b61420184613c07565b61420b91906159b9565b9050818110156142795760006142218284615afd565b6001600160a01b0385166000908152603b602052604090205490915081111561426d576001600160a01b0384166000908152603b6020526040902054614268908590613f8c565b614277565b6142778482613f8c565b505b505050565b6001600160a01b03811660009081526034602052604090205460ff16801561431a576001600160a01b0382166000908152603b602052604081205460378054919290916142cc908490615afd565b90915550506001600160a01b0382166000908152603460205260408120805460ff19169055603a8054916142ff83615b40565b90915550506046805490600061431483615b40565b91905055505b61432382612a22565b156143a5576001600160a01b0382166000908152603b602052604081205460378054919290916143549084906159b9565b90915550506001600160a01b0382166000908152603460205260408120805460ff19166001179055603a80549161438a83615b92565b90915550506046805490600061439f83615b92565b91905055505b6001600160a01b03821660009081526034602052604090205460ff161515811515146137a957604051811581526001600160a01b038316904290600080516020615c0f8339815191529060200160405180910390a35050565b6001600160a01b0381166000908152602080526040902054601f54106117be57601f5461442c9060016159b9565b6001600160a01b038216600090815260208052604090205561444d81613c07565b6001600160a01b03821660009081526042602052604090205561446f81611c4c565b6001600160a01b0382166000818152604460209081526040808320948555604282528083205460418352818420601f805486529084528285209190915584845294546043835281842086548552835281842055338352603b82528083205493835290819052812092549192916144e790600190615afd565b815260208101919091526040016000205561450181612089565b6001600160a01b0382166000908152605b60205260408120601f5490919061452b90600190615afd565b81526020810191909152604001600020805460ff1916911515919091179055614553816114ed565b6001600160a01b0382166000908152605c60205260408120601f5490919061457d90600190615afd565b81526020810191909152604001600020805460ff19169115159190911790556145a581612c6e565b6001600160a01b0382166000908152605e60205260408120601f549091906145cf90600190615afd565b81526020810191909152604001600020805460ff19169115159190911790556145f7816138a1565b6001600160a01b0382166000908152605d60205260408120601f5490919061462190600190615afd565b81526020810191909152604001600020805460ff191691151591909117905561464981613a0a565b6001600160a01b0382166000908152605f60205260408120601f5490919061467390600190615afd565b81526020810191909152604001600020805460ff191691151591909117905561469b81613cf2565b6001600160a01b0382166000908152606060205260408120601f549091906146c590600190615afd565b81526020810191909152604001600020805460ff19169115159190911790556146ed81611d7c565b6001600160a01b0382166000908152606160205260408120601f5490919061471790600190615afd565b81526020810191909152604001600020805460ff191691151591909117905561473f81612a22565b6001600160a01b0382166000908152606260205260408120601f5490919061476990600190615afd565b815260200190815260200160002060006101000a81548160ff021916908315150217905550806001600160a01b03167f527e2cac87a0f06e1102c21d4d5c884fe456c3fe85a12c5450f69505009d2c1b6001601f546147c89190615afd565b6001600160a01b0384166000908152605b60205260408120601f549091906147f290600190615afd565b815260208082019290925260409081016000908120546001600160a01b0388168252605e909352908120601f5460ff9093169290919061483490600190615afd565b815260208082019290925260409081016000908120546001600160a01b0389168252605d909352908120601f5460ff9093169290919061487690600190615afd565b815260208082019290925260409081016000908120546001600160a01b038a168252605c909352908120601f5460ff909316929091906148b890600190615afd565b815260208082019290925260409081016000908120546001600160a01b038b168252605f909352908120601f5460ff909316929091906148fa90600190615afd565b815260208082019290925260409081016000908120546001600160a01b038c1682526060909352908120601f5460ff9093169290919061493c90600190615afd565b815260208082019290925260409081016000908120546001600160a01b038d1682526061909352908120601f5460ff9093169290919061497e90600190615afd565b81526020808201929092526040908101600020548151998a529715159189019190915294151594870194909452911515606086015215156080850152151560a0840152151560c083015260ff16151560e08201526101000160405180910390a250565b6149ea81612a22565b158015614a0f57506001600160a01b03811660009081526010602052604090205460ff165b15614a5a576001600160a01b0381166000818152601060209081526040808320805460ff19169055519182524291600080516020615c2f83398151915291015b60405180910390a350565b614a6381612a22565b8015614a8857506001600160a01b03811660009081526010602052604090205460ff16155b156117be576001600160a01b0381166000908152601060205260409020805460ff19166001179055602254601f54614ac091906159b9565b6001600160a01b03821660008181526021602090815260409182902093909355516001815290914291600080516020615c2f8339815191529101614a4f565b6000614b0b8484613a2c565b905060001981146142775781811015614b665760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016113f9565b6142778484848403613e70565b6001600160a01b038316614bd75760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016113f9565b6001600160a01b038216614c395760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016113f9565b6001600160a01b03821660009081526047602052604090205460ff16614c925760458054906000614c6983615b92565b90915550506001600160a01b0382166000908152604760205260409020805460ff191660011790555b6001600160a01b03831660009081526002602052604090205481811015614d0a5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016113f9565b6001600160a01b03808516600090815260026020526040808220858503905591851681529081208054849290614d419084906159b9565b90915550506001600160a01b038416600090815260026020526040902054614d995760458054906000614d7383615b40565b90915550506001600160a01b0384166000908152604760205260409020805460ff191690555b614da284614dfd565b614dab83614dfd565b614db48461427e565b614dbd8361427e565b826001600160a01b0316846001600160a01b0316600080516020615c4f83398151915284604051614df091815260200190565b60405180910390a3614277565b614e0561293d565b614e0e816141bd565b614e178161427e565b614e20816143fe565b614e29816149e1565b601b546001600160a01b031615614ea357601b60009054906101000a90046001600160a01b03166001600160a01b031663c8aaf64b6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015614e8a57600080fd5b505af1158015614e9e573d6000803e3d6000fd5b505050505b601c546001600160a01b031615614f1d57601c60009054906101000a90046001600160a01b03166001600160a01b031663c8aaf64b6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015614f0457600080fd5b505af1158015614f18573d6000803e3d6000fd5b505050505b601d546001600160a01b0316156117be57601d60009054906101000a90046001600160a01b03166001600160a01b031663c8aaf64b6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015614f7e57600080fd5b505af1158015611659573d6000803e3d6000fd5b6001600160a01b038216614fe85760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016113f9565b8060046000828254614ffa91906159b9565b90915550506001600160a01b038216600090815260026020526040812080548392906150279084906159b9565b90915550506040518181526001600160a01b03831690600090600080516020615c4f8339815191529060200160405180910390a35050565b6001600160a01b03821660009081526034602052604090205460ff1680156150fb576001600160a01b0383166000908152603b602052604081205460378054919290916150ad908490615afd565b90915550506001600160a01b0383166000908152603460205260408120805460ff19169055603a8054916150e083615b40565b9091555050604680549060006150f583615b40565b91905055505b6001600160a01b0383166000908152603b602052604090205461512e576039805490600061512883615b92565b91905055505b6001600160a01b0383166000908152603b6020526040812080548492906151569084906159b9565b92505081905550816036600082825461516f91906159b9565b9091555061517e905083612a22565b15615200576001600160a01b0383166000908152603b602052604081205460378054919290916151af9084906159b9565b90915550506001600160a01b0383166000908152603460205260408120805460ff19166001179055603a8054916151e583615b92565b9091555050604680549060006151fa83615b92565b91905055505b6001600160a01b03831660009081526034602052604090205460ff1615158115151461427957604051811581526001600160a01b038416904290600080516020615c0f83398151915290602001612710565b82805461525e90615b57565b90600052602060002090601f01602090048101928261528057600085556152c6565b82601f1061529957805160ff19168380011785556152c6565b828001600101855582156152c6579182015b828111156152c65782518255916020019190600101906152ab565b506152d2929150615316565b5090565b8280548282559060005260206000209081019282156152c65760005260206000209182015b828111156152c65782548255916001019190600101906152fb565b5b808211156152d25760008155600101615317565b600082601f83011261533c57600080fd5b813561534f61534a82615992565b615962565b81815284602083860101111561536457600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561539357600080fd5b813561539e81615bd9565b9392505050565b600080604083850312156153b857600080fd5b82356153c381615bd9565b915060208301356153d381615bd9565b809150509250929050565b6000806000606084860312156153f357600080fd5b83356153fe81615bd9565b9250602084013561540e81615bd9565b929592945050506040919091013590565b6000806040838503121561543257600080fd5b823561543d81615bd9565b946020939093013593505050565b60006020828403121561545d57600080fd5b8151801515811461539e57600080fd5b60006020828403121561547f57600080fd5b81356001600160401b0381111561549557600080fd5b6154a18482850161532b565b949350505050565b6000602082840312156154bb57600080fd5b81516001600160401b038111156154d157600080fd5b8201601f810184136154e257600080fd5b80516154f061534a82615992565b81815285602083850101111561550557600080fd5b611786826020830160208601615b14565b6000806000806080858703121561552c57600080fd5b84356001600160401b038082111561554357600080fd5b61554f8883890161532b565b9550602087013591508082111561556557600080fd5b6155718883890161532b565b9450604087013591508082111561558757600080fd5b6155938883890161532b565b935060608701359150808211156155a957600080fd5b506155b68782880161532b565b91505092959194509250565b600080600080600060a086880312156155da57600080fd5b85356001600160401b03808211156155f157600080fd5b6155fd89838a0161532b565b9650602088013591508082111561561357600080fd5b61561f89838a0161532b565b9550604088013591508082111561563557600080fd5b61564189838a0161532b565b9450606088013591508082111561565757600080fd5b61566389838a0161532b565b9350608088013591508082111561567957600080fd5b506156868882890161532b565b9150509295509295909350565b600080600080608085870312156156a957600080fd5b84356001600160401b03808211156156c057600080fd5b6156cc8883890161532b565b955060208701359150808211156156e257600080fd5b6156ee8883890161532b565b9450604087013591508082111561570457600080fd5b506157118782880161532b565b949793965093946060013593505050565b60006020828403121561573457600080fd5b5035919050565b60006020828403121561574d57600080fd5b5051919050565b6000806040838503121561576757600080fd5b8235915060208301356153d381615bd9565b6000825161578b818460208701615b14565b9190910192915050565b600080835481600182811c9150808316806157b157607f831692505b60208084108214156157d157634e487b7160e01b86526022600452602486fd5b8180156157e557600181146157f657615823565b60ff19861689528489019650615823565b60008a81526020902060005b8681101561581b5781548b820152908501908301615802565b505084890196505b509498975050505050505050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b602081526000825180602084015261587d816040850160208701615b14565b601f01601f19169190910160400192915050565b6020808252602c90820152600080516020615bef83398151915260408201526b34b990333ab731ba34b7b71760a11b606082015260800190565b60208082526026908201527f596f7520617265206e6f742061626c6520746f2063616c6c20746869732066756040820152653731ba34b7b760d11b606082015260800190565b6020808252602b90820152600080516020615bef83398151915260408201526a34b990333ab731ba34b7b760a91b606082015260800190565b92835260208301919091521515604082015260600190565b604051601f8201601f191681016001600160401b038111828210171561598a5761598a615bc3565b604052919050565b60006001600160401b038211156159ab576159ab615bc3565b50601f01601f191660200190565b600082198211156159cc576159cc615bad565b500190565b6000826159ee57634e487b7160e01b600052601260045260246000fd5b500490565b600181815b80851115615a2e578160001904821115615a1457615a14615bad565b80851615615a2157918102915b93841c93908002906159f8565b509250929050565b600061539e8383600082615a4c575060016114ce565b81615a59575060006114ce565b8160018114615a6f5760028114615a7957615a95565b60019150506114ce565b60ff841115615a8a57615a8a615bad565b50506001821b6114ce565b5060208310610133831016604e8410600b8410161715615ab8575081810a6114ce565b615ac283836159f3565b8060001904821115615ad657615ad6615bad565b029392505050565b6000816000190483118215151615615af857615af8615bad565b500290565b600082821015615b0f57615b0f615bad565b500390565b60005b83811015615b2f578181015183820152602001615b17565b838111156142775750506000910152565b600081615b4f57615b4f615bad565b506000190190565b600181811c90821680615b6b57607f821691505b60208210811415615b8c57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415615ba657615ba6615bad565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146117be57600080fdfe596f7520617265206e6f74207175616c696669656420746f2063616c6c20746806450a68843513e906a6efb7847c7647be951acc890120744c8e1ec91014f8ca7ee0265bf5adc943b87293232f34cef62f3f2c4b91156c24f460349766250ae9ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efc327d4bbc6ddb4c022b1e87bcadd36113256d88be3b6c55ca717b474a56881a3a2646970667358221220a24787eff837165ab19b4835bf6fe9ce149d7345e543adf4c68fbbcbf8db069a64736f6c63430008070033
Deployed Bytecode Sourcemap
180989:82:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;145852:47;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;157849:296;;;;;;:::i;:::-;;:::i;:::-;;144837:69;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;16861:25:1;;;16849:2;16834:18;144837:69:0;16715:177:1;175419:100:0;;;:::i;145076:65::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;176417:226;;;;;;:::i;:::-;;:::i;:::-;;;9302:14:1;;9295:22;9277:41;;9265:2;9250:18;176417:226:0;9137:187:1;145386:31:0;;;;;;147067:74;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;145800:43;;;;;;:::i;:::-;;:::i;159260:141::-;;;;;;:::i;:::-;;:::i;144521:44::-;;;;;;144964:87;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;146303:50;;;;;;:::i;:::-;;:::i;154746:704::-;;;;;;:::i;:::-;;:::i;142333:33::-;;;;;;143441:31;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;175740:108::-;175828:12;;175740:108;;158411:692;;;;;;:::i;:::-;;:::i;151236:160::-;;;;;;:::i;:::-;;:::i;143232:52::-;;;;;;:::i;:::-;;;;;;;;;;;;;;141528:85;;;;;-1:-1:-1;;;;;141528:85:0;;;153956:782;;;;;;:::i;:::-;;:::i;164749:603::-;;;;;;:::i;:::-;;:::i;145148:49::-;;;;;;:::i;:::-;;;;;;;;;;;;;;143354:35;;;;;;176651:295;;;;;;:::i;:::-;;:::i;141620:86::-;;;;;-1:-1:-1;;;;;141620:86:0;;;146996:64;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;141129:28;;;;;;146924:65;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;143597:30;;;;;;175639:93;;;175722:2;18127:36:1;;18115:2;18100:18;175639:93:0;17985:184:1;144397:35:0;;;;;;141290:51;;;;;;165924:236;;;;;;:::i;:::-;;:::i;176954:265::-;;;;;;:::i;:::-;;:::i;155458:691::-;;;;;;:::i;:::-;;:::i;144617:50::-;;;;;;:::i;:::-;;;;;;;;;;;;;;144572:38;;;;;;146704:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;142496:89;;;;;-1:-1:-1;;;;;142496:89:0;;;141348:45;;;;;;163600:240;;;;;;:::i;:::-;;:::i;160449:128::-;;;;;;:::i;:::-;;:::i;152615:1317::-;;;:::i;161063:580::-;;;;;;:::i;:::-;;:::i;142235:69::-;;;;;-1:-1:-1;;;;;142235:69:0;;;166402:451;;;:::i;146245:51::-;;;;;;:::i;:::-;;:::i;143291:56::-;;;;;;:::i;:::-;;;;;;;;;;;;;;143112:60;;;;;;:::i;:::-;;;;;;;;;;;;;;143887:54;;;;;;:::i;:::-;;;;;;;;;;;;;;162450:331;;;;;;:::i;:::-;;:::i;142979:53::-;;;;;;:::i;:::-;;;;;;;;;;;;;;160298:143;;;;;;:::i;:::-;;:::i;151404:1203::-;;;:::i;167922:243::-;;;;;;:::i;:::-;;:::i;147148:66::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;145352:27;;;;;;141812:52;;;;;;:::i;:::-;;;;;;;;;;;;;;;;141871:43;;;;;;:::i;:::-;;;;;;;;;;;;;;143683:47;;;;;;:::i;:::-;;;;;;;;;;;;;;146188:50;;;;;;:::i;:::-;;:::i;142722:27::-;;;;;-1:-1:-1;;;;;142722:27:0;;;146852:65;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;142894:24;;;;;;147221:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;145614:37;;;;;;141166:44;;;;;;143996:65;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;143563:27;;;;;;146536:65;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;167662:252;;;;;;:::i;:::-;;:::i;175856:143::-;;;;;;:::i;:::-;-1:-1:-1;;;;;175973:18:0;175946:7;175973:18;;;:9;:18;;;;;;;175856:143;144326:44;;;;;;:::i;:::-;;;;;;;;;;;;;;173562:786;;;;;;:::i;:::-;;:::i;164096:645::-;;;:::i;161651:508::-;;;;;;:::i;:::-;;:::i;168667:137::-;;;;;;:::i;:::-;;:::i;145206:65::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;147318:28;;;:::i;159409:147::-;;;;;;:::i;:::-;;:::i;149285:629::-;;;;;;:::i;:::-;;:::i;141959:69::-;;;;;-1:-1:-1;;;;;141959:69:0;;;145961:47;;;;;;:::i;:::-;;:::i;145708:16::-;;;;;;;;;143508:48;;;;;;141713:69;;;;;-1:-1:-1;;;;;141713:69:0;;;149922:1306;;;:::i;144439:39::-;;;;;;175527:104;;;:::i;142842:28::-;;;;;-1:-1:-1;;;;;142842:28:0;;;145906:48;;;;;;:::i;:::-;;:::i;144113:51::-;;;;;;:::i;:::-;;;;;;;;;;;;;;162167:146;;;;;;:::i;:::-;;:::i;160142:148::-;;;;;;:::i;:::-;;:::i;163848:240::-;;;;;;:::i;:::-;;:::i;143634:40::-;;;;;;158153:250;;;;;;:::i;:::-;;:::i;160585:470::-;;;;;;:::i;:::-;;:::i;144243:43::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;177227:500;;;;;;:::i;:::-;;:::i;166861:263::-;;;;;;:::i;:::-;;:::i;140837:41::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;156935:298;;;:::i;176007:218::-;;;;;;:::i;:::-;;:::i;145771:22::-;;;;;;157241:296;;;;;;:::i;:::-;;:::i;145527:50::-;;;;;;:::i;:::-;;:::i;159564:147::-;;;;;;:::i;:::-;;:::i;145278:49::-;;;;;;:::i;:::-;;;;;;;;;;;;;;144771:31;;;;;-1:-1:-1;;;;;144771:31:0;;;145471:49;;;;;;:::i;:::-;;:::i;144728:36::-;;;;;;146362:50;;;;;;:::i;:::-;;:::i;146779:66::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;146477:50;;;;;;:::i;:::-;;:::i;142056:32::-;;;;;;143780:54;;;;;;:::i;:::-;;;;;;;;;;;;;;142097:69;;;;;-1:-1:-1;;;;;142097:69:0;;;141420:101;;;;;-1:-1:-1;;;;;141420:101:0;;;146419:51;;;;;;:::i;:::-;;:::i;142925:47::-;;;;;;:::i;:::-;;;;;;;;;;;;;;167132:256;;;;;;:::i;:::-;;:::i;143396:38::-;;;;;;157545:296;;;;;;:::i;:::-;;:::i;146073:50::-;;;;;;:::i;:::-;;:::i;145424:40::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;141233:50;;;;;;144674:47;;;;;;:::i;:::-;;;;;;;;;;;;;;143179:46;;;;;;:::i;:::-;;;;;;;;;;;;;;;;146130:49;;;;;;:::i;:::-;;:::i;159111:141::-;;;;;;:::i;:::-;;:::i;142756:27::-;;;;;-1:-1:-1;;;;;142756:27:0;;;176233:176;;;;;;:::i;:::-;;:::i;144485:29::-;;;;;;143039:43;;;;;;144171:63;;;;;;:::i;:::-;;;;;;;;;;;;;;156157:770;;;;;;:::i;:::-;;:::i;163352:240::-;;;;;;:::i;:::-;;:::i;168424:235::-;;;;;;:::i;:::-;;:::i;146017:49::-;;;;;;:::i;:::-;;:::i;159719:415::-;;;;;;:::i;:::-;;:::i;167396:258::-;;;;;;:::i;:::-;;:::i;142194:32::-;;;;;;166284:110;;;;;;:::i;:::-;;:::i;142402:87::-;;;;;-1:-1:-1;;;;;142402:87:0;;;142790:25;;;;;-1:-1:-1;;;;;142790:25:0;;;168173:243;;;;;;:::i;:::-;;:::i;166168:108::-;;;;;;:::i;:::-;;:::i;145852:47::-;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;157849:296::-;157960:15;;-1:-1:-1;;;;;157960:15:0;157946:10;:29;;:56;;-1:-1:-1;157993:9:0;;-1:-1:-1;;;;;157993:9:0;157979:10;:23;157946:56;157924:144;;;;-1:-1:-1;;;157924:144:0;;;;;;;:::i;:::-;;;;;;;;;158079:4;:22;;-1:-1:-1;;;;;;158079:22:0;-1:-1:-1;;;;;158079:22:0;;;;;;;;;;;158112:13;:25;157849:296::o;175419:100::-;175473:13;175506:5;175499:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;175419:100;:::o;176417:226::-;176525:4;26114:10;176581:32;26114:10;176597:7;176606:6;176581:8;:32::i;:::-;176631:4;176624:11;;;176417:226;;;;;:::o;145800:43::-;;;;;;;;;;;;;;;;:::i;159260:141::-;-1:-1:-1;;;;;159369:23:0;159324:4;159369:23;;;:15;:23;;;;;;;;;159349:9;:17;;;;;;;:43;;159260:141::o;146303:50::-;;;;;;;;;;;;;;;;:::i;154746:704::-;155005:16;;-1:-1:-1;;;;;155005:16:0;154991:10;:30;;:82;;-1:-1:-1;155056:17:0;;-1:-1:-1;;;;;155056:17:0;155042:10;:31;154991:82;:132;;;-1:-1:-1;155108:15:0;;-1:-1:-1;;;;;155108:15:0;155094:10;:29;154991:132;154969:225;;;;-1:-1:-1;;;154969:225:0;;;;;;;:::i;:::-;155237:15;155207:14;:27;155232:1;155222:7;;:11;;;;:::i;:::-;155207:27;;;;;;;;;;;:45;;;;;;;;;;;;:::i;:::-;;155297:17;155265:16;:29;155292:1;155282:7;;:11;;;;:::i;:::-;155265:29;;;;;;;;;;;:49;;;;;;;;;;;;:::i;:::-;;155360:18;155327:17;:30;155355:1;155345:7;;:11;;;;:::i;:::-;155327:30;;;;;;;;;;;:51;;;;;;;;;;;;:::i;:::-;;155424:18;155391:17;:30;155419:1;155409:7;;:11;;;;:::i;:::-;155391:30;;;;;;;;;;;:51;;;;;;;;;;;;:::i;:::-;;154746:704;;;;:::o;143441:31::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;143441:31:0;;-1:-1:-1;143441:31:0;:::o;158411:692::-;158477:7;158501:24;;158529:1;158501:29;:52;;;;158535:18;158546:6;158535:10;:18::i;:::-;158534:19;158501:52;158497:66;;;-1:-1:-1;158562:1:0;;158411:692;-1:-1:-1;158411:692:0:o;158497:66::-;158667:24;;-1:-1:-1;;;;;158640:23:0;;158576:14;158640:23;;;:15;:23;;;;;;;;;158608:15;;158595:29;;:12;:29;;;;;;158576:14;;158667:24;158595:68;;158640:23;158595:68;:::i;:::-;158594:97;;;;:::i;:::-;158747:15;;158703:21;158727:36;;;:19;:36;;;;;;;;;158797:12;:29;;;;;;;158576:116;;-1:-1:-1;158727:36:0;158859:22;158576:116;158727:36;158859:22;:::i;:::-;158843:12;:39;158839:111;;;158909:28;158924:13;158909:12;:28;:::i;:::-;158899:39;;158839:111;159002:9;;-1:-1:-1;;;;;158976:23:0;;;;;;:15;:23;;;;;;:35;;159002:9;158976:35;:::i;:::-;158966:6;:46;158962:107;;;159060:9;;-1:-1:-1;;;;;159034:23:0;;;;;;:15;:23;;;;;;:35;;159060:9;159034:35;:::i;:::-;159027:42;158411:692;-1:-1:-1;;;;;158411:692:0:o;158962:107::-;-1:-1:-1;159089:6:0;;158411:692;-1:-1:-1;;;158411:692:0:o;151236:160::-;151312:10;151296:27;;;;:15;:27;;;;;;:37;-1:-1:-1;151296:37:0;151288:46;;;;;;151347:41;151369:10;151381:6;151347:21;:41::i;:::-;151236:160;:::o;153956:782::-;154253:16;;-1:-1:-1;;;;;154253:16:0;154239:10;:30;;:82;;-1:-1:-1;154304:17:0;;-1:-1:-1;;;;;154304:17:0;154290:10;:31;154239:82;:132;;;-1:-1:-1;154356:15:0;;-1:-1:-1;;;;;154356:15:0;154342:10;:29;154239:132;154217:225;;;;-1:-1:-1;;;154217:225:0;;;;;;;:::i;:::-;154463:7;;154453:18;;;;:9;:18;;;;;;;;:31;;;;;;;;:::i;:::-;-1:-1:-1;154511:7:0;;154497:22;;;;:13;:22;;;;;;;;:39;;;;;;;;:::i;:::-;-1:-1:-1;154565:7:0;;154549:24;;;;:15;:24;;;;;;;;:43;;;;;;;;:::i;:::-;-1:-1:-1;154622:7:0;;154605:25;;;;:16;:25;;;;;;;;:45;;;;;;;;:::i;:::-;-1:-1:-1;154680:7:0;;154663:25;;;;:16;:25;;;;;;;;:45;;;;;;;;:::i;:::-;-1:-1:-1;154721:7:0;:9;;;:7;:9;;;:::i;:::-;;;;;;153956:782;;;;;:::o;164749:603::-;164802:24;:22;:24::i;:::-;164837:21;164851:6;164837:13;:21::i;:::-;164869:38;164900:6;164869:30;:38::i;:::-;164918:16;164927:6;164918:8;:16::i;:::-;164945:24;164962:6;164945:16;:24::i;:::-;164986:13;;-1:-1:-1;;;;;164986:13:0;:35;164982:98;;165038:13;;;;;;;;;-1:-1:-1;;;;;165038:13:0;-1:-1:-1;;;;;165038:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;164982:98;165096:13;;-1:-1:-1;;;;;165096:13:0;:35;165092:98;;165148:13;;;;;;;;;-1:-1:-1;;;;;165148:13:0;-1:-1:-1;;;;;165148:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;165092:98;165206:11;;-1:-1:-1;;;;;165206:11:0;:33;165202:94;;165256:11;;;;;;;;;-1:-1:-1;;;;;165256:11:0;-1:-1:-1;;;;;165256:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;165202:94;165313:31;;-1:-1:-1;;;;;165313:31:0;;;165320:15;;165313:31;;;;;164749:603;:::o;176651:295::-;176782:4;26114:10;176840:38;176856:4;26114:10;176871:6;176840:15;:38::i;:::-;176889:27;176899:4;176905:2;176909:6;176889:9;:27::i;:::-;-1:-1:-1;176934:4:0;;176651:295;-1:-1:-1;;;;176651:295:0:o;165924:236::-;165985:24;:22;:24::i;:::-;166020:21;166034:6;166020:13;:21::i;:::-;166052:38;166083:6;166052:30;:38::i;:::-;166101:16;166110:6;166101:8;:16::i;:::-;166128:24;166145:6;166128:16;:24::i;176954:265::-;26114:10;177067:4;177148:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;177148:27:0;;;;;;;;;;177067:4;;26114:10;177123:66;;26114:10;;177148:27;;:40;;177178:10;;177148:40;:::i;:::-;177123:8;:66::i;155458:691::-;155712:16;;-1:-1:-1;;;;;155712:16:0;155698:10;:30;;:82;;-1:-1:-1;155763:17:0;;-1:-1:-1;;;;;155763:17:0;155749:10;:31;155698:82;:132;;;-1:-1:-1;155815:15:0;;-1:-1:-1;;;;;155815:15:0;155801:10;:29;155698:132;155676:225;;;;-1:-1:-1;;;155676:225:0;;;;;;;:::i;:::-;155943:14;155914:13;:26;155938:1;155928:7;;:11;;;;:::i;:::-;155914:26;;;;;;;;;;;:43;;;;;;;;;;;;:::i;:::-;;156001:16;155970:15;:28;155996:1;155986:7;;:11;;;;:::i;:::-;155970:28;;;;;;;;;;;:47;;;;;;;;;;;;:::i;:::-;;156062:17;156030:16;:29;156057:1;156047:7;;:11;;;;:::i;:::-;156030:29;;;;;;;;;;;:49;;;;;;;;;;;;:::i;:::-;;156124:17;156092:16;:29;156119:1;156109:7;;:11;;;;:::i;163600:240::-;163663:7;163687:13;;163704:2;163687:19;163683:81;;;163730:4;;:22;;-1:-1:-1;;;163730:22:0;;-1:-1:-1;;;;;163730:4:0;;;;:14;;:22;;163745:6;;163730:22;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;163683:81::-;163818:13;;163813:18;;:2;:18;:::i;:::-;163806:26;;:2;:26;:::i;:::-;163781:4;;:22;;-1:-1:-1;;;163781:22:0;;-1:-1:-1;;;;;163781:4:0;;;;:14;;:22;;163796:6;;163781:22;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:51;;;;:::i;160449:128::-;-1:-1:-1;;;;;160537:21:0;;160513:4;160537:21;;;:13;:21;;;;;160559:5;;160513:4;;160559:9;;160567:1;;160559:9;:::i;:::-;160537:32;;;;;;;;;;;-1:-1:-1;160537:32:0;;;;;160449:128;-1:-1:-1;;160449:128:0:o;152615:1317::-;152655:22;152666:10;152655;:22::i;:::-;152743:9;;152728:10;152712:27;;;;:15;:27;;;;;;152697:12;;:42;;152712:27;152697:42;:::i;:::-;152696:56;152688:65;;;;;;152786:27;152802:10;152786:15;:27::i;:::-;152764:114;;;;-1:-1:-1;;;152764:114:0;;13343:2:1;152764:114:0;;;13325:21:1;13382:2;13362:18;;;13355:30;13421:34;13401:18;;;13394:62;-1:-1:-1;;;13472:18:1;;;13465:35;13517:19;;152764:114:0;13141:401:1;152764:114:0;152972:5;;152958:10;152939:30;;;;:18;:30;;;;;;:38;152917:133;;;;-1:-1:-1;;;152917:133:0;;15737:2:1;152917:133:0;;;15719:21:1;15776:2;15756:18;;;15749:30;15815:34;15795:18;;;15788:62;-1:-1:-1;;;15866:18:1;;;15859:43;15919:19;;152917:133:0;15535:409:1;152917:133:0;153188:10;153146:27;;;;:15;:27;;;;;;;;153092:117;;153116:15;;153092:117;;;;16861:25:1;;16849:2;16834:18;;16715:177;153092:117:0;;;;;;;;153228:10;153240:27;;;;:15;:27;;;;;;153222:46;;153228:10;153222:5;:46::i;:::-;153302:10;153316:5;153281:32;;;:20;:32;;;;;;;;:40;;-1:-1:-1;;153281:40:0;;;153339:14;:26;;;;;;153281:40;153339:26;153334:180;;153410:14;153439:24;;;;;;;153382:25;153439:24;;;;;;;-1:-1:-1;;;;;;153439:24:0;153452:10;153439:24;;;153478;;;;153410:14;;;;153478:24;:::i;:::-;;153367:147;153334:180;153541:10;153526:26;;;;:14;:26;;;;;;;;:33;;-1:-1:-1;;153526:33:0;153555:4;153526:33;;;153572:17;:29;;;;;:31;;;;;;:::i;:::-;;;;-1:-1:-1;;153614:20:0;:22;;;:20;:22;;;:::i;:::-;;;;-1:-1:-1;;153675:10:0;153649:37;;;;:25;:37;;;;;:39;;;;;;:::i;:::-;;;;-1:-1:-1;;153744:10:0;153728:27;;;;:15;:27;;;;;;153701:23;:54;;153728:27;;153701:23;;:54;;153728:27;;153701:54;:::i;:::-;;;;-1:-1:-1;;153819:10:0;153803:27;;;;:15;:27;;;;;;;;;153766:21;:33;;;;;:64;;153803:27;;153766:33;;:64;;153803:27;;153766:64;:::i;:::-;;;;-1:-1:-1;;153872:10:0;153886:1;153843:40;;;:28;:40;;;;;:44;153900:24;:22;:24::i;:::-;152615:1317::o;161063:580::-;161240:13;;161129:4;;;;;;;;-1:-1:-1;;;;;161240:13:0;:35;161236:112;;161301:13;;:31;;-1:-1:-1;;;161301:31:0;;161335:1;;-1:-1:-1;;;;;161301:13:0;;:23;;:31;;161325:6;;161301:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:35;161292:44;;161236:112;161364:13;;-1:-1:-1;;;;;161364:13:0;:35;161360:112;;161425:13;;:31;;-1:-1:-1;;;161425:31:0;;161459:1;;-1:-1:-1;;;;;161425:13:0;;:23;;:31;;161449:6;;161425:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:35;161416:44;;161360:112;161488:11;;-1:-1:-1;;;;;161488:11:0;:33;161484:106;;161545:11;;:29;;-1:-1:-1;;;161545:29:0;;161577:1;;-1:-1:-1;;;;;161545:11:0;;:21;;:29;;161567:6;;161545:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:33;161538:40;;161484:106;161610:6;:16;;;;161620:6;161610:16;:24;;;-1:-1:-1;161630:4:0;161602:33;-1:-1:-1;;;;161063:580:0:o;166402:451::-;166514:6;166489:21;;166471:15;:39;;;;:::i;:::-;166470:50;166448:129;;;;-1:-1:-1;;;166448:129:0;;13749:2:1;166448:129:0;;;13731:21:1;13788:2;13768:18;;;13761:30;13827:31;13807:18;;;13800:59;13876:18;;166448:129:0;13547:353:1;166448:129:0;166624:15;;-1:-1:-1;;;;;166624:15:0;166610:10;:29;166588:125;;;;-1:-1:-1;;;166588:125:0;;12928:2:1;166588:125:0;;;12910:21:1;12967:2;12947:18;;;12940:30;13006:34;12986:18;;;12979:62;-1:-1:-1;;;13057:18:1;;;13050:44;13111:19;;166588:125:0;12726:410:1;166588:125:0;166748:4;;:48;;-1:-1:-1;;;166748:48:0;;-1:-1:-1;;;;;166748:4:0;;;;:13;;:48;;166762:10;;166774:21;;166748:48;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;166726:119;;;;-1:-1:-1;;;166726:119:0;;12578:2:1;166726:119:0;;;12560:21:1;12617:2;12597:18;;;12590:30;-1:-1:-1;;;12636:18:1;;;12629:51;12697:18;;166726:119:0;12376:345:1;146245:51:0;;;;;;;;;;;;;;;;:::i;162450:331::-;162568:23;;162560:5;;162511:4;;162539;;162560:31;162556:49;;;-1:-1:-1;162600:5:0;;162450:331;-1:-1:-1;;162450:331:0:o;162556:49::-;162623:9;162643:23;;162635:5;;:31;;;;:::i;:::-;162623:43;;162618:133;162672:5;;162668:1;:9;162618:133;;;162705:3;:34;;;;-1:-1:-1;;;;;;162712:24:0;;;;;;:16;:24;;;;;;;;:27;;;;;;;;;;;162705:34;162699:40;-1:-1:-1;162679:3:0;;;;:::i;:::-;;;;162618:133;;;-1:-1:-1;162770:3:0;162450:331;-1:-1:-1;;162450:331:0:o;160298:143::-;160384:7;160429:4;160412:13;:6;160421:4;160412:13;:::i;:::-;160411:22;;;;:::i;151404:1203::-;151475:15;;151439:20;151462:29;;;:12;:29;;;;;;;;;151526:19;:36;;;;;;151598:10;151584:25;;:13;:25;;;;;:42;;;;;;;;;;;151462:29;;151526:36;151584:42;;151583:43;151575:52;;;;;;151677:10;151667:21;;;;:9;:21;;;;;;151648:15;;:40;;151640:49;;;;;;151708:22;151719:10;151708;:22::i;:::-;151700:31;;;;;;151744:25;151772:31;151792:10;151772:19;:31::i;:::-;151744:59;;151844:1;151824:17;:21;151816:30;;;;;;151884:33;151900:17;151884:13;:33;:::i;:::-;151867:12;:51;;151859:60;;;;;;151992:9;;151972:29;;:17;:29;:::i;:::-;151956:10;151940:27;;;;:15;:27;;;;;;:62;;151932:71;;;;;;152024:4;;:44;;-1:-1:-1;;;152024:44:0;;-1:-1:-1;;;;;152024:4:0;;;;:13;;:44;;152038:10;;152050:17;;152024:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;152016:53;;;;;;152082:64;152104:10;152136:9;;152116:17;:29;;;;:::i;:::-;152082:21;:64::i;:::-;152179:15;;152159:36;;;;:19;:36;;;;;:57;;152199:17;;152159:36;:57;;152199:17;;152159:57;:::i;:::-;;;;-1:-1:-1;;152241:10:0;152227:25;;;;:13;:25;;;;;;;;152253:15;;152227:42;;;;;;;:49;;-1:-1:-1;;152227:49:0;152272:4;152227:49;;;152287:25;:46;;152316:17;;152227:25;152287:46;;152316:17;;152287:46;:::i;:::-;;;;-1:-1:-1;;152361:10:0;152344:28;;;;:16;:28;;;;;:49;;152376:17;;152344:28;:49;;152376:17;;152344:49;:::i;:::-;;;;-1:-1:-1;;152433:10:0;152404:40;;;;:28;:40;;;;;:61;;152448:17;;152404:40;:61;;152448:17;;152404:61;:::i;:::-;;;;-1:-1:-1;152478:22:0;;-1:-1:-1;152489:10:0;152478;:22::i;:::-;152542:57;;16861:25:1;;;152588:10:0;;152552:15;;152542:57;;16849:2:1;16834:18;152542:57:0;;;;;;;;151428:1179;;;151404:1203::o;167922:243::-;168026:9;;-1:-1:-1;;;;;168026:9:0;168012:10;:23;167990:116;;;;-1:-1:-1;;;167990:116:0;;;;;;;:::i;:::-;168119:13;:38;;-1:-1:-1;;;;;;168119:38:0;-1:-1:-1;;;;;168119:38:0;;;;;;;;;;167922:243::o;146188:50::-;;;;;;;;;;;;;;;;:::i;167662:252::-;167759:15;;-1:-1:-1;;;;;167759:15:0;167745:10;:29;;:56;;-1:-1:-1;167792:9:0;;-1:-1:-1;;;;;167792:9:0;167778:10;:23;167745:56;167723:150;;;;-1:-1:-1;;;167723:150:0;;;;;;;:::i;:::-;167884:9;:22;167662:252::o;173562:786::-;173709:9;;-1:-1:-1;;;;;173709:9:0;173687:10;:32;173679:41;;;;;;173731:65;173773:6;173781:14;173731:41;:65::i;:::-;173807:18;173818:6;173807:10;:18::i;:::-;173840;173851:6;173840:10;:18::i;:::-;173836:80;;;173875:16;:29;;-1:-1:-1;;;;;;173875:29:0;173894:10;173875:29;;;173836:80;173953:18;173970:1;173953:14;:18;:::i;:::-;173939:8;;173926:22;;;;:12;:22;;;;;:46;;:22;;;:46;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;173983:20:0;;;;;;:12;:20;;;;;:38;;174007:14;;173983:20;:38;;174007:14;;173983:38;:::i;:::-;;;;-1:-1:-1;;;;;;;174032:22:0;;;;;;:14;:22;;;;;;;;174055:5;;174032:29;;;;;;;:47;;174065:14;;174032:22;:47;;174065:14;;174032:47;:::i;:::-;;;;-1:-1:-1;;174110:8:0;;-1:-1:-1;;;;;174090:17:0;;;;;;:9;:17;;;;;:28;;;;174129:14;:16;;;;;;:::i;:::-;;;;-1:-1:-1;174185:18:0;;-1:-1:-1;174202:1:0;174185:14;:18;:::i;:::-;174158:22;;:46;;;;;;;:::i;:::-;;;;-1:-1:-1;;174241:15:0;174217:21;:39;174312:5;;174297:43;;-1:-1:-1;;;;;174297:43:0;;;-1:-1:-1;;;;;;;;;;;174297:43:0;;;174312:5;174319:14;;174335:4;;174297:43;:::i;:::-;;;;;;;;173562:786;;:::o;164096:645::-;164190:8;;164170:29;;;;:19;:29;;;;;;164152:15;:47;164148:586;;;164399:15;;164379:36;;;;:19;:36;;;;;;;;;164330:12;:29;;;;;;;:85;;164379:36;164330:85;:::i;:::-;164316:8;;164303:22;;;;:12;:22;;;;;:113;;:22;;;:113;;;;;:::i;:::-;;;;-1:-1:-1;;164433:5:0;:7;;;:5;:7;;;:::i;:::-;;;;-1:-1:-1;;164489:5:0;;164460:35;;164472:15;;164460:35;;;;;164530:8;;;164512:15;:26;;;164530:8;-1:-1:-1;164553:10:0;164530:8;164553:10;:::i;:::-;;;;-1:-1:-1;;164702:20:0;;164667:55;;:15;:55;:::i;:::-;164638:8;;164618:29;;;;:19;:29;;;;;:104;164096:645::o;161651:508::-;161739:15;;161708:4;;-1:-1:-1;;;;;161729:25:0;;;161739:15;;161729:25;;:48;;-1:-1:-1;161768:9:0;;-1:-1:-1;;;;;161758:19:0;;;161768:9;;161758:19;161729:48;161725:65;;;-1:-1:-1;161786:4:0;;161651:508;-1:-1:-1;161651:508:0:o;161725:65::-;-1:-1:-1;;;;;161811:24:0;;;;;;:16;:24;;;;;161836:5;;161811:24;;;161836:9;;161844:1;;161836:9;:::i;:::-;161811:35;;;;;;;;;;;-1:-1:-1;161811:35:0;;;;:84;;;;-1:-1:-1;;;;;;161863:21:0;;;;;;:13;:21;;;;;161885:5;;161863:21;;;161885:9;;161893:1;;161885:9;:::i;:::-;161863:32;;;;;;;;;;;-1:-1:-1;161863:32:0;;;;161811:84;:133;;;;-1:-1:-1;;;;;;161912:21:0;;;;;;:13;:21;;;;;161934:5;;161912:21;;;161934:9;;161942:1;;161934:9;:::i;:::-;161912:32;;;;;;;;;;;-1:-1:-1;161912:32:0;;;;161811:133;:183;;;;-1:-1:-1;;;;;;161961:22:0;;;;;;:14;:22;;;;;161984:5;;161961:22;;;161984:9;;161992:1;;161984:9;:::i;:::-;161961:33;;;;;;;;;;;-1:-1:-1;161961:33:0;;;;161811:183;:231;;;;-1:-1:-1;;;;;;162011:20:0;;;;;;:12;:20;;;;;162032:5;;162011:20;;;162032:9;;162040:1;;162032:9;:::i;:::-;162011:31;;;;;;;;;;;-1:-1:-1;162011:31:0;;;;161811:231;:289;;;;-1:-1:-1;;;;;;162059:30:0;;;;;;:22;:30;;;;;162090:5;;162059:30;;;162090:9;;162098:1;;162090:9;:::i;:::-;162059:41;;;;;;;;;;;-1:-1:-1;162059:41:0;;;;161811:289;:339;;;;-1:-1:-1;;;;;;162117:22:0;;;;;;:14;:22;;;;;162140:5;;162117:22;;;162140:9;;162148:1;;162140:9;:::i;168667:137::-;168754:9;;-1:-1:-1;;;;;168754:9:0;168740:10;:23;168732:32;;;;;;168775:9;:21;;-1:-1:-1;;;;;;168775:21:0;-1:-1:-1;;;;;168775:21:0;;;;;;;;;;168667:137::o;147318:28::-;;;;;;;:::i;159409:147::-;-1:-1:-1;;;;;159524:23:0;;159472:4;159524:23;;;:15;:23;;;;;;159497:24;159540:6;159497:16;:24::i;:::-;:50;;159409:147;-1:-1:-1;;159409:147:0:o;149285:629::-;149389:13;;:32;;-1:-1:-1;;;149389:32:0;;149351:7;;;;-1:-1:-1;;;;;149389:13:0;;;;:24;;:32;;149414:6;;149389:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;149371:50;;149432:14;149449:13;;;;;;;;;-1:-1:-1;;;;;149449:13:0;-1:-1:-1;;;;;149449:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;149573:15;;:33;;-1:-1:-1;;;149573:33:0;;149432:38;;-1:-1:-1;149481:9:0;;;;-1:-1:-1;;;;;149573:15:0;;:25;;:33;;149599:6;;149573:33;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;149526:13;;:31;;-1:-1:-1;;;149526:31:0;;-1:-1:-1;;;;;149526:13:0;;;;:23;;:31;;149550:6;;149526:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:80;;;;:::i;:::-;149501:105;;149619:138;149627:10;149626:11;:21;;;;;149645:2;149641:1;:6;149626:21;149619:138;;;149677:13;;-1:-1:-1;;;;;149677:13:0;:30;149708:6;149716:10;149725:1;149716:6;:10;:::i;:::-;149677:50;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;149664:63;-1:-1:-1;149742:3:0;;;;:::i;:::-;;;;149619:138;;;149771:10;149767:106;;;149823:13;;:37;;-1:-1:-1;;;149823:37:0;;-1:-1:-1;;;;;149823:13:0;;;;:29;;:37;;149853:6;;149823:37;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;149806:54;;:14;:54;:::i;:::-;149798:63;149285:629;-1:-1:-1;;;;;;149285:629:0:o;145961:47::-;;;;;;;;;;;;;;;;:::i;149922:1306::-;149985:25;;149967:15;:43;149959:52;;;;;;150041:10;150031:21;;;;:9;:21;;;;;;;;150030:22;150022:31;;;;;;150134:13;;:65;;-1:-1:-1;;;150134:65:0;;-1:-1:-1;;;;;150134:13:0;;;;:29;;:65;;150178:10;;150134:65;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;150119:10;150103:27;;;;:15;:27;;;;;:96;;:27;;;:96;;;;;:::i;:::-;;;;-1:-1:-1;;150250:10:0;150234:27;;;;:15;:27;;;;;;150210:20;:51;;150234:27;;150210:20;;:51;;150234:27;;150210:51;:::i;:::-;;;;-1:-1:-1;;150300:13:0;;:38;;-1:-1:-1;;;150300:38:0;;-1:-1:-1;;;;;150300:13:0;;;;:26;;:38;;150327:10;;150300:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;150285:10;150272:24;;;;:12;:24;;;;;:66;;:24;;;:66;;;;;:::i;:::-;;;;-1:-1:-1;;150412:13:0;;:41;;-1:-1:-1;;;150412:41:0;;-1:-1:-1;;;;;150412:13:0;;;;:29;;:41;;150442:10;;150412:41;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;150412:41:0;;;;;;;;;;;;:::i;:::-;150398:10;150382:27;;;;:15;:27;;;;;;;;:71;;;;:27;;:71;;;;;;:::i;:::-;-1:-1:-1;150495:13:0;;:66;;-1:-1:-1;;;150495:66:0;;-1:-1:-1;;;;;150495:13:0;;;;:30;;:66;;150540:10;;150495:66;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;150495:66:0;;;;;;;;;;;;:::i;:::-;150481:10;150464:28;;;;:16;:28;;;;;;;;:97;;;;:28;;:97;;;;;;:::i;:::-;;150617:50;150623:10;150635:31;150655:10;150635:19;:31::i;:::-;150617:5;:50::i;:::-;150684:13;;:35;;-1:-1:-1;;;150684:35:0;;150722:1;;-1:-1:-1;;;;;150684:13:0;;:23;;:35;;150708:10;;150684:35;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:39;:64;;;;-1:-1:-1;150737:10:0;150728:20;;;;:8;:20;;;;;;;;150727:21;150684:64;150680:153;;;150765:12;:14;;;:12;:14;;;:::i;:::-;;;;-1:-1:-1;;150803:10:0;150794:20;;;;:8;:20;;;;;:27;;-1:-1:-1;;150794:27:0;150817:4;150794:27;;;150680:153;150896:22;150907:10;150896;:22::i;:::-;:50;;;;-1:-1:-1;150935:10:0;150923:23;;;;:11;:23;;;;;;;;150922:24;150896:50;150892:288;;;151007:10;150991:27;;;;:15;:27;;;;;;150963:24;:55;;150991:27;;150963:24;;:55;;150991:27;;150963:55;:::i;:::-;;;;-1:-1:-1;;151045:10:0;151033:23;;;;:11;:23;;;;;:30;;-1:-1:-1;;151033:30:0;151059:4;151033:30;;;151078:16;:18;;;;;;:::i;:::-;;;;-1:-1:-1;;151116:52:0;;151163:4;9277:41:1;;151151:10:0;;151134:15;;-1:-1:-1;;;;;;;;;;;151116:52:0;9265:2:1;9250:18;151116:52:0;;;;;;;150892:288;151202:10;151192:21;;;;151216:4;151192:21;;;;;;;;:28;;-1:-1:-1;;151192:28:0;;;;;;149922:1306::o;175527:104::-;175583:13;175616:7;175609:14;;;;;:::i;145906:48::-;;;;;;;;;;;;;;;;:::i;162167:146::-;162229:4;162254:18;162265:6;162254:10;:18::i;:::-;:50;;;;-1:-1:-1;;;;;;;162276:28:0;;;;;:20;:28;;;;;;;;;162167:146::o;160142:148::-;-1:-1:-1;;;;;160233:18:0;;160204:7;160233:18;;;:10;:18;;;;;160252:5;;160275:6;;160233:18;160204:7;;160252:9;;160260:1;;160252:9;:::i;:::-;160233:29;;;;;;;;;;;;160265:6;160233:38;;;;:::i;163848:240::-;163911:7;163935:13;;163952:2;163935:19;163931:81;;;163978:4;;:22;;-1:-1:-1;;;163978:22:0;;-1:-1:-1;;;;;163978:4:0;;;;:14;;:22;;163993:6;;163978:22;;;:::i;163931:81::-;164066:13;;164061:18;;:2;:18;:::i;:::-;164054:26;;:2;:26;:::i;:::-;164029:4;;:22;;-1:-1:-1;;;164029:22:0;;-1:-1:-1;;;;;164029:4:0;;;;:14;;:22;;164044:6;;164029:22;;;:::i;158153:250::-;158258:15;;-1:-1:-1;;;;;158258:15:0;158244:10;:29;158222:123;;;;-1:-1:-1;;;158222:123:0;;;;;;;:::i;:::-;158358:15;:37;;-1:-1:-1;;;;;;158358:37:0;-1:-1:-1;;;;;158358:37:0;;;;;;;;;;158153:250::o;160585:470::-;-1:-1:-1;;;;;160808:23:0;;160668:7;160808:23;;;:15;:23;;;;;;;;;160748:31;;;;;;160780:5;;160706:99;;160748:31;160668:7;;160780:9;;160788:1;;160780:9;:::i;:::-;160748:42;;;;;;;;;;;;160706:23;:99::i;:::-;:125;160688:339;;;-1:-1:-1;;;;;160992:23:0;;;;;;:15;:23;;;;;;;;;160928:31;;;;;;160960:5;;160992:23;;160882:107;;160960:9;;160968:1;;160960:9;:::i;160882:107::-;:133;;;;:::i;160688:339::-;-1:-1:-1;161046:1:0;;160585:470;-1:-1:-1;160585:470:0:o;177227:500::-;26114:10;177345:4;177428:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;177428:27:0;;;;;;;;;;177345:4;;26114:10;177488:35;;;;177466:122;;;;-1:-1:-1;;;177466:122:0;;16151:2:1;177466:122:0;;;16133:21:1;16190:2;16170:18;;;16163:30;16229:34;16209:18;;;16202:62;-1:-1:-1;;;16280:18:1;;;16273:35;16325:19;;177466:122:0;15949:401:1;177466:122:0;177624:60;177633:5;177640:7;177668:15;177649:16;:34;177624:8;:60::i;166861:263::-;166962:16;;-1:-1:-1;;;;;166962:16:0;166948:10;:30;;:63;;-1:-1:-1;166996:15:0;;-1:-1:-1;;;;;166996:15:0;166982:10;:29;166948:63;166926:156;;;;-1:-1:-1;;;166926:156:0;;;;;;;:::i;:::-;167095:21;;;;:14;;:21;;;;;:::i;:::-;;166861:263;:::o;156935:298::-;157013:15;;-1:-1:-1;;;;;157013:15:0;156999:10;:29;;:80;;-1:-1:-1;157063:16:0;;-1:-1:-1;;;;;157063:16:0;157049:10;:30;156999:80;:132;;;-1:-1:-1;157114:17:0;;-1:-1:-1;;;;;157114:17:0;157100:10;:31;156999:132;156977:225;;;;-1:-1:-1;;;156977:225:0;;;;;;;:::i;:::-;157221:4;;;-1:-1:-1;;157213:12:0;;157221:4;;;;157220:5;157213:12;;;156935:298::o;176007:218::-;176111:4;26114:10;176167:28;26114:10;176184:2;176188:6;176167:9;:28::i;157241:296::-;157352:15;;-1:-1:-1;;;;;157352:15:0;157338:10;:29;;:56;;-1:-1:-1;157385:9:0;;-1:-1:-1;;;;;157385:9:0;157371:10;:23;157338:56;157316:144;;;;-1:-1:-1;;;157316:144:0;;;;;;;:::i;:::-;157471:4;:22;;-1:-1:-1;;;;;;157471:22:0;-1:-1:-1;;;;;157471:22:0;;;;;;;;;;;157504:13;:25;157241:296::o;145527:50::-;;;;;;;;;;;;;;;;:::i;159564:147::-;-1:-1:-1;;;;;159679:23:0;;159627:4;159679:23;;;:15;:23;;;;;;159652:24;159695:6;159652:16;:24::i;145471:49::-;;;;;;;;;;;;;;;;:::i;146362:50::-;;;;;;;;;;;;;;;;:::i;146477:::-;;;;;;;;;;;;;;;;:::i;146419:51::-;;;;;;;;;;;;;;;;:::i;167132:256::-;167245:15;;-1:-1:-1;;;;;167245:15:0;167231:10;:29;167209:122;;;;-1:-1:-1;;;167209:122:0;;;;;;;:::i;:::-;167344:16;:36;;-1:-1:-1;;;;;;167344:36:0;-1:-1:-1;;;;;167344:36:0;;;;;;;;;;167132:256::o;157545:296::-;157656:15;;-1:-1:-1;;;;;157656:15:0;157642:10;:29;;:56;;-1:-1:-1;157689:9:0;;-1:-1:-1;;;;;157689:9:0;157675:10;:23;157642:56;157620:144;;;;-1:-1:-1;;;157620:144:0;;;;;;;:::i;:::-;157775:4;:22;;-1:-1:-1;;;;;;157775:22:0;-1:-1:-1;;;;;157775:22:0;;;;;;;;;;;157808:13;:25;157545:296::o;146073:50::-;;;;;;;;;;;;;;;;:::i;146130:49::-;;;;;;;;;;;;;;;;:::i;159111:141::-;159225:18;;-1:-1:-1;;;;;159198:23:0;;;159173:4;159198:23;;;:15;:23;;;;;;:45;;;159111:141::o;176233:176::-;-1:-1:-1;;;;;176374:18:0;;;176347:7;176374:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;176233:176::o;156157:770::-;156326:10;156423:25;;;:15;:25;;;;;;;;156405:45;;;;;;:::i;:::-;;;;;;;;;;;;;156395:56;;;;;;156368:7;156350:27;;;;;;;;:::i;:::-;;;;-1:-1:-1;;156350:27:0;;;;;;;;;156340:38;;156350:27;156340:38;;;;156463:11;156561:26;;;:16;:26;;;;;156340:111;;;-1:-1:-1;156463:11:0;;156543:46;;156561:26;;156543:46;;:::i;:::-;;;;;;;;;;;;;156533:57;;;;;;156506:7;156488:27;;;;;;;;:::i;:::-;;;;-1:-1:-1;;156488:27:0;;;;;;;;;156478:38;;156488:27;156478:38;;;;156602:10;156699:25;;;:15;:25;;;;;156478:112;;;-1:-1:-1;156602:10:0;;156681:45;;156699:25;;156681:45;;:::i;:::-;;;;;;;;;;;;;156671:56;;;;;;156644:7;156626:27;;;;;;;;:::i;:::-;;;;;;;;;;;;;156616:38;;;;;;:111;156602:126;;156776:5;:15;;;;;156785:6;156776:15;:24;;;;;156795:5;156776:24;156755:10;156741:25;;;;:13;:25;;;;;;;;156767:5;;156741:32;;;;;;;:59;;-1:-1:-1;;156741:59:0;;;;;;;;;;;156830:15;156818:66;156847:5;:15;;;;;156856:6;156847:15;:24;;;;;156866:5;156847:24;156818:66;;9302:14:1;;9295:22;9277:41;;9265:2;9250:18;156818:66:0;;;;;;;156897:22;156908:10;156897;:22::i;:::-;156315:612;;;156157:770;;;;:::o;163352:240::-;163415:7;163439:13;;163456:2;163439:19;163435:81;;;163482:4;;:22;;-1:-1:-1;;;163482:22:0;;-1:-1:-1;;;;;163482:4:0;;;;:14;;:22;;163497:6;;163482:22;;;:::i;163435:81::-;163570:13;;163565:18;;:2;:18;:::i;:::-;163558:26;;:2;:26;:::i;:::-;163533:4;;:22;;-1:-1:-1;;;163533:22:0;;-1:-1:-1;;;;;163533:4:0;;;;:14;;:22;;163548:6;;163533:22;;;:::i;168424:235::-;168524:9;;-1:-1:-1;;;;;168524:9:0;168510:10;:23;168488:116;;;;-1:-1:-1;;;168488:116:0;;;;;;;:::i;:::-;168617:11;:34;;-1:-1:-1;;;;;;168617:34:0;-1:-1:-1;;;;;168617:34:0;;;;;;;;;;168424:235::o;146017:49::-;;;;;;;;;;;;;;;;:::i;159719:415::-;-1:-1:-1;;;;;159827:23:0;;159806:4;159827:23;;;:15;:23;;;;;;159823:46;;-1:-1:-1;159864:5:0;;159719:415;-1:-1:-1;159719:415:0:o;159823:46::-;159894:1;159886:5;;:9;159882:221;;;-1:-1:-1;;;;;160029:31:0;;;;;;:23;:31;;;;;;160061:5;;159983:107;;160029:31;160061:9;;160069:1;;160061:9;:::i;159983:107::-;-1:-1:-1;;;;;159920:31:0;;;;;;:23;:31;;;;;;159952:5;;159920:31;;;159952:9;;159960:1;;159952:9;:::i;:::-;159920:42;;;;;;;;;;;;:170;;159912:179;;159719:415;;;:::o;159882:221::-;-1:-1:-1;160122:4:0;;159719:415;-1:-1:-1;159719:415:0:o;167396:258::-;167510:15;;-1:-1:-1;;;;;167510:15:0;167496:10;:29;167474:122;;;;-1:-1:-1;;;167474:122:0;;;;;;;:::i;:::-;167609:17;:37;;-1:-1:-1;;;;;;167609:37:0;-1:-1:-1;;;;;167609:37:0;;;;;;;;;;167396:258::o;166284:110::-;166368:10;166351:28;;;;:16;:28;;;;;;;;:35;;;;;;;;:::i;168173:243::-;168277:9;;-1:-1:-1;;;;;168277:9:0;168263:10;:23;168241:116;;;;-1:-1:-1;;;168241:116:0;;;;;;;:::i;:::-;168370:13;:38;;-1:-1:-1;;;;;;168370:38:0;-1:-1:-1;;;;;168370:38:0;;;;;;;;;;168173:243::o;166168:108::-;166250:10;166234:27;;;;:15;:27;;;;;;;;:34;;;;;;;;:::i;179827:380::-;-1:-1:-1;;;;;179963:19:0;;179955:68;;;;-1:-1:-1;;;179955:68:0;;15332:2:1;179955:68:0;;;15314:21:1;15371:2;15351:18;;;15344:30;15410:34;15390:18;;;15383:62;-1:-1:-1;;;15461:18:1;;;15454:34;15505:19;;179955:68:0;15130:400:1;179955:68:0;-1:-1:-1;;;;;180042:21:0;;180034:68;;;;-1:-1:-1;;;180034:68:0;;10997:2:1;180034:68:0;;;10979:21:1;11036:2;11016:18;;;11009:30;11075:34;11055:18;;;11048:62;-1:-1:-1;;;11126:18:1;;;11119:32;11168:19;;180034:68:0;10795:398:1;180034:68:0;-1:-1:-1;;;;;180115:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;180167:32;;16861:25:1;;;180167:32:0;;16834:18:1;180167:32:0;16715:177:1;174356:1003:0;-1:-1:-1;;;;;174460:19:0;;174438;174460;;;:11;:19;;;;;;;;174492:218;;;;-1:-1:-1;;;;;174560:23:0;;;;;;:15;:23;;;;;;174532:24;:51;;174560:23;;174532:24;;:51;;174560:23;;174532:51;:::i;:::-;;;;-1:-1:-1;;;;;;;174598:19:0;;174620:5;174598:19;;;:11;:19;;;;;:27;;-1:-1:-1;;174598:27:0;;;174640:23;:25;;;;;;:::i;:::-;;;;-1:-1:-1;;174680:16:0;:18;;;:16;:18;;;:::i;:::-;;;;;;174492:218;-1:-1:-1;;;;;174722:23:0;;;;;;:15;:23;;;;;:33;;174749:6;;174722:23;:33;;174749:6;;174722:33;:::i;:::-;;;;;;;;174790:6;174766:20;;:30;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;174813:23:0;;;;;;:15;:23;;;;;;174809:92;;174858:29;:31;;;:29;:31;;;:::i;:::-;;;;;;174809:92;174917:18;174928:6;174917:10;:18::i;:::-;174913:216;;;-1:-1:-1;;;;;174980:23:0;;;;;;:15;:23;;;;;;174952:24;:51;;174980:23;;174952:24;;:51;;174980:23;;174952:51;:::i;:::-;;;;-1:-1:-1;;;;;;;175018:19:0;;;;;;:11;:19;;;;;:26;;-1:-1:-1;;175018:26:0;175040:4;175018:26;;;175059:23;:25;;;;;;:::i;:::-;;;;-1:-1:-1;;175099:16:0;:18;;;:16;:18;;;:::i;:::-;;;;;;174913:216;-1:-1:-1;;;;;175163:19:0;;;;;;:11;:19;;;;;;;;175145:37;;;;;;175141:134;;175204:59;;175247:15;;9277:41:1;;-1:-1:-1;;;;;175204:59:0;;;175222:15;;-1:-1:-1;;;;;;;;;;;175204:59:0;9265:2:1;9250:18;175204:59:0;;;;;;;175141:134;175322:6;-1:-1:-1;;;;;175315:36:0;-1:-1:-1;;;;;;;;;;;175330:5:0;;175337:6;175345:5;175315:36;;;;;;;;:::i;:::-;;;;;;;;174427:932;174356:1003;;:::o;170549:617::-;-1:-1:-1;;;;;170674:22:0;;170607:26;170674:22;;;:14;:22;;;;;;;;;170636:14;:22;;;;;;:60;;170674:22;170636:60;:::i;:::-;170607:89;;170707:28;170778:24;170795:6;170778:16;:24::i;:::-;170738;170755:6;170738:16;:24::i;:::-;:64;;;;:::i;:::-;170707:95;;170842:18;170819:20;:41;170815:344;;;170877:11;170891:41;170912:20;170891:18;:41;:::i;:::-;-1:-1:-1;;;;;170959:23:0;;;;;;:15;:23;;;;;;170877:55;;-1:-1:-1;170953:29:0;;170949:199;;;-1:-1:-1;;;;;171033:23:0;;;;;;:15;:23;;;;;;171003:54;;171025:6;;171003:21;:54::i;:::-;170949:199;;;171098:34;171120:6;171128:3;171098:21;:34::i;:::-;170862:297;170815:344;170596:570;;170549:617;:::o;169813:728::-;-1:-1:-1;;;;;169910:19:0;;169888;169910;;;:11;:19;;;;;;;;169942:218;;;;-1:-1:-1;;;;;170010:23:0;;;;;;:15;:23;;;;;;169982:24;:51;;170010:23;;169982:24;;:51;;170010:23;;169982:51;:::i;:::-;;;;-1:-1:-1;;;;;;;170048:19:0;;170070:5;170048:19;;;:11;:19;;;;;:27;;-1:-1:-1;;170048:27:0;;;170090:23;:25;;;;;;:::i;:::-;;;;-1:-1:-1;;170130:16:0;:18;;;:16;:18;;;:::i;:::-;;;;;;169942:218;170176:18;170187:6;170176:10;:18::i;:::-;170172:216;;;-1:-1:-1;;;;;170239:23:0;;;;;;:15;:23;;;;;;170211:24;:51;;170239:23;;170211:24;;:51;;170239:23;;170211:51;:::i;:::-;;;;-1:-1:-1;;;;;;;170277:19:0;;;;;;:11;:19;;;;;:26;;-1:-1:-1;;170277:26:0;170299:4;170277:26;;;170318:23;:25;;;;;;:::i;:::-;;;;-1:-1:-1;;170358:16:0;:18;;;:16;:18;;;:::i;:::-;;;;;;170172:216;-1:-1:-1;;;;;170422:19:0;;;;;;:11;:19;;;;;;;;170404:37;;;;;;170400:134;;170463:59;;170506:15;;9277:41:1;;-1:-1:-1;;;;;170463:59:0;;;170481:15;;-1:-1:-1;;;;;;;;;;;170463:59:0;9265:2:1;9250:18;170463:59:0;;;;;;;169877:664;169813:728;:::o;171807:1655::-;-1:-1:-1;;;;;171873:20:0;;;;;;:12;:20;;;;;;171864:5;;:29;171860:1595;;171933:5;;:9;;171941:1;171933:9;:::i;:::-;-1:-1:-1;;;;;171910:20:0;;;;;;:12;:20;;;;;:32;171984:24;171923:6;171984:16;:24::i;:::-;-1:-1:-1;;;;;171959:22:0;;;;;;:14;:22;;;;;:49;172048:24;171974:6;172048:16;:24::i;:::-;-1:-1:-1;;;;;172023:22:0;;;;;;:14;:22;;;;;;;;:49;;;172117:14;:22;;;;;;172089:10;:18;;;;;172108:5;;;172089:25;;;;;;;;:50;;;;172182:22;;;;;172154:10;:18;;;;;172173:5;;172154:25;;;;;;;:50;172300:10;172266:59;;:15;:59;;;;;;172221:31;;;;;;;;;172253:5;;172266:59;;172221:31;172253:9;;172261:1;;172253:9;:::i;:::-;172221:42;;;;;;;;;;;-1:-1:-1;172221:42:0;:104;172378:27;172398:6;172378:19;:27::i;:::-;-1:-1:-1;;;;;172340:24:0;;;;;;:16;:24;;;;;172365:5;;172340:24;;;172365:9;;172373:1;;172365:9;:::i;:::-;172340:35;;;;;;;;;;;-1:-1:-1;172340:35:0;:65;;-1:-1:-1;;172340:65:0;;;;;;;;;;172456:25;172474:6;172456:17;:25::i;:::-;-1:-1:-1;;;;;172420:22:0;;;;;;:14;:22;;;;;172443:5;;172420:22;;;172443:9;;172451:1;;172443:9;:::i;:::-;172420:33;;;;;;;;;;;-1:-1:-1;172420:33:0;:61;;-1:-1:-1;;172420:61:0;;;;;;;;;;172531:24;172548:6;172531:16;:24::i;:::-;-1:-1:-1;;;;;172496:21:0;;;;;;:13;:21;;;;;172518:5;;172496:21;;;172518:9;;172526:1;;172518:9;:::i;:::-;172496:32;;;;;;;;;;;-1:-1:-1;172496:32:0;:59;;-1:-1:-1;;172496:59:0;;;;;;;;;;172605:24;172622:6;172605:16;:24::i;:::-;-1:-1:-1;;;;;172570:21:0;;;;;;:13;:21;;;;;172592:5;;172570:21;;;172592:9;;172600:1;;172592:9;:::i;:::-;172570:32;;;;;;;;;;;-1:-1:-1;172570:32:0;:59;;-1:-1:-1;;172570:59:0;;;;;;;;;;172678:23;172694:6;172678:15;:23::i;:::-;-1:-1:-1;;;;;172644:20:0;;;;;;:12;:20;;;;;172665:5;;172644:20;;;172665:9;;172673:1;;172665:9;:::i;:::-;172644:31;;;;;;;;;;;-1:-1:-1;172644:31:0;:57;;-1:-1:-1;;172644:57:0;;;;;;;;;;172792:32;172817:6;172792:24;:32::i;:::-;-1:-1:-1;;;;;172716:30:0;;;;;;:22;:30;;;;;172765:5;;172716:30;;;172765:9;;172773:1;;172765:9;:::i;:::-;172716:73;;;;;;;;;;;-1:-1:-1;172716:73:0;:108;;-1:-1:-1;;172716:108:0;;;;;;;;;;172875:25;172893:6;172875:17;:25::i;:::-;-1:-1:-1;;;;;172839:22:0;;;;;;:14;:22;;;;;172862:5;;172839:22;;;172862:9;;172870:1;;172862:9;:::i;:::-;172839:33;;;;;;;;;;;-1:-1:-1;172839:33:0;:61;;-1:-1:-1;;172839:61:0;;;;;;;;;;172955:18;172966:6;172955:10;:18::i;:::-;-1:-1:-1;;;;;172917:24:0;;;;;;:16;:24;;;;;172942:5;;172917:24;;;172942:9;;172950:1;;172942:9;:::i;:::-;172917:35;;;;;;;;;;;;:56;;;;;;;;;;;;;;;;;;173024:6;-1:-1:-1;;;;;172995:448:0;;173057:1;173049:5;;:9;;;;:::i;:::-;-1:-1:-1;;;;;173077:24:0;;;;;;:16;:24;;;;;173102:5;;173077:24;;;173102:9;;173110:1;;173102:9;:::i;:::-;173077:35;;;;;;;;;;;;;;-1:-1:-1;173077:35:0;;;;-1:-1:-1;;;;;173131:21:0;;;;:13;:21;;;;;;173153:5;;173077:35;;;;;173131:21;;-1:-1:-1;173153:9:0;;173077:35;;173153:9;:::i;:::-;173131:32;;;;;;;;;;;;;;-1:-1:-1;173131:32:0;;;;-1:-1:-1;;;;;173182:21:0;;;;:13;:21;;;;;;173204:5;;173131:32;;;;;173182:21;;-1:-1:-1;173204:9:0;;173131:32;;173204:9;:::i;:::-;173182:32;;;;;;;;;;;;;;-1:-1:-1;173182:32:0;;;;-1:-1:-1;;;;;173233:22:0;;;;:14;:22;;;;;;173256:5;;173182:32;;;;;173233:22;;-1:-1:-1;173256:9:0;;173182:32;;173256:9;:::i;:::-;173233:33;;;;;;;;;;;;;;-1:-1:-1;173233:33:0;;;;-1:-1:-1;;;;;173285:20:0;;;;:12;:20;;;;;;173306:5;;173233:33;;;;;173285:20;;-1:-1:-1;173306:9:0;;173233:33;;173306:9;:::i;:::-;173285:31;;;;;;;;;;;;;;-1:-1:-1;173285:31:0;;;;-1:-1:-1;;;;;173335:30:0;;;;:22;:30;;;;;;173366:5;;173285:31;;;;;173335:30;;-1:-1:-1;173366:9:0;;173285:31;;173366:9;:::i;:::-;173335:41;;;;;;;;;;;;;;-1:-1:-1;173335:41:0;;;;-1:-1:-1;;;;;173395:22:0;;;;:14;:22;;;;;;173418:5;;173335:41;;;;;173395:22;;-1:-1:-1;173418:9:0;;173335:41;;173418:9;:::i;:::-;173395:33;;;;;;;;;;;;;;-1:-1:-1;173395:33:0;;172995:448;;17198:25:1;;;17266:14;;17259:22;17239:18;;;17232:50;;;;17325:14;;17318:22;17298:18;;;17291:50;;;;17384:14;;17377:22;17372:2;17357:18;;17350:50;17444:14;17437:22;17431:3;17416:19;;17409:51;17504:14;17497:22;17491:3;17476:19;;17469:51;17564:14;17557:22;17551:3;17536:19;;17529:51;173395:33:0;;17624:14:1;17617:22;17611:3;17596:19;;17589:51;17185:3;17170:19;172995:448:0;;;;;;;171807:1655;:::o;171174:585::-;171240:18;171251:6;171240:10;:18::i;:::-;171239:19;:51;;;;-1:-1:-1;;;;;;171262:28:0;;;;;;:20;:28;;;;;;;;171239:51;171235:216;;;-1:-1:-1;;;;;171307:28:0;;171338:5;171307:28;;;:20;:28;;;;;;;;:36;;-1:-1:-1;;171307:36:0;;;171363:55;9277:41:1;;;171387:15:0;;-1:-1:-1;;;;;;;;;;;171363:55:0;9250:18:1;171363:55:0;;;;;;;;171174:585;:::o;171235:216::-;171467:18;171478:6;171467:10;:18::i;:::-;:51;;;;-1:-1:-1;;;;;;171490:28:0;;;;;;:20;:28;;;;;;;;171489:29;171467:51;171463:289;;;-1:-1:-1;;;;;171535:28:0;;;;;;:20;:28;;;;;:35;;-1:-1:-1;;171535:35:0;171566:4;171535:35;;;171622:23;;171614:5;;:31;;171622:23;171614:31;:::i;:::-;-1:-1:-1;;;;;171585:26:0;;;;;;:18;:26;;;;;;;;;:60;;;;171665:54;171714:4;9277:41:1;;171585:26:0;;171689:15;;-1:-1:-1;;;;;;;;;;;171665:54:0;9250:18:1;171665:54:0;9137:187:1;180215:502:0;180350:24;180377:25;180387:5;180394:7;180377:9;:25::i;:::-;180350:52;;-1:-1:-1;;180417:16:0;:37;180413:297;;180517:6;180497:16;:26;;180471:117;;;;-1:-1:-1;;;180471:117:0;;11400:2:1;180471:117:0;;;11382:21:1;11439:2;11419:18;;;11412:30;11478:31;11458:18;;;11451:59;11527:18;;180471:117:0;11198:353:1;180471:117:0;180632:51;180641:5;180648:7;180676:6;180657:16;:25;180632:8;:51::i;177735:1078::-;-1:-1:-1;;;;;177866:18:0;;177858:68;;;;-1:-1:-1;;;177858:68:0;;14926:2:1;177858:68:0;;;14908:21:1;14965:2;14945:18;;;14938:30;15004:34;14984:18;;;14977:62;-1:-1:-1;;;15055:18:1;;;15048:35;15100:19;;177858:68:0;14724:401:1;177858:68:0;-1:-1:-1;;;;;177945:16:0;;177937:64;;;;-1:-1:-1;;;177937:64:0;;10593:2:1;177937:64:0;;;10575:21:1;10632:2;10612:18;;;10605:30;10671:34;10651:18;;;10644:62;-1:-1:-1;;;10722:18:1;;;10715:33;10765:19;;177937:64:0;10391:399:1;177937:64:0;-1:-1:-1;;;;;178070:12:0;;;;;;:8;:12;;;;;;;;178065:94;;178099:12;:14;;;:12;:14;;;:::i;:::-;;;;-1:-1:-1;;;;;;;178128:12:0;;;;;;:8;:12;;;;;:19;;-1:-1:-1;;178128:19:0;178143:4;178128:19;;;178065:94;-1:-1:-1;;;;;178193:15:0;;178171:19;178193:15;;;:9;:15;;;;;;178241:21;;;;178219:109;;;;-1:-1:-1;;;178219:109:0;;12171:2:1;178219:109:0;;;12153:21:1;12210:2;12190:18;;;12183:30;12249:34;12229:18;;;12222:62;-1:-1:-1;;;12300:18:1;;;12293:36;12346:19;;178219:109:0;11969:402:1;178219:109:0;-1:-1:-1;;;;;178364:15:0;;;;;;;:9;:15;;;;;;178382:20;;;178364:38;;178424:13;;;;;;;;:23;;178396:6;;178364:15;178424:23;;178396:6;;178424:23;:::i;:::-;;;;-1:-1:-1;;;;;;;178464:15:0;;;;;;:9;:15;;;;;;178460:104;;178501:12;:14;;;:12;:14;;;:::i;:::-;;;;-1:-1:-1;;;;;;;178530:14:0;;178547:5;178530:14;;;:8;:14;;;;;:22;;-1:-1:-1;;178530:22:0;;;178460:104;178576:16;178587:4;178576:10;:16::i;:::-;178603:14;178614:2;178603:10;:14::i;:::-;178630:36;178661:4;178630:30;:36::i;:::-;178677:34;178708:2;178677:30;:34::i;:::-;178744:2;-1:-1:-1;;;;;178729:26:0;178738:4;-1:-1:-1;;;;;178729:26:0;-1:-1:-1;;;;;;;;;;;178748:6:0;178729:26;;;;16861:25:1;;16849:2;16834:18;;16715:177;178729:26:0;;;;;;;;178768:37;170549:617;165360:556;165415:24;:22;:24::i;:::-;165450:21;165464:6;165450:13;:21::i;:::-;165482:38;165513:6;165482:30;:38::i;:::-;165531:16;165540:6;165531:8;:16::i;:::-;165558:24;165575:6;165558:16;:24::i;:::-;165599:13;;-1:-1:-1;;;;;165599:13:0;:35;165595:98;;165651:13;;;;;;;;;-1:-1:-1;;;;;165651:13:0;-1:-1:-1;;;;;165651:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;165595:98;165709:13;;-1:-1:-1;;;;;165709:13:0;:35;165705:98;;165761:13;;;;;;;;;-1:-1:-1;;;;;165761:13:0;-1:-1:-1;;;;;165761:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;165705:98;165819:11;;-1:-1:-1;;;;;165819:11:0;:33;165815:94;;165869:11;;;;;;;;;-1:-1:-1;;;;;165869:11:0;-1:-1:-1;;;;;165869:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;178821:399;-1:-1:-1;;;;;178905:21:0;;178897:65;;;;-1:-1:-1;;;178897:65:0;;16557:2:1;178897:65:0;;;16539:21:1;16596:2;16576:18;;;16569:30;16635:33;16615:18;;;16608:61;16686:18;;178897:65:0;16355:355:1;178897:65:0;179053:6;179037:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;179070:18:0;;;;;;:9;:18;;;;;:28;;179092:6;;179070:18;:28;;179092:6;;179070:28;:::i;:::-;;;;-1:-1:-1;;179114:37:0;;16861:25:1;;;-1:-1:-1;;;;;179114:37:0;;;179131:1;;-1:-1:-1;;;;;;;;;;;179114:37:0;16849:2:1;16834:18;179114:37:0;;;;;;;167095:21;166861:263;:::o;168834:971::-;-1:-1:-1;;;;;168983:19:0;;168961;168983;;;:11;:19;;;;;;;;169015:218;;;;-1:-1:-1;;;;;169083:23:0;;;;;;:15;:23;;;;;;169055:24;:51;;169083:23;;169055:24;;:51;;169083:23;;169055:51;:::i;:::-;;;;-1:-1:-1;;;;;;;169121:19:0;;169143:5;169121:19;;;:11;:19;;;;;:27;;-1:-1:-1;;169121:27:0;;;169163:23;:25;;;;;;:::i;:::-;;;;-1:-1:-1;;169203:16:0;:18;;;:16;:18;;;:::i;:::-;;;;;;169015:218;-1:-1:-1;;;;;169249:23:0;;;;;;:15;:23;;;;;;169245:92;;169294:29;:31;;;:29;:31;;;:::i;:::-;;;;;;169245:92;-1:-1:-1;;;;;169349:23:0;;;;;;:15;:23;;;;;:33;;169376:6;;169349:23;:33;;169376:6;;169349:33;:::i;:::-;;;;;;;;169417:6;169393:20;;:30;;;;;;;:::i;:::-;;;;-1:-1:-1;169440:18:0;;-1:-1:-1;169451:6:0;169440:10;:18::i;:::-;169436:216;;;-1:-1:-1;;;;;169503:23:0;;;;;;:15;:23;;;;;;169475:24;:51;;169503:23;;169475:24;;:51;;169503:23;;169475:51;:::i;:::-;;;;-1:-1:-1;;;;;;;169541:19:0;;;;;;:11;:19;;;;;:26;;-1:-1:-1;;169541:26:0;169563:4;169541:26;;;169582:23;:25;;;;;;:::i;:::-;;;;-1:-1:-1;;169622:16:0;:18;;;:16;:18;;;:::i;:::-;;;;;;169436:216;-1:-1:-1;;;;;169686:19:0;;;;;;:11;:19;;;;;;;;169668:37;;;;;;169664:134;;169727:59;;169770:15;;9277:41:1;;-1:-1:-1;;;;;169727:59:0;;;169745:15;;-1:-1:-1;;;;;;;;;;;169727:59:0;9265:2:1;9250:18;169727:59:0;9137:187:1;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:464:1;57:5;110:3;103:4;95:6;91:17;87:27;77:55;;128:1;125;118:12;77:55;164:6;151:20;195:49;211:32;240:2;211:32;:::i;:::-;195:49;:::i;:::-;269:2;260:7;253:19;315:3;308:4;303:2;295:6;291:15;287:26;284:35;281:55;;;332:1;329;322:12;281:55;397:2;390:4;382:6;378:17;371:4;362:7;358:18;345:55;445:1;420:16;;;438:4;416:27;409:38;;;;424:7;14:464;-1:-1:-1;;;14:464:1:o;483:247::-;542:6;595:2;583:9;574:7;570:23;566:32;563:52;;;611:1;608;601:12;563:52;650:9;637:23;669:31;694:5;669:31;:::i;:::-;719:5;483:247;-1:-1:-1;;;483:247:1:o;735:388::-;803:6;811;864:2;852:9;843:7;839:23;835:32;832:52;;;880:1;877;870:12;832:52;919:9;906:23;938:31;963:5;938:31;:::i;:::-;988:5;-1:-1:-1;1045:2:1;1030:18;;1017:32;1058:33;1017:32;1058:33;:::i;:::-;1110:7;1100:17;;;735:388;;;;;:::o;1128:456::-;1205:6;1213;1221;1274:2;1262:9;1253:7;1249:23;1245:32;1242:52;;;1290:1;1287;1280:12;1242:52;1329:9;1316:23;1348:31;1373:5;1348:31;:::i;:::-;1398:5;-1:-1:-1;1455:2:1;1440:18;;1427:32;1468:33;1427:32;1468:33;:::i;:::-;1128:456;;1520:7;;-1:-1:-1;;;1574:2:1;1559:18;;;;1546:32;;1128:456::o;1589:315::-;1657:6;1665;1718:2;1706:9;1697:7;1693:23;1689:32;1686:52;;;1734:1;1731;1724:12;1686:52;1773:9;1760:23;1792:31;1817:5;1792:31;:::i;:::-;1842:5;1894:2;1879:18;;;;1866:32;;-1:-1:-1;;;1589:315:1:o;1909:277::-;1976:6;2029:2;2017:9;2008:7;2004:23;2000:32;1997:52;;;2045:1;2042;2035:12;1997:52;2077:9;2071:16;2130:5;2123:13;2116:21;2109:5;2106:32;2096:60;;2152:1;2149;2142:12;2463:322;2532:6;2585:2;2573:9;2564:7;2560:23;2556:32;2553:52;;;2601:1;2598;2591:12;2553:52;2628:23;;-1:-1:-1;;;;;2663:30:1;;2660:50;;;2706:1;2703;2696:12;2660:50;2729;2771:7;2762:6;2751:9;2747:22;2729:50;:::i;:::-;2719:60;2463:322;-1:-1:-1;;;;2463:322:1:o;2790:636::-;2870:6;2923:2;2911:9;2902:7;2898:23;2894:32;2891:52;;;2939:1;2936;2929:12;2891:52;2966:16;;-1:-1:-1;;;;;2994:30:1;;2991:50;;;3037:1;3034;3027:12;2991:50;3060:22;;3113:4;3105:13;;3101:27;-1:-1:-1;3091:55:1;;3142:1;3139;3132:12;3091:55;3171:2;3165:9;3196:49;3212:32;3241:2;3212:32;:::i;3196:49::-;3268:2;3261:5;3254:17;3308:7;3303:2;3298;3294;3290:11;3286:20;3283:33;3280:53;;;3329:1;3326;3319:12;3280:53;3342:54;3393:2;3388;3381:5;3377:14;3372:2;3368;3364:11;3342:54;:::i;3431:944::-;3557:6;3565;3573;3581;3634:3;3622:9;3613:7;3609:23;3605:33;3602:53;;;3651:1;3648;3641:12;3602:53;3678:23;;-1:-1:-1;;;;;3750:14:1;;;3747:34;;;3777:1;3774;3767:12;3747:34;3800:50;3842:7;3833:6;3822:9;3818:22;3800:50;:::i;:::-;3790:60;;3903:2;3892:9;3888:18;3875:32;3859:48;;3932:2;3922:8;3919:16;3916:36;;;3948:1;3945;3938:12;3916:36;3971:52;4015:7;4004:8;3993:9;3989:24;3971:52;:::i;:::-;3961:62;;4076:2;4065:9;4061:18;4048:32;4032:48;;4105:2;4095:8;4092:16;4089:36;;;4121:1;4118;4111:12;4089:36;4144:52;4188:7;4177:8;4166:9;4162:24;4144:52;:::i;:::-;4134:62;;4249:2;4238:9;4234:18;4221:32;4205:48;;4278:2;4268:8;4265:16;4262:36;;;4294:1;4291;4284:12;4262:36;;4317:52;4361:7;4350:8;4339:9;4335:24;4317:52;:::i;:::-;4307:62;;;3431:944;;;;;;;:::o;4380:1145::-;4525:6;4533;4541;4549;4557;4610:3;4598:9;4589:7;4585:23;4581:33;4578:53;;;4627:1;4624;4617:12;4578:53;4654:23;;-1:-1:-1;;;;;4726:14:1;;;4723:34;;;4753:1;4750;4743:12;4723:34;4776:50;4818:7;4809:6;4798:9;4794:22;4776:50;:::i;:::-;4766:60;;4879:2;4868:9;4864:18;4851:32;4835:48;;4908:2;4898:8;4895:16;4892:36;;;4924:1;4921;4914:12;4892:36;4947:52;4991:7;4980:8;4969:9;4965:24;4947:52;:::i;:::-;4937:62;;5052:2;5041:9;5037:18;5024:32;5008:48;;5081:2;5071:8;5068:16;5065:36;;;5097:1;5094;5087:12;5065:36;5120:52;5164:7;5153:8;5142:9;5138:24;5120:52;:::i;:::-;5110:62;;5225:2;5214:9;5210:18;5197:32;5181:48;;5254:2;5244:8;5241:16;5238:36;;;5270:1;5267;5260:12;5238:36;5293:52;5337:7;5326:8;5315:9;5311:24;5293:52;:::i;:::-;5283:62;;5398:3;5387:9;5383:19;5370:33;5354:49;;5428:2;5418:8;5415:16;5412:36;;;5444:1;5441;5434:12;5412:36;;5467:52;5511:7;5500:8;5489:9;5485:24;5467:52;:::i;:::-;5457:62;;;4380:1145;;;;;;;;:::o;5530:812::-;5646:6;5654;5662;5670;5723:3;5711:9;5702:7;5698:23;5694:33;5691:53;;;5740:1;5737;5730:12;5691:53;5767:23;;-1:-1:-1;;;;;5839:14:1;;;5836:34;;;5866:1;5863;5856:12;5836:34;5889:50;5931:7;5922:6;5911:9;5907:22;5889:50;:::i;:::-;5879:60;;5992:2;5981:9;5977:18;5964:32;5948:48;;6021:2;6011:8;6008:16;6005:36;;;6037:1;6034;6027:12;6005:36;6060:52;6104:7;6093:8;6082:9;6078:24;6060:52;:::i;:::-;6050:62;;6165:2;6154:9;6150:18;6137:32;6121:48;;6194:2;6184:8;6181:16;6178:36;;;6210:1;6207;6200:12;6178:36;;6233:52;6277:7;6266:8;6255:9;6251:24;6233:52;:::i;:::-;5530:812;;;;-1:-1:-1;6223:62:1;;6332:2;6317:18;6304:32;;-1:-1:-1;;;5530:812:1:o;6347:180::-;6406:6;6459:2;6447:9;6438:7;6434:23;6430:32;6427:52;;;6475:1;6472;6465:12;6427:52;-1:-1:-1;6498:23:1;;6347:180;-1:-1:-1;6347:180:1:o;6532:184::-;6602:6;6655:2;6643:9;6634:7;6630:23;6626:32;6623:52;;;6671:1;6668;6661:12;6623:52;-1:-1:-1;6694:16:1;;6532:184;-1:-1:-1;6532:184:1:o;6721:315::-;6789:6;6797;6850:2;6838:9;6829:7;6825:23;6821:32;6818:52;;;6866:1;6863;6856:12;6818:52;6902:9;6889:23;6879:33;;6962:2;6951:9;6947:18;6934:32;6975:31;7000:5;6975:31;:::i;7041:276::-;7172:3;7210:6;7204:13;7226:53;7272:6;7267:3;7260:4;7252:6;7248:17;7226:53;:::i;:::-;7295:16;;;;;7041:276;-1:-1:-1;;7041:276:1:o;7322:1099::-;7450:3;7479:1;7512:6;7506:13;7542:3;7564:1;7592:9;7588:2;7584:18;7574:28;;7652:2;7641:9;7637:18;7674;7664:61;;7718:4;7710:6;7706:17;7696:27;;7664:61;7744:2;7792;7784:6;7781:14;7761:18;7758:38;7755:165;;;-1:-1:-1;;;7819:33:1;;7875:4;7872:1;7865:15;7905:4;7826:3;7893:17;7755:165;7936:18;7963:104;;;;8081:1;8076:320;;;;7929:467;;7963:104;-1:-1:-1;;7996:24:1;;7984:37;;8041:16;;;;-1:-1:-1;7963:104:1;;8076:320;18719:1;18712:14;;;18756:4;18743:18;;8171:1;8185:165;8199:6;8196:1;8193:13;8185:165;;;8277:14;;8264:11;;;8257:35;8320:16;;;;8214:10;;8185:165;;;8189:3;;8379:6;8374:3;8370:16;8363:23;;7929:467;-1:-1:-1;8412:3:1;;7322:1099;-1:-1:-1;;;;;;;;7322:1099:1:o;8426:203::-;-1:-1:-1;;;;;8590:32:1;;;;8572:51;;8560:2;8545:18;;8426:203::o;8858:274::-;-1:-1:-1;;;;;9050:32:1;;;;9032:51;;9114:2;9099:18;;9092:34;9020:2;9005:18;;8858:274::o;10003:383::-;10152:2;10141:9;10134:21;10115:4;10184:6;10178:13;10227:6;10222:2;10211:9;10207:18;10200:34;10243:66;10302:6;10297:2;10286:9;10282:18;10277:2;10269:6;10265:15;10243:66;:::i;:::-;10370:2;10349:15;-1:-1:-1;;10345:29:1;10330:45;;;;10377:2;10326:54;;10003:383;-1:-1:-1;;10003:383:1:o;11556:408::-;11758:2;11740:21;;;11797:2;11777:18;;;11770:30;-1:-1:-1;;;;;;;;;;;11831:2:1;11816:18;;11809:62;-1:-1:-1;;;11902:2:1;11887:18;;11880:42;11954:3;11939:19;;11556:408::o;13905:402::-;14107:2;14089:21;;;14146:2;14126:18;;;14119:30;14185:34;14180:2;14165:18;;14158:62;-1:-1:-1;;;14251:2:1;14236:18;;14229:36;14297:3;14282:19;;13905:402::o;14312:407::-;14514:2;14496:21;;;14553:2;14533:18;;;14526:30;-1:-1:-1;;;;;;;;;;;14587:2:1;14572:18;;14565:62;-1:-1:-1;;;14658:2:1;14643:18;;14636:41;14709:3;14694:19;;14312:407::o;17651:329::-;17847:25;;;17903:2;17888:18;;17881:34;;;;17958:14;17951:22;17946:2;17931:18;;17924:50;17835:2;17820:18;;17651:329::o;18174:275::-;18245:2;18239:9;18310:2;18291:13;;-1:-1:-1;;18287:27:1;18275:40;;-1:-1:-1;;;;;18330:34:1;;18366:22;;;18327:62;18324:88;;;18392:18;;:::i;:::-;18428:2;18421:22;18174:275;;-1:-1:-1;18174:275:1:o;18454:187::-;18503:4;-1:-1:-1;;;;;18525:30:1;;18522:56;;;18558:18;;:::i;:::-;-1:-1:-1;18624:2:1;18603:15;-1:-1:-1;;18599:29:1;18630:4;18595:40;;18454:187::o;18772:128::-;18812:3;18843:1;18839:6;18836:1;18833:13;18830:39;;;18849:18;;:::i;:::-;-1:-1:-1;18885:9:1;;18772:128::o;18905:217::-;18945:1;18971;18961:132;;19015:10;19010:3;19006:20;19003:1;18996:31;19050:4;19047:1;19040:15;19078:4;19075:1;19068:15;18961:132;-1:-1:-1;19107:9:1;;18905:217::o;19127:422::-;19216:1;19259:5;19216:1;19273:270;19294:7;19284:8;19281:21;19273:270;;;19353:4;19349:1;19345:6;19341:17;19335:4;19332:27;19329:53;;;19362:18;;:::i;:::-;19412:7;19402:8;19398:22;19395:55;;;19432:16;;;;19395:55;19511:22;;;;19471:15;;;;19273:270;;;19277:3;19127:422;;;;;:::o;19554:131::-;19614:5;19643:36;19670:8;19664:4;19739:5;19769:8;19759:80;;-1:-1:-1;19810:1:1;19824:5;;19759:80;19858:4;19848:76;;-1:-1:-1;19895:1:1;19909:5;;19848:76;19940:4;19958:1;19953:59;;;;20026:1;20021:130;;;;19933:218;;19953:59;19983:1;19974:10;;19997:5;;;20021:130;20058:3;20048:8;20045:17;20042:43;;;20065:18;;:::i;:::-;-1:-1:-1;;20121:1:1;20107:16;;20136:5;;19933:218;;20235:2;20225:8;20222:16;20216:3;20210:4;20207:13;20203:36;20197:2;20187:8;20184:16;20179:2;20173:4;20170:12;20166:35;20163:77;20160:159;;;-1:-1:-1;20272:19:1;;;20304:5;;20160:159;20351:34;20376:8;20370:4;20351:34;:::i;:::-;20421:6;20417:1;20413:6;20409:19;20400:7;20397:32;20394:58;;;20432:18;;:::i;:::-;20470:20;;19690:806;-1:-1:-1;;;19690:806:1:o;20501:168::-;20541:7;20607:1;20603;20599:6;20595:14;20592:1;20589:21;20584:1;20577:9;20570:17;20566:45;20563:71;;;20614:18;;:::i;:::-;-1:-1:-1;20654:9:1;;20501:168::o;20674:125::-;20714:4;20742:1;20739;20736:8;20733:34;;;20747:18;;:::i;:::-;-1:-1:-1;20784:9:1;;20674:125::o;20804:258::-;20876:1;20886:113;20900:6;20897:1;20894:13;20886:113;;;20976:11;;;20970:18;20957:11;;;20950:39;20922:2;20915:10;20886:113;;;21017:6;21014:1;21011:13;21008:48;;;-1:-1:-1;;21052:1:1;21034:16;;21027:27;20804:258::o;21067:136::-;21106:3;21134:5;21124:39;;21143:18;;:::i;:::-;-1:-1:-1;;;21179:18:1;;21067:136::o;21208:380::-;21287:1;21283:12;;;;21330;;;21351:61;;21405:4;21397:6;21393:17;21383:27;;21351:61;21458:2;21450:6;21447:14;21427:18;21424:38;21421:161;;;21504:10;21499:3;21495:20;21492:1;21485:31;21539:4;21536:1;21529:15;21567:4;21564:1;21557:15;21421:161;;21208:380;;;:::o;21593:135::-;21632:3;-1:-1:-1;;21653:17:1;;21650:43;;;21673:18;;:::i;:::-;-1:-1:-1;21720:1:1;21709:13;;21593:135::o;21733:127::-;21794:10;21789:3;21785:20;21782:1;21775:31;21825:4;21822:1;21815:15;21849:4;21846:1;21839:15;21865:127;21926:10;21921:3;21917:20;21914:1;21907:31;21957:4;21954:1;21947:15;21981:4;21978:1;21971:15;21997:131;-1:-1:-1;;;;;22072:31:1;;22062:42;;22052:70;;22118:1;22115;22108:12
Swarm Source
ipfs://a24787eff837165ab19b4835bf6fe9ce149d7345e543adf4c68fbbcbf8db069a
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$14.77
Net Worth in GLMR
Token Allocations
DAI
100.00%
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| GLMR | 100.00% | $1 | 14.7666 | $14.77 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.