More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
18297289 | 5 hrs ago | 0 ETH | ||||
18297289 | 5 hrs ago | 0 ETH | ||||
18297289 | 5 hrs ago | 0 ETH | ||||
18296462 | 6 hrs ago | 0 ETH | ||||
18296462 | 6 hrs ago | 0 ETH | ||||
18296462 | 6 hrs ago | 0 ETH | ||||
18214021 | 2 days ago | 0 ETH | ||||
18214021 | 2 days ago | 0 ETH | ||||
18214021 | 2 days ago | 0 ETH | ||||
18176724 | 4 days ago | 0 ETH | ||||
18176724 | 4 days ago | 0 ETH | ||||
18176724 | 4 days ago | 0 ETH | ||||
18176085 | 4 days ago | 0 ETH | ||||
18176085 | 4 days ago | 0 ETH | ||||
18176085 | 4 days ago | 0 ETH | ||||
18140901 | 5 days ago | 0 ETH | ||||
18140901 | 5 days ago | 0 ETH | ||||
18140901 | 5 days ago | 0 ETH | ||||
18140896 | 5 days ago | 0 ETH | ||||
18140896 | 5 days ago | 0 ETH | ||||
18140896 | 5 days ago | 0 ETH | ||||
18140835 | 5 days ago | 0 ETH | ||||
18140835 | 5 days ago | 0 ETH | ||||
18140835 | 5 days ago | 0 ETH | ||||
18121267 | 6 days ago | 0 ETH |
Loading...
Loading
Contract Name:
TownStoryCreateAccount
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity)
/** *Submitted for verification at lineascan.build/ on 2024-02-20 */ pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; } pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } } pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } pragma solidity ^0.8.0; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(account), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } } pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } pragma solidity ^0.8.0; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } } pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @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); } pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); } pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721ReceiverUpgradeable { /** * @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); } pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721MetadataUpgradeable is IERC721Upgradeable { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } pragma solidity ^0.8.2; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } } pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; } pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } } pragma solidity ^0.8.0; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = MathUpgradeable.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, MathUpgradeable.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; } pragma solidity ^0.8.0; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable { using AddressUpgradeable for address; using StringsUpgradeable for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC721_init_unchained(name_, symbol_); } function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { return interfaceId == type(IERC721Upgradeable).interfaceId || interfaceId == type(IERC721MetadataUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721Upgradeable.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721Upgradeable.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721Upgradeable.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721Upgradeable.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721Upgradeable.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721Upgradeable.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721ReceiverUpgradeable.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256, /* firstTokenId */ uint256 batchSize ) internal virtual { if (batchSize > 1) { if (from != address(0)) { _balances[from] -= batchSize; } if (to != address(0)) { _balances[to] += batchSize; } } } /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual {} /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[44] private __gap; } pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721EnumerableUpgradeable is IERC721Upgradeable { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } pragma solidity ^0.8.0; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721EnumerableUpgradeable is Initializable, ERC721Upgradeable, IERC721EnumerableUpgradeable { function __ERC721Enumerable_init() internal onlyInitializing { } function __ERC721Enumerable_init_unchained() internal onlyInitializing { } // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC721Upgradeable) returns (bool) { return interfaceId == type(IERC721EnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721Upgradeable.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721EnumerableUpgradeable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev See {ERC721-_beforeTokenTransfer}. */ function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual override { super._beforeTokenTransfer(from, to, firstTokenId, batchSize); if (batchSize > 1) { // Will only trigger during construction. Batch transferring (minting) is not available afterwards. revert("ERC721Enumerable: consecutive transfers not supported"); } uint256 tokenId = firstTokenId; if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721Upgradeable.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721Upgradeable.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[46] private __gap; } pragma solidity ^0.8.0; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library CountersUpgradeable { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } pragma solidity ^0.8.0; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. * * _Available since v4.5._ */ interface IERC2981Upgradeable is IERC165Upgradeable { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address receiver, uint256 royaltyAmount); } pragma solidity ^0.8.0; /** * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. * * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. * * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the * fee is specified in basis points by default. * * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. * * _Available since v4.5._ */ abstract contract ERC2981Upgradeable is Initializable, IERC2981Upgradeable, ERC165Upgradeable { function __ERC2981_init() internal onlyInitializing { } function __ERC2981_init_unchained() internal onlyInitializing { } struct RoyaltyInfo { address receiver; uint96 royaltyFraction; } RoyaltyInfo private _defaultRoyaltyInfo; mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC165Upgradeable) returns (bool) { return interfaceId == type(IERC2981Upgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @inheritdoc IERC2981Upgradeable */ function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) { RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId]; if (royalty.receiver == address(0)) { royalty = _defaultRoyaltyInfo; } uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator(); return (royalty.receiver, royaltyAmount); } /** * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an * override. */ function _feeDenominator() internal pure virtual returns (uint96) { return 10000; } /** * @dev Sets the royalty information that all ids in this contract will default to. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); require(receiver != address(0), "ERC2981: invalid receiver"); _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Removes default royalty information. */ function _deleteDefaultRoyalty() internal virtual { delete _defaultRoyaltyInfo; } /** * @dev Sets the royalty information for a specific token id, overriding the global default. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setTokenRoyalty( uint256 tokenId, address receiver, uint96 feeNumerator ) internal virtual { require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); require(receiver != address(0), "ERC2981: Invalid parameters"); _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Resets royalty information for the token id back to the global default. */ function _resetTokenRoyalty(uint256 tokenId) internal virtual { delete _tokenRoyaltyInfo[tokenId]; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[48] private __gap; } pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } pragma solidity ^0.8.0; contract GameOwnerUpgradeable is Initializable, OwnableUpgradeable { mapping (address => bool) private gameRoles; uint256 public gameRolesCount; modifier onlyGame { require(gameRoles[_msgSender()], "TownStory: Permission denied"); _; } function __GameOwner_init() internal onlyInitializing { } function __GameOwner_init_unchained() internal onlyInitializing { } function _isGameOwner(address _addr) internal view returns(bool) { return gameRoles[_addr]; } function _addGameOwner(address _addr) internal { require(!_isGameOwner(_addr), "TownStory: Owner already exists"); gameRolesCount++; gameRoles[_addr] = true; } function _removeGameOwner(address _addr) internal { require(_isGameOwner(_addr), "TownStory: Owner does not exist"); gameRolesCount--; gameRoles[_addr] = false; } function addGameOwnerBatch(address[] memory _addrs) public onlyOwner { for (uint256 i = 0; i < _addrs.length; i++) { _addGameOwner(_addrs[i]); } } function removeGameOwnerBatch(address[] memory _addrs) public onlyOwner { for (uint256 i = 0; i < _addrs.length; i++) { _removeGameOwner(_addrs[i]); } } function isGameOwner(address addr) public view returns(bool) { return _isGameOwner(addr); } uint256[48] private __gap; } pragma solidity ^0.8.0; /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); } pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } pragma solidity ^0.8.0; struct AccountInfo { uint256 tokenId; uint256 passId; address owner; address holder; } contract TownStoryAccountUpgradeable is Initializable, ERC721Upgradeable, ERC721EnumerableUpgradeable, ERC2981Upgradeable, PausableUpgradeable, GameOwnerUpgradeable { using CountersUpgradeable for CountersUpgradeable.Counter; CountersUpgradeable.Counter private _tokenIdCounter; address private signer; string private baseURI; bool public userAccountUnique; mapping(uint256 => uint256) private gamePass; mapping(uint256 => uint256) private passAccountId; mapping (uint256 => address) private holders; event AccountMinted(address indexed sender, uint256 indexed accountId, address indexed accountHolder); /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } function initialize(uint256 startId) initializer public { __ERC721_init("TownStory Account", "TSA"); __ERC721Enumerable_init(); __Pausable_init(); __Ownable_init(); __ERC2981_init(); __GameOwner_init(); _tokenIdCounter._value = startId; } function setBaseURI(string memory _uri) public onlyOwner { baseURI = _uri; } function _baseURI() internal view override returns (string memory) { return baseURI; } function pause() public onlyOwner { _pause(); } function unpause() public onlyOwner { _unpause(); } function setUserAccountUnique(bool _userAccountUnique) public onlyOwner { userAccountUnique = _userAccountUnique; } function setDefaultRoyalty(address _receiver, uint96 _feeNumerator) public onlyOwner { _setDefaultRoyalty(_receiver, _feeNumerator); } function deleteDefaultRoyalty() public onlyOwner { _deleteDefaultRoyalty(); } function setTokenRoyalty( uint256 _tokenId, address _receiver, uint96 _feeNumerator ) public onlyOwner { _setTokenRoyalty(_tokenId, _receiver, _feeNumerator); } function resetTokenRoyalty(uint256 _tokenId) public onlyOwner { _resetTokenRoyalty(_tokenId); } function createAccount(address to) public onlyGame returns (uint256, address) { uint256 tokenId = _tokenIdCounter.current(); _tokenIdCounter.increment(); _safeMint(to, tokenId); AccountHolder holder = new AccountHolder(this, tokenId); holders[tokenId] = address(holder); emit AccountMinted(to, tokenId, address(holder)); return (tokenId, holders[tokenId]); } function createAccountById(address to, uint256 tokenId) public onlyGame returns (uint256, address) { _safeMint(to, tokenId); AccountHolder holder = new AccountHolder(this, tokenId); holders[tokenId] = address(holder); emit AccountMinted(to, tokenId, address(holder)); return (tokenId, holders[tokenId]); } function transferFrom( address from, address to, uint256 tokenId ) public onlyGame override(ERC721Upgradeable) { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId ) public onlyGame override(ERC721Upgradeable) { safeTransferFrom(from, to, tokenId, ""); } function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public onlyGame override(ERC721Upgradeable) { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } // Game pass function bindGamePass(uint256[] memory accountIds, uint256[] memory passIds) public onlyGame { for (uint256 i = 0; i < accountIds.length; i++) { require(gamePass[accountIds[i]] == 0 && passAccountId[passIds[i]] == 0, "TownStory: Already bound"); gamePass[accountIds[i]] = passIds[i]; passAccountId[passIds[i]] = accountIds[i]; } } function unbindGamePass(uint256[] memory accountIds) public onlyGame { for (uint256 i = 0; i < accountIds.length; i++) { uint256 passId = gamePass[accountIds[i]]; require(passId > 0 && passAccountId[passId] > 0, "TownStory: Not bound"); gamePass[accountIds[i]] = 0; passAccountId[passId] = 0; } } function getGamePass(uint256 accountId) public view returns (uint256) { return gamePass[accountId]; } function getPassAccountId(uint256 passId) public view returns (uint256) { return passAccountId[passId]; } function gameTransfer(address from, address to, uint256 tokenId) public onlyGame returns (bool) { _transfer(from, to, tokenId); return true; } function gameApprove(address to, uint256 tokenId) public onlyGame returns (bool) { _approve(to, tokenId); return true; } function gameBurn(uint256 tokenId) public onlyGame returns (bool) { _burn(tokenId); return true; } function accountInfoById(uint256 _tokenId) public view returns (AccountInfo memory) { address gameOwner = ownerOf(_tokenId); address holder = holders[_tokenId]; uint256 _passId = getGamePass(_tokenId); return AccountInfo({ tokenId: _tokenId, passId: _passId, owner: gameOwner, holder: holder }); } function accountInfo(address _address) public view returns (AccountInfo memory) { uint256 _tokenId = tokenOfOwnerByIndex(_address, 0); address gameOwner = ownerOf(_tokenId); address holder = holders[_tokenId]; uint256 _passId = getGamePass(_tokenId); return AccountInfo({ tokenId: _tokenId, passId: _passId, owner: gameOwner, holder: holder }); } function accountInfoBatch(address _address) public view returns (AccountInfo[] memory) { uint256 balance = balanceOf(_address); AccountInfo[] memory accounts = new AccountInfo[](balance); for (uint256 i = 0; i < balance; i++) { uint256 _tokenId = tokenOfOwnerByIndex(_address, i); address gameOwner = ownerOf(_tokenId); address holder = holders[_tokenId]; uint256 _passId = getGamePass(_tokenId); AccountInfo memory account = AccountInfo({ tokenId: _tokenId, passId: _passId, owner: gameOwner, holder: holder }); accounts[i] = account; } return accounts; } function setTokenIdCounter(uint256 num) public onlyOwner { _tokenIdCounter._value = num; } function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal whenNotPaused override(ERC721Upgradeable, ERC721EnumerableUpgradeable) { if (to != address(0) && userAccountUnique) { uint256 balance = balanceOf(to); require(balance < 1, "TownStory: The recipient account already exists"); } super._beforeTokenTransfer(from, to, tokenId, batchSize); } // The following functions are overrides required by Solidity. function supportsInterface(bytes4 interfaceId) public view override (ERC721Upgradeable, ERC721EnumerableUpgradeable, ERC2981Upgradeable) returns (bool) { return super.supportsInterface(interfaceId); } } contract AccountHolder is ERC165, IERC721Receiver, IERC1155Receiver { TownStoryAccountUpgradeable private tsAccount; uint256 private tokenId; uint256 public version; constructor(TownStoryAccountUpgradeable _tsAccount, uint256 _tokenId) { tsAccount = _tsAccount; tokenId = _tokenId; version = 100; } function onERC721Received( address, address, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC721Received.selector; } function onERC1155Received( address, address, uint256, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155Received.selector; } function onERC1155BatchReceived( address, address, uint256[] memory, uint256[] memory, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155BatchReceived.selector; } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); } function withdraw() public { require(tsAccount.ownerOf(tokenId) == msg.sender, "Permission denied"); payable(msg.sender).transfer(address(this).balance); } } pragma solidity ^0.8.0; contract TownStoryCreateAccount is AccessControl, ReentrancyGuard { using ECDSA for bytes32; address private signer; address private _owner; TownStoryAccountUpgradeable tsAccount; bytes32 public constant SERVER_ROLE = keccak256("SERVER_ROLE"); uint256 public mintPrice; mapping(address => bool) private created; mapping(bytes32 => bool) public executed; event CreateAccountMinted(address indexed sender, uint256 indexed accountId, address indexed accountHolder); constructor(TownStoryAccountUpgradeable _account, address _signer, address _minter) { tsAccount = _account; signer = _signer; _owner = msg.sender; _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); _grantRole(SERVER_ROLE, _minter); } modifier _notContract() { uint256 size; address addr = msg.sender; assembly { size := extcodesize(addr) } require(size == 0, "Contract is not allowed"); require(msg.sender == tx.origin, "Proxy contract is not allowed"); _; } function createAccount(uint256 limit) external nonReentrant _notContract onlyRole(DEFAULT_ADMIN_ROLE) payable { address user = _msgSender(); uint256 balance = tsAccount.balanceOf(user); require(balance < limit, "TownStory: The recipient account already exists"); require( mintPrice <= msg.value, "TownStory: Not enough value sent" ); (uint256 tokenId, address holder) = tsAccount.createAccount(user); emit CreateAccountMinted(user, tokenId, holder); } function gameCreateAccount(address user, uint256 limit) external onlyRole(SERVER_ROLE) { uint256 balance = tsAccount.balanceOf(user); require(balance < limit, "TownStory: The recipient account already exists"); (uint256 tokenId, address holder) = tsAccount.createAccount(user); emit CreateAccountMinted(user, tokenId, holder); } function createAccountSign( bytes memory signature, uint256 passId, uint deadline ) external nonReentrant _notContract payable { require(deadline >= block.timestamp, "TownStory: Deadline Passed"); address user = _msgSender(); bytes32 txHash = keccak256(abi.encode(_msgSender(), passId, deadline)); require(!executed[txHash], "TownStory: Tx Executed"); require(verify(txHash, signature), "TownStory: Unauthorised"); executed[txHash] = true; require( msg.value >= mintPrice, "TownStory: Not enough value sent" ); (uint256 tokenId, address holder) = tsAccount.createAccount(user); AccountInfo memory accountInfo = tsAccount.accountInfoById(tokenId); require(accountInfo.owner == _msgSender(), "TownStory: You do not own this account"); if (passId > 0) { uint256[] memory accountIds = new uint256[](1); accountIds[0] = tokenId; uint256[] memory passIds = new uint256[](1); passIds[0] = passId; tsAccount.bindGamePass(accountIds, passIds); } emit CreateAccountMinted(user, tokenId, holder); } function syncSignatureMint( uint256 deadline, uint256[][] memory mintIds, uint256[][] memory mintAmounts, int256 tokens ) private view returns(bytes32) { return keccak256(abi.encode(tokens, mintIds, mintAmounts, _msgSender(), deadline)); } function verify(bytes32 hash, bytes memory signature) private view returns (bool) { bytes32 ethSignedHash = hash.toEthSignedMessageHash(); return ethSignedHash.recover(signature) == signer; } // Setting function setMintPrice(uint256 _price) public onlyRole(DEFAULT_ADMIN_ROLE) { mintPrice = _price; } function transferSigner(address _signer) public onlyRole(DEFAULT_ADMIN_ROLE) { signer = _signer; } function destroy() public onlyRole(DEFAULT_ADMIN_ROLE) payable { address payable owner = payable(address(_owner)); selfdestruct(owner); } function withdraw() external onlyRole(DEFAULT_ADMIN_ROLE) { uint balance = address(this).balance; payable(msg.sender).transfer(balance); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract TownStoryAccountUpgradeable","name":"_account","type":"address"},{"internalType":"address","name":"_signer","type":"address"},{"internalType":"address","name":"_minter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"accountId","type":"uint256"},{"indexed":true,"internalType":"address","name":"accountHolder","type":"address"}],"name":"CreateAccountMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SERVER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"createAccount","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256","name":"passId","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"createAccountSign","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"destroy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"executed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"gameCreateAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"transferSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162001b1338038062001b13833981016040819052620000349162000172565b60018055600480546001600160a01b03199081166001600160a01b03868116919091179092556002805482169285169290921790915560038054339216821790556200008390600090620000b8565b620000af7fa8a7bc421f721cb936ea99efdad79237e6ee0b871a2a08cf648691f9584cdc7782620000b8565b505050620001c6565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1662000155576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620001143390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6001600160a01b03811681146200016f57600080fd5b50565b6000806000606084860312156200018857600080fd5b8351620001958162000159565b6020850151909350620001a88162000159565b6040850151909250620001bb8162000159565b809150509250925092565b61193d80620001d66000396000f3fe6080604052600436106100fe5760003560e01c80636817c76c11610095578063a9fcfb3311610064578063a9fcfb3314610294578063cab13915146102c4578063d547741f146102d7578063f160619b146102f7578063f4a0a5281461030a57600080fd5b80636817c76c1461024157806383197ef01461025757806391d148541461025f578063a217fddf1461027f57600080fd5b80632f2ff15d116100d15780632f2ff15d146101cc57806336568abe146101ec5780633660a0841461020c5780633ccfd60b1461022c57600080fd5b806301ffc9a7146101035780630384ebe41461013857806318cf28341461015a578063248a9ca31461019c575b600080fd5b34801561010f57600080fd5b5061012361011e366004611476565b61032a565b60405190151581526020015b60405180910390f35b34801561014457600080fd5b506101586101533660046114b5565b610361565b005b34801561016657600080fd5b5061018e7fa8a7bc421f721cb936ea99efdad79237e6ee0b871a2a08cf648691f9584cdc7781565b60405190815260200161012f565b3480156101a857600080fd5b5061018e6101b73660046114e1565b60009081526020819052604090206001015490565b3480156101d857600080fd5b506101586101e73660046114fa565b610509565b3480156101f857600080fd5b506101586102073660046114fa565b610533565b34801561021857600080fd5b5061015861022736600461152a565b6105b1565b34801561023857600080fd5b506101586105df565b34801561024d57600080fd5b5061018e60055481565b610158610619565b34801561026b57600080fd5b5061012361027a3660046114fa565b610633565b34801561028b57600080fd5b5061018e600081565b3480156102a057600080fd5b506101236102af3660046114e1565b60076020526000908152604090205460ff1681565b6101586102d23660046114e1565b61065c565b3480156102e357600080fd5b506101586102f23660046114fa565b6108de565b61015861030536600461158e565b610903565b34801561031657600080fd5b506101586103253660046114e1565b610e09565b60006001600160e01b03198216637965db0b60e01b148061035b57506301ffc9a760e01b6001600160e01b03198316145b92915050565b7fa8a7bc421f721cb936ea99efdad79237e6ee0b871a2a08cf648691f9584cdc7761038b81610e1a565b600480546040516370a0823160e01b81526001600160a01b0386811693820193909352600092909116906370a082319060240160206040518083038186803b1580156103d657600080fd5b505afa1580156103ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040e9190611634565b90508281106104385760405162461bcd60e51b815260040161042f9061164d565b60405180910390fd5b60048054604051639859387b60e01b81526001600160a01b038781169382019390935260009283921690639859387b906024016040805180830381600087803b15801561048457600080fd5b505af1158015610498573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bc919061169c565b91509150806001600160a01b031682876001600160a01b03167f0eaa91b9d05ba24d077176868a6095c7b079b759e8bde7355e3f53a1779672a860405160405180910390a4505050505050565b60008281526020819052604090206001015461052481610e1a565b61052e8383610e24565b505050565b6001600160a01b03811633146105a35760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840161042f565b6105ad8282610ea8565b5050565b60006105bc81610e1a565b50600280546001600160a01b0319166001600160a01b0392909216919091179055565b60006105ea81610e1a565b6040514790339082156108fc029083906000818181858888f1935050505015801561052e573d6000803e3d6000fd5b600061062481610e1a565b6003546001600160a01b031680ff5b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b610664610f0d565b33803b9081156106b05760405162461bcd60e51b815260206004820152601760248201527610dbdb9d1c9858dd081a5cc81b9bdd08185b1b1bddd959604a1b604482015260640161042f565b3332146106ff5760405162461bcd60e51b815260206004820152601d60248201527f50726f787920636f6e7472616374206973206e6f7420616c6c6f776564000000604482015260640161042f565b600061070a81610e1a565b60048054604080516370a0823160e01b81523393810184905290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561075757600080fd5b505afa15801561076b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078f9190611634565b90508581106107b05760405162461bcd60e51b815260040161042f9061164d565b3460055411156108025760405162461bcd60e51b815260206004820181905260248201527f546f776e53746f72793a204e6f7420656e6f7567682076616c75652073656e74604482015260640161042f565b60048054604051639859387b60e01b81526001600160a01b038581169382019390935260009283921690639859387b906024016040805180830381600087803b15801561084e57600080fd5b505af1158015610862573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610886919061169c565b91509150806001600160a01b031682856001600160a01b03167f0eaa91b9d05ba24d077176868a6095c7b079b759e8bde7355e3f53a1779672a860405160405180910390a4505050505050506108db60018055565b50565b6000828152602081905260409020600101546108f981610e1a565b61052e8383610ea8565b61090b610f0d565b33803b9081156109575760405162461bcd60e51b815260206004820152601760248201527610dbdb9d1c9858dd081a5cc81b9bdd08185b1b1bddd959604a1b604482015260640161042f565b3332146109a65760405162461bcd60e51b815260206004820152601d60248201527f50726f787920636f6e7472616374206973206e6f7420616c6c6f776564000000604482015260640161042f565b428310156109f65760405162461bcd60e51b815260206004820152601a60248201527f546f776e53746f72793a20446561646c696e6520506173736564000000000000604482015260640161042f565b6000339050600033604080516001600160a01b03909216602083015281018790526060810186905260800160408051601f1981840301815291815281516020928301206000818152600790935291205490915060ff1615610a925760405162461bcd60e51b8152602060048201526016602482015275151bdddb94dd1bdc9e4e88151e08115e1958dd5d195960521b604482015260640161042f565b610a9c8188610f67565b610ae85760405162461bcd60e51b815260206004820152601760248201527f546f776e53746f72793a20556e617574686f7269736564000000000000000000604482015260640161042f565b6000818152600760205260409020805460ff19166001179055600554341015610b535760405162461bcd60e51b815260206004820181905260248201527f546f776e53746f72793a204e6f7420656e6f7567682076616c75652073656e74604482015260640161042f565b60048054604051639859387b60e01b81526001600160a01b038581169382019390935260009283921690639859387b906024016040805180830381600087803b158015610b9f57600080fd5b505af1158015610bb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd7919061169c565b60048054604051639b0e309560e01b81529182018490529294509092506000916001600160a01b031690639b0e30959060240160806040518083038186803b158015610c2257600080fd5b505afa158015610c36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5a91906116c1565b60408101519091506001600160a01b03163314610cc85760405162461bcd60e51b815260206004820152602660248201527f546f776e53746f72793a20596f7520646f206e6f74206f776e2074686973206160448201526518d8dbdd5b9d60d21b606482015260840161042f565b8815610db857604080516001808252818301909252600091602080830190803683370190505090508381600081518110610d0457610d04611736565b60209081029190910101526040805160018082528183019092526000918160200160208202803683370190505090508a81600081518110610d4757610d47611736565b60209081029190910101526004805460405163423caec560e11b81526001600160a01b03909116916384795d8a91610d83918691869101611787565b600060405180830381600087803b158015610d9d57600080fd5b505af1158015610db1573d6000803e3d6000fd5b5050505050505b816001600160a01b031683866001600160a01b03167f0eaa91b9d05ba24d077176868a6095c7b079b759e8bde7355e3f53a1779672a860405160405180910390a45050505050505061052e60018055565b6000610e1481610e1a565b50600555565b6108db8133610fec565b610e2e8282610633565b6105ad576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055610e643390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b610eb28282610633565b156105ad576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60026001541415610f605760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161042f565b6002600155565b600080610fc1846040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b6002549091506001600160a01b0316610fda8285611045565b6001600160a01b031614949350505050565b610ff68282610633565b6105ad5761100381611069565b61100e83602061107b565b60405160200161101f9291906117e5565b60408051601f198184030181529082905262461bcd60e51b825261042f9160040161185a565b6000806000611054858561121e565b9150915061106181611264565b509392505050565b606061035b6001600160a01b03831660145b6060600061108a8360026118a3565b6110959060026118c2565b67ffffffffffffffff8111156110ad576110ad611547565b6040519080825280601f01601f1916602001820160405280156110d7576020820181803683370190505b509050600360fc1b816000815181106110f2576110f2611736565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061112157611121611736565b60200101906001600160f81b031916908160001a90535060006111458460026118a3565b6111509060016118c2565b90505b60018111156111c8576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061118457611184611736565b1a60f81b82828151811061119a5761119a611736565b60200101906001600160f81b031916908160001a90535060049490941c936111c1816118da565b9050611153565b5083156112175760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161042f565b9392505050565b6000808251604114156112555760208301516040840151606085015160001a611249878285856113b2565b9450945050505061125d565b506000905060025b9250929050565b6000816004811115611278576112786118f1565b14156112815750565b6001816004811115611295576112956118f1565b14156112e35760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161042f565b60028160048111156112f7576112f76118f1565b14156113455760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161042f565b6003816004811115611359576113596118f1565b14156108db5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161042f565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156113e9575060009050600361146d565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561143d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166114665760006001925092505061146d565b9150600090505b94509492505050565b60006020828403121561148857600080fd5b81356001600160e01b03198116811461121757600080fd5b6001600160a01b03811681146108db57600080fd5b600080604083850312156114c857600080fd5b82356114d3816114a0565b946020939093013593505050565b6000602082840312156114f357600080fd5b5035919050565b6000806040838503121561150d57600080fd5b82359150602083013561151f816114a0565b809150509250929050565b60006020828403121561153c57600080fd5b8135611217816114a0565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561158657611586611547565b604052919050565b6000806000606084860312156115a357600080fd5b833567ffffffffffffffff808211156115bb57600080fd5b818601915086601f8301126115cf57600080fd5b81356020828211156115e3576115e3611547565b6115f5601f8301601f1916820161155d565b9250818352888183860101111561160b57600080fd5b818185018285013760009183018101919091529097908601359650604090950135949350505050565b60006020828403121561164657600080fd5b5051919050565b6020808252602f908201527f546f776e53746f72793a2054686520726563697069656e74206163636f756e7460408201526e20616c72656164792065786973747360881b606082015260800190565b600080604083850312156116af57600080fd5b82519150602083015161151f816114a0565b6000608082840312156116d357600080fd5b6040516080810181811067ffffffffffffffff821117156116f6576116f6611547565b806040525082518152602083015160208201526040830151611717816114a0565b6040820152606083015161172a816114a0565b60608201529392505050565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b8381101561177c57815187529582019590820190600101611760565b509495945050505050565b60408152600061179a604083018561174c565b82810360208401526117ac818561174c565b95945050505050565b60005b838110156117d05781810151838201526020016117b8565b838111156117df576000848401525b50505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161181d8160178501602088016117b5565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161184e8160288401602088016117b5565b01602801949350505050565b60208152600082518060208401526118798160408501602087016117b5565b601f01601f19169190910160400192915050565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156118bd576118bd61188d565b500290565b600082198211156118d5576118d561188d565b500190565b6000816118e9576118e961188d565b506000190190565b634e487b7160e01b600052602160045260246000fdfea264697066735822122008a842452f6a793cb19a78c4d8bcad010af00e14dbdccb4c6a4015240fd8d8cf64736f6c63430008090033000000000000000000000000da36df0764d138993f9811353ecadd6b32caafb9000000000000000000000000428a8a0a62f4f5344ba7285bd8a24e36625267c3000000000000000000000000428a8a0a62f4f5344ba7285bd8a24e36625267c3
Deployed Bytecode
0x6080604052600436106100fe5760003560e01c80636817c76c11610095578063a9fcfb3311610064578063a9fcfb3314610294578063cab13915146102c4578063d547741f146102d7578063f160619b146102f7578063f4a0a5281461030a57600080fd5b80636817c76c1461024157806383197ef01461025757806391d148541461025f578063a217fddf1461027f57600080fd5b80632f2ff15d116100d15780632f2ff15d146101cc57806336568abe146101ec5780633660a0841461020c5780633ccfd60b1461022c57600080fd5b806301ffc9a7146101035780630384ebe41461013857806318cf28341461015a578063248a9ca31461019c575b600080fd5b34801561010f57600080fd5b5061012361011e366004611476565b61032a565b60405190151581526020015b60405180910390f35b34801561014457600080fd5b506101586101533660046114b5565b610361565b005b34801561016657600080fd5b5061018e7fa8a7bc421f721cb936ea99efdad79237e6ee0b871a2a08cf648691f9584cdc7781565b60405190815260200161012f565b3480156101a857600080fd5b5061018e6101b73660046114e1565b60009081526020819052604090206001015490565b3480156101d857600080fd5b506101586101e73660046114fa565b610509565b3480156101f857600080fd5b506101586102073660046114fa565b610533565b34801561021857600080fd5b5061015861022736600461152a565b6105b1565b34801561023857600080fd5b506101586105df565b34801561024d57600080fd5b5061018e60055481565b610158610619565b34801561026b57600080fd5b5061012361027a3660046114fa565b610633565b34801561028b57600080fd5b5061018e600081565b3480156102a057600080fd5b506101236102af3660046114e1565b60076020526000908152604090205460ff1681565b6101586102d23660046114e1565b61065c565b3480156102e357600080fd5b506101586102f23660046114fa565b6108de565b61015861030536600461158e565b610903565b34801561031657600080fd5b506101586103253660046114e1565b610e09565b60006001600160e01b03198216637965db0b60e01b148061035b57506301ffc9a760e01b6001600160e01b03198316145b92915050565b7fa8a7bc421f721cb936ea99efdad79237e6ee0b871a2a08cf648691f9584cdc7761038b81610e1a565b600480546040516370a0823160e01b81526001600160a01b0386811693820193909352600092909116906370a082319060240160206040518083038186803b1580156103d657600080fd5b505afa1580156103ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040e9190611634565b90508281106104385760405162461bcd60e51b815260040161042f9061164d565b60405180910390fd5b60048054604051639859387b60e01b81526001600160a01b038781169382019390935260009283921690639859387b906024016040805180830381600087803b15801561048457600080fd5b505af1158015610498573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bc919061169c565b91509150806001600160a01b031682876001600160a01b03167f0eaa91b9d05ba24d077176868a6095c7b079b759e8bde7355e3f53a1779672a860405160405180910390a4505050505050565b60008281526020819052604090206001015461052481610e1a565b61052e8383610e24565b505050565b6001600160a01b03811633146105a35760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840161042f565b6105ad8282610ea8565b5050565b60006105bc81610e1a565b50600280546001600160a01b0319166001600160a01b0392909216919091179055565b60006105ea81610e1a565b6040514790339082156108fc029083906000818181858888f1935050505015801561052e573d6000803e3d6000fd5b600061062481610e1a565b6003546001600160a01b031680ff5b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b610664610f0d565b33803b9081156106b05760405162461bcd60e51b815260206004820152601760248201527610dbdb9d1c9858dd081a5cc81b9bdd08185b1b1bddd959604a1b604482015260640161042f565b3332146106ff5760405162461bcd60e51b815260206004820152601d60248201527f50726f787920636f6e7472616374206973206e6f7420616c6c6f776564000000604482015260640161042f565b600061070a81610e1a565b60048054604080516370a0823160e01b81523393810184905290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561075757600080fd5b505afa15801561076b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078f9190611634565b90508581106107b05760405162461bcd60e51b815260040161042f9061164d565b3460055411156108025760405162461bcd60e51b815260206004820181905260248201527f546f776e53746f72793a204e6f7420656e6f7567682076616c75652073656e74604482015260640161042f565b60048054604051639859387b60e01b81526001600160a01b038581169382019390935260009283921690639859387b906024016040805180830381600087803b15801561084e57600080fd5b505af1158015610862573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610886919061169c565b91509150806001600160a01b031682856001600160a01b03167f0eaa91b9d05ba24d077176868a6095c7b079b759e8bde7355e3f53a1779672a860405160405180910390a4505050505050506108db60018055565b50565b6000828152602081905260409020600101546108f981610e1a565b61052e8383610ea8565b61090b610f0d565b33803b9081156109575760405162461bcd60e51b815260206004820152601760248201527610dbdb9d1c9858dd081a5cc81b9bdd08185b1b1bddd959604a1b604482015260640161042f565b3332146109a65760405162461bcd60e51b815260206004820152601d60248201527f50726f787920636f6e7472616374206973206e6f7420616c6c6f776564000000604482015260640161042f565b428310156109f65760405162461bcd60e51b815260206004820152601a60248201527f546f776e53746f72793a20446561646c696e6520506173736564000000000000604482015260640161042f565b6000339050600033604080516001600160a01b03909216602083015281018790526060810186905260800160408051601f1981840301815291815281516020928301206000818152600790935291205490915060ff1615610a925760405162461bcd60e51b8152602060048201526016602482015275151bdddb94dd1bdc9e4e88151e08115e1958dd5d195960521b604482015260640161042f565b610a9c8188610f67565b610ae85760405162461bcd60e51b815260206004820152601760248201527f546f776e53746f72793a20556e617574686f7269736564000000000000000000604482015260640161042f565b6000818152600760205260409020805460ff19166001179055600554341015610b535760405162461bcd60e51b815260206004820181905260248201527f546f776e53746f72793a204e6f7420656e6f7567682076616c75652073656e74604482015260640161042f565b60048054604051639859387b60e01b81526001600160a01b038581169382019390935260009283921690639859387b906024016040805180830381600087803b158015610b9f57600080fd5b505af1158015610bb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd7919061169c565b60048054604051639b0e309560e01b81529182018490529294509092506000916001600160a01b031690639b0e30959060240160806040518083038186803b158015610c2257600080fd5b505afa158015610c36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5a91906116c1565b60408101519091506001600160a01b03163314610cc85760405162461bcd60e51b815260206004820152602660248201527f546f776e53746f72793a20596f7520646f206e6f74206f776e2074686973206160448201526518d8dbdd5b9d60d21b606482015260840161042f565b8815610db857604080516001808252818301909252600091602080830190803683370190505090508381600081518110610d0457610d04611736565b60209081029190910101526040805160018082528183019092526000918160200160208202803683370190505090508a81600081518110610d4757610d47611736565b60209081029190910101526004805460405163423caec560e11b81526001600160a01b03909116916384795d8a91610d83918691869101611787565b600060405180830381600087803b158015610d9d57600080fd5b505af1158015610db1573d6000803e3d6000fd5b5050505050505b816001600160a01b031683866001600160a01b03167f0eaa91b9d05ba24d077176868a6095c7b079b759e8bde7355e3f53a1779672a860405160405180910390a45050505050505061052e60018055565b6000610e1481610e1a565b50600555565b6108db8133610fec565b610e2e8282610633565b6105ad576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055610e643390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b610eb28282610633565b156105ad576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60026001541415610f605760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161042f565b6002600155565b600080610fc1846040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b6002549091506001600160a01b0316610fda8285611045565b6001600160a01b031614949350505050565b610ff68282610633565b6105ad5761100381611069565b61100e83602061107b565b60405160200161101f9291906117e5565b60408051601f198184030181529082905262461bcd60e51b825261042f9160040161185a565b6000806000611054858561121e565b9150915061106181611264565b509392505050565b606061035b6001600160a01b03831660145b6060600061108a8360026118a3565b6110959060026118c2565b67ffffffffffffffff8111156110ad576110ad611547565b6040519080825280601f01601f1916602001820160405280156110d7576020820181803683370190505b509050600360fc1b816000815181106110f2576110f2611736565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061112157611121611736565b60200101906001600160f81b031916908160001a90535060006111458460026118a3565b6111509060016118c2565b90505b60018111156111c8576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061118457611184611736565b1a60f81b82828151811061119a5761119a611736565b60200101906001600160f81b031916908160001a90535060049490941c936111c1816118da565b9050611153565b5083156112175760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161042f565b9392505050565b6000808251604114156112555760208301516040840151606085015160001a611249878285856113b2565b9450945050505061125d565b506000905060025b9250929050565b6000816004811115611278576112786118f1565b14156112815750565b6001816004811115611295576112956118f1565b14156112e35760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161042f565b60028160048111156112f7576112f76118f1565b14156113455760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161042f565b6003816004811115611359576113596118f1565b14156108db5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161042f565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156113e9575060009050600361146d565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561143d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166114665760006001925092505061146d565b9150600090505b94509492505050565b60006020828403121561148857600080fd5b81356001600160e01b03198116811461121757600080fd5b6001600160a01b03811681146108db57600080fd5b600080604083850312156114c857600080fd5b82356114d3816114a0565b946020939093013593505050565b6000602082840312156114f357600080fd5b5035919050565b6000806040838503121561150d57600080fd5b82359150602083013561151f816114a0565b809150509250929050565b60006020828403121561153c57600080fd5b8135611217816114a0565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561158657611586611547565b604052919050565b6000806000606084860312156115a357600080fd5b833567ffffffffffffffff808211156115bb57600080fd5b818601915086601f8301126115cf57600080fd5b81356020828211156115e3576115e3611547565b6115f5601f8301601f1916820161155d565b9250818352888183860101111561160b57600080fd5b818185018285013760009183018101919091529097908601359650604090950135949350505050565b60006020828403121561164657600080fd5b5051919050565b6020808252602f908201527f546f776e53746f72793a2054686520726563697069656e74206163636f756e7460408201526e20616c72656164792065786973747360881b606082015260800190565b600080604083850312156116af57600080fd5b82519150602083015161151f816114a0565b6000608082840312156116d357600080fd5b6040516080810181811067ffffffffffffffff821117156116f6576116f6611547565b806040525082518152602083015160208201526040830151611717816114a0565b6040820152606083015161172a816114a0565b60608201529392505050565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b8381101561177c57815187529582019590820190600101611760565b509495945050505050565b60408152600061179a604083018561174c565b82810360208401526117ac818561174c565b95945050505050565b60005b838110156117d05781810151838201526020016117b8565b838111156117df576000848401525b50505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161181d8160178501602088016117b5565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161184e8160288401602088016117b5565b01602801949350505050565b60208152600082518060208401526118798160408501602087016117b5565b601f01601f19169190910160400192915050565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156118bd576118bd61188d565b500290565b600082198211156118d5576118d561188d565b500190565b6000816118e9576118e961188d565b506000190190565b634e487b7160e01b600052602160045260246000fdfea264697066735822122008a842452f6a793cb19a78c4d8bcad010af00e14dbdccb4c6a4015240fd8d8cf64736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000da36df0764d138993f9811353ecadd6b32caafb9000000000000000000000000428a8a0a62f4f5344ba7285bd8a24e36625267c3000000000000000000000000428a8a0a62f4f5344ba7285bd8a24e36625267c3
-----Decoded View---------------
Arg [0] : _account (address): 0xDA36dF0764d138993F9811353EcADD6B32CAAFb9
Arg [1] : _signer (address): 0x428A8a0A62F4F5344bA7285bd8a24e36625267C3
Arg [2] : _minter (address): 0x428A8a0A62F4F5344bA7285bd8a24e36625267C3
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000da36df0764d138993f9811353ecadd6b32caafb9
Arg [1] : 000000000000000000000000428a8a0a62f4f5344ba7285bd8a24e36625267c3
Arg [2] : 000000000000000000000000428a8a0a62f4f5344ba7285bd8a24e36625267c3
Deployed Bytecode Sourcemap
133106:4438:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22727:204;;;;;;;;;;-1:-1:-1;22727:204:0;;;;;:::i;:::-;;:::i;:::-;;;470:14:1;;463:22;445:41;;433:2;418:18;22727:204:0;;;;;;;;134785:371;;;;;;;;;;-1:-1:-1;134785:371:0;;;;;:::i;:::-;;:::i;:::-;;133313:62;;;;;;;;;;;;133351:24;133313:62;;;;;1099:25:1;;;1087:2;1072:18;133313:62:0;953:177:1;24550:131:0;;;;;;;;;;-1:-1:-1;24550:131:0;;;;;:::i;:::-;24624:7;24651:12;;;;;;;;;;:22;;;;24550:131;24991:147;;;;;;;;;;-1:-1:-1;24991:147:0;;;;;:::i;:::-;;:::i;26135:218::-;;;;;;;;;;-1:-1:-1;26135:218:0;;;;;:::i;:::-;;:::i;137092:112::-;;;;;;;;;;-1:-1:-1;137092:112:0;;;;;:::i;:::-;;:::i;137380:161::-;;;;;;;;;;;;;:::i;133384:24::-;;;;;;;;;;;;;;;;137212:160;;;:::i;23023:147::-;;;;;;;;;;-1:-1:-1;23023:147:0;;;;;:::i;:::-;;:::i;22128:49::-;;;;;;;;;;-1:-1:-1;22128:49:0;22173:4;22128:49;;133462:40;;;;;;;;;;-1:-1:-1;133462:40:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;134224:553;;;;;;:::i;:::-;;:::i;25431:149::-;;;;;;;;;;-1:-1:-1;25431:149:0;;;;;:::i;:::-;;:::i;135164:1259::-;;;;;;:::i;:::-;;:::i;136973:111::-;;;;;;;;;;-1:-1:-1;136973:111:0;;;;;:::i;:::-;;:::i;22727:204::-;22812:4;-1:-1:-1;;;;;;22836:47:0;;-1:-1:-1;;;22836:47:0;;:87;;-1:-1:-1;;;;;;;;;;20244:40:0;;;22887:36;22829:94;22727:204;-1:-1:-1;;22727:204:0:o;134785:371::-;133351:24;22619:16;22630:4;22619:10;:16::i;:::-;134901:9:::1;::::0;;:25:::1;::::0;-1:-1:-1;;;134901:25:0;;-1:-1:-1;;;;;3741:32:1;;;134901:25:0;;::::1;3723:51:1::0;;;;134883:15:0::1;::::0;134901:9;;::::1;::::0;:19:::1;::::0;3696:18:1;;134901:25:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;134883:43;;134955:5;134945:7;:15;134937:75;;;;-1:-1:-1::0;;;134937:75:0::1;;;;;;;:::i;:::-;;;;;;;;;135061:9;::::0;;:29:::1;::::0;-1:-1:-1;;;135061:29:0;;-1:-1:-1;;;;;3741:32:1;;;135061:29:0;;::::1;3723:51:1::0;;;;135026:15:0::1;::::0;;;135061:9:::1;::::0;:23:::1;::::0;3696:18:1;;135061:29:0::1;::::0;::::1;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;135025:65;;;;135141:6;-1:-1:-1::0;;;;;135106:42:0::1;135132:7;135126:4;-1:-1:-1::0;;;;;135106:42:0::1;;;;;;;;;;;134872:284;;;134785:371:::0;;;:::o;24991:147::-;24624:7;24651:12;;;;;;;;;;:22;;;22619:16;22630:4;22619:10;:16::i;:::-;25105:25:::1;25116:4;25122:7;25105:10;:25::i;:::-;24991:147:::0;;;:::o;26135:218::-;-1:-1:-1;;;;;26231:23:0;;3560:10;26231:23;26223:83;;;;-1:-1:-1;;;26223:83:0;;4909:2:1;26223:83:0;;;4891:21:1;4948:2;4928:18;;;4921:30;4987:34;4967:18;;;4960:62;-1:-1:-1;;;5038:18:1;;;5031:45;5093:19;;26223:83:0;4707:411:1;26223:83:0;26319:26;26331:4;26337:7;26319:11;:26::i;:::-;26135:218;;:::o;137092:112::-;22173:4;22619:16;22173:4;22619:10;:16::i;:::-;-1:-1:-1;137180:6:0::1;:16:::0;;-1:-1:-1;;;;;;137180:16:0::1;-1:-1:-1::0;;;;;137180:16:0;;;::::1;::::0;;;::::1;::::0;;137092:112::o;137380:161::-;22173:4;22619:16;22173:4;22619:10;:16::i;:::-;137496:37:::1;::::0;137464:21:::1;::::0;137504:10:::1;::::0;137496:37;::::1;;;::::0;137464:21;;137449:12:::1;137496:37:::0;137449:12;137496:37;137464:21;137504:10;137496:37;::::1;;;;;;;;;;;;;::::0;::::1;;;;137212:160:::0;22173:4;22619:16;22173:4;22619:10;:16::i;:::-;137326:6:::1;::::0;-1:-1:-1;;;;;137326:6:0::1;::::0;137345:19:::1;23023:147:::0;23109:4;23133:12;;;;;;;;;;;-1:-1:-1;;;;;23133:29:0;;;;;;;;;;;;;;;23023:147::o;134224:553::-;30592:21;:19;:21::i;:::-;133984:10:::1;134037:17:::0;::::1;::::0;134083:9;;134075:45:::1;;;::::0;-1:-1:-1;;;134075:45:0;;5325:2:1;134075:45:0::1;::::0;::::1;5307:21:1::0;5364:2;5344:18;;;5337:30;-1:-1:-1;;;5383:18:1;;;5376:53;5446:18;;134075:45:0::1;5123:347:1::0;134075:45:0::1;134139:10;134153:9;134139:23;134131:65;;;::::0;-1:-1:-1;;;134131:65:0;;5677:2:1;134131:65:0::1;::::0;::::1;5659:21:1::0;5716:2;5696:18;;;5689:30;5755:31;5735:18;;;5728:59;5804:18;;134131:65:0::1;5475:353:1::0;134131:65:0::1;22173:4:::2;22619:16;22173:4:::0;22619:10:::2;:16::i;:::-;134403:9:::3;::::0;;:25:::3;::::0;;-1:-1:-1;;;134403:25:0;;3560:10;134403:25;;::::3;3723:51:1::0;;;134403:25:0;;134345:12:::3;::::0;-1:-1:-1;;;;;134403:9:0::3;::::0;:19:::3;::::0;3696:18:1;;;;;134403:25:0::3;::::0;;;;;;;;:9;:25;::::3;;::::0;::::3;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;134385:43;;134457:5;134447:7;:15;134439:75;;;;-1:-1:-1::0;;;134439:75:0::3;;;;;;;:::i;:::-;134562:9;134549;;:22;;134527:104;;;::::0;-1:-1:-1;;;134527:104:0;;6035:2:1;134527:104:0::3;::::0;::::3;6017:21:1::0;;;6054:18;;;6047:30;6113:34;6093:18;;;6086:62;6165:18;;134527:104:0::3;5833:356:1::0;134527:104:0::3;134680:9;::::0;;:29:::3;::::0;-1:-1:-1;;;134680:29:0;;-1:-1:-1;;;;;3741:32:1;;;134680:29:0;;::::3;3723:51:1::0;;;;134645:15:0::3;::::0;;;134680:9:::3;::::0;:23:::3;::::0;3696:18:1;;134680:29:0::3;::::0;::::3;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;134644:65;;;;134762:6;-1:-1:-1::0;;;;;134727:42:0::3;134753:7;134747:4;-1:-1:-1::0;;;;;134727:42:0::3;;;;;;;;;;;134334:443;;;;134207:1:::2;133935:281:::1;;30636:20:::0;30030:1;31156:22;;30973:213;30636:20;134224:553;:::o;25431:149::-;24624:7;24651:12;;;;;;;;;;:22;;;22619:16;22630:4;22619:10;:16::i;:::-;25546:26:::1;25558:4;25564:7;25546:11;:26::i;135164:1259::-:0;30592:21;:19;:21::i;:::-;133984:10:::1;134037:17:::0;::::1;::::0;134083:9;;134075:45:::1;;;::::0;-1:-1:-1;;;134075:45:0;;5325:2:1;134075:45:0::1;::::0;::::1;5307:21:1::0;5364:2;5344:18;;;5337:30;-1:-1:-1;;;5383:18:1;;;5376:53;5446:18;;134075:45:0::1;5123:347:1::0;134075:45:0::1;134139:10;134153:9;134139:23;134131:65;;;::::0;-1:-1:-1;;;134131:65:0;;5677:2:1;134131:65:0::1;::::0;::::1;5659:21:1::0;5716:2;5696:18;;;5689:30;5755:31;5735:18;;;5728:59;5804:18;;134131:65:0::1;5475:353:1::0;134131:65:0::1;135354:15:::2;135342:8;:27;;135334:66;;;::::0;-1:-1:-1;;;135334:66:0;;6396:2:1;135334:66:0::2;::::0;::::2;6378:21:1::0;6435:2;6415:18;;;6408:30;6474:28;6454:18;;;6447:56;6520:18;;135334:66:0::2;6194:350:1::0;135334:66:0::2;135413:12;3560:10:::0;135413:27;-1:-1:-1;135451:14:0::2;3560:10:::0;135478:42:::2;::::0;;-1:-1:-1;;;;;6769:32:1;;;135478:42:0::2;::::0;::::2;6751:51:1::0;6818:18;;6811:34;;;6861:18;;;6854:34;;;6724:18;;135478:42:0::2;::::0;;-1:-1:-1;;135478:42:0;;::::2;::::0;;;;;;135468:53;;135478:42:::2;135468:53:::0;;::::2;::::0;135543:16:::2;::::0;;;:8:::2;:16:::0;;;;;;135468:53;;-1:-1:-1;135543:16:0::2;;135542:17;135534:52;;;::::0;-1:-1:-1;;;135534:52:0;;7101:2:1;135534:52:0::2;::::0;::::2;7083:21:1::0;7140:2;7120:18;;;7113:30;-1:-1:-1;;;7159:18:1;;;7152:52;7221:18;;135534:52:0::2;6899:346:1::0;135534:52:0::2;135605:25;135612:6;135620:9;135605:6;:25::i;:::-;135597:61;;;::::0;-1:-1:-1;;;135597:61:0;;7452:2:1;135597:61:0::2;::::0;::::2;7434:21:1::0;7491:2;7471:18;;;7464:30;7530:25;7510:18;;;7503:53;7573:18;;135597:61:0::2;7250:347:1::0;135597:61:0::2;135669:16;::::0;;;:8:::2;:16;::::0;;;;:23;;-1:-1:-1;;135669:23:0::2;135688:4;135669:23;::::0;;135740:9:::2;::::0;135727::::2;:22;;135705:104;;;::::0;-1:-1:-1;;;135705:104:0;;6035:2:1;135705:104:0::2;::::0;::::2;6017:21:1::0;;;6054:18;;;6047:30;6113:34;6093:18;;;6086:62;6165:18;;135705:104:0::2;5833:356:1::0;135705:104:0::2;135858:9;::::0;;:29:::2;::::0;-1:-1:-1;;;135858:29:0;;-1:-1:-1;;;;;3741:32:1;;;135858:29:0;;::::2;3723:51:1::0;;;;135823:15:0::2;::::0;;;135858:9:::2;::::0;:23:::2;::::0;3696:18:1;;135858:29:0::2;::::0;::::2;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;135933:9;::::0;;:34:::2;::::0;-1:-1:-1;;;135933:34:0;;;;::::2;1099:25:1::0;;;135822:65:0;;-1:-1:-1;135822:65:0;;-1:-1:-1;135900:30:0::2;::::0;-1:-1:-1;;;;;135933:9:0::2;::::0;:25:::2;::::0;1072:18:1;;135933:34:0::2;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;135986:17;::::0;::::2;::::0;135900:67;;-1:-1:-1;;;;;;135986:33:0::2;3560:10:::0;135986:33:::2;135978:84;;;::::0;-1:-1:-1;;;135978:84:0;;8574:2:1;135978:84:0::2;::::0;::::2;8556:21:1::0;8613:2;8593:18;;;8586:30;8652:34;8632:18;;;8625:62;-1:-1:-1;;;8703:18:1;;;8696:36;8749:19;;135978:84:0::2;8372:402:1::0;135978:84:0::2;136079:10:::0;;136075:281:::2;;136136:16;::::0;;136150:1:::2;136136:16:::0;;;;;::::2;::::0;;;136106:27:::2;::::0;136136:16:::2;::::0;;::::2;::::0;;::::2;::::0;::::2;;::::0;-1:-1:-1;136136:16:0::2;136106:46;;136183:7;136167:10;136178:1;136167:13;;;;;;;;:::i;:::-;;::::0;;::::2;::::0;;;;;:23;136234:16:::2;::::0;;136248:1:::2;136234:16:::0;;;;;::::2;::::0;;;136207:24:::2;::::0;136234:16:::2;;;;;;;;;;;::::0;-1:-1:-1;136234:16:0::2;136207:43;;136278:6;136265:7;136273:1;136265:10;;;;;;;;:::i;:::-;;::::0;;::::2;::::0;;;;;:19;136301:9:::2;::::0;;:43:::2;::::0;-1:-1:-1;;;136301:43:0;;-1:-1:-1;;;;;136301:9:0;;::::2;::::0;:22:::2;::::0;:43:::2;::::0;136324:10;;136336:7;;136301:43:::2;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;136091:265;;136075:281;136408:6;-1:-1:-1::0;;;;;136373:42:0::2;136399:7;136393:4;-1:-1:-1::0;;;;;136373:42:0::2;;;;;;;;;;;135323:1100;;;;;133935:281:::1;;30636:20:::0;30030:1;31156:22;;30973:213;136973:111;22173:4;22619:16;22173:4;22619:10;:16::i;:::-;-1:-1:-1;137058:9:0::1;:18:::0;136973:111::o;23474:105::-;23541:30;23552:4;3560:10;23541;:30::i;27732:238::-;27816:22;27824:4;27830:7;27816;:22::i;:::-;27811:152;;27855:6;:12;;;;;;;;;;;-1:-1:-1;;;;;27855:29:0;;;;;;;;;:36;;-1:-1:-1;;27855:36:0;27887:4;27855:36;;;27938:12;3560:10;;3480:98;27938:12;-1:-1:-1;;;;;27911:40:0;27929:7;-1:-1:-1;;;;;27911:40:0;27923:4;27911:40;;;;;;;;;;27732:238;;:::o;28150:239::-;28234:22;28242:4;28248:7;28234;:22::i;:::-;28230:152;;;28305:5;28273:12;;;;;;;;;;;-1:-1:-1;;;;;28273:29:0;;;;;;;;;;:37;;-1:-1:-1;;28273:37:0;;;28330:40;3560:10;;28273:12;;28330:40;;28305:5;28330:40;28150:239;;:::o;30672:293::-;30074:1;30806:7;;:19;;30798:63;;;;-1:-1:-1;;;30798:63:0;;10023:2:1;30798:63:0;;;10005:21:1;10062:2;10042:18;;;10035:30;10101:33;10081:18;;;10074:61;10152:18;;30798:63:0;9821:355:1;30798:63:0;30074:1;30939:7;:18;30672:293::o;136735:214::-;136811:4;136828:21;136852:29;:4;38690:58;;11865:66:1;38690:58:0;;;11853:79:1;11948:12;;;11941:28;;;38557:7:0;;11985:12:1;;38690:58:0;;;;;;;;;;;;38680:69;;;;;;38673:76;;38488:269;;;;136852:29;136935:6;;136828:53;;-1:-1:-1;;;;;;136935:6:0;136899:32;136828:53;136921:9;136899:21;:32::i;:::-;-1:-1:-1;;;;;136899:42:0;;;136735:214;-1:-1:-1;;;;136735:214:0:o;23869:492::-;23958:22;23966:4;23972:7;23958;:22::i;:::-;23953:401;;24146:28;24166:7;24146:19;:28::i;:::-;24247:38;24275:4;24282:2;24247:19;:38::i;:::-;24051:257;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;24051:257:0;;;;;;;;;;-1:-1:-1;;;23997:345:0;;;;;;;:::i;34798:231::-;34876:7;34897:17;34916:18;34938:27;34949:4;34955:9;34938:10;:27::i;:::-;34896:69;;;;34976:18;34988:5;34976:11;:18::i;:::-;-1:-1:-1;35012:9:0;34798:231;-1:-1:-1;;;34798:231:0:o;18475:151::-;18533:13;18566:52;-1:-1:-1;;;;;18578:22:0;;16630:2;17871:447;17946:13;17972:19;18004:10;18008:6;18004:1;:10;:::i;:::-;:14;;18017:1;18004:14;:::i;:::-;17994:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;17994:25:0;;17972:47;;-1:-1:-1;;;18030:6:0;18037:1;18030:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;18030:15:0;;;;;;;;;-1:-1:-1;;;18056:6:0;18063:1;18056:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;18056:15:0;;;;;;;;-1:-1:-1;18087:9:0;18099:10;18103:6;18099:1;:10;:::i;:::-;:14;;18112:1;18099:14;:::i;:::-;18087:26;;18082:131;18119:1;18115;:5;18082:131;;;-1:-1:-1;;;18163:5:0;18171:3;18163:11;18154:21;;;;;;;:::i;:::-;;;;18142:6;18149:1;18142:9;;;;;;;;:::i;:::-;;;;:33;-1:-1:-1;;;;;18142:33:0;;;;;;;;-1:-1:-1;18200:1:0;18190:11;;;;;18122:3;;;:::i;:::-;;;18082:131;;;-1:-1:-1;18231:10:0;;18223:55;;;;-1:-1:-1;;;18223:55:0;;12789:2:1;18223:55:0;;;12771:21:1;;;12808:18;;;12801:30;12867:34;12847:18;;;12840:62;12919:18;;18223:55:0;12587:356:1;18223:55:0;18303:6;17871:447;-1:-1:-1;;;17871:447:0:o;33249:747::-;33330:7;33339:12;33368:9;:16;33388:2;33368:22;33364:625;;;33712:4;33697:20;;33691:27;33762:4;33747:20;;33741:27;33820:4;33805:20;;33799:27;33407:9;33791:36;33863:25;33874:4;33791:36;33691:27;33741;33863:10;:25::i;:::-;33856:32;;;;;;;;;33364:625;-1:-1:-1;33937:1:0;;-1:-1:-1;33941:35:0;33364:625;33249:747;;;;;:::o;31642:521::-;31720:20;31711:5;:29;;;;;;;;:::i;:::-;;31707:449;;;31642:521;:::o;31707:449::-;31818:29;31809:5;:38;;;;;;;;:::i;:::-;;31805:351;;;31864:34;;-1:-1:-1;;;31864:34:0;;13282:2:1;31864:34:0;;;13264:21:1;13321:2;13301:18;;;13294:30;13360:26;13340:18;;;13333:54;13404:18;;31864:34:0;13080:348:1;31805:351:0;31929:35;31920:5;:44;;;;;;;;:::i;:::-;;31916:240;;;31981:41;;-1:-1:-1;;;31981:41:0;;13635:2:1;31981:41:0;;;13617:21:1;13674:2;13654:18;;;13647:30;13713:33;13693:18;;;13686:61;13764:18;;31981:41:0;13433:355:1;31916:240:0;32053:30;32044:5;:39;;;;;;;;:::i;:::-;;32040:116;;;32100:44;;-1:-1:-1;;;32100:44:0;;13995:2:1;32100:44:0;;;13977:21:1;14034:2;14014:18;;;14007:30;14073:34;14053:18;;;14046:62;-1:-1:-1;;;14124:18:1;;;14117:32;14166:19;;32100:44:0;13793:398:1;36250:1520:0;36381:7;;37315:66;37302:79;;37298:163;;;-1:-1:-1;37414:1:0;;-1:-1:-1;37418:30:0;37398:51;;37298:163;37575:24;;;37558:14;37575:24;;;;;;;;;14423:25:1;;;14496:4;14484:17;;14464:18;;;14457:45;;;;14518:18;;;14511:34;;;14561:18;;;14554:34;;;37575:24:0;;14395:19:1;;37575:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;37575:24:0;;-1:-1:-1;;37575:24:0;;;-1:-1:-1;;;;;;;37614:20:0;;37610:103;;37667:1;37671:29;37651:50;;;;;;;37610:103;37733:6;-1:-1:-1;37741:20:0;;-1:-1:-1;36250:1520:0;;;;;;;;:::o;14:286:1:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:1;;209:43;;199:71;;266:1;263;256:12;497:131;-1:-1:-1;;;;;572:31:1;;562:42;;552:70;;618:1;615;608:12;633:315;701:6;709;762:2;750:9;741:7;737:23;733:32;730:52;;;778:1;775;768:12;730:52;817:9;804:23;836:31;861:5;836:31;:::i;:::-;886:5;938:2;923:18;;;;910:32;;-1:-1:-1;;;633:315:1:o;1135:180::-;1194:6;1247:2;1235:9;1226:7;1222:23;1218:32;1215:52;;;1263:1;1260;1253:12;1215:52;-1:-1:-1;1286:23:1;;1135:180;-1:-1:-1;1135:180:1:o;1320:315::-;1388:6;1396;1449:2;1437:9;1428:7;1424:23;1420:32;1417:52;;;1465:1;1462;1455:12;1417:52;1501:9;1488:23;1478:33;;1561:2;1550:9;1546:18;1533:32;1574:31;1599:5;1574:31;:::i;:::-;1624:5;1614:15;;;1320:315;;;;;:::o;1640:247::-;1699:6;1752:2;1740:9;1731:7;1727:23;1723:32;1720:52;;;1768:1;1765;1758:12;1720:52;1807:9;1794:23;1826:31;1851:5;1826:31;:::i;2259:127::-;2320:10;2315:3;2311:20;2308:1;2301:31;2351:4;2348:1;2341:15;2375:4;2372:1;2365:15;2391:275;2462:2;2456:9;2527:2;2508:13;;-1:-1:-1;;2504:27:1;2492:40;;2562:18;2547:34;;2583:22;;;2544:62;2541:88;;;2609:18;;:::i;:::-;2645:2;2638:22;2391:275;;-1:-1:-1;2391:275:1:o;2671:901::-;2757:6;2765;2773;2826:2;2814:9;2805:7;2801:23;2797:32;2794:52;;;2842:1;2839;2832:12;2794:52;2882:9;2869:23;2911:18;2952:2;2944:6;2941:14;2938:34;;;2968:1;2965;2958:12;2938:34;3006:6;2995:9;2991:22;2981:32;;3051:7;3044:4;3040:2;3036:13;3032:27;3022:55;;3073:1;3070;3063:12;3022:55;3109:2;3096:16;3131:4;3154:2;3150;3147:10;3144:36;;;3160:18;;:::i;:::-;3202:53;3245:2;3226:13;;-1:-1:-1;;3222:27:1;3218:36;;3202:53;:::i;:::-;3189:66;;3278:2;3271:5;3264:17;3318:7;3313:2;3308;3304;3300:11;3296:20;3293:33;3290:53;;;3339:1;3336;3329:12;3290:53;3394:2;3389;3385;3381:11;3376:2;3369:5;3365:14;3352:45;3438:1;3417:14;;;3413:23;;3406:34;;;;3421:5;;3496:18;;;3483:32;;-1:-1:-1;3562:2:1;3547:18;;;3534:32;;2671:901;-1:-1:-1;;;;2671:901:1:o;3785:184::-;3855:6;3908:2;3896:9;3887:7;3883:23;3879:32;3876:52;;;3924:1;3921;3914:12;3876:52;-1:-1:-1;3947:16:1;;3785:184;-1:-1:-1;3785:184:1:o;3974:411::-;4176:2;4158:21;;;4215:2;4195:18;;;4188:30;4254:34;4249:2;4234:18;;4227:62;-1:-1:-1;;;4320:2:1;4305:18;;4298:45;4375:3;4360:19;;3974:411::o;4390:312::-;4469:6;4477;4530:2;4518:9;4509:7;4505:23;4501:32;4498:52;;;4546:1;4543;4536:12;4498:52;4575:9;4569:16;4559:26;;4628:2;4617:9;4613:18;4607:25;4641:31;4666:5;4641:31;:::i;7602:765::-;7701:6;7754:3;7742:9;7733:7;7729:23;7725:33;7722:53;;;7771:1;7768;7761:12;7722:53;7804:2;7798:9;7846:3;7838:6;7834:16;7916:6;7904:10;7901:22;7880:18;7868:10;7865:34;7862:62;7859:88;;;7927:18;;:::i;:::-;7967:10;7963:2;7956:22;;8008:9;8002:16;7994:6;7987:32;8073:2;8062:9;8058:18;8052:25;8047:2;8039:6;8035:15;8028:50;8121:2;8110:9;8106:18;8100:25;8134:31;8159:5;8134:31;:::i;:::-;8193:2;8181:15;;8174:30;8249:2;8234:18;;8228:25;8262:33;8228:25;8262:33;:::i;:::-;8323:2;8311:15;;8304:32;8315:6;7602:765;-1:-1:-1;;;7602:765:1:o;8779:127::-;8840:10;8835:3;8831:20;8828:1;8821:31;8871:4;8868:1;8861:15;8895:4;8892:1;8885:15;8911:435;8964:3;9002:5;8996:12;9029:6;9024:3;9017:19;9055:4;9084:2;9079:3;9075:12;9068:19;;9121:2;9114:5;9110:14;9142:1;9152:169;9166:6;9163:1;9160:13;9152:169;;;9227:13;;9215:26;;9261:12;;;;9296:15;;;;9188:1;9181:9;9152:169;;;-1:-1:-1;9337:3:1;;8911:435;-1:-1:-1;;;;;8911:435:1:o;9351:465::-;9608:2;9597:9;9590:21;9571:4;9634:56;9686:2;9675:9;9671:18;9663:6;9634:56;:::i;:::-;9738:9;9730:6;9726:22;9721:2;9710:9;9706:18;9699:50;9766:44;9803:6;9795;9766:44;:::i;:::-;9758:52;9351:465;-1:-1:-1;;;;;9351:465:1:o;10181:258::-;10253:1;10263:113;10277:6;10274:1;10271:13;10263:113;;;10353:11;;;10347:18;10334:11;;;10327:39;10299:2;10292:10;10263:113;;;10394:6;10391:1;10388:13;10385:48;;;10429:1;10420:6;10415:3;10411:16;10404:27;10385:48;;10181:258;;;:::o;10444:786::-;10855:25;10850:3;10843:38;10825:3;10910:6;10904:13;10926:62;10981:6;10976:2;10971:3;10967:12;10960:4;10952:6;10948:17;10926:62;:::i;:::-;-1:-1:-1;;;11047:2:1;11007:16;;;11039:11;;;11032:40;11097:13;;11119:63;11097:13;11168:2;11160:11;;11153:4;11141:17;;11119:63;:::i;:::-;11202:17;11221:2;11198:26;;10444:786;-1:-1:-1;;;;10444:786:1:o;11235:383::-;11384:2;11373:9;11366:21;11347:4;11416:6;11410:13;11459:6;11454:2;11443:9;11439:18;11432:34;11475:66;11534:6;11529:2;11518:9;11514:18;11509:2;11501:6;11497:15;11475:66;:::i;:::-;11602:2;11581:15;-1:-1:-1;;11577:29:1;11562:45;;;;11609:2;11558:54;;11235:383;-1:-1:-1;;11235:383:1:o;12008:127::-;12069:10;12064:3;12060:20;12057:1;12050:31;12100:4;12097:1;12090:15;12124:4;12121:1;12114:15;12140:168;12180:7;12246:1;12242;12238:6;12234:14;12231:1;12228:21;12223:1;12216:9;12209:17;12205:45;12202:71;;;12253:18;;:::i;:::-;-1:-1:-1;12293:9:1;;12140:168::o;12313:128::-;12353:3;12384:1;12380:6;12377:1;12374:13;12371:39;;;12390:18;;:::i;:::-;-1:-1:-1;12426:9:1;;12313:128::o;12446:136::-;12485:3;12513:5;12503:39;;12522:18;;:::i;:::-;-1:-1:-1;;;12558:18:1;;12446:136::o;12948:127::-;13009:10;13004:3;13000:20;12997:1;12990:31;13040:4;13037:1;13030:15;13064:4;13061:1;13054:15
Swarm Source
ipfs://08a842452f6a793cb19a78c4d8bcad010af00e14dbdccb4c6a4015240fd8d8cf
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.