Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Latest 1 internal transaction
Parent Txn Hash | Block | From | To | Value | |||
---|---|---|---|---|---|---|---|
0x3a39b1c26c47c4246b22c01a4eae853464f693bc602de9a78ecd25680ec9987a | 4413941 | 161 days 6 hrs ago | 0x00f5e2a16503bc5992858867cc675472c81161b1 | Contract Creation | 0 CRO |
[ Download CSV Export ]
Contract Name:
CRKPOOL
Compiler Version
v0.8.13+commit.abaa5c0e
Contract Source Code (Solidity)
/** *Submitted for verification at cronoscan.com on 2022-08-31 */ /** *Submitted for verification at cronoscan.com on 2022-08-21 */ /** *Submitted for verification at cronoscan.com on 2022-08-21 */ // File: @openzeppelin/contracts/utils/structs/EnumerableSet.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } } // File: CRKSTAKE.sol //SPDX-License-Identifier: MIT pragma solidity 0.8.13; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ contract Context { // Empty internal constructor, to prevent people from mistakenly deploying // an instance of this contract, which should be used via inheritance. constructor() {} function _msgSender() internal view returns (address payable) { return payable(msg.sender); } function _msgData() internal view returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; } /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ 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() { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(_owner == _msgSender(), 'Ownable: caller is not the owner'); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = 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 onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0), 'Ownable: new owner is the zero address'); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, 'SafeMath: addition overflow'); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, 'SafeMath: subtraction overflow'); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, 'SafeMath: multiplication overflow'); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, 'SafeMath: division by zero'); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, 'SafeMath: modulo by zero'); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } function min(uint256 x, uint256 y) internal pure returns (uint256 z) { z = x < y ? x : y; } // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) function sqrt(uint256 y) internal pure returns (uint256 z) { if (y > 3) { z = y; uint256 x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } } library SafeMathInt { int256 private constant MIN_INT256 = int256(1) << 255; int256 private constant MAX_INT256 = ~(int256(1) << 255); /** * @dev Multiplies two int256 variables and fails on overflow. */ function mul(int256 a, int256 b) internal pure returns (int256) { int256 c = a * b; // Detect overflow when multiplying MIN_INT256 with -1 require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256)); require((b == 0) || (c / b == a)); return c; } /** * @dev Division of two int256 variables and fails on overflow. */ function div(int256 a, int256 b) internal pure returns (int256) { // Prevent overflow when dividing MIN_INT256 by -1 require(b != -1 || a != MIN_INT256); // Solidity already throws when dividing by 0. return a / b; } /** * @dev Subtracts two int256 variables and fails on overflow. */ function sub(int256 a, int256 b) internal pure returns (int256) { int256 c = a - b; require((b >= 0 && c <= a) || (b < 0 && c > a)); return c; } /** * @dev Adds two int256 variables and fails on overflow. */ function add(int256 a, int256 b) internal pure returns (int256) { int256 c = a + b; require((b >= 0 && c >= a) || (b < 0 && c < a)); return c; } /** * @dev Converts to absolute value, and fails on overflow. */ function abs(int256 a) internal pure returns (int256) { require(a != MIN_INT256); return a < 0 ? -a : a; } function toUint256Safe(int256 a) internal pure returns (uint256) { require(a >= 0); return uint256(a); } } library SafeMathUint { function toInt256Safe(uint256 a) internal pure returns (int256) { int256 b = int256(a); require(b >= 0); return b; } } interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, 'Address: insufficient balance'); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{value: amount}(''); require(success, 'Address: unable to send value, recipient may have reverted'); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, 'Address: low-level call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, 'Address: low-level call with value failed'); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, 'Address: insufficient balance for call'); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue( address target, bytes memory data, uint256 weiValue, string memory errorMessage ) private returns (bytes memory) { require(isContract(target), 'Address: call to non-contract'); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{value: weiValue}(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } 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); } interface DividendPayingTokenOptionalInterface { /// @notice View the amount of dividend in wei that an address can withdraw. /// @param _owner The address of a token holder. /// @return The amount of dividend in wei that `_owner` can withdraw. function withdrawableDividendOf(address _owner) external view returns(uint256); /// @notice View the amount of dividend in wei that an address has withdrawn. /// @param _owner The address of a token holder. /// @return The amount of dividend in wei that `_owner` has withdrawn. function withdrawnDividendOf(address _owner) external view returns(uint256); /// @notice View the amount of dividend in wei that an address has earned in total. /// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner) /// @param _owner The address of a token holder. /// @return The amount of dividend in wei that `_owner` has earned in total. function accumulativeDividendOf(address _owner) external view returns(uint256); } interface DividendPayingTokenInterface { /// @notice View the amount of dividend in wei that an address can withdraw. /// @param _owner The address of a token holder. /// @return The amount of dividend in wei that `_owner` can withdraw. function dividendOf(address _owner) external view returns(uint256); /// @notice Distributes ether to token holders as dividends. /// @dev SHOULD distribute the paid ether to token holders as dividends. /// SHOULD NOT directly transfer ether to token holders in this function. /// MUST emit a `DividendsDistributed` event when the amount of distributed ether is greater than 0. function distributeDividends() external payable; /// @notice Withdraws the ether distributed to the sender. /// @dev SHOULD transfer `dividendOf(msg.sender)` wei to `msg.sender`, and `dividendOf(msg.sender)` SHOULD be 0 after the transfer. /// MUST emit a `DividendWithdrawn` event if the amount of ether transferred is greater than 0. function withdrawDividend() external; /// @dev This event MUST emit when ether is distributed to token holders. /// @param from The address which sends ether to this contract. /// @param weiAmount The amount of distributed ether in wei. event DividendsDistributed( address indexed from, uint256 weiAmount ); /// @dev This event MUST emit when an address withdraws their dividend. /// @param to The address which withdraws ether from this contract. /// @param weiAmount The amount of withdrawn ether in wei. event DividendWithdrawn( address indexed to, uint256 weiAmount ); } contract DividendPayingToken is DividendPayingTokenInterface, DividendPayingTokenOptionalInterface, Ownable { using SafeMath for uint256; using SafeMathUint for uint256; using SafeMathInt for int256; // With `magnitude`, we can properly distribute dividends even if the amount of received ether is small. // For more discussion about choosing the value of `magnitude`, // see https://github.com/ethereum/EIPs/issues/1726#issuecomment-472352728 uint256 constant internal magnitude = 2**128; uint256 internal magnifiedDividendPerShare; address public immutable token = address(0x5C7F8A570d578ED84E63fdFA7b1eE72dEae1AE23); // About dividendCorrection: // If the token balance of a `_user` is never changed, the dividend of `_user` can be computed with: // `dividendOf(_user) = dividendPerShare * balanceOf(_user)`. // When `balanceOf(_user)` is changed (via minting/burning/transferring tokens), // `dividendOf(_user)` should not be changed, // but the computed value of `dividendPerShare * balanceOf(_user)` is changed. // To keep the `dividendOf(_user)` unchanged, we add a correction term: // `dividendOf(_user) = dividendPerShare * balanceOf(_user) + dividendCorrectionOf(_user)`, // where `dividendCorrectionOf(_user)` is updated whenever `balanceOf(_user)` is changed: // `dividendCorrectionOf(_user) = dividendPerShare * (old balanceOf(_user)) - (new balanceOf(_user))`. // So now `dividendOf(_user)` returns the same value before and after `balanceOf(_user)` is changed. mapping(address => int256) internal magnifiedDividendCorrections; mapping(address => uint256) internal withdrawnDividends; mapping (address => uint256) public holderBalance; uint256 public totalBalance; uint256 public totalDividendsDistributed; uint256 public totalDividendsWaitingToSend; /// @dev Distributes dividends whenever ether is paid to this contract. receive() external payable { distributeDividends(); } /// @notice Distributes ether to token holders as dividends. /// @dev It reverts if the total supply of tokens is 0. /// It emits the `DividendsDistributed` event if the amount of received ether is greater than 0. /// About undistributed ether: /// In each distribution, there is a small amount of ether not distributed, /// the magnified amount of which is /// `(msg.value * magnitude) % totalSupply()`. /// With a well-chosen `magnitude`, the amount of undistributed ether /// (de-magnified) in a distribution can be less than 1 wei. /// We can actually keep track of the undistributed ether in a distribution /// and try to distribute it in the next distribution, /// but keeping track of such data on-chain costs much more than /// the saved ether, so we don't do that. function distributeDividends() public override payable { require(false, "Cannot send BNB directly to tracker as it is unrecoverable"); // } function distributeTokenDividends() external onlyOwner { if(totalBalance > 0){ uint256 tokensToAdd; uint256 balance = IERC20(token).balanceOf(address(this)); if(totalDividendsWaitingToSend < balance){ tokensToAdd = balance - totalDividendsWaitingToSend; } else { tokensToAdd = 0; } if (tokensToAdd > 0) { magnifiedDividendPerShare = magnifiedDividendPerShare.add( (tokensToAdd).mul(magnitude) / totalBalance ); emit DividendsDistributed(msg.sender, tokensToAdd); totalDividendsDistributed = totalDividendsDistributed.add(tokensToAdd); totalDividendsWaitingToSend = totalDividendsWaitingToSend.add(tokensToAdd); } } } /// @notice Withdraws the ether distributed to the sender. /// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0. function withdrawDividend() external virtual override { _withdrawDividendOfUser(payable(msg.sender)); } /// @notice Withdraws the ether distributed to the sender. /// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0. function _withdrawDividendOfUser(address payable user) internal returns (uint256) { uint256 _withdrawableDividend = withdrawableDividendOf(user); if (_withdrawableDividend > 0) { withdrawnDividends[user] = withdrawnDividends[user].add(_withdrawableDividend); if(totalDividendsWaitingToSend >= _withdrawableDividend){ totalDividendsWaitingToSend -= _withdrawableDividend; } else { totalDividendsWaitingToSend = 0; } emit DividendWithdrawn(user, _withdrawableDividend); bool success = IERC20(token).transfer(user, _withdrawableDividend); if(!success) { withdrawnDividends[user] = withdrawnDividends[user].sub(_withdrawableDividend); return 0; } return _withdrawableDividend; } return 0; } /// @notice View the amount of dividend in wei that an address can withdraw. /// @param _owner The address of a token holder. /// @return The amount of dividend in wei that `_owner` can withdraw. function dividendOf(address _owner) external view override returns(uint256) { return withdrawableDividendOf(_owner); } /// @notice View the amount of dividend in wei that an address can withdraw. /// @param _owner The address of a token holder. /// @return The amount of dividend in wei that `_owner` can withdraw. function withdrawableDividendOf(address _owner) public view override returns(uint256) { return accumulativeDividendOf(_owner).sub(withdrawnDividends[_owner]); } /// @notice View the amount of dividend in wei that an address has withdrawn. /// @param _owner The address of a token holder. /// @return The amount of dividend in wei that `_owner` has withdrawn. function withdrawnDividendOf(address _owner) external view override returns(uint256) { return withdrawnDividends[_owner]; } /// @notice View the amount of dividend in wei that an address has earned in total. /// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner) /// = (magnifiedDividendPerShare * balanceOf(_owner) + magnifiedDividendCorrections[_owner]) / magnitude /// @param _owner The address of a token holder. /// @return The amount of dividend in wei that `_owner` has earned in total. function accumulativeDividendOf(address _owner) public view override returns(uint256) { return magnifiedDividendPerShare.mul(holderBalance[_owner]).toInt256Safe() .add(magnifiedDividendCorrections[_owner]).toUint256Safe() / magnitude; } /// @dev Internal function that increases tokens to an account. /// Update magnifiedDividendCorrections to keep dividends unchanged. /// @param account The account that will receive the created tokens. /// @param value The amount that will be created. function _increase(address account, uint256 value) internal { magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account] .sub( (magnifiedDividendPerShare.mul(value)).toInt256Safe() ); } /// @dev Internal function that reduces an amount of the token of a given account. /// Update magnifiedDividendCorrections to keep dividends unchanged. /// @param account The account whose tokens will be burnt. /// @param value The amount that will be burnt. function _reduce(address account, uint256 value) internal { magnifiedDividendCorrections[account] = magnifiedDividendCorrections[account] .add( (magnifiedDividendPerShare.mul(value)).toInt256Safe() ); } function _setBalance(address account, uint256 newBalance) internal { uint256 currentBalance = holderBalance[account]; holderBalance[account] = newBalance; if(newBalance > currentBalance) { uint256 increaseAmount = newBalance.sub(currentBalance); _increase(account, increaseAmount); totalBalance += increaseAmount; } else if(newBalance < currentBalance) { uint256 reduceAmount = currentBalance.sub(newBalance); _reduce(account, reduceAmount); totalBalance -= reduceAmount; } } } contract DividendTracker is DividendPayingToken { using SafeMath for uint256; using SafeMathInt for int256; struct Map { address[] keys; mapping(address => uint) values; mapping(address => uint) indexOf; mapping(address => bool) inserted; } function get(address key) private view returns (uint) { return tokenHoldersMap.values[key]; } function getIndexOfKey(address key) private view returns (int) { if(!tokenHoldersMap.inserted[key]) { return -1; } return int(tokenHoldersMap.indexOf[key]); } function getKeyAtIndex(uint index) private view returns (address) { return tokenHoldersMap.keys[index]; } function size() private view returns (uint) { return tokenHoldersMap.keys.length; } function set(address key, uint val) private { if (tokenHoldersMap.inserted[key]) { tokenHoldersMap.values[key] = val; } else { tokenHoldersMap.inserted[key] = true; tokenHoldersMap.values[key] = val; tokenHoldersMap.indexOf[key] = tokenHoldersMap.keys.length; tokenHoldersMap.keys.push(key); } } function remove(address key) private { if (!tokenHoldersMap.inserted[key]) { return; } delete tokenHoldersMap.inserted[key]; delete tokenHoldersMap.values[key]; uint index = tokenHoldersMap.indexOf[key]; uint lastIndex = tokenHoldersMap.keys.length - 1; address lastKey = tokenHoldersMap.keys[lastIndex]; tokenHoldersMap.indexOf[lastKey] = index; delete tokenHoldersMap.indexOf[key]; tokenHoldersMap.keys[index] = lastKey; tokenHoldersMap.keys.pop(); } Map private tokenHoldersMap; uint256 public lastProcessedIndex; mapping (address => bool) public excludedFromDividends; mapping (address => uint256) public lastClaimTimes; uint256 public claimWait; uint256 public immutable minimumTokenBalanceForDividends; event ExcludeFromDividends(address indexed account); event IncludeInDividends(address indexed account); event ClaimWaitUpdated(uint256 indexed newValue, uint256 indexed oldValue); event Claim(address indexed account, uint256 amount, bool indexed automatic); constructor() { claimWait = 1; minimumTokenBalanceForDividends = 1 * (10**18); //must hold 10,000+ tokens } function excludeFromDividends(address account) external onlyOwner { excludedFromDividends[account] = true; _setBalance(account, 0); remove(account); emit ExcludeFromDividends(account); } function includeInDividends(address account) external onlyOwner { require(excludedFromDividends[account]); excludedFromDividends[account] = false; emit IncludeInDividends(account); } function updateClaimWait(uint256 newClaimWait) external onlyOwner { require(newClaimWait >= 1200 && newClaimWait <= 86400, "Dividend_Tracker: claimWait must be updated to between 1 and 24 hours"); require(newClaimWait != claimWait, "Dividend_Tracker: Cannot update claimWait to same value"); emit ClaimWaitUpdated(newClaimWait, claimWait); claimWait = newClaimWait; } function getLastProcessedIndex() external view returns(uint256) { return lastProcessedIndex; } function getNumberOfTokenHolders() external view returns(uint256) { return tokenHoldersMap.keys.length; } // Check to see if I really made this contract or if it is a clone! // @Sir_Tris on TG, @SirTrisCrypto on Twitter function getAccount(address _account) public view returns ( address account, int256 index, int256 iterationsUntilProcessed, uint256 withdrawableDividends, uint256 totalDividends, uint256 lastClaimTime, uint256 nextClaimTime, uint256 secondsUntilAutoClaimAvailable) { account = _account; index = getIndexOfKey(account); iterationsUntilProcessed = -1; if(index >= 0) { if(uint256(index) > lastProcessedIndex) { iterationsUntilProcessed = index.sub(int256(lastProcessedIndex)); } else { uint256 processesUntilEndOfArray = tokenHoldersMap.keys.length > lastProcessedIndex ? tokenHoldersMap.keys.length.sub(lastProcessedIndex) : 0; iterationsUntilProcessed = index.add(int256(processesUntilEndOfArray)); } } withdrawableDividends = withdrawableDividendOf(account); totalDividends = accumulativeDividendOf(account); lastClaimTime = lastClaimTimes[account]; nextClaimTime = lastClaimTime > 0 ? lastClaimTime.add(claimWait) : 0; secondsUntilAutoClaimAvailable = nextClaimTime > block.timestamp ? nextClaimTime.sub(block.timestamp) : 0; } function getAccountAtIndex(uint256 index) external view returns ( address, int256, int256, uint256, uint256, uint256, uint256, uint256) { if(index >= size()) { return (0x0000000000000000000000000000000000000000, -1, -1, 0, 0, 0, 0, 0); } address account = getKeyAtIndex(index); return getAccount(account); } function canAutoClaim(uint256 lastClaimTime) private view returns (bool) { if(lastClaimTime > block.timestamp) { return false; } return block.timestamp.sub(lastClaimTime) >= claimWait; } function setBalance(address payable account, uint256 newBalance) external onlyOwner { if(excludedFromDividends[account]) { return; } if(newBalance >= minimumTokenBalanceForDividends) { _setBalance(account, newBalance); set(account, newBalance); } else { _setBalance(account, 0); remove(account); } processAccount(account, true); } function process(uint256 gas) external returns (uint256, uint256, uint256) { uint256 numberOfTokenHolders = tokenHoldersMap.keys.length; if(numberOfTokenHolders == 0) { return (0, 0, lastProcessedIndex); } uint256 _lastProcessedIndex = lastProcessedIndex; uint256 gasUsed = 0; uint256 gasLeft = gasleft(); uint256 iterations = 0; uint256 claims = 0; while(gasUsed < gas && iterations < numberOfTokenHolders) { _lastProcessedIndex++; if(_lastProcessedIndex >= tokenHoldersMap.keys.length) { _lastProcessedIndex = 0; } address account = tokenHoldersMap.keys[_lastProcessedIndex]; if(canAutoClaim(lastClaimTimes[account])) { if(processAccount(payable(account), true)) { claims++; } } iterations++; uint256 newGasLeft = gasleft(); if(gasLeft > newGasLeft) { gasUsed = gasUsed.add(gasLeft.sub(newGasLeft)); } gasLeft = newGasLeft; } lastProcessedIndex = _lastProcessedIndex; return (iterations, claims, lastProcessedIndex); } function processAccount(address payable account, bool automatic) public onlyOwner returns (bool) { uint256 amount = _withdrawDividendOfUser(account); if(amount > 0) { lastClaimTimes[account] = block.timestamp; emit Claim(account, amount, automatic); return true; } return false; } } abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } contract CRKPOOL is Ownable, ReentrancyGuard { using SafeMath for uint256; using EnumerableSet for EnumerableSet.UintSet; DividendTracker public dividendTracker; IERC20 public immutable WCRO = IERC20(0x5C7F8A570d578ED84E63fdFA7b1eE72dEae1AE23); // Info of each user. struct UserInfo { uint256 amount; // How many LP tokens the user has provided. uint256 multipliedAmount; uint256 rewardDebt; // Reward debt. See explanation below. } // Info of each pool. struct PoolInfo { IERC20 lpToken; // Address of LP token contract. uint256 allocPoint; // How many allocation points assigned to this pool. Tokens to distribute per block. uint256 lastRewardTimestamp; // Last block number that Tokens distribution occurs. uint256 accTokensPerShare; // Accumulated Tokens per share, times 1e12. See below. } IERC20 public immutable stakingToken; IERC20 public immutable rewardToken; mapping (address => uint256) public holderUnlockTime; mapping (address => uint256) public holderNftsStakedAmount; mapping (address => mapping (address => EnumerableSet.UintSet)) private holderNftsStaked; mapping (address => bool) public isValidNftToStake; uint256 public totalStaked; uint256 public totalStakedMultiplied; uint256 public rewardsPerSecond; uint256 public lockDuration; uint256 public exitPenaltyPerc; // Info of each pool. PoolInfo[] public poolInfo; // Info of each user that stakes LP tokens. mapping (address => UserInfo) public userInfo; // Total allocation poitns. Must be the sum of all allocation points in all pools. uint256 private totalAllocPoint = 0; event Deposit(address indexed user, uint256 amount); event Withdraw(address indexed user, uint256 amount); event EmergencyWithdraw(address indexed user, uint256 amount); event StakedNFT(address indexed nftAddress, uint256 indexed tokenId, address indexed sender); event UnstakedNFT(address indexed nftAddress, uint256 indexed tokenId, address indexed sender); constructor( ) { stakingToken = IERC20(0x065DE42E28E42d90c2052a1B49e7f83806Af0e1F); rewardToken = IERC20(0x065DE42E28E42d90c2052a1B49e7f83806Af0e1F); dividendTracker = new DividendTracker(); rewardsPerSecond = 3.8 * 1e6 * 1e9; lockDuration = 0; exitPenaltyPerc = 0; isValidNftToStake[0xAD4bDA67bB8b6A502496EEF4dFba2ffdBAc38dB6] = true; isValidNftToStake[0x51D25FB5FBfe57FF67B20c499d4dd1d3c64844B7] = true; // staking pool poolInfo.push(PoolInfo({ lpToken: stakingToken, allocPoint: 1000, lastRewardTimestamp: 99999999999, accTokensPerShare: 0 })); totalAllocPoint = 1000; } function getHolderNfts(address nftAddress, address wallet) external view returns (uint256[] memory){ return holderNftsStaked[wallet][nftAddress].values(); } function stopReward() external onlyOwner { updatePool(0); rewardsPerSecond = 0; } function updateNftToStake(address nftAddress, bool enabledToStake) external onlyOwner { isValidNftToStake[nftAddress] = enabledToStake; } function startReward() external onlyOwner { require(poolInfo[0].lastRewardTimestamp == 99999999999, "Can only start rewards once"); poolInfo[0].lastRewardTimestamp = block.timestamp; } function stakeNft(address nftAddress, uint256 tokenId) external nonReentrant { require(isValidNftToStake[nftAddress], "NFT address not valid to stake"); require(holderNftsStaked[msg.sender][nftAddress].length() < 3, "Cannot stake more than 3 of the same NFT"); IERC721 nft = IERC721(nftAddress); UserInfo storage user = userInfo[msg.sender]; PoolInfo storage pool = poolInfo[0]; require(nft.getApproved(tokenId) == address(this), "Must approve token to be sent"); updatePool(0); if (user.amount > 0) { uint256 pending = user.multipliedAmount.mul(pool.accTokensPerShare).div(1e12).sub(user.rewardDebt); if(pending >= rewardsRemaining()){ pending = rewardsRemaining(); } if(pending > 0) { rewardToken.transfer(address(msg.sender), pending); } } nft.transferFrom(msg.sender, address(this), tokenId); holderNftsStakedAmount[msg.sender] += 1; holderNftsStaked[msg.sender][nftAddress].add(tokenId); totalStakedMultiplied -= user.multipliedAmount; user.multipliedAmount = user.amount * getStakingMultiplier(msg.sender) / 100; totalStakedMultiplied += user.multipliedAmount; user.rewardDebt = user.multipliedAmount.mul(pool.accTokensPerShare).div(1e12); emit StakedNFT(nftAddress, tokenId, msg.sender); } function unstakeNft(address nftAddress, uint256 tokenId) external nonReentrant { require(holderNftsStaked[msg.sender][nftAddress].contains(tokenId), "Can only unstake a tokenID allocated from this NFT address for the sender"); IERC721 nft = IERC721(nftAddress); UserInfo storage user = userInfo[msg.sender]; PoolInfo storage pool = poolInfo[0]; updatePool(0); if (user.amount > 0) { uint256 pending = user.multipliedAmount.mul(pool.accTokensPerShare).div(1e12).sub(user.rewardDebt); if(pending >= rewardsRemaining()){ pending = rewardsRemaining(); } if(pending > 0) { rewardToken.transfer(address(msg.sender), pending); } } nft.transferFrom(address(this), msg.sender, tokenId); holderNftsStakedAmount[msg.sender] -= 1; holderNftsStaked[msg.sender][nftAddress].remove(tokenId); totalStakedMultiplied -= user.multipliedAmount; user.multipliedAmount = user.amount * getStakingMultiplier(msg.sender) / 100; totalStakedMultiplied += user.multipliedAmount; user.rewardDebt = user.multipliedAmount.mul(pool.accTokensPerShare).div(1e12); emit UnstakedNFT(nftAddress, tokenId, msg.sender); } // @dev note that you must divide this by 100 after multiplying against tokens. function getStakingMultiplier(address holder) public view returns (uint256) { if(holderNftsStakedAmount[holder] == 0){ return 100; } // 15% additive boost per NFT staked return 100 + (holderNftsStakedAmount[holder]*15); } // View function to see pending Reward on frontend. function pendingReward(address _user) external view returns (uint256) { PoolInfo storage pool = poolInfo[0]; UserInfo storage user = userInfo[_user]; if(pool.lastRewardTimestamp == 99999999999){ return 0; } uint256 accTokensPerShare = pool.accTokensPerShare; uint256 lpSupply = totalStakedMultiplied; if (block.timestamp > pool.lastRewardTimestamp && lpSupply != 0) { uint256 tokenReward = calculateNewRewards().mul(pool.allocPoint).div(totalAllocPoint); accTokensPerShare = accTokensPerShare.add(tokenReward.mul(1e12).div(lpSupply)); } return user.multipliedAmount.mul(accTokensPerShare).div(1e12).sub(user.rewardDebt); } // Update reward variables of the given pool to be up-to-date. function updatePool(uint256 _pid) internal { // transfer any accumulated tokens. if(WCRO.balanceOf(address(this)) > 0){ WCRO.transfer(address(dividendTracker), WCRO.balanceOf(address(this))); } dividendTracker.distributeTokenDividends(); PoolInfo storage pool = poolInfo[_pid]; if (block.timestamp <= pool.lastRewardTimestamp) { return; } uint256 lpSupply = totalStakedMultiplied; if (lpSupply == 0) { pool.lastRewardTimestamp = block.timestamp; return; } uint256 tokenReward = calculateNewRewards().mul(pool.allocPoint).div(totalAllocPoint); pool.accTokensPerShare = pool.accTokensPerShare.add(tokenReward.mul(1e12).div(lpSupply)); pool.lastRewardTimestamp = block.timestamp; } // Update reward variables for all pools. Be careful of gas spending! function massUpdatePools() public onlyOwner { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { updatePool(pid); } } // Stake primary tokens function deposit(uint256 _amount) public nonReentrant { if(holderUnlockTime[msg.sender] == 0){ holderUnlockTime[msg.sender] = block.timestamp + lockDuration; } PoolInfo storage pool = poolInfo[0]; UserInfo storage user = userInfo[msg.sender]; updatePool(0); if (user.amount > 0) { uint256 pending = user.multipliedAmount.mul(pool.accTokensPerShare).div(1e12).sub(user.rewardDebt); if(pending >= rewardsRemaining()){ pending = rewardsRemaining(); } if(pending > 0) { rewardToken.transfer(address(msg.sender), pending); } } uint256 amountTransferred = 0; if(_amount > 0) { uint256 initialBalance = pool.lpToken.balanceOf(address(this)); pool.lpToken.transferFrom(address(msg.sender), address(this), _amount); amountTransferred = pool.lpToken.balanceOf(address(this)) - initialBalance; totalStakedMultiplied -= user.multipliedAmount; user.amount = user.amount.add(amountTransferred); user.multipliedAmount = user.amount * getStakingMultiplier(msg.sender) / 100; totalStaked += amountTransferred; totalStakedMultiplied += user.multipliedAmount; } dividendTracker.setBalance(payable(msg.sender), user.amount); user.rewardDebt = user.multipliedAmount.mul(pool.accTokensPerShare).div(1e12); emit Deposit(msg.sender, _amount); } // Withdraw primary tokens from STAKING. function withdraw(uint256 _amount) public nonReentrant { require(holderUnlockTime[msg.sender] <= block.timestamp, "May not do normal withdraw early"); PoolInfo storage pool = poolInfo[0]; UserInfo storage user = userInfo[msg.sender]; updatePool(0); uint256 pending = user.multipliedAmount.mul(pool.accTokensPerShare).div(1e12).sub(user.rewardDebt); if(pending >= rewardsRemaining()){ pending = rewardsRemaining(); } if(pending > 0) { rewardToken.transfer(payable(address(msg.sender)), pending); } if(_amount > 0) { user.amount -= _amount; user.multipliedAmount = user.amount * getStakingMultiplier(msg.sender) / 100; totalStaked -= _amount; totalStakedMultiplied -= _amount * getStakingMultiplier(msg.sender) / 100; pool.lpToken.transfer(address(msg.sender), _amount); } dividendTracker.setBalance(payable(msg.sender), user.amount); user.rewardDebt = user.multipliedAmount.mul(pool.accTokensPerShare).div(1e12); if(user.amount > 0){ holderUnlockTime[msg.sender] = block.timestamp + lockDuration; } else { holderUnlockTime[msg.sender] = 0; } emit Withdraw(msg.sender, _amount); } // Withdraw without caring about rewards. EMERGENCY ONLY. function emergencyWithdraw() external nonReentrant { PoolInfo storage pool = poolInfo[0]; UserInfo storage user = userInfo[msg.sender]; uint256 _amount = user.amount; totalStaked -= _amount; totalStakedMultiplied -= user.multipliedAmount; // exit penalty for early unstakers, penalty held on contract as rewards. if(holderUnlockTime[msg.sender] >= block.timestamp){ _amount -= _amount * exitPenaltyPerc / 100; } holderUnlockTime[msg.sender] = 0; pool.lpToken.transfer(address(msg.sender), _amount); user.amount = 0; user.multipliedAmount = 0; user.rewardDebt = 0; dividendTracker.setBalance(payable(msg.sender), 0); emit EmergencyWithdraw(msg.sender, _amount); } // Withdraw reward. EMERGENCY ONLY. This allows the owner to migrate rewards to a new staking pool since we are not minting new tokens. function emergencyRewardWithdraw(uint256 _amount) external onlyOwner { require(_amount <= rewardsRemaining(), 'not enough tokens to take out'); rewardToken.transfer(address(msg.sender), _amount); } function calculateNewRewards() public view returns (uint256) { PoolInfo storage pool = poolInfo[0]; if(pool.lastRewardTimestamp > block.timestamp){ return 0; } return ((block.timestamp - pool.lastRewardTimestamp) * rewardsPerSecond); } function rewardsRemaining() public view returns (uint256){ return rewardToken.balanceOf(address(this)) - totalStaked; } function updateRewardsPerSecond(uint256 newRewardsPerSecond) external onlyOwner { require(rewardsPerSecond <= 10000000 * 1e9, "Rewards per second must be below 10,000,000"); updatePool(0); rewardsPerSecond = newRewardsPerSecond * 1e9; } function updateExitPenalty(uint256 newPenaltyPerc) external onlyOwner { require(newPenaltyPerc <= 20, "May not set higher than 20%"); exitPenaltyPerc = newPenaltyPerc; } function claim() external nonReentrant { dividendTracker.processAccount(payable(msg.sender), false); } }
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"nftAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"StakedNFT","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"nftAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"UnstakedNFT","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"WCRO","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calculateNewRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dividendTracker","outputs":[{"internalType":"contract DividendTracker","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"emergencyRewardWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"exitPenaltyPerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nftAddress","type":"address"},{"internalType":"address","name":"wallet","type":"address"}],"name":"getHolderNfts","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"}],"name":"getStakingMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"holderNftsStakedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"holderUnlockTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isValidNftToStake","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"pendingReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"contract IERC20","name":"lpToken","type":"address"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardTimestamp","type":"uint256"},{"internalType":"uint256","name":"accTokensPerShare","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsPerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsRemaining","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nftAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"stakeNft","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stopReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakedMultiplied","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"nftAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"unstakeNft","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPenaltyPerc","type":"uint256"}],"name":"updateExitPenalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"nftAddress","type":"address"},{"internalType":"bool","name":"enabledToStake","type":"bool"}],"name":"updateNftToStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newRewardsPerSecond","type":"uint256"}],"name":"updateRewardsPerSecond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"multipliedAmount","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60e0604052735c7f8a570d578ed84e63fdfa7b1ee72deae1ae236080526000600e553480156200002e57600080fd5b50600080546001600160a01b031916339081178255604051909182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001805573065de42e28e42d90c2052a1b49e7f83806af0e1f60a081905260c0526040516200009f9062000243565b604051809103906000f080158015620000bc573d6000803e3d6000fd5b50600280546001600160a01b039283166001600160a01b031991821617909155660d8014722580006009556000600a819055600b819055600660209081527fcc82402dd09bb21526b47a53a1323e78d55d2899170c8afdd3ee8c28aa0f2e17805460ff1990811660019081179092557f16be138c1cc2752616726dd2f7ed1d111203eb6959a0d366605ff1fe309ce4bf8054909116821790556040805160808101825260a051871681526103e893810184815264174876e7ff92820192835260608201868152600c80549586018155909652905160049093027fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c781018054949098169390961692909217909555517fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c884015592517fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c9830155517fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8ca90910155600e5562000251565b611b978062002c6183390190565b60805160a05160c0516129a8620002b960003960008181610512015281816106b7015281816109df01528181610ce701528181611197015281816115710152611c31015260006103760152600081816102be01528181611f67015261200001526129a86000f3fe608060405234801561001057600080fd5b50600436106102115760003560e01c8063817b1cd211610125578063b6b55f25116100ad578063eacdaabc1161007c578063eacdaabc146104cb578063f2bee231146104d4578063f2fde38b146104e7578063f40f0f52146104fa578063f7c618c11461050d57600080fd5b8063b6b55f251461045d578063c3c235c214610470578063d4da5eb414610490578063db2e21bc146104c357600080fd5b80639a7c5473116100f45780639a7c5473146103ee5780639d757bb5146103f75780639f5662e21461040a578063a0df342b1461041d578063a913a5f71461043d57600080fd5b8063817b1cd2146103b95780638da5cb5b146103c25780638e0b0198146103d3578063999e2f75146103e657600080fd5b80634e71d92d116101a857806372f702f31161017757806372f702f314610371578063746c8ae11461039857806378c196f3146103a05780637b280def146103a857806380dc0672146103b157600080fd5b80634e71d92d1461034657806356a23f331461034e578063630b5ba114610361578063715018a61461036957600080fd5b80632c1f5216116101e45780632c1f5216146102f85780632e1a7d4d1461030b5780633279beab146103205780633660130b1461033357600080fd5b806304554443146102165780631526fe27146102325780631959a0021461026f5780631d470cb1146102b9575b600080fd5b61021f600a5481565b6040519081526020015b60405180910390f35b61024561024036600461264a565b610534565b604080516001600160a01b0390951685526020850193909352918301526060820152608001610229565b61029e61027d366004612678565b600d6020526000908152604090208054600182015460029092015490919083565b60408051938452602084019290925290820152606001610229565b6102e07f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610229565b6002546102e0906001600160a01b031681565b61031e61031936600461264a565b610578565b005b61031e61032e36600461264a565b610947565b61031e610341366004612695565b610a5d565b61031e610ee0565b61021f61035c366004612678565b610f83565b61031e610fdf565b61031e611030565b6102e07f000000000000000000000000000000000000000000000000000000000000000081565b61031e6110a4565b61021f611173565b61021f600b5481565b61031e611211565b61021f60075481565b6000546001600160a01b03166102e0565b61031e6103e136600461264a565b61124c565b61021f6112cc565b61021f60085481565b61031e6104053660046126cf565b611329565b61031e61041836600461264a565b61137e565b61043061042b366004612708565b611433565b6040516102299190612736565b61021f61044b366004612678565b60036020526000908152604090205481565b61031e61046b36600461264a565b61146b565b61021f61047e366004612678565b60046020526000908152604090205481565b6104b361049e366004612678565b60066020526000908152604090205460ff1681565b6040519015158152602001610229565b61031e61189d565b61021f60095481565b61031e6104e2366004612695565b611aad565b61031e6104f5366004612678565b611e2a565b61021f610508366004612678565b611e60565b6102e07f000000000000000000000000000000000000000000000000000000000000000081565b600c818154811061054457600080fd5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169350919084565b6002600154036105a35760405162461bcd60e51b815260040161059a9061277a565b60405180910390fd5b6002600155336000908152600360205260409020544210156106075760405162461bcd60e51b815260206004820181905260248201527f4d6179206e6f7420646f206e6f726d616c207769746864726177206561726c79604482015260640161059a565b6000600c60008154811061061d5761061d6127b1565b60009182526020808320338452600d9091526040832060049092020192509061064590611f4f565b600061067f826002015461067964e8d4a51000610673876003015487600101546121d890919063ffffffff16565b9061225a565b9061229c565b9050610689611173565b811061069a57610697611173565b90505b80156107335760405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906106ee90339085906004016127c7565b6020604051808303816000875af115801561070d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073191906127e0565b505b831561083f578382600001600082825461074d9190612813565b909155506064905061075e33610f83565b835461076a919061282a565b6107749190612849565b8260010181905550836007600082825461078e9190612813565b909155506064905061079f33610f83565b6107a9908661282a565b6107b39190612849565b600860008282546107c49190612813565b9091555050825460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906107fa90339088906004016127c7565b6020604051808303816000875af1158015610819573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083d91906127e0565b505b60025482546040516338c110ef60e21b81526001600160a01b039092169163e30443bc91610872913391906004016127c7565b600060405180830381600087803b15801561088c57600080fd5b505af11580156108a0573d6000803e3d6000fd5b505050506108c864e8d4a51000610673856003015485600101546121d890919063ffffffff16565b60028301558154156108f657600a546108e1904261286b565b33600090815260036020526040902055610907565b336000908152600360205260408120555b60405184815233907f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364906020015b60405180910390a25050600180555050565b6000546001600160a01b031633146109715760405162461bcd60e51b815260040161059a90612883565b610979611173565b8111156109c85760405162461bcd60e51b815260206004820152601d60248201527f6e6f7420656e6f75676820746f6b656e7320746f2074616b65206f7574000000604482015260640161059a565b60405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90610a1690339085906004016127c7565b6020604051808303816000875af1158015610a35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5991906127e0565b5050565b600260015403610a7f5760405162461bcd60e51b815260040161059a9061277a565b60026001556001600160a01b03821660009081526006602052604090205460ff16610aec5760405162461bcd60e51b815260206004820152601e60248201527f4e46542061646472657373206e6f742076616c696420746f207374616b650000604482015260640161059a565b3360009081526005602090815260408083206001600160a01b03861684529091529020600390610b1b906122de565b10610b795760405162461bcd60e51b815260206004820152602860248201527f43616e6e6f74207374616b65206d6f7265207468616e2033206f6620746865206044820152671cd85b594813919560c21b606482015260840161059a565b336000908152600d60205260408120600c8054859391908290610b9e57610b9e6127b1565b6000918252602090912060405163020604bf60e21b8152600481810188905290920201915030906001600160a01b0385169063081812fc90602401602060405180830381865afa158015610bf6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1a91906128b8565b6001600160a01b031614610c705760405162461bcd60e51b815260206004820152601d60248201527f4d75737420617070726f766520746f6b656e20746f2062652073656e74000000604482015260640161059a565b610c7a6000611f4f565b815415610d65576000610caf836002015461067964e8d4a51000610673866003015488600101546121d890919063ffffffff16565b9050610cb9611173565b8110610cca57610cc7611173565b90505b8015610d635760405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90610d1e90339085906004016127c7565b6020604051808303816000875af1158015610d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6191906127e0565b505b505b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038416906323b872dd90606401600060405180830381600087803b158015610db357600080fd5b505af1158015610dc7573d6000803e3d6000fd5b5050336000908152600460205260408120805460019450909250610dec90849061286b565b90915550503360009081526005602090815260408083206001600160a01b03891684529091529020610e1e90856122e8565b50816001015460086000828254610e359190612813565b9091555060649050610e4633610f83565b8354610e52919061282a565b610e5c9190612849565b6001830181905560088054600090610e7590849061286b565b909155505060038101546001830154610e989164e8d4a5100091610673916121d8565b6002830155604051339085906001600160a01b038816907f31461cc1f2e75f983949638b472aa50bc262a5c01efc3ae2103864f984c4d49f90600090a4505060018055505050565b600260015403610f025760405162461bcd60e51b815260040161059a9061277a565b600260018190555460405163bc4c4b3760e01b8152336004820152600060248201526001600160a01b039091169063bc4c4b37906044016020604051808303816000875af1158015610f58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7c91906127e0565b5060018055565b6001600160a01b0381166000908152600460205260408120548103610faa57506064919050565b6001600160a01b038216600090815260046020526040902054610fce90600f61282a565b610fd990606461286b565b92915050565b6000546001600160a01b031633146110095760405162461bcd60e51b815260040161059a90612883565b600c5460005b81811015610a595761102081611f4f565b611029816128d5565b905061100f565b6000546001600160a01b0316331461105a5760405162461bcd60e51b815260040161059a90612883565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031633146110ce5760405162461bcd60e51b815260040161059a90612883565b600c6000815481106110e2576110e26127b1565b90600052602060002090600402016002015464174876e7ff146111475760405162461bcd60e51b815260206004820152601b60248201527f43616e206f6e6c792073746172742072657761726473206f6e63650000000000604482015260640161059a565b42600c60008154811061115c5761115c6127b1565b906000526020600020906004020160020181905550565b6007546040516370a0823160e01b8152306004820152600091906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156111de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061120291906128ee565b61120c9190612813565b905090565b6000546001600160a01b0316331461123b5760405162461bcd60e51b815260040161059a90612883565b6112456000611f4f565b6000600955565b6000546001600160a01b031633146112765760405162461bcd60e51b815260040161059a90612883565b60148111156112c75760405162461bcd60e51b815260206004820152601b60248201527f4d6179206e6f742073657420686967686572207468616e203230250000000000604482015260640161059a565b600b55565b600080600c6000815481106112e3576112e36127b1565b90600052602060002090600402019050428160020154111561130757600091505090565b60095460028201546113199042612813565b611323919061282a565b91505090565b6000546001600160a01b031633146113535760405162461bcd60e51b815260040161059a90612883565b6001600160a01b03919091166000908152600660205260409020805460ff1916911515919091179055565b6000546001600160a01b031633146113a85760405162461bcd60e51b815260040161059a90612883565b662386f26fc1000060095411156114155760405162461bcd60e51b815260206004820152602b60248201527f5265776172647320706572207365636f6e64206d7573742062652062656c6f7760448201526a02031302c3030302c3030360ac1b606482015260840161059a565b61141f6000611f4f565b61142d81633b9aca0061282a565b60095550565b6001600160a01b038082166000908152600560209081526040808320938616835292905220606090611464906122f4565b9392505050565b60026001540361148d5760405162461bcd60e51b815260040161059a9061277a565b60026001553360009081526003602052604081205490036114c657600a546114b5904261286b565b336000908152600360205260409020555b6000600c6000815481106114dc576114dc6127b1565b60009182526020808320338452600d9091526040832060049092020192509061150490611f4f565b8054156115ef576000611539826002015461067964e8d4a51000610673876003015487600101546121d890919063ffffffff16565b9050611543611173565b811061155457611551611173565b90505b80156115ed5760405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906115a890339085906004016127c7565b6020604051808303816000875af11580156115c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115eb91906127e0565b505b505b600083156117dd5782546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa15801561163f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061166391906128ee565b84546040516323b872dd60e01b8152336004820152306024820152604481018890529192506001600160a01b0316906323b872dd906064016020604051808303816000875af11580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de91906127e0565b5083546040516370a0823160e01b815230600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015611726573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061174a91906128ee565b6117549190612813565b915082600101546008600082825461176c9190612813565b9091555050825461177d9083612301565b8355606461178a33610f83565b8454611796919061282a565b6117a09190612849565b836001018190555081600760008282546117ba919061286b565b90915550506001830154600880546000906117d690849061286b565b9091555050505b60025482546040516338c110ef60e21b81526001600160a01b039092169163e30443bc91611810913391906004016127c7565b600060405180830381600087803b15801561182a57600080fd5b505af115801561183e573d6000803e3d6000fd5b5050505061186664e8d4a51000610673856003015485600101546121d890919063ffffffff16565b600283015560405184815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c90602001610935565b6002600154036118bf5760405162461bcd60e51b815260040161059a9061277a565b60026001819055506000600c6000815481106118dd576118dd6127b1565b60009182526020808320338452600d90915260408320805460078054600490950290930195509093909283929190611916908490612813565b9091555050600182015460088054600090611932908490612813565b9091555050336000908152600360205260409020544211611974576064600b548261195d919061282a565b6119679190612849565b6119719082612813565b90505b33600081815260036020526040808220919091558454905163a9059cbb60e01b81526001600160a01b039091169163a9059cbb916119b7919085906004016127c7565b6020604051808303816000875af11580156119d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119fa91906127e0565b506000808355600183018190556002808401829055546040516338c110ef60e21b81526001600160a01b039091169163e30443bc91611a3d9133916004016127c7565b600060405180830381600087803b158015611a5757600080fd5b505af1158015611a6b573d6000803e3d6000fd5b50506040518381523392507f5fafa99d0643513820be26656b45130b01e1c03062e1266bf36f88cbd3bd9695915060200160405180910390a250506001805550565b600260015403611acf5760405162461bcd60e51b815260040161059a9061277a565b60026001553360009081526005602090815260408083206001600160a01b03861684529091529020611b019082612360565b611b855760405162461bcd60e51b815260206004820152604960248201527f43616e206f6e6c7920756e7374616b65206120746f6b656e494420616c6c6f6360448201527f617465642066726f6d2074686973204e4654206164647265737320666f72207460648201526834329039b2b73232b960b91b608482015260a40161059a565b336000908152600d60205260408120600c8054859391908290611baa57611baa6127b1565b90600052602060002090600402019050611bc46000611f4f565b815415611caf576000611bf9836002015461067964e8d4a51000610673866003015488600101546121d890919063ffffffff16565b9050611c03611173565b8110611c1457611c11611173565b90505b8015611cad5760405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90611c6890339085906004016127c7565b6020604051808303816000875af1158015611c87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cab91906127e0565b505b505b6040516323b872dd60e01b8152306004820152336024820152604481018590526001600160a01b038416906323b872dd90606401600060405180830381600087803b158015611cfd57600080fd5b505af1158015611d11573d6000803e3d6000fd5b5050336000908152600460205260408120805460019450909250611d36908490612813565b90915550503360009081526005602090815260408083206001600160a01b03891684529091529020611d689085612378565b50816001015460086000828254611d7f9190612813565b9091555060649050611d9033610f83565b8354611d9c919061282a565b611da69190612849565b6001830181905560088054600090611dbf90849061286b565b909155505060038101546001830154611de29164e8d4a5100091610673916121d8565b6002830155604051339085906001600160a01b038816907fb2f8dc0208beec4fd9cd28491960f2897e6bf6eed6e00d2d1eb4cbfa5e76b25990600090a4505060018055505050565b6000546001600160a01b03163314611e545760405162461bcd60e51b815260040161059a90612883565b611e5d81612384565b50565b600080600c600081548110611e7757611e776127b1565b600091825260208083206001600160a01b0387168452600d9091526040909220600260049092029092019081015490925064174876e7ff03611ebd575060009392505050565b6003820154600854600284015442118015611ed757508015155b15611f1d576000611efa600e546106738760010154611ef46112cc565b906121d8565b9050611f19611f12836106738464e8d4a510006121d8565b8490612301565b9250505b611f45836002015461067964e8d4a510006106738688600101546121d890919063ffffffff16565b9695505050505050565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611fb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fda91906128ee565b11156120d9576002546040516370a0823160e01b81523060048201526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263a9059cbb9291169083906370a0823190602401602060405180830381865afa158015612053573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207791906128ee565b6040518363ffffffff1660e01b81526004016120949291906127c7565b6020604051808303816000875af11580156120b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d791906127e0565b505b600260009054906101000a90046001600160a01b03166001600160a01b031663b51312916040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561212957600080fd5b505af115801561213d573d6000803e3d6000fd5b505050506000600c8281548110612156576121566127b1565b9060005260206000209060040201905080600201544211612175575050565b600854600081900361218c57504260029091015550565b60006121a4600e546106738560010154611ef46112cc565b90506121c76121bc836106738464e8d4a510006121d8565b600385015490612301565b600384015550504260029091015550565b6000826000036121ea57506000610fd9565b60006121f6838561282a565b9050826122038583612849565b146114645760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b606482015260840161059a565b600061146483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612444565b600061146483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061247b565b6000610fd9825490565b600061146483836124ac565b60606000611464836124fb565b60008061230e838561286b565b9050838110156114645760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015260640161059a565b60008181526001830160205260408120541515611464565b60006114648383612557565b6001600160a01b0381166123e95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161059a565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600081836124655760405162461bcd60e51b815260040161059a9190612907565b5060006124728486612849565b95945050505050565b6000818484111561249f5760405162461bcd60e51b815260040161059a9190612907565b5060006124728486612813565b60008181526001830160205260408120546124f357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610fd9565b506000610fd9565b60608160000180548060200260200160405190810160405280929190818152602001828054801561254b57602002820191906000526020600020905b815481526020019060010190808311612537575b50505050509050919050565b6000818152600183016020526040812054801561264057600061257b600183612813565b855490915060009061258f90600190612813565b90508181146125f45760008660000182815481106125af576125af6127b1565b90600052602060002001549050808760000184815481106125d2576125d26127b1565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806126055761260561295c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610fd9565b6000915050610fd9565b60006020828403121561265c57600080fd5b5035919050565b6001600160a01b0381168114611e5d57600080fd5b60006020828403121561268a57600080fd5b813561146481612663565b600080604083850312156126a857600080fd5b82356126b381612663565b946020939093013593505050565b8015158114611e5d57600080fd5b600080604083850312156126e257600080fd5b82356126ed81612663565b915060208301356126fd816126c1565b809150509250929050565b6000806040838503121561271b57600080fd5b823561272681612663565b915060208301356126fd81612663565b6020808252825182820181905260009190848201906040850190845b8181101561276e57835183529284019291840191600101612752565b50909695505050505050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03929092168252602082015260400190565b6000602082840312156127f257600080fd5b8151611464816126c1565b634e487b7160e01b600052601160045260246000fd5b600082821015612825576128256127fd565b500390565b6000816000190483118215151615612844576128446127fd565b500290565b60008261286657634e487b7160e01b600052601260045260246000fd5b500490565b6000821982111561287e5761287e6127fd565b500190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6000602082840312156128ca57600080fd5b815161146481612663565b6000600182016128e7576128e76127fd565b5060010190565b60006020828403121561290057600080fd5b5051919050565b600060208083528351808285015260005b8181101561293457858101830151858201604001528201612918565b81811115612946576000604083870101525b50601f01601f1916929092016040019392505050565b634e487b7160e01b600052603160045260246000fdfea264697066735822122077ba8d6977f86dcbd8d63b7bc14de958fbd100a57a774dce8f81df52e4d936b564736f6c634300080d003360c0604052735c7f8a570d578ed84e63fdfa7b1ee72deae1ae2360805234801561002857600080fd5b50600080546001600160a01b031916339081178255604051909182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001600f55670de0b6b3a764000060a05260805160a051611ae26100b5600039600081816104c10152610bac0152600081816105c001528181610901015261137f0152611ae26000f3fe6080604052600436106101d15760003560e01c8063aafd847a116100f7578063e30443bc11610095578063f2fde38b11610064578063f2fde38b1461056e578063fbcbc0f11461058e578063fc0c546a146105ae578063ffb2c479146105e257600080fd5b8063e30443bc14610503578063e7841ec014610523578063e98030c714610538578063f2e65d6f1461055857600080fd5b8063b5131291116100d1578063b51312911461047a578063bc4c4b371461048f578063be10b614146104af578063c0f306ef146104e357600080fd5b8063aafd847a14610401578063ab6ddfa814610437578063ad7a672f1461046457600080fd5b80635183d6fd1161016f57806385a6b3ae1161013e57806385a6b3ae146103795780638da5cb5b1461038f57806391b89fba146103c1578063a8b9d240146103e157600080fd5b80635183d6fd146102d45780636a474002146103395780636f2789ec1461034e578063715018a61461036457600080fd5b806327ce0147116101ab57806327ce01471461023e5780633009a6091461025e57806331e79db0146102745780634e7b827f1461029457600080fd5b806303c83302146101e557806309bbedde146101ed578063226cfa3d1461021157600080fd5b366101e0576101de61061d565b005b600080fd5b6101de61061d565b3480156101f957600080fd5b506008545b6040519081526020015b60405180910390f35b34801561021d57600080fd5b506101fe61022c3660046117f8565b600e6020526000908152604090205481565b34801561024a57600080fd5b506101fe6102593660046117f8565b610692565b34801561026a57600080fd5b506101fe600c5481565b34801561028057600080fd5b506101de61028f3660046117f8565b6106f5565b3480156102a057600080fd5b506102c46102af3660046117f8565b600d6020526000908152604090205460ff1681565b6040519015158152602001610208565b3480156102e057600080fd5b506102f46102ef366004611815565b61078d565b604080516001600160a01b0390991689526020890197909752958701949094526060860192909252608085015260a084015260c083015260e082015261010001610208565b34801561034557600080fd5b506101de6107fa565b34801561035a57600080fd5b506101fe600f5481565b34801561037057600080fd5b506101de610806565b34801561038557600080fd5b506101fe60065481565b34801561039b57600080fd5b506000546001600160a01b03165b6040516001600160a01b039091168152602001610208565b3480156103cd57600080fd5b506101fe6103dc3660046117f8565b61087a565b3480156103ed57600080fd5b506101fe6103fc3660046117f8565b610881565b34801561040d57600080fd5b506101fe61041c3660046117f8565b6001600160a01b031660009081526003602052604090205490565b34801561044357600080fd5b506101fe6104523660046117f8565b60046020526000908152604090205481565b34801561047057600080fd5b506101fe60055481565b34801561048657600080fd5b506101de6108ad565b34801561049b57600080fd5b506102c46104aa36600461183c565b610a1c565b3480156104bb57600080fd5b506101fe7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104ef57600080fd5b506101de6104fe3660046117f8565b610ac8565b34801561050f57600080fd5b506101de61051e366004611875565b610b60565b34801561052f57600080fd5b50600c546101fe565b34801561054457600080fd5b506101de610553366004611815565b610c0e565b34801561056457600080fd5b506101fe60075481565b34801561057a57600080fd5b506101de6105893660046117f8565b610d77565b34801561059a57600080fd5b506102f46105a93660046117f8565b610daa565b3480156105ba57600080fd5b506103a97f000000000000000000000000000000000000000000000000000000000000000081565b3480156105ee57600080fd5b506106026105fd366004611815565b610e91565b60408051938452602084019290925290820152606001610208565b60405162461bcd60e51b815260206004820152603a60248201527f43616e6e6f742073656e6420424e42206469726563746c7920746f207472616360448201527f6b657220617320697420697320756e7265636f76657261626c6500000000000060648201526084015b60405180910390fd5b565b6001600160a01b0381166000908152600260209081526040808320546004909252822054600154600160801b926106e5926106e0926106da916106d59190610fae565b611037565b90611047565b611085565b6106ef91906118b7565b92915050565b6000546001600160a01b0316331461071f5760405162461bcd60e51b8152600401610687906118d9565b6001600160a01b0381166000908152600d60205260408120805460ff1916600117905561074d908290611098565b61075681611131565b6040516001600160a01b038216907fa878b31040b2e6d0a9a3d3361209db3908ba62014b0dca52adbaee451d128b2590600090a250565b6000806000806000806000806107a260085490565b89106107c75750600096506000199550859450869350839250829150819050806107ef565b60006107d28a611264565b90506107dd81610daa565b98509850985098509850985098509850505b919395975091939597565b61080333611297565b50565b6000546001600160a01b031633146108305760405162461bcd60e51b8152600401610687906118d9565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60006106ef825b6001600160a01b0381166000908152600360205260408120546106ef906108a784610692565b9061144d565b6000546001600160a01b031633146108d75760405162461bcd60e51b8152600401610687906118d9565b60055415610690576040516370a0823160e01b815230600482015260009081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610948573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096c919061190e565b905080600754101561098c576007546109859082611927565b9150610991565b600091505b8115610a18576005546109bf906109ac84600160801b610fae565b6109b691906118b7565b6001549061148f565b60015560405182815233907fa493a9229478c3fcd73f66d2cdeb7f94fd0f341da924d1054236d784541165119060200160405180910390a2600654610a04908361148f565b600655600754610a14908361148f565b6007555b5050565b600080546001600160a01b03163314610a475760405162461bcd60e51b8152600401610687906118d9565b6000610a5284611297565b90508015610abe576001600160a01b0384166000818152600e6020526040908190204290555184151591907fa2c38e2d2fb7e3e1912d937fd1ca11ed6d51864dee4cfa7a7bf02becd7acf09290610aac9085815260200190565b60405180910390a360019150506106ef565b5060009392505050565b6000546001600160a01b03163314610af25760405162461bcd60e51b8152600401610687906118d9565b6001600160a01b0381166000908152600d602052604090205460ff16610b1757600080fd5b6001600160a01b0381166000818152600d6020526040808220805460ff19169055517f40a78dcf8526b72f2eaf598af1c7e49c8d5fc577f6c8f1bed887f3e4dfa289329190a250565b6000546001600160a01b03163314610b8a5760405162461bcd60e51b8152600401610687906118d9565b6001600160a01b0382166000908152600d602052604090205460ff16610a18577f00000000000000000000000000000000000000000000000000000000000000008110610bea57610bdb8282611098565b610be582826114ee565b610bfe565b610bf5826000611098565b610bfe82611131565b610c09826001610a1c565b505050565b6000546001600160a01b03163314610c385760405162461bcd60e51b8152600401610687906118d9565b6104b08110158015610c4d5750620151808111155b610ccd5760405162461bcd60e51b815260206004820152604560248201527f4469766964656e645f547261636b65723a20636c61696d57616974206d75737460448201527f206265207570646174656420746f206265747765656e203120616e6420323420606482015264686f75727360d81b608482015260a401610687565b600f548103610d445760405162461bcd60e51b815260206004820152603760248201527f4469766964656e645f547261636b65723a2043616e6e6f74207570646174652060448201527f636c61696d5761697420746f2073616d652076616c75650000000000000000006064820152608401610687565b600f5460405182907f474ea64804364a1e29a4487ddb63c3342a2dd826ccd8acf48825e680a0e6f20f90600090a3600f55565b6000546001600160a01b03163314610da15760405162461bcd60e51b8152600401610687906118d9565b610803816115ac565b806000808080808080610dbc8861166c565b9650600019955060008712610e1e57600c54871115610dea57600c54610de39088906116b1565b9550610e1e565b600c5460085460009110610dff576000610e0e565b600c54600854610e0e9161144d565b9050610e1a8882611047565b9650505b610e2788610881565b9450610e3288610692565b6001600160a01b0389166000908152600e6020526040902054909450925082610e5c576000610e6a565b600f54610e6a90849061148f565b9150428211610e7a576000610e84565b610e84824261144d565b9050919395975091939597565b60085460009081908190808203610eb3575050600c5460009250829150610fa7565b600c546000805a90506000805b8984108015610ece57508582105b15610f965784610edd8161193e565b60085490965086109050610ef057600094505b600060086000018681548110610f0857610f08611957565b60009182526020808320909101546001600160a01b0316808352600e909152604090912054909150610f39906116ee565b15610f5c57610f49816001610a1c565b15610f5c5781610f588161193e565b9250505b82610f668161193e565b93505060005a905080851115610f8d57610f8a610f83868361144d565b879061148f565b95505b9350610ec09050565b600c85905590975095509193505050505b9193909250565b600082600003610fc0575060006106ef565b6000610fcc838561196d565b905082610fd985836118b7565b146110305760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610687565b9392505050565b600081818112156106ef57600080fd5b600080611054838561198c565b9050600083121580156110675750838112155b8061107c575060008312801561107c57508381125b61103057600080fd5b60008082121561109457600080fd5b5090565b6001600160a01b0382166000908152600460205260409020805490829055808211156110f45760006110ca838361144d565b90506110d68482611715565b80600560008282546110e891906119cd565b90915550610c09915050565b80821015610c09576000611108828461144d565b9050611114848261176f565b80600560008282546111269190611927565b909155505050505050565b6001600160a01b0381166000908152600b602052604090205460ff166111545750565b6001600160a01b0381166000908152600b60209081526040808320805460ff1916905560098252808320839055600a90915281205460085490919061119b90600190611927565b90506000600860000182815481106111b5576111b5611957565b60009182526020808320909101546001600160a01b03908116808452600a909252604080842087905590871683528220919091556008805491925082918590811061120257611202611957565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055600880548061123c5761123c6119e5565b600082815260209020810160001990810180546001600160a01b031916905501905550505050565b60006008600001828154811061127c5761127c611957565b6000918252602090912001546001600160a01b031692915050565b6000806112a383610881565b90508015611444576001600160a01b0383166000908152600360205260409020546112ce908261148f565b6001600160a01b038416600090815260036020526040902055600754811161130d5780600760008282546113029190611927565b909155506113139050565b60006007555b826001600160a01b03167fee503bee2bb6a87e57bc57db795f98137327401a0e7b7ce42e37926cc1a9ca4d8260405161134e91815260200190565b60405180910390a260405163a9059cbb60e01b81526001600160a01b038481166004830152602482018390526000917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303816000875af11580156113ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ee91906119fb565b90508061143d576001600160a01b038416600090815260036020526040902054611418908361144d565b6001600160a01b03909416600090815260036020526040812094909455509192915050565b5092915050565b50600092915050565b600061103083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506117a9565b60008061149c83856119cd565b9050838110156110305760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610687565b6001600160a01b0382166000908152600b602052604090205460ff161561152c576001600160a01b0391909116600090815260096020526040902055565b6001600160a01b0382166000818152600b60209081526040808320805460ff191660019081179091556009835281842086905560088054600a909452918420839055820181559091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b03191690911790555050565b6001600160a01b0381166116115760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610687565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0381166000908152600b602052604081205460ff166116955750600019919050565b506001600160a01b03166000908152600a602052604090205490565b6000806116be8385611a18565b9050600083121580156116d15750838113155b8061107c575060008312801561107c575083811361103057600080fd5b60004282111561170057506000919050565b600f5461170d428461144d565b101592915050565b61174f6117306106d583600154610fae90919063ffffffff16565b6001600160a01b038416600090815260026020526040902054906116b1565b6001600160a01b0390921660009081526002602052604090209190915550565b61174f61178a6106d583600154610fae90919063ffffffff16565b6001600160a01b03841660009081526002602052604090205490611047565b600081848411156117cd5760405162461bcd60e51b81526004016106879190611a57565b5060006117da8486611927565b95945050505050565b6001600160a01b038116811461080357600080fd5b60006020828403121561180a57600080fd5b8135611030816117e3565b60006020828403121561182757600080fd5b5035919050565b801515811461080357600080fd5b6000806040838503121561184f57600080fd5b823561185a816117e3565b9150602083013561186a8161182e565b809150509250929050565b6000806040838503121561188857600080fd5b8235611893816117e3565b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b6000826118d457634e487b7160e01b600052601260045260246000fd5b500490565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60006020828403121561192057600080fd5b5051919050565b600082821015611939576119396118a1565b500390565b600060018201611950576119506118a1565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6000816000190483118215151615611987576119876118a1565b500290565b600080821280156001600160ff1b03849003851316156119ae576119ae6118a1565b600160ff1b83900384128116156119c7576119c76118a1565b50500190565b600082198211156119e0576119e06118a1565b500190565b634e487b7160e01b600052603160045260246000fd5b600060208284031215611a0d57600080fd5b81516110308161182e565b60008083128015600160ff1b850184121615611a3657611a366118a1565b6001600160ff1b0384018313811615611a5157611a516118a1565b50500390565b600060208083528351808285015260005b81811015611a8457858101830151858201604001528201611a68565b81811115611a96576000604083870101525b50601f01601f191692909201604001939250505056fea264697066735822122065dba3b9ce639b73c51a0731ede8db12193a7c965a0600358496ad2b61b887d464736f6c634300080d0033
Deployed ByteCode Sourcemap
60928:14168:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62355:27;;;;;;;;;160:25:1;;;148:2;133:18;62355:27:0;;;;;;;;62455:26;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;645:32:1;;;627:51;;709:2;694:18;;687:34;;;;737:18;;;730:34;795:2;780:18;;773:34;614:3;599:19;62455:26:0;381:432:1;62537:45:0;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1408:25:1;;;1464:2;1449:18;;1442:34;;;;1492:18;;;1485:34;1396:2;1381:18;62537:45:0;1206:319:1;61114:81:0;;;;;;;;-1:-1:-1;;;;;1709:32:1;;;1691:51;;1679:2;1664:18;61114:81:0;1530:218:1;61067:38:0;;;;;-1:-1:-1;;;;;61067:38:0;;;71417:1383;;;;;;:::i;:::-;;:::i;:::-;;73835:220;;;;;;:::i;:::-;;:::i;64533:1487::-;;;;;;:::i;:::-;;:::i;74977:116::-;;;:::i;67466:275::-;;;;;;:::i;:::-;;:::i;69570:190::-;;;:::i;21481:140::-;;;:::i;61872:36::-;;;;;64318:207;;;:::i;74360:133::-;;;:::i;62389:30::-;;;;;;64047:104;;;:::i;62241:26::-;;;;;;20839:79;20877:7;20904:6;-1:-1:-1;;;;;20904:6:0;20839:79;;74777:192;;;;;;:::i;:::-;;:::i;74063:289::-;;;:::i;62274:36::-;;;;;;64159:151;;;;;;:::i;:::-;;:::i;74501:268::-;;;;;;:::i;:::-;;:::i;63869:170::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;61957:52::-;;;;;;:::i;:::-;;;;;;;;;;;;;;69797:1564;;;;;;:::i;:::-;;:::i;62018:58::-;;;;;;:::i;:::-;;;;;;;;;;;;;;62182:50;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;4226:14:1;;4219:22;4201:41;;4189:2;4174:18;62182:50:0;4061:187:1;72871:815:0;;;:::i;62317:31::-;;;;;;66028:1345;;;;;;:::i;:::-;;:::i;21776:109::-;;;;;;:::i;:::-;;:::i;67806:747::-;;;;;;:::i;:::-;;:::i;61915:35::-;;;;;62455:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;62455:26:0;;;;-1:-1:-1;62455:26:0;;;:::o;71417:1383::-;59981:1;60579:7;;:19;60571:63;;;;-1:-1:-1;;;60571:63:0;;;;;;;:::i;:::-;;;;;;;;;59981:1;60712:7;:18;71510:10:::1;71493:28;::::0;;;:16:::1;:28;::::0;;;;;71525:15:::1;-1:-1:-1::0;71493:47:0::1;71485:92;;;::::0;-1:-1:-1;;;71485:92:0;;4815:2:1;71485:92:0::1;::::0;::::1;4797:21:1::0;;;4834:18;;;4827:30;4893:34;4873:18;;;4866:62;4945:18;;71485:92:0::1;4613:356:1::0;71485:92:0::1;71598:21;71622:8;71631:1;71622:11;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;71677:10:::1;71668:20:::0;;:8:::1;:20:::0;;;;;;71622:11:::1;::::0;;::::1;;::::0;-1:-1:-1;71668:20:0;71701:13:::1;::::0;:10:::1;:13::i;:::-;71725:15;71743:80;71807:4;:15;;;71743:59;71797:4;71743:49;71769:4;:22;;;71743:4;:21;;;:25;;:49;;;;:::i;:::-;:53:::0;::::1;:59::i;:::-;:63:::0;::::1;:80::i;:::-;71725:98;;71848:18;:16;:18::i;:::-;71837:7;:29;71834:88;;71892:18;:16;:18::i;:::-;71882:28;;71834:88;71935:11:::0;;71932:102:::1;;71963:59;::::0;-1:-1:-1;;;71963:59:0;;-1:-1:-1;;;;;71963:11:0::1;:20;::::0;::::1;::::0;:59:::1;::::0;72000:10:::1;::::0;72014:7;;71963:59:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;71932:102;72049:11:::0;;72046:347:::1;;72092:7;72077:4;:11;;;:22;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;72187:3:0::1;::::0;-1:-1:-1;72152:32:0::1;72173:10;72152:20;:32::i;:::-;72138:11:::0;;:46:::1;::::0;;::::1;:::i;:::-;:52;;;;:::i;:::-;72114:4;:21;;:76;;;;72220:7;72205:11;;:22;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;72312:3:0::1;::::0;-1:-1:-1;72277:32:0::1;72298:10;72277:20;:32::i;:::-;72267:42;::::0;:7;:42:::1;:::i;:::-;:48;;;;:::i;:::-;72242:21;;:73;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;72330:12:0;;:51:::1;::::0;-1:-1:-1;;;72330:51:0;;-1:-1:-1;;;;;72330:12:0;;::::1;::::0;:21:::1;::::0;:51:::1;::::0;72360:10:::1;::::0;72373:7;;72330:51:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;72046:347;72405:15;::::0;72453:11;;72405:60:::1;::::0;-1:-1:-1;;;72405:60:0;;-1:-1:-1;;;;;72405:15:0;;::::1;::::0;:26:::1;::::0;:60:::1;::::0;72440:10:::1;::::0;72453:11;72405:60:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;72494:59;72548:4;72494:49;72520:4;:22;;;72494:4;:21;;;:25;;:49;;;;:::i;:59::-;72476:15;::::0;::::1;:77:::0;72577:11;;:15;72574:172:::1;;72657:12;::::0;72639:30:::1;::::0;:15:::1;:30;:::i;:::-;72625:10;72608:28;::::0;;;:16:::1;:28;::::0;;;;:61;72574:172:::1;;;72719:10;72733:1;72702:28:::0;;;:16:::1;:28;::::0;;;;:32;72574:172:::1;72763:29;::::0;160:25:1;;;72772:10:0::1;::::0;72763:29:::1;::::0;148:2:1;133:18;72763:29:0::1;;;;;;;;-1:-1:-1::0;;59937:1:0;60891:22;;-1:-1:-1;;71417:1383:0:o;73835:220::-;21051:6;;-1:-1:-1;;;;;21051:6:0;14125:10;21051:22;21043:67;;;;-1:-1:-1;;;21043:67:0;;;;;;;:::i;:::-;73934:18:::1;:16;:18::i;:::-;73923:7;:29;;73915:71;;;::::0;-1:-1:-1;;;73915:71:0;;7570:2:1;73915:71:0::1;::::0;::::1;7552:21:1::0;7609:2;7589:18;;;7582:30;7648:31;7628:18;;;7621:59;7697:18;;73915:71:0::1;7368:353:1::0;73915:71:0::1;73997:50;::::0;-1:-1:-1;;;73997:50:0;;-1:-1:-1;;;;;73997:11:0::1;:20;::::0;::::1;::::0;:50:::1;::::0;74026:10:::1;::::0;74039:7;;73997:50:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;73835:220:::0;:::o;64533:1487::-;59981:1;60579:7;;:19;60571:63;;;;-1:-1:-1;;;60571:63:0;;;;;;;:::i;:::-;59981:1;60712:7;:18;-1:-1:-1;;;;;64629:29:0;::::1;;::::0;;;:17:::1;:29;::::0;;;;;::::1;;64621:72;;;::::0;-1:-1:-1;;;64621:72:0;;7928:2:1;64621:72:0::1;::::0;::::1;7910:21:1::0;7967:2;7947:18;;;7940:30;8006:32;7986:18;;;7979:60;8056:18;;64621:72:0::1;7726:354:1::0;64621:72:0::1;64729:10;64712:28;::::0;;;:16:::1;:28;::::0;;;;;;;-1:-1:-1;;;;;64712:40:0;::::1;::::0;;;;;;;64764:1:::1;::::0;64712:49:::1;::::0;:47:::1;:49::i;:::-;:53;64704:106;;;::::0;-1:-1:-1;;;64704:106:0;;8287:2:1;64704:106:0::1;::::0;::::1;8269:21:1::0;8326:2;8306:18;;;8299:30;8365:34;8345:18;;;8338:62;-1:-1:-1;;;8416:18:1;;;8409:38;8464:19;;64704:106:0::1;8085:404:1::0;64704:106:0::1;64918:10;64831:11;64909:20:::0;;;:8:::1;:20;::::0;;;;64964:8:::1;:11:::0;;64853:10;;64831:11;64964:8;64831:11;;64964::::1;;;;:::i;:::-;;::::0;;;::::1;::::0;;;64996:24:::1;::::0;-1:-1:-1;;;64996:24:0;;64964:11:::1;64996:24:::0;;::::1;160:25:1::0;;;64964:11:0;;::::1;;::::0;-1:-1:-1;65032:4:0::1;::::0;-1:-1:-1;;;;;64996:15:0;::::1;::::0;::::1;::::0;133:18:1;;64996:24:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;64996:41:0::1;;64988:83;;;::::0;-1:-1:-1;;;64988:83:0;;8952:2:1;64988:83:0::1;::::0;::::1;8934:21:1::0;8991:2;8971:18;;;8964:30;9030:31;9010:18;;;9003:59;9079:18;;64988:83:0::1;8750:353:1::0;64988:83:0::1;65084:13;65095:1;65084:10;:13::i;:::-;65114:11:::0;;:15;65110:371:::1;;65146:15;65164:80;65228:4;:15;;;65164:59;65218:4;65164:49;65190:4;:22;;;65164:4;:21;;;:25;;:49;;;;:::i;:80::-;65146:98;;65273:18;:16;:18::i;:::-;65262:7;:29;65259:96;;65321:18;:16;:18::i;:::-;65311:28;;65259:96;65372:11:::0;;65369:101:::1;;65404:50;::::0;-1:-1:-1;;;65404:50:0;;-1:-1:-1;;;;;65404:11:0::1;:20;::::0;::::1;::::0;:50:::1;::::0;65433:10:::1;::::0;65446:7;;65404:50:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;65369:101;65131:350;65110:371;65493:52;::::0;-1:-1:-1;;;65493:52:0;;65510:10:::1;65493:52;::::0;::::1;9348:34:1::0;65530:4:0::1;9398:18:1::0;;;9391:43;9450:18;;;9443:34;;;-1:-1:-1;;;;;65493:16:0;::::1;::::0;::::1;::::0;9283:18:1;;65493:52:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;65579:10:0::1;65556:34;::::0;;;:22:::1;:34;::::0;;;;:39;;65594:1:::1;::::0;-1:-1:-1;65556:34:0;;-1:-1:-1;65556:39:0::1;::::0;65594:1;;65556:39:::1;:::i;:::-;::::0;;;-1:-1:-1;;65623:10:0::1;65606:28;::::0;;;:16:::1;:28;::::0;;;;;;;-1:-1:-1;;;;;65606:40:0;::::1;::::0;;;;;;;:53:::1;::::0;65651:7;65606:44:::1;:53::i;:::-;;65697:4;:21;;;65672;;:46;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;65802:3:0::1;::::0;-1:-1:-1;65767:32:0::1;65788:10;65767:20;:32::i;:::-;65753:11:::0;;:46:::1;::::0;;::::1;:::i;:::-;:52;;;;:::i;:::-;65729:21;::::0;::::1;:76:::0;;;65816:21:::1;:46:::0;;:21:::1;::::0;:46:::1;::::0;65729:76;;65816:46:::1;:::i;:::-;::::0;;;-1:-1:-1;;65919:22:0::1;::::0;::::1;::::0;65893:21:::1;::::0;::::1;::::0;:59:::1;::::0;65947:4:::1;::::0;65893:49:::1;::::0;:25:::1;:49::i;:59::-;65875:15;::::0;::::1;:77:::0;65970:42:::1;::::0;66001:10:::1;::::0;65992:7;;-1:-1:-1;;;;;65970:42:0;::::1;::::0;::::1;::::0;;;::::1;-1:-1:-1::0;;59937:1:0;60891:22;;-1:-1:-1;;;64533:1487:0:o;74977:116::-;59981:1;60579:7;;:19;60571:63;;;;-1:-1:-1;;;60571:63:0;;;;;;;:::i;:::-;59981:1;60712:7;:18;;;75027:15;:58:::1;::::0;-1:-1:-1;;;75027:58:0;;75066:10:::1;75027:58;::::0;::::1;9672:51:1::0;75027:15:0::1;9739:18:1::0;;;9732:50;-1:-1:-1;;;;;75027:15:0;;::::1;::::0;:30:::1;::::0;9645:18:1;;75027:58:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;59937:1:0;60891:22;;74977:116::o;67466:275::-;-1:-1:-1;;;;;67556:30:0;;67533:7;67556:30;;;:22;:30;;;;;;:35;;67553:76;;-1:-1:-1;67614:3:0;;67466:275;-1:-1:-1;67466:275:0:o;67553:76::-;-1:-1:-1;;;;;67699:30:0;;;;;;:22;:30;;;;;;:33;;67730:2;67699:33;:::i;:::-;67692:41;;:3;:41;:::i;:::-;67685:48;67466:275;-1:-1:-1;;67466:275:0:o;69570:190::-;21051:6;;-1:-1:-1;;;;;21051:6:0;14125:10;21051:22;21043:67;;;;-1:-1:-1;;;21043:67:0;;;;;;;:::i;:::-;69642:8:::1;:15:::0;69625:14:::1;69668:85;69696:6;69690:3;:12;69668:85;;;69726:15;69737:3;69726:10;:15::i;:::-;69704:5;::::0;::::1;:::i;:::-;;;69668:85;;21481:140:::0;21051:6;;-1:-1:-1;;;;;21051:6:0;14125:10;21051:22;21043:67;;;;-1:-1:-1;;;21043:67:0;;;;;;;:::i;:::-;21580:1:::1;21564:6:::0;;21543:40:::1;::::0;-1:-1:-1;;;;;21564:6:0;;::::1;::::0;21543:40:::1;::::0;21580:1;;21543:40:::1;21611:1;21594:19:::0;;-1:-1:-1;;;;;;21594:19:0::1;::::0;;21481:140::o;64318:207::-;21051:6;;-1:-1:-1;;;;;21051:6:0;14125:10;21051:22;21043:67;;;;-1:-1:-1;;;21043:67:0;;;;;;;:::i;:::-;64379:8:::1;64388:1;64379:11;;;;;;;;:::i;:::-;;;;;;;;;;;:31;;;64414:11;64379:46;64371:86;;;::::0;-1:-1:-1;;;64371:86:0;;10135:2:1;64371:86:0::1;::::0;::::1;10117:21:1::0;10174:2;10154:18;;;10147:30;10213:29;10193:18;;;10186:57;10260:18;;64371:86:0::1;9933:351:1::0;64371:86:0::1;64502:15;64468:8;64477:1;64468:11;;;;;;;;:::i;:::-;;;;;;;;;;;:31;;:49;;;;64318:207::o:0;74360:133::-;74474:11;;74435:36;;-1:-1:-1;;;74435:36:0;;74465:4;74435:36;;;1691:51:1;74409:7:0;;74474:11;-1:-1:-1;;;;;74435:11:0;:21;;;;1664:18:1;;74435:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:50;;;;:::i;:::-;74428:57;;74360:133;:::o;64047:104::-;21051:6;;-1:-1:-1;;;;;21051:6:0;14125:10;21051:22;21043:67;;;;-1:-1:-1;;;21043:67:0;;;;;;;:::i;:::-;64099:13:::1;64110:1;64099:10;:13::i;:::-;64142:1;64123:16;:20:::0;64047:104::o;74777:192::-;21051:6;;-1:-1:-1;;;;;21051:6:0;14125:10;21051:22;21043:67;;;;-1:-1:-1;;;21043:67:0;;;;;;;:::i;:::-;74884:2:::1;74866:14;:20;;74858:60;;;::::0;-1:-1:-1;;;74858:60:0;;10680:2:1;74858:60:0::1;::::0;::::1;10662:21:1::0;10719:2;10699:18;;;10692:30;10758:29;10738:18;;;10731:57;10805:18;;74858:60:0::1;10478:351:1::0;74858:60:0::1;74929:15;:32:::0;74777:192::o;74063:289::-;74115:7;74135:21;74159:8;74168:1;74159:11;;;;;;;;:::i;:::-;;;;;;;;;;;74135:35;;74211:15;74184:4;:24;;;:42;74181:81;;;74249:1;74242:8;;;74063:289;:::o;74181:81::-;74327:16;;74299:24;;;;74281:42;;:15;:42;:::i;:::-;74280:63;;;;:::i;:::-;74272:72;;;74063:289;:::o;64159:151::-;21051:6;;-1:-1:-1;;;;;21051:6:0;14125:10;21051:22;21043:67;;;;-1:-1:-1;;;21043:67:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;64256:29:0;;;::::1;;::::0;;;:17:::1;:29;::::0;;;;:46;;-1:-1:-1;;64256:46:0::1;::::0;::::1;;::::0;;;::::1;::::0;;64159:151::o;74501:268::-;21051:6;;-1:-1:-1;;;;;21051:6:0;14125:10;21051:22;21043:67;;;;-1:-1:-1;;;21043:67:0;;;;;;;:::i;:::-;74620:14:::1;74600:16;;:34;;74592:90;;;::::0;-1:-1:-1;;;74592:90:0;;11036:2:1;74592:90:0::1;::::0;::::1;11018:21:1::0;11075:2;11055:18;;;11048:30;11114:34;11094:18;;;11087:62;-1:-1:-1;;;11165:18:1;;;11158:41;11216:19;;74592:90:0::1;10834:407:1::0;74592:90:0::1;74693:13;74704:1;74693:10;:13::i;:::-;74736:25;:19:::0;74758:3:::1;74736:25;:::i;:::-;74717:16;:44:::0;-1:-1:-1;74501:268:0:o;63869:170::-;-1:-1:-1;;;;;63986:24:0;;;;;;;:16;:24;;;;;;;;:36;;;;;;;;;63951:16;;63986:45;;:43;:45::i;:::-;63979:52;63869:170;-1:-1:-1;;;63869:170:0:o;69797:1564::-;59981:1;60579:7;;:19;60571:63;;;;-1:-1:-1;;;60571:63:0;;;;;;;:::i;:::-;59981:1;60712:7;:18;69882:10:::1;69865:28;::::0;;;:16:::1;:28;::::0;;;;;:33;;69862:125:::1;;69963:12;::::0;69945:30:::1;::::0;:15:::1;:30;:::i;:::-;69931:10;69914:28;::::0;;;:16:::1;:28;::::0;;;;:61;69862:125:::1;69997:21;70021:8;70030:1;70021:11;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;70076:10:::1;70067:20:::0;;:8:::1;:20:::0;;;;;;70021:11:::1;::::0;;::::1;;::::0;-1:-1:-1;70067:20:0;70100:13:::1;::::0;:10:::1;:13::i;:::-;70128:11:::0;;:15;70124:371:::1;;70160:15;70178:80;70242:4;:15;;;70178:59;70232:4;70178:49;70204:4;:22;;;70178:4;:21;;;:25;;:49;;;;:::i;:80::-;70160:98;;70287:18;:16;:18::i;:::-;70276:7;:29;70273:96;;70335:18;:16;:18::i;:::-;70325:28;;70273:96;70386:11:::0;;70383:101:::1;;70418:50;::::0;-1:-1:-1;;;70418:50:0;;-1:-1:-1;;;;;70418:11:0::1;:20;::::0;::::1;::::0;:50:::1;::::0;70447:10:::1;::::0;70460:7;;70418:50:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;70383:101;70145:350;70124:371;70505:25;70548:11:::0;;70545:602:::1;;70601:12:::0;;:37:::1;::::0;-1:-1:-1;;;70601:37:0;;70632:4:::1;70601:37;::::0;::::1;1691:51:1::0;70576:22:0::1;::::0;-1:-1:-1;;;;;70601:12:0::1;::::0;:22:::1;::::0;1664:18:1;;70601:37:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;70653:12:::0;;:70:::1;::::0;-1:-1:-1;;;70653:70:0;;70687:10:::1;70653:70;::::0;::::1;9348:34:1::0;70708:4:0::1;9398:18:1::0;;;9391:43;9450:18;;;9443:34;;;70576:62:0;;-1:-1:-1;;;;;;70653:12:0::1;::::0;:25:::1;::::0;9283:18:1;;70653:70:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;70758:12:0;;:37:::1;::::0;-1:-1:-1;;;70758:37:0;;70789:4:::1;70758:37;::::0;::::1;1691:51:1::0;70798:14:0;;-1:-1:-1;;;;;70758:12:0::1;::::0;:22:::1;::::0;1664:18:1;;70758:37:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:54;;;;:::i;:::-;70738:74;;70852:4;:21;;;70827;;:46;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;70902:11:0;;:34:::1;::::0;70918:17;70902:15:::1;:34::i;:::-;70888:48:::0;;71024:3:::1;70989:32;71010:10;70989:20;:32::i;:::-;70975:11:::0;;:46:::1;::::0;;::::1;:::i;:::-;:52;;;;:::i;:::-;70951:4;:21;;:76;;;;71057:17;71042:11;;:32;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;71114:21:0::1;::::0;::::1;::::0;71089::::1;:46:::0;;:21:::1;::::0;:46:::1;::::0;71114:21;;71089:46:::1;:::i;:::-;::::0;;;-1:-1:-1;;;70545:602:0::1;71159:15;::::0;71207:11;;71159:60:::1;::::0;-1:-1:-1;;;71159:60:0;;-1:-1:-1;;;;;71159:15:0;;::::1;::::0;:26:::1;::::0;:60:::1;::::0;71194:10:::1;::::0;71207:11;71159:60:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;71248:59;71302:4;71248:49;71274:4;:22;;;71248:4;:21;;;:25;;:49;;;;:::i;:59::-;71230:15;::::0;::::1;:77:::0;71325:28:::1;::::0;160:25:1;;;71333:10:0::1;::::0;71325:28:::1;::::0;148:2:1;133:18;71325:28:0::1;14:177:1::0;72871:815:0;59981:1;60579:7;;:19;60571:63;;;;-1:-1:-1;;;60571:63:0;;;;;;;:::i;:::-;59981:1;60712:7;:18;;;;72933:21:::1;72957:8;72966:1;72957:11;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;73012:10:::1;73003:20:::0;;:8:::1;:20:::0;;;;;;73052:11;;73074::::1;:22:::0;;72957:11:::1;::::0;;::::1;::::0;;::::1;::::0;-1:-1:-1;73003:20:0;;73052:11;;;;73074;72957;73074:22:::1;::::0;73052:11;;73074:22:::1;:::i;:::-;::::0;;;-1:-1:-1;;73132:21:0::1;::::0;::::1;::::0;73107::::1;:46:::0;;:21:::1;::::0;:46:::1;::::0;73132:21;;73107:46:::1;:::i;:::-;::::0;;;-1:-1:-1;;73267:10:0::1;73250:28;::::0;;;:16:::1;:28;::::0;;;;;73282:15:::1;-1:-1:-1::0;73247:120:0::1;;73352:3;73334:15;;73324:7;:25;;;;:::i;:::-;:31;;;;:::i;:::-;73313:42;::::0;;::::1;:::i;:::-;;;73247:120;73394:10;73408:1;73377:28:::0;;;:16:::1;:28;::::0;;;;;:32;;;;73420:12;;:51;;-1:-1:-1;;;73420:51:0;;-1:-1:-1;;;;;73420:12:0;;::::1;::::0;:21:::1;::::0;:51:::1;::::0;73394:10;73463:7;;73420:51:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;73496:1:0::1;73482:15:::0;;;73508:21:::1;::::0;::::1;:25:::0;;;73544:15:::1;::::0;;::::1;:19:::0;;;73574:15;:50:::1;::::0;-1:-1:-1;;;73574:50:0;;-1:-1:-1;;;;;73574:15:0;;::::1;::::0;:26:::1;::::0;:50:::1;::::0;73609:10:::1;::::0;73574:50:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;73640:38:0::1;::::0;160:25:1;;;73658:10:0::1;::::0;-1:-1:-1;73640:38:0::1;::::0;-1:-1:-1;148:2:1;133:18;73640:38:0::1;;;;;;;-1:-1:-1::0;;59937:1:0;60891:22;;-1:-1:-1;72871:815:0:o;66028:1345::-;59981:1;60579:7;;:19;60571:63;;;;-1:-1:-1;;;60571:63:0;;;;;;;:::i;:::-;59981:1;60712:7;:18;66143:10:::1;66126:28;::::0;;;:16:::1;:28;::::0;;;;;;;-1:-1:-1;;;;;66126:40:0;::::1;::::0;;;;;;;:58:::1;::::0;66176:7;66126:49:::1;:58::i;:::-;66118:144;;;::::0;-1:-1:-1;;;66118:144:0;;11751:2:1;66118:144:0::1;::::0;::::1;11733:21:1::0;11790:2;11770:18;;;11763:30;11829:34;11809:18;;;11802:62;11900:34;11880:18;;;11873:62;-1:-1:-1;;;11951:19:1;;;11944:40;12001:19;;66118:144:0::1;11549:477:1::0;66118:144:0::1;66362:10;66283:11;66353:20:::0;;;:8:::1;:20;::::0;;;;66408:8:::1;:11:::0;;66305:10;;66283:11;66408:8;66283:11;;66408::::1;;;;:::i;:::-;;;;;;;;;;;66384:35;;66432:13;66443:1;66432:10;:13::i;:::-;66462:11:::0;;:15;66458:371:::1;;66494:15;66512:80;66576:4;:15;;;66512:59;66566:4;66512:49;66538:4;:22;;;66512:4;:21;;;:25;;:49;;;;:::i;:80::-;66494:98;;66621:18;:16;:18::i;:::-;66610:7;:29;66607:96;;66669:18;:16;:18::i;:::-;66659:28;;66607:96;66720:11:::0;;66717:101:::1;;66752:50;::::0;-1:-1:-1;;;66752:50:0;;-1:-1:-1;;;;;66752:11:0::1;:20;::::0;::::1;::::0;:50:::1;::::0;66781:10:::1;::::0;66794:7;;66752:50:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;66717:101;66479:350;66458:371;66841:52;::::0;-1:-1:-1;;;66841:52:0;;66866:4:::1;66841:52;::::0;::::1;9348:34:1::0;66873:10:0::1;9398:18:1::0;;;9391:43;9450:18;;;9443:34;;;-1:-1:-1;;;;;66841:16:0;::::1;::::0;::::1;::::0;9283:18:1;;66841:52:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;66927:10:0::1;66904:34;::::0;;;:22:::1;:34;::::0;;;;:39;;66942:1:::1;::::0;-1:-1:-1;66904:34:0;;-1:-1:-1;66904:39:0::1;::::0;66942:1;;66904:39:::1;:::i;:::-;::::0;;;-1:-1:-1;;66971:10:0::1;66954:28;::::0;;;:16:::1;:28;::::0;;;;;;;-1:-1:-1;;;;;66954:40:0;::::1;::::0;;;;;;;:56:::1;::::0;67002:7;66954:47:::1;:56::i;:::-;;67048:4;:21;;;67023;;:46;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;67153:3:0::1;::::0;-1:-1:-1;67118:32:0::1;67139:10;67118:20;:32::i;:::-;67104:11:::0;;:46:::1;::::0;;::::1;:::i;:::-;:52;;;;:::i;:::-;67080:21;::::0;::::1;:76:::0;;;67167:21:::1;:46:::0;;:21:::1;::::0;:46:::1;::::0;67080:76;;67167:46:::1;:::i;:::-;::::0;;;-1:-1:-1;;67270:22:0::1;::::0;::::1;::::0;67244:21:::1;::::0;::::1;::::0;:59:::1;::::0;67298:4:::1;::::0;67244:49:::1;::::0;:25:::1;:49::i;:59::-;67226:15;::::0;::::1;:77:::0;67321:44:::1;::::0;67354:10:::1;::::0;67345:7;;-1:-1:-1;;;;;67321:44:0;::::1;::::0;::::1;::::0;;;::::1;-1:-1:-1::0;;59937:1:0;60891:22;;-1:-1:-1;;;66028:1345:0:o;21776:109::-;21051:6;;-1:-1:-1;;;;;21051:6:0;14125:10;21051:22;21043:67;;;;-1:-1:-1;;;21043:67:0;;;;;;;:::i;:::-;21849:28:::1;21868:8;21849:18;:28::i;:::-;21776:109:::0;:::o;67806:747::-;67867:7;67887:21;67911:8;67920:1;67911:11;;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;67957:15:0;;;;:8;:15;;;;;;;67986:24;67911:11;;;;;;;67986:24;;;;67911:11;;-1:-1:-1;68014:11:0;67986:39;67983:78;;-1:-1:-1;68048:1:0;;67806:747;-1:-1:-1;;;67806:747:0:o;67983:78::-;68099:22;;;;68151:21;;68205:24;;;;68187:15;:42;:59;;;;-1:-1:-1;68233:13:0;;;68187:59;68183:270;;;68263:19;68285:63;68332:15;;68285:42;68311:4;:15;;;68285:21;:19;:21::i;:::-;:25;;:42::i;:63::-;68263:85;-1:-1:-1;68383:58:0;68405:35;68431:8;68405:21;68263:85;68421:4;68405:15;:21::i;:35::-;68383:17;;:21;:58::i;:::-;68363:78;;68248:205;68183:270;68470:75;68529:4;:15;;;68470:54;68519:4;68470:44;68496:17;68470:4;:21;;;:25;;:44;;;;:::i;:75::-;68463:82;67806:747;-1:-1:-1;;;;;;67806:747:0:o;68629:858::-;68731:29;;-1:-1:-1;;;68731:29:0;;68754:4;68731:29;;;1691:51:1;68763:1:0;;68731:4;-1:-1:-1;;;;;68731:14:0;;;;1664:18:1;;68731:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:33;68728:134;;;68802:15;;68820:29;;-1:-1:-1;;;68820:29:0;;68843:4;68820:29;;;1691:51:1;-1:-1:-1;;;;;68780:4:0;:13;;;;;68802:15;;;68780:13;;68820:14;;1664:18:1;;68820:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68780:70;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;68728:134;68878:15;;;;;;;;;-1:-1:-1;;;;;68878:15:0;-1:-1:-1;;;;;68878:40:0;;:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68931:21;68955:8;68964:4;68955:14;;;;;;;;:::i;:::-;;;;;;;;;;;68931:38;;69003:4;:24;;;68984:15;:43;68980:82;;69044:7;68629:858;:::o;68980:82::-;69091:21;;69072:16;69127:13;;;69123:109;;-1:-1:-1;69184:15:0;69157:24;;;;:42;-1:-1:-1;68629:858:0:o;69123:109::-;69242:19;69264:63;69311:15;;69264:42;69290:4;:15;;;69264:21;:19;:21::i;:63::-;69242:85;-1:-1:-1;69363:63:0;69390:35;69416:8;69390:21;69242:85;69406:4;69390:15;:21::i;:35::-;69363:22;;;;;:26;:63::i;:::-;69338:22;;;:88;-1:-1:-1;;69464:15:0;69437:24;;;;:42;-1:-1:-1;68629:858:0:o;24455:471::-;24513:7;24758:1;24763;24758:6;24754:47;;-1:-1:-1;24788:1:0;24781:8;;24754:47;24813:9;24825:5;24829:1;24825;:5;:::i;:::-;24813:17;-1:-1:-1;24858:1:0;24849:5;24853:1;24813:17;24849:5;:::i;:::-;:10;24841:56;;;;-1:-1:-1;;;24841:56:0;;12233:2:1;24841:56:0;;;12215:21:1;12272:2;12252:18;;;12245:30;12311:34;12291:18;;;12284:62;-1:-1:-1;;;12362:18:1;;;12355:31;12403:19;;24841:56:0;12031:397:1;25402:132:0;25460:7;25487:39;25491:1;25494;25487:39;;;;;;;;;;;;;;;;;:3;:39::i;23531:136::-;23589:7;23616:43;23620:1;23623;23616:43;;;;;;;;;;;;;;;;;:3;:43::i;11764:114::-;11824:7;11851:19;11859:3;4749:18;;4666:109;11002:131;11069:4;11093:32;11098:3;11118:5;11093:4;:32::i;12919:307::-;12979:16;13008:22;13033:19;13041:3;13033:7;:19::i;23067:181::-;23125:7;;23157:5;23161:1;23157;:5;:::i;:::-;23145:17;;23186:1;23181;:6;;23173:46;;;;-1:-1:-1;;;23173:46:0;;12635:2:1;23173:46:0;;;12617:21:1;12674:2;12654:18;;;12647:30;12713:29;12693:18;;;12686:57;12760:18;;23173:46:0;12433:351:1;11532:146:0;11609:4;4548:19;;;:12;;;:19;;;;;;:24;;11633:37;4451:129;11309:137;11379:4;11403:35;11411:3;11431:5;11403:7;:35::i;21991:229::-;-1:-1:-1;;;;;22065:22:0;;22057:73;;;;-1:-1:-1;;;22057:73:0;;12991:2:1;22057:73:0;;;12973:21:1;13030:2;13010:18;;;13003:30;13069:34;13049:18;;;13042:62;-1:-1:-1;;;13120:18:1;;;13113:36;13166:19;;22057:73:0;12789:402:1;22057:73:0;22167:6;;;22146:38;;-1:-1:-1;;;;;22146:38:0;;;;22167:6;;;22146:38;;;22195:6;:17;;-1:-1:-1;;;;;;22195:17:0;-1:-1:-1;;;;;22195:17:0;;;;;;;;;;21991:229::o;26030:312::-;26150:7;26185:12;26178:5;26170:28;;;;-1:-1:-1;;;26170:28:0;;;;;;;;:::i;:::-;-1:-1:-1;26209:9:0;26221:5;26225:1;26221;:5;:::i;:::-;26209:17;26030:312;-1:-1:-1;;;;;26030:312:0:o;23970:226::-;24090:7;24126:12;24118:6;;;;24110:29;;;;-1:-1:-1;;;24110:29:0;;;;;;;;:::i;:::-;-1:-1:-1;24150:9:0;24162:5;24166:1;24162;:5;:::i;2355:414::-;2418:4;4548:19;;;:12;;;:19;;;;;;2435:327;;-1:-1:-1;2478:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;2661:18;;2639:19;;;:12;;;:19;;;;;;:40;;;;2694:11;;2435:327;-1:-1:-1;2745:5:0;2738:12;;5799:111;5855:16;5891:3;:11;;5884:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5799:111;;;:::o;2945:1420::-;3011:4;3150:19;;;:12;;;:19;;;;;;3186:15;;3182:1176;;3561:21;3585:14;3598:1;3585:10;:14;:::i;:::-;3634:18;;3561:38;;-1:-1:-1;3614:17:0;;3634:22;;3655:1;;3634:22;:::i;:::-;3614:42;;3690:13;3677:9;:26;3673:405;;3724:17;3744:3;:11;;3756:9;3744:22;;;;;;;;:::i;:::-;;;;;;;;;3724:42;;3898:9;3869:3;:11;;3881:13;3869:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;3983:23;;;:12;;;:23;;;;;:36;;;3673:405;4159:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;4254:3;:12;;:19;4267:5;4254:19;;;;;;;;;;;4247:26;;;4297:4;4290:11;;;;;;;3182:1176;4341:5;4334:12;;;;;196:180:1;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:1;;196:180;-1:-1:-1;196:180:1:o;818:131::-;-1:-1:-1;;;;;893:31:1;;883:42;;873:70;;939:1;936;929:12;954:247;1013:6;1066:2;1054:9;1045:7;1041:23;1037:32;1034:52;;;1082:1;1079;1072:12;1034:52;1121:9;1108:23;1140:31;1165:5;1140:31;:::i;1993:315::-;2061:6;2069;2122:2;2110:9;2101:7;2097:23;2093:32;2090:52;;;2138:1;2135;2128:12;2090:52;2177:9;2164:23;2196:31;2221:5;2196:31;:::i;:::-;2246:5;2298:2;2283:18;;;;2270:32;;-1:-1:-1;;;1993:315:1:o;2521:118::-;2607:5;2600:13;2593:21;2586:5;2583:32;2573:60;;2629:1;2626;2619:12;2644:382;2709:6;2717;2770:2;2758:9;2749:7;2745:23;2741:32;2738:52;;;2786:1;2783;2776:12;2738:52;2825:9;2812:23;2844:31;2869:5;2844:31;:::i;:::-;2894:5;-1:-1:-1;2951:2:1;2936:18;;2923:32;2964:30;2923:32;2964:30;:::i;:::-;3013:7;3003:17;;;2644:382;;;;;:::o;3031:388::-;3099:6;3107;3160:2;3148:9;3139:7;3135:23;3131:32;3128:52;;;3176:1;3173;3166:12;3128:52;3215:9;3202:23;3234:31;3259:5;3234:31;:::i;:::-;3284:5;-1:-1:-1;3341:2:1;3326:18;;3313:32;3354:33;3313:32;3354:33;:::i;3424:632::-;3595:2;3647:21;;;3717:13;;3620:18;;;3739:22;;;3566:4;;3595:2;3818:15;;;;3792:2;3777:18;;;3566:4;3861:169;3875:6;3872:1;3869:13;3861:169;;;3936:13;;3924:26;;4005:15;;;;3970:12;;;;3897:1;3890:9;3861:169;;;-1:-1:-1;4047:3:1;;3424:632;-1:-1:-1;;;;;;3424:632:1:o;4253:355::-;4455:2;4437:21;;;4494:2;4474:18;;;4467:30;4533:33;4528:2;4513:18;;4506:61;4599:2;4584:18;;4253:355::o;4974:127::-;5035:10;5030:3;5026:20;5023:1;5016:31;5066:4;5063:1;5056:15;5090:4;5087:1;5080:15;5106:282;-1:-1:-1;;;;;5306:32:1;;;;5288:51;;5370:2;5355:18;;5348:34;5276:2;5261:18;;5106:282::o;5393:245::-;5460:6;5513:2;5501:9;5492:7;5488:23;5484:32;5481:52;;;5529:1;5526;5519:12;5481:52;5561:9;5555:16;5580:28;5602:5;5580:28;:::i;5643:127::-;5704:10;5699:3;5695:20;5692:1;5685:31;5735:4;5732:1;5725:15;5759:4;5756:1;5749:15;5775:125;5815:4;5843:1;5840;5837:8;5834:34;;;5848:18;;:::i;:::-;-1:-1:-1;5885:9:1;;5775:125::o;5905:168::-;5945:7;6011:1;6007;6003:6;5999:14;5996:1;5993:21;5988:1;5981:9;5974:17;5970:45;5967:71;;;6018:18;;:::i;:::-;-1:-1:-1;6058:9:1;;5905:168::o;6078:217::-;6118:1;6144;6134:132;;6188:10;6183:3;6179:20;6176:1;6169:31;6223:4;6220:1;6213:15;6251:4;6248:1;6241:15;6134:132;-1:-1:-1;6280:9:1;;6078:217::o;6874:128::-;6914:3;6945:1;6941:6;6938:1;6935:13;6932:39;;;6951:18;;:::i;:::-;-1:-1:-1;6987:9:1;;6874:128::o;7007:356::-;7209:2;7191:21;;;7228:18;;;7221:30;7287:34;7282:2;7267:18;;7260:62;7354:2;7339:18;;7007:356::o;8494:251::-;8564:6;8617:2;8605:9;8596:7;8592:23;8588:32;8585:52;;;8633:1;8630;8623:12;8585:52;8665:9;8659:16;8684:31;8709:5;8684:31;:::i;9793:135::-;9832:3;9853:17;;;9850:43;;9873:18;;:::i;:::-;-1:-1:-1;9920:1:1;9909:13;;9793:135::o;10289:184::-;10359:6;10412:2;10400:9;10391:7;10387:23;10383:32;10380:52;;;10428:1;10425;10418:12;10380:52;-1:-1:-1;10451:16:1;;10289:184;-1:-1:-1;10289:184:1:o;13196:597::-;13308:4;13337:2;13366;13355:9;13348:21;13398:6;13392:13;13441:6;13436:2;13425:9;13421:18;13414:34;13466:1;13476:140;13490:6;13487:1;13484:13;13476:140;;;13585:14;;;13581:23;;13575:30;13551:17;;;13570:2;13547:26;13540:66;13505:10;;13476:140;;;13634:6;13631:1;13628:13;13625:91;;;13704:1;13699:2;13690:6;13679:9;13675:22;13671:31;13664:42;13625:91;-1:-1:-1;13777:2:1;13756:15;-1:-1:-1;;13752:29:1;13737:45;;;;13784:2;13733:54;;13196:597;-1:-1:-1;;;13196:597:1:o;13798:127::-;13859:10;13854:3;13850:20;13847:1;13840:31;13890:4;13887:1;13880:15;13914:4;13911:1;13904:15
Swarm Source
ipfs://65dba3b9ce639b73c51a0731ede8db12193a7c965a0600358496ad2b61b887d4
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.