This nametag was submitted by Kleros Scout.
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| 0x18de7467440f6f0c717e6f721dd7154bea1e90d41d27971dc4c432d2e235e0fd | - | (pending) | 9 days ago | IN | 0 ETH | (Pending) | |||
| 0xbaf1df6727f3c1d882cb647db6bae6a0dfd6df5fd3eeea787603db1dc31c84c5 | - | (pending) | 9 days ago | IN | 0 ETH | (Pending) | |||
| Create Account S... | 22859685 | 144 days ago | IN | 0 ETH | 0.00002795 | ||||
| Create Account S... | 22858041 | 144 days ago | IN | 0 ETH | 0.00002735 | ||||
| Create Account S... | 22855526 | 144 days ago | IN | 0 ETH | 0.00002732 | ||||
| Create Account S... | 22815047 | 145 days ago | IN | 0 ETH | 0.00002695 | ||||
| Create Account S... | 22813408 | 145 days ago | IN | 0 ETH | 0.00003064 | ||||
| Create Account S... | 22807420 | 146 days ago | IN | 0 ETH | 0.00003033 | ||||
| Create Account S... | 22783396 | 146 days ago | IN | 0 ETH | 0.00004569 | ||||
| Create Account S... | 22776881 | 146 days ago | IN | 0 ETH | 0.00003116 | ||||
| Create Account S... | 22690361 | 148 days ago | IN | 0 ETH | 0.00002854 | ||||
| Create Account S... | 22570947 | 151 days ago | IN | 0 ETH | 0.00002666 | ||||
| Create Account S... | 22560281 | 152 days ago | IN | 0 ETH | 0.00003192 | ||||
| Create Account S... | 22327741 | 157 days ago | IN | 0 ETH | 0.00002906 | ||||
| Create Account S... | 22314378 | 157 days ago | IN | 0 ETH | 0.00002746 | ||||
| Create Account S... | 22312014 | 157 days ago | IN | 0 ETH | 0.00002697 | ||||
| Create Account S... | 22271504 | 158 days ago | IN | 0 ETH | 0.00002571 | ||||
| Create Account S... | 22233236 | 159 days ago | IN | 0 ETH | 0.00003329 | ||||
| Create Account S... | 22190568 | 160 days ago | IN | 0 ETH | 0.00003301 | ||||
| Create Account S... | 22182381 | 161 days ago | IN | 0 ETH | 0.00002922 | ||||
| Create Account S... | 22130571 | 162 days ago | IN | 0 ETH | 0.00003137 | ||||
| Create Account S... | 21856322 | 168 days ago | IN | 0 ETH | 0.00002767 | ||||
| Create Account S... | 21686810 | 172 days ago | IN | 0 ETH | 0.00002946 | ||||
| Create Account S... | 21564641 | 176 days ago | IN | 0 ETH | 0.00002499 | ||||
| Create Account S... | 21530280 | 177 days ago | IN | 0 ETH | 0.00002618 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 22859685 | 144 days ago | 0 ETH | ||||
| 22859685 | 144 days ago | 0 ETH | ||||
| 22859685 | 144 days ago | 0 ETH | ||||
| 22858041 | 144 days ago | 0 ETH | ||||
| 22858041 | 144 days ago | 0 ETH | ||||
| 22858041 | 144 days ago | 0 ETH | ||||
| 22855526 | 144 days ago | 0 ETH | ||||
| 22855526 | 144 days ago | 0 ETH | ||||
| 22855526 | 144 days ago | 0 ETH | ||||
| 22815047 | 145 days ago | 0 ETH | ||||
| 22815047 | 145 days ago | 0 ETH | ||||
| 22815047 | 145 days ago | 0 ETH | ||||
| 22813408 | 145 days ago | 0 ETH | ||||
| 22813408 | 145 days ago | 0 ETH | ||||
| 22813408 | 145 days ago | 0 ETH | ||||
| 22807420 | 146 days ago | 0 ETH | ||||
| 22807420 | 146 days ago | 0 ETH | ||||
| 22807420 | 146 days ago | 0 ETH | ||||
| 22783396 | 146 days ago | 0 ETH | ||||
| 22783396 | 146 days ago | 0 ETH | ||||
| 22783396 | 146 days ago | 0 ETH | ||||
| 22776881 | 146 days ago | 0 ETH | ||||
| 22776881 | 146 days ago | 0 ETH | ||||
| 22776881 | 146 days ago | 0 ETH | ||||
| 22690361 | 148 days ago | 0 ETH |
Cross-Chain Transactions
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
Loading...
Loading
Net Worth in USD
$82.11
Net Worth in ETH
Token Allocations
ETH
89.70%
BNB
10.30%
Multichain Portfolio | 35 Chains
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.