Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
SharkzGenesisV1
Compiler Version
v0.8.15+commit.e14f2714
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
/**
█
▐█████▄█ ▀████ █████ ▐████ ████████ ███████████ ████▌ ▄████ ███████████
▐██████ █▄ ▀██ █████ ▐████ ██████████ ████ ████▌ ████▌ ████▀ ████▀
▀████ ███▄ ▀ █████▄▄▐████ ████ ▐██████ ████▄▄▄████ █████████ ████▀
▐▄ ▀██ █████▄ █████▀▀▐████ ▄████ ██████ █████████ █████████ ▄████
▐██▄ █ ██████ █████ ▐█████████▀ ▐█████████ ▀████▄ █████ ▀███▄ █████
▐████ █▀█████ █████ ▐████████▀ ███████ █████ █████ ████ ███████████
█
*******************************************************************************
* Sharkz NFT (ERC721A)
*******************************************************************************
* Creator: Sharkz Entertainment
* Author: Jason Hoi
*
*/
pragma solidity ^0.8.12;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "../lib-upgradeable/sharkz/AdminableUpgradeable.sol";
import "../lib-upgradeable/721AStruct/ERC721AStructUpgradeable.sol";
import "../lib-upgradeable/721AStruct/extensions/ERC721ABurnableUpgradeable.sol";
import "../lib-upgradeable/721AStruct/extensions/ERC4907Upgradeable.sol";
import "../lib-upgradeable/712/EIP712WhitelistTypedUpgradeable.sol";
import "../lib/sharkz/IScore.sol";
import "./MintSetupUpgradeable.sol";
interface IBalanceOf {
function balanceOf(address owner) external view returns (uint256 balance);
}
// @credit: Azuki https://github.com/chiru-labs/ERC721A
contract SharkzGenesisV1 is Initializable, UUPSUpgradeable, AdminableUpgradeable, ERC721AStructUpgradeable, ERC721ABurnableUpgradeable, ERC4907Upgradeable, IScore, EIP712WhitelistTypedUpgradeable, MintSetupUpgradeable {
// Implementation version number
function version() external pure virtual returns (string memory) { return "1"; }
string public PROVENANCE;
uint256 public constant MAX_SUPPLY = 7777;
uint256 public burnedSupply;
string public baseTokenURI;
string public unrevealURI;
// Soul ID linking
address public soulIdContract;
// Soulbound base score
uint256 internal _baseScore;
// Init this upgradeable contract
function initialize() public initializer onlyProxy {
__Adminable_init();
__ERC721AStruct_init("Sharkz Genesis", "SHARKZG");
__EIP712WhitelistTyped_init();
__MintSetup_init();
soulIdContract = 0x12DEb1Cb5732E40Dd55B89aBB6D5C31dF13A6e38;
_baseScore = 1;
}
// only admins can upgrade the contract
function _authorizeUpgrade(address newImplementation) internal override onlyAdmin {}
function _beforeTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual override(ERC721AStructUpgradeable, ERC4907Upgradeable) {
super._beforeTokenTransfers(from, to, startTokenId, quantity);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721AStructUpgradeable, ERC4907Upgradeable) returns (bool) {
// See: https://eips.ethereum.org/EIPS/eip-165
// return true to show proof of supporting following interface, we use bytes4
// interface id to avoid importing the whole interface codes.
return super.supportsInterface(interfaceId) ||
interfaceId == type(IScore).interfaceId;
}
// Set provenance hash
function setProvenance(string memory _hash) external onlyAdmin {
PROVENANCE = _hash;
}
// Change linking Soul ID contract address
function setSoulIdContract(address _contract) external onlyAdmin {
soulIdContract = _contract;
}
// Change base score
function setBaseScore(uint256 _score) external virtual onlyAdmin {
_baseScore = _score;
}
/**
* @dev See {IScore-baseScore}.
*/
function baseScore() public view virtual override returns (uint256) {
return _baseScore;
}
/**
* @dev See {IScore-scoreByToken}.
*/
function scoreByToken(uint256 _tokenId) external view virtual override returns (uint256) {
if (_exists(_tokenId)) {
return _baseScore;
} else {
return 0;
}
}
/**
* @dev See {IScore-scoreByAddress}.
*/
function scoreByAddress(address _addr) external view virtual override returns (uint256) {
return balanceOf(_addr) * _baseScore;
}
// first token start at 1 instead of 0
function _startTokenId() internal view virtual override(ERC721AStructUpgradeable) returns (uint256) {
return 1;
}
// do not allow contract to call
modifier callerIsWallet() {
require(tx.origin == msg.sender, "The caller is another contract");
_;
}
function getMintSupply() public view returns (uint256) {
return MAX_SUPPLY - burnedSupply;
}
modifier checkMintQuantity(uint256 _qty) {
require(_totalMinted() + _qty <= getMintSupply(), "Reached max supply of the collection");
_;
}
// ======== Minting methods ========
function ownerMint(address _to, uint256 _qty)
external
onlyAdmin
checkMintQuantity(_qty)
{
_mint(_to, _qty);
}
function soulIdMint(uint256 _qty)
external
payable
callerIsWallet
checkMintQuantity(_qty)
isFreeMintActive
{
require(_isExternalTokenOwner(soulIdContract, msg.sender), "Caller is not Soul ID owner");
require(_numberSoulIdFreeMinted(msg.sender) + _qty <= mintConfig.freeMintBySoulIdPerWallet, "Reached minting limit per wallet");
_increaseSoulIdFreeMinted(msg.sender, _qty);
_mint(msg.sender, _qty);
}
function freeMint(uint256 _qty, bytes calldata _signature)
external
payable
callerIsWallet
checkMintQuantity(_qty)
isFreeMintActive
checkWhitelist(_signature,"freemint")
{
require(_numberFreeMinted(msg.sender) + _qty <= mintConfig.freeMintByWLPerWallet, "Reached minting limit per wallet");
_increaseFreeMinted(msg.sender, _qty);
_mint(msg.sender, _qty);
}
function presaleMint(uint256 _qty, bytes calldata _signature)
external
payable
callerIsWallet
checkMintQuantity(_qty)
isPresaleActive
checkWhitelist(_signature,"presale")
{
require(msg.value >= mintConfig.presaleMintPrice * _qty, "Need to send more ether");
require(_numberPresaleMinted(msg.sender) + _qty <= mintConfig.presaleMintPerWallet, "Reached minting limit per wallet");
_increasePresaleMinted(msg.sender, _qty);
_mint(msg.sender, _qty);
}
function publicMint(uint256 _qty)
external
payable
callerIsWallet
checkMintQuantity(_qty)
isPublicMintActive
{
require(msg.value >= mintConfig.publicMintPrice * _qty, "Need to send more ether");
require(_numberPublicMinted(msg.sender) + _qty <= mintConfig.publicMintPerWallet, "Reached minting limit per wallet");
_increasePublicMinted(msg.sender, _qty);
_mint(msg.sender, _qty);
}
// count NFT token minted by any owner even the owner may have transferred to other already
function numberMinted(address _addr) public view returns (uint256) {
return _numberMinted(_addr);
}
// reduce collection MAX SUPPLY to decrease collection size
function reduceMaxSupply(uint256 _amount) external onlyAdmin {
require(totalSupply() <= (MAX_SUPPLY - burnedSupply), "Burn amount too much");
unchecked {
burnedSupply += _amount;
}
}
// ======== Unreveal/Reveal token URI functions =========
function _baseURI() internal view virtual override returns (string memory) {
return baseTokenURI;
}
function setBaseURI(string calldata _uri) external onlyAdmin {
baseTokenURI = _uri;
}
function setUnrevealURI(string calldata _uri) external onlyAdmin {
unrevealURI = _uri;
}
function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {
if (!_exists(_tokenId)) revert URIQueryForNonexistentToken();
string memory baseURI = _baseURI();
return bytes(baseURI).length != 0 ?
string(abi.encodePacked(baseURI, _toString(_tokenId))) :
string(abi.encodePacked(unrevealURI, _toString(_tokenId)));
}
// ======== Extra functions =========
// Token ownership data {address addr, uint64 startTimestamp}
function ownershipOf(uint256 _tokenId) external view returns (TokenOwnership memory) {
return _ownershipOf(_tokenId);
}
// Address data for owner
function addressDataOf(address _owner) external view returns (AddressData memory) {
return _addressDataOf(_owner);
}
// ======== Withdraw =========
function withdraw(address payable _to) public onlyAdmin {
// Call returns a boolean value indicating success or failure.
uint256 balance = address(this).balance;
(bool success, ) = _to.call{value: balance}("");
require(success, "Withdraw failed");
}
/**
* @dev Returns whether an address is external NFT owner
*/
function _isExternalTokenOwner(address _contract, address _ownerAddress) internal view returns (bool) {
try IBalanceOf(_contract).balanceOf(_ownerAddress) returns (uint256 balance) {
return balance > 0;
} catch (bytes memory) {
// when reverted, just returns...
return false;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
import "../../utils/AddressUpgradeable.sol";
/**
* @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. Equivalent to `reinitializer(1)`.
*/
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.
*
* `initializer` is equivalent to `reinitializer(1)`, so 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.
*
* 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.
*/
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.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized < type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol)
pragma solidity ^0.8.0;
import "../../interfaces/draft-IERC1822Upgradeable.sol";
import "../ERC1967/ERC1967UpgradeUpgradeable.sol";
import "./Initializable.sol";
/**
* @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
* {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
*
* A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
* reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
* `UUPSUpgradeable` with a custom implementation of upgrades.
*
* The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
*
* _Available since v4.1._
*/
abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {
function __UUPSUpgradeable_init() internal onlyInitializing {
}
function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
}
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
address private immutable __self = address(this);
/**
* @dev Check that the execution is being performed through a delegatecall call and that the execution context is
* a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
* for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
* function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
* fail.
*/
modifier onlyProxy() {
require(address(this) != __self, "Function must be called through delegatecall");
require(_getImplementation() == __self, "Function must be called through active proxy");
_;
}
/**
* @dev Check that the execution is not being performed through a delegate call. This allows a function to be
* callable on the implementing contract but not through proxies.
*/
modifier notDelegated() {
require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall");
_;
}
/**
* @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
* implementation. It is used to validate that the this implementation remains valid after an upgrade.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
*/
function proxiableUUID() external view virtual override notDelegated returns (bytes32) {
return _IMPLEMENTATION_SLOT;
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*/
function upgradeTo(address newImplementation) external virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, new bytes(0), false);
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
* encoded in `data`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*/
function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, data, true);
}
/**
* @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
* {upgradeTo} and {upgradeToAndCall}.
*
* Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
*
* ```solidity
* function _authorizeUpgrade(address) internal override onlyOwner {}
* ```
*/
function _authorizeUpgrade(address newImplementation) 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[50] private __gap;
}// SPDX-License-Identifier: MIT
/**
*******************************************************************************
* Adminable access control
*******************************************************************************
* Author: Jason Hoi
*
*/
pragma solidity ^0.8.7;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides basic multi-admin access control mechanism,
* admins are granted exclusive access to specific functions with the provided
* modifier.
*
* By default, the contract owner is the first admin.
*
* This module is used through inheritance. It will make available the modifier
* `onlyAdmin`, which can be applied to your functions to restrict access.
*
*/
contract AdminableUpgradeable is Initializable {
event AdminCreated(address indexed addr);
event AdminRemoved(address indexed addr);
// mapping for admin address
mapping(address => uint256) _admins;
// Initializes the contract setting the deployer as the initial admin.
function __Adminable_init() internal onlyInitializing {
__Adminable_init_unchained();
}
function __Adminable_init_unchained() internal onlyInitializing {
_admins[_msgSenderAdminable()] = 1;
}
modifier onlyAdmin() {
require(isAdmin(_msgSenderAdminable()), "Adminable: caller is not admin");
_;
}
function isAdmin(address addr) public view virtual returns (bool) {
return _admins[addr] == 1;
}
function setAdmin(address to, bool approved) public virtual onlyAdmin {
require(to != address(0), "Adminable: cannot set admin for the zero address");
if (approved) {
require(!isAdmin(to), "Adminable: add existing admin");
_admins[to] = 1;
emit AdminCreated(to);
} else {
require(isAdmin(to), "Adminable: remove non-existent admin");
delete _admins[to];
emit AdminRemoved(to);
}
}
/**
* @dev Returns the message sender (defaults to `msg.sender`).
*
* For GSN compatible contracts, you need to override this function.
*/
function _msgSenderAdminable() internal view virtual returns (address) {
return msg.sender;
}
/**
* @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;
}// SPDX-License-Identifier: MIT
// ERC721A Contracts v3.3.0
// Creator: Chiru Labs
/**
* @dev This is a modified version from original ERC721A v3.3.0
* - TokenOwnership included transferCount
* - AddressData added custom minting counters
* - Add public functions, transferCount(), totalBurned()
*/
pragma solidity ^0.8.4;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import './IERC721AUpgradeable.sol';
/**
* @dev Interface of ERC721 token receiver.
*/
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);
}
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata extension. Built to optimize for lower gas during batch mints.
*
* Assumes serials are sequentially minted starting at _startTokenId() (defaults to 1, e.g. 1, 2, 3..).
*
* Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
*
* Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
*/
contract ERC721AStructUpgradeable is IERC721AUpgradeable, Initializable {
// The tokenId of the next token to be minted.
uint256 internal _currentIndex;
// The number of tokens burned.
uint256 internal _burnCounter;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to ownership details
// An empty struct value does not necessarily mean the token is unowned. See _ownershipOf implementation for details.
mapping(uint256 => TokenOwnership) internal _ownerships;
// Mapping owner address to address data
mapping(address => AddressData) private _addressData;
// 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;
function __ERC721AStruct_init(string memory name_, string memory symbol_) internal onlyInitializing {
__ERC721AStruct_init_unchained(name_, symbol_);
}
function __ERC721AStruct_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {
_name = name_;
_symbol = symbol_;
_currentIndex = _startTokenId();
}
/**
* To change the starting tokenId, please override this function.
*/
function _startTokenId() internal view virtual returns (uint256) {
return 1;
}
/**
* @dev Burned tokens are calculated here, use _totalMinted() if you want to count just minted tokens.
*/
function totalSupply() public view virtual override returns (uint256) {
// Counter underflow is impossible as _burnCounter cannot be incremented
// more than _currentIndex - _startTokenId() times
unchecked {
return _currentIndex - _burnCounter - _startTokenId();
}
}
/**
* Returns the (after minting) transfer counter for a token.
*/
function transferCount(uint256 tokenId) public view virtual returns (uint256) {
return _ownershipOf(tokenId).transferCount;
}
/**
* @dev Returns the total number of tokens burned.
*/
function totalBurned() public view virtual returns (uint256) {
return _burnCounter;
}
/**
* Returns the total amount of tokens minted in the contract.
*/
function _totalMinted() internal view virtual returns (uint256) {
// Counter underflow is impossible as _currentIndex does not decrement,
// and it is initialized to _startTokenId()
unchecked {
return _currentIndex - _startTokenId();
}
}
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
* to learn more about how these ids are created.
*
* This function call must use less than 30000 gas.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
// The interface IDs are constants representing the first 4 bytes
// of the XOR of all function selectors in the interface.
// See: [ERC165](https://eips.ethereum.org/EIPS/eip-165)
// (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`)
return
interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
}
/**
* @dev See {IERC721-balanceOf}.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
if (owner == address(0)) revert BalanceQueryForZeroAddress();
return uint256(_addressData[owner].balance);
}
/**
* Returns the number of tokens minted by `owner`.
*/
function _numberMinted(address owner) internal view returns (uint256) {
return uint256(_addressData[owner].numberMinted);
}
/**
* Returns the number of tokens Soul ID free minted by `addr`.
*/
function _numberSoulIdFreeMinted(address owner) internal view returns (uint256) {
return uint256(_addressData[owner].numberSoulIdFreeMinted);
}
/**
* Returns the number of tokens free minted by `addr`.
*/
function _numberFreeMinted(address owner) internal view returns (uint256) {
return uint256(_addressData[owner].numberFreeMinted);
}
/**
* Returns the number of tokens presale minted by `addr`.
*/
function _numberPresaleMinted(address owner) internal view returns (uint256) {
return uint256(_addressData[owner].numberPresaleMinted);
}
/**
* Returns the number of tokens public minted by `addr`.
*/
function _numberPublicMinted(address owner) internal view returns (uint256) {
return uint256(_addressData[owner].numberPublicMinted);
}
/**
* Increase the Soul ID free mint counter for msg sender
*/
function _increaseSoulIdFreeMinted(address owner, uint256 qty) internal {
// 2**16 - 1 should be well-over the max mint per wallet
unchecked {
_addressData[owner].numberSoulIdFreeMinted += uint16(qty);
}
}
/**
* Increase the WL free mint counter for msg sender
*/
function _increaseFreeMinted(address owner, uint256 qty) internal {
// 2**16 - 1 should be well-over the max mint per wallet
unchecked {
_addressData[owner].numberFreeMinted += uint16(qty);
}
}
/**
* Increase the presale mint counter for msg sender
*/
function _increasePresaleMinted(address owner, uint256 qty) internal {
// 2**16 - 1 should be well-over the max mint per wallet
unchecked {
_addressData[owner].numberPresaleMinted += uint16(qty);
}
}
/**
* Increase the public mint counter for msg sender
*/
function _increasePublicMinted(address owner, uint256 qty) internal {
// 2**16 - 1 should be well-over the max mint per wallet
unchecked {
_addressData[owner].numberPublicMinted += uint16(qty);
}
}
/**
* Returns the number of tokens burned by or on behalf of `owner`.
*/
function _numberBurned(address owner) internal view returns (uint256) {
return uint256(_addressData[owner].numberBurned);
}
/**
* Returns address data of a token owner
*/
function _addressDataOf(address owner) internal view returns (AddressData memory) {
return _addressData[owner];
}
/**
* Gas spent here starts off proportional to the maximum mint batch size.
* It gradually moves to O(1) as tokens get transferred around in the collection over time.
*/
function _ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) {
uint256 curr = tokenId;
unchecked {
if (_startTokenId() <= curr) if (curr < _currentIndex) {
TokenOwnership memory ownership = _ownerships[curr];
if (!ownership.burned) {
if (ownership.addr != address(0)) {
return ownership;
}
// Invariant:
// There will always be an ownership that has an address and is not burned
// before an ownership that does not have an address and is not burned.
// Hence, curr will not underflow.
while (true) {
curr--;
ownership = _ownerships[curr];
if (ownership.addr != address(0)) {
return ownership;
}
}
}
}
}
revert OwnerQueryForNonexistentToken();
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
return _ownershipOf(tokenId).addr;
}
/**
* @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) {
if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
string memory baseURI = _baseURI();
return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : '';
}
/**
* @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 overriden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return '';
}
/**
* @dev See {IERC721-approve}.
*/
function approve(address to, uint256 tokenId) public payable virtual override {
address owner = ownerOf(tokenId);
if (to == owner) revert ApprovalToCurrentOwner();
if (_msgSenderERC721A() != owner) if(!isApprovedForAll(owner, _msgSenderERC721A())) {
revert ApprovalCallerNotOwnerNorApproved();
}
_approve(to, tokenId, owner);
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();
return _tokenApprovals[tokenId];
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
if (operator == _msgSenderERC721A()) revert ApproveToCaller();
_operatorApprovals[_msgSenderERC721A()][operator] = approved;
emit ApprovalForAll(_msgSenderERC721A(), 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 payable virtual override {
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public payable virtual override {
safeTransferFrom(from, to, tokenId, '');
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public payable virtual override {
_transfer(from, to, tokenId);
if (to.code.length != 0) if(!_checkContractOnERC721Received(from, to, tokenId, _data)) {
revert TransferToNonERC721ReceiverImplementer();
}
}
/**
* @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`),
*/
function _exists(uint256 tokenId) internal view returns (bool) {
return _startTokenId() <= tokenId && tokenId < _currentIndex && !_ownerships[tokenId].burned;
}
/**
* @dev Equivalent to `_safeMint(to, quantity, '')`.
*/
function _safeMint(address to, uint256 quantity) internal {
_safeMint(to, quantity, '');
}
/**
* @dev Safely mints `quantity` tokens and transfers them to `to`.
*
* Requirements:
*
* - If `to` refers to a smart contract, it must implement
* {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
* - `quantity` must be greater than 0.
*
* Emits a {Transfer} event.
*/
function _safeMint(
address to,
uint256 quantity,
bytes memory _data
) internal {
uint256 startTokenId = _currentIndex;
if (to == address(0)) revert MintToZeroAddress();
if (quantity == 0) revert MintZeroQuantity();
_beforeTokenTransfers(address(0), to, startTokenId, quantity);
// Overflows are incredibly unrealistic.
// balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
// updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
unchecked {
_addressData[to].balance += uint64(quantity);
_addressData[to].numberMinted += uint64(quantity);
_ownerships[startTokenId].addr = to;
_ownerships[startTokenId].startTimestamp = uint64(block.timestamp);
uint256 updatedIndex = startTokenId;
uint256 end = updatedIndex + quantity;
if (to.code.length != 0) {
do {
emit Transfer(address(0), to, updatedIndex);
if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) {
revert TransferToNonERC721ReceiverImplementer();
}
} while (updatedIndex < end);
// Reentrancy protection
if (_currentIndex != startTokenId) revert();
} else {
do {
emit Transfer(address(0), to, updatedIndex++);
} while (updatedIndex < end);
}
_currentIndex = updatedIndex;
}
_afterTokenTransfers(address(0), to, startTokenId, quantity);
}
/**
* @dev Mints `quantity` tokens and transfers them to `to`.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `quantity` must be greater than 0.
*
* Emits a {Transfer} event.
*/
function _mint(address to, uint256 quantity) internal {
uint256 startTokenId = _currentIndex;
if (to == address(0)) revert MintToZeroAddress();
if (quantity == 0) revert MintZeroQuantity();
_beforeTokenTransfers(address(0), to, startTokenId, quantity);
// Overflows are incredibly unrealistic.
// balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
// updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
unchecked {
_addressData[to].balance += uint64(quantity);
_addressData[to].numberMinted += uint64(quantity);
_ownerships[startTokenId].addr = to;
_ownerships[startTokenId].startTimestamp = uint64(block.timestamp);
uint256 updatedIndex = startTokenId;
uint256 end = updatedIndex + quantity;
do {
emit Transfer(address(0), to, updatedIndex++);
} while (updatedIndex < end);
_currentIndex = updatedIndex;
}
_afterTokenTransfers(address(0), to, startTokenId, quantity);
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
*
* 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
) private {
TokenOwnership memory prevOwnership = _ownershipOf(tokenId);
if (prevOwnership.addr != from) revert TransferFromIncorrectOwner();
bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
isApprovedForAll(from, _msgSenderERC721A()) ||
getApproved(tokenId) == _msgSenderERC721A());
if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
if (to == address(0)) revert TransferToZeroAddress();
_beforeTokenTransfers(from, to, tokenId, 1);
// Clear approvals from the previous owner
_approve(address(0), tokenId, from);
// Underflow of the sender's balance is impossible because we check for
// ownership above and the recipient's balance can't realistically overflow.
// Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
unchecked {
_addressData[from].balance -= 1;
_addressData[to].balance += 1;
TokenOwnership storage currSlot = _ownerships[tokenId];
currSlot.addr = to;
currSlot.startTimestamp = uint64(block.timestamp);
// Increase Trasfer counter
currSlot.transferCount += 1;
// If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.
// Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
uint256 nextTokenId = tokenId + 1;
TokenOwnership storage nextSlot = _ownerships[nextTokenId];
if (nextSlot.addr == address(0)) {
// This will suffice for checking _exists(nextTokenId),
// as a burned slot cannot contain the zero address.
if (nextTokenId != _currentIndex) {
nextSlot.addr = from;
nextSlot.startTimestamp = prevOwnership.startTimestamp;
}
}
}
emit Transfer(from, to, tokenId);
_afterTokenTransfers(from, to, tokenId, 1);
}
/**
* @dev Equivalent to `_burn(tokenId, false)`.
*/
function _burn(uint256 tokenId) internal virtual {
_burn(tokenId, false);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
TokenOwnership memory prevOwnership = _ownershipOf(tokenId);
address from = prevOwnership.addr;
if (approvalCheck) {
bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
isApprovedForAll(from, _msgSenderERC721A()) ||
getApproved(tokenId) == _msgSenderERC721A());
if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
}
_beforeTokenTransfers(from, address(0), tokenId, 1);
// Clear approvals from the previous owner
_approve(address(0), tokenId, from);
// Underflow of the sender's balance is impossible because we check for
// ownership above and the recipient's balance can't realistically overflow.
// Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
unchecked {
AddressData storage addressData = _addressData[from];
addressData.balance -= 1;
addressData.numberBurned += 1;
// Keep track of who burned the token, and the timestamp of burning.
TokenOwnership storage currSlot = _ownerships[tokenId];
currSlot.addr = from;
currSlot.startTimestamp = uint64(block.timestamp);
currSlot.burned = true;
// If the ownership slot of tokenId+1 is not explicitly set, that means the burn initiator owns it.
// Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
uint256 nextTokenId = tokenId + 1;
TokenOwnership storage nextSlot = _ownerships[nextTokenId];
if (nextSlot.addr == address(0)) {
// This will suffice for checking _exists(nextTokenId),
// as a burned slot cannot contain the zero address.
if (nextTokenId != _currentIndex) {
nextSlot.addr = from;
nextSlot.startTimestamp = prevOwnership.startTimestamp;
}
}
}
emit Transfer(from, address(0), tokenId);
_afterTokenTransfers(from, address(0), tokenId, 1);
// Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
unchecked {
_burnCounter++;
}
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits a {Approval} event.
*/
function _approve(
address to,
uint256 tokenId,
address owner
) private {
_tokenApprovals[tokenId] = to;
emit Approval(owner, to, tokenId);
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target 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 _checkContractOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
try IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (bytes4 retval) {
return retval == IERC721Receiver(to).onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert TransferToNonERC721ReceiverImplementer();
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
}
/**
* @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting.
* And also called before burning one token.
*
* startTokenId - the first token id to be transferred
* quantity - the amount to be transferred
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, `tokenId` will be burned by `from`.
* - `from` and `to` are never both zero.
*/
function _beforeTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual {}
/**
* @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes
* minting.
* And also called after one token has been burned.
*
* startTokenId - the first token id to be transferred
* quantity - the amount to be transferred
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
* transferred to `to`.
* - When `from` is zero, `tokenId` has been minted for `to`.
* - When `to` is zero, `tokenId` has been burned by `from`.
* - `from` and `to` are never both zero.
*/
function _afterTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual {}
// =============================================================
// OTHER OPERATIONS
// =============================================================
/**
* @dev Returns the message sender (defaults to `msg.sender`).
*
* If you are writing GSN compatible contracts, you need to override this function.
*/
function _msgSenderERC721A() internal view virtual returns (address) {
return msg.sender;
}
/**
* @dev Converts a uint256 to its ASCII string decimal representation.
*/
function _toString(uint256 value) internal pure virtual returns (string memory str) {
assembly {
// The maximum value of a uint256 contains 78 digits (1 byte per digit), but
// we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
// We will need 1 word for the trailing zeros padding, 1 word for the length,
// and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0.
let m := add(mload(0x40), 0xa0)
// Update the free memory pointer to allocate.
mstore(0x40, m)
// Assign the `str` to the end.
str := sub(m, 0x20)
// Zeroize the slot after the string.
mstore(str, 0)
// Cache the end of the memory to calculate the length later.
let end := str
// We write the string from rightmost digit to leftmost digit.
// The following is essentially a do-while loop that also handles the zero case.
// prettier-ignore
for { let temp := value } 1 {} {
str := sub(str, 1)
// Write the character to the pointer.
// The ASCII index of the '0' character is 48.
mstore8(str, add(48, mod(temp, 10)))
// Keep dividing `temp` until zero.
temp := div(temp, 10)
// prettier-ignore
if iszero(temp) { break }
}
let length := sub(end, str)
// Move the pointer 32 bytes leftwards to make room for the length.
str := sub(str, 0x20)
// Store the length.
mstore(str, length)
}
}
/**
* @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[42] private __gap;
}// SPDX-License-Identifier: MIT
// ERC721A Contracts v3.3.0
// Creator: Chiru Labs
pragma solidity ^0.8.4;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import '../ERC721AStructUpgradeable.sol';
/**
* @title ERC721A Burnable Token
* @dev ERC721A Token that can be irreversibly burned (destroyed).
*/
abstract contract ERC721ABurnableUpgradeable is Initializable, ERC721AStructUpgradeable {
function __ERC721ABurnable_init() internal onlyInitializing {
}
function __ERC721ABurnable_init_unchained() internal onlyInitializing {
}
/**
* @dev Burns `tokenId`. See {ERC721A-_burn}.
*
* Requirements:
*
* - The caller must own `tokenId` or be an approved operator.
*/
function burn(uint256 tokenId) public virtual {
_burn(tokenId, true);
}
/**
* @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;
}// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "./IERC4907Upgradeable.sol";
import "../ERC721AStructUpgradeable.sol";
abstract contract ERC4907Upgradeable is Initializable, ERC721AStructUpgradeable, IERC4907Upgradeable {
// Compiler will pack this into a single 256bit word.
struct UserInfo {
address user; // address of user role
uint64 expires; // unix timestamp, user expires
}
mapping (uint256 => UserInfo) internal _users;
function __ERC4907_init() internal onlyInitializing {
}
function __ERC4907_init_unchained() internal onlyInitializing {
}
/**
* @dev Set the user and expires of `tokenId`. See {IERC4907-setUser}.
*
* Requirements:
*
* - The caller must own `tokenId` or be an approved operator.
*/
function setUser(uint256 tokenId, address user, uint64 expires) external virtual override {
address ownerAddr = _ownershipOf(tokenId).addr;
bool isApprovedOrOwner = (_msgSenderERC721A() == ownerAddr ||
isApprovedForAll(ownerAddr, _msgSenderERC721A()) ||
getApproved(tokenId) == _msgSenderERC721A());
require (isApprovedOrOwner, "ERC4907: transfer caller is not owner nor approved");
UserInfo storage info = _users[tokenId];
info.user = user;
info.expires = expires;
emit UpdateUser(tokenId, user, expires);
}
/**
* @dev Returns the user address for `tokenId`.
* The zero address indicates that there is no user or if the user is expired.
*/
function userOf(uint256 tokenId) external view virtual override returns (address) {
if (uint256(_users[tokenId].expires) >= block.timestamp){
return _users[tokenId].user;
} else {
return address(0);
}
}
/**
* @dev Returns the user's expires timestamp of `tokenId`.
* The zero value indicates that there is no user.
*/
function userExpires(uint256 tokenId) external view virtual override returns (uint256) {
return _users[tokenId].expires;
}
/**
* @dev Clear the user info (on transfer, burn) for `tokenId`.
*
*/
function _beforeTokenTransfers(
address from,
address to,
uint256 startTokenId,
uint256 quantity
) internal virtual override {
super._beforeTokenTransfers(from, to, startTokenId, quantity);
// ERC721 transfer or burn should only affect one token at a time
if (quantity == 1) {
uint256 tokenId = startTokenId;
if (from != to && _users[tokenId].user != address(0)) {
// clear user info
delete _users[tokenId];
emit UpdateUser(tokenId, address(0), 0);
}
}
}
/**
* @dev Override of {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
// The interface ID for ERC4907 is `0xad092b5c`,
// as defined in [ERC4907](https://eips.ethereum.org/EIPS/eip-4907).
return super.supportsInterface(interfaceId) || interfaceId == 0xad092b5c;
}
/**
* @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;
}// SPDX-License-Identifier: MIT
/**
*******************************************************************************
* EIP 712 whitelist with qty parameter
*******************************************************************************
* Author: Jason Hoi
*
*/
pragma solidity ^0.8.7;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol";
import "../sharkz/AdminableUpgradeable.sol";
contract EIP712WhitelistTypedUpgradeable is Initializable, AdminableUpgradeable {
event SetSigner(address indexed sender, address indexed signer);
using ECDSAUpgradeable for bytes32;
// Verify signature with this signer address
address public eip712Signer;
// Domain separator is EIP-712 defined struct to make sure
// signature is coming from the this contract in same ETH newtork.
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md#definition-of-domainseparator
// @MATCHING cliend-side code
bytes32 public DOMAIN_SEPARATOR;
// HASH_STRUCT should not contain unnecessary whitespace between each parameters
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md#definition-of-encodetype
// @MATCHING cliend-side code
bytes32 public constant HASH_STRUCT = keccak256("Minter(address wallet,bytes32 type)");
function __EIP712WhitelistTyped_init() internal onlyInitializing {
__EIP712WhitelistTyped_init_unchained();
}
function __EIP712WhitelistTyped_init_unchained() internal onlyInitializing {
// @MATCHING cliend-side code
DOMAIN_SEPARATOR = keccak256(
abi.encode(
keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
),
// @MATCHING cliend-side code
keccak256(bytes("WhitelistToken")),
keccak256(bytes("1")),
block.chainid,
address(this)
)
);
// initial signer is contract creator
setSigner(_msgSenderEIP712());
}
function setSigner(address _addr) public onlyAdmin {
eip712Signer = _addr;
emit SetSigner(_msgSenderEIP712(), _addr);
}
modifier checkWhitelist(bytes calldata _signature, string memory _type) {
require(eip712Signer == _recoverSigner(_signature, _type), "EIP712: Invalid Signature");
_;
}
function verifySignature(bytes calldata _signature, string memory _type) public view returns (bool) {
return eip712Signer == _recoverSigner(_signature, _type);
}
// Recover the signer address
function _recoverSigner(bytes calldata _signature, string memory _type) internal view returns (address) {
require(eip712Signer != address(0), "EIP712: Whitelist not enabled");
// Verify EIP-712 signature by recreating the data structure
// that we signed on the client side, and then using that to recover
// the address that signed the signature for this data.
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
keccak256(abi.encode(HASH_STRUCT, _msgSenderEIP712(), bytes32(bytes(_type))))
)
);
return digest.recover(_signature);
}
/**
* @dev Returns the message sender (defaults to `msg.sender`).
*
* For GSN compatible contracts, you need to override this function.
*/
function _msgSenderEIP712() internal view virtual returns (address) {
return msg.sender;
}
/**
* @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;
}// SPDX-License-Identifier: MIT
/**
*******************************************************************************
* IScore interface
*******************************************************************************
* Creator: Sharkz Entertainment
* Author: Jason Hoi
*
*/
pragma solidity ^0.8.7;
/**
* @dev Interface of token score, external token contract may accumulate total
* score from multiple IScore tokens.
*/
interface IScore {
/**
* @dev Get base score for each token (this is the unit score for different
* `tokenId` or owner address)
*/
function baseScore() external view returns (uint256);
/**
* @dev Get score for individual `tokenId`
* This function is needed only when score varies between token ids.
* In order to accumulate score, try to avoid any revert() if user submitted
* non-existent token id or owner address.
*
*/
function scoreByToken(uint256 tokenId) external view returns (uint256);
/**
* @dev Get score of an address
* In order to accumulate score, try to avoid any revert() if user submitted
* non-existent token id or owner address.
*
*/
function scoreByAddress(address addr) external view returns (uint256);
}// SPDX-License-Identifier: MIT
/**
*******************************************************************************
* Sharkz NFT minting setup
*******************************************************************************
* Creator: Sharkz Entertainment
* Author: Jason Hoi
*
*/
pragma solidity ^0.8.7;
import "../lib-upgradeable/sharkz/AdminableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
contract MintSetupUpgradeable is AdminableUpgradeable {
struct MintConfig {
// Free Mint by Soul ID or WL
uint32 freeMintStartTime;
uint32 freeMintEndTime;
uint16 freeMintBySoulIdPerWallet;
uint16 freeMintByWLPerWallet;
// Presale Mint by WL
uint32 presaleMintStartTime;
uint32 presaleMintEndTime;
uint16 presaleMintPerWallet;
// Public Mint
uint32 publicMintStartTime;
uint32 publicMintEndTime;
uint16 publicMintPerWallet;
uint256 presaleMintPrice;
uint256 publicMintPrice;
}
MintConfig public mintConfig;
function __MintSetup_init() internal onlyInitializing {
__MintSetup_init_unchained();
}
function __MintSetup_init_unchained() internal onlyInitializing {
// Free Mint by Soul ID or WL
mintConfig.freeMintStartTime = 1664539200;
mintConfig.freeMintEndTime = 1665144000;
mintConfig.freeMintBySoulIdPerWallet = 1;
mintConfig.freeMintByWLPerWallet = 1;
// Presale Mint by WL
mintConfig.presaleMintPrice = 0.02 ether;
mintConfig.presaleMintStartTime = 1664541000;
mintConfig.presaleMintEndTime = 1665144000;
mintConfig.presaleMintPerWallet = 10;
// Public Mint
mintConfig.publicMintPrice = 0.05 ether;
mintConfig.publicMintStartTime = 1664541000;
mintConfig.publicMintEndTime = 1665144000;
mintConfig.publicMintPerWallet = 20;
}
//////// Free Mint (Soul ID or Free Mint WL)
function setFreeMint(uint32 _startTime, uint32 _endTime, uint16 _soulIdMintPerWallet, uint16 _wlMintPerWallet)
external
onlyAdmin
{
mintConfig.freeMintStartTime = _startTime;
mintConfig.freeMintEndTime = _endTime;
mintConfig.freeMintBySoulIdPerWallet = _soulIdMintPerWallet;
mintConfig.freeMintByWLPerWallet = _wlMintPerWallet;
}
function checkFreeMintTime() public view returns (bool) {
uint256 _currentTime = block.timestamp;
return
mintConfig.freeMintStartTime > 0
&& _currentTime >= mintConfig.freeMintStartTime
&& _currentTime <= mintConfig.freeMintEndTime;
}
modifier isFreeMintActive() {
require(checkFreeMintTime(), "Free mint is not active");
_;
}
//////// Presale Mint by WL
function setPresale(uint256 _price, uint32 _startTime, uint32 _endTime, uint16 _maxPerWallet) external onlyAdmin {
mintConfig.presaleMintPrice = _price;
mintConfig.presaleMintStartTime = _startTime;
mintConfig.presaleMintEndTime = _endTime;
mintConfig.presaleMintPerWallet = _maxPerWallet;
}
function checkPresaleTime() public view returns (bool) {
uint256 _currentTime = block.timestamp;
return
mintConfig.presaleMintStartTime > 0
&& _currentTime >= mintConfig.presaleMintStartTime
&& _currentTime <= mintConfig.presaleMintEndTime;
}
modifier isPresaleActive() {
require(checkPresaleTime(), "Presale mint is not active");
_;
}
//////// Public minting
function setPublicMint(uint256 _price, uint32 _startTime, uint32 _endTime, uint16 _maxPerWallet) external onlyAdmin {
mintConfig.publicMintPrice = _price;
mintConfig.publicMintStartTime = _startTime;
mintConfig.publicMintEndTime = _endTime;
mintConfig.publicMintPerWallet = _maxPerWallet;
}
function checkPublicMintTime() public view returns (bool) {
uint256 _currentTime = block.timestamp;
return
mintConfig.publicMintStartTime > 0
&& _currentTime >= mintConfig.publicMintStartTime
&& _currentTime <= mintConfig.publicMintEndTime;
}
modifier isPublicMintActive() {
require(checkPublicMintTime(), "Public mint is not active");
_;
}
/**
* @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[19] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)
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 functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(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) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason 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 {
// 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);
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)
pragma solidity ^0.8.0;
/**
* @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
* proxy whose upgrades are fully controlled by the current implementation.
*/
interface IERC1822ProxiableUpgradeable {
/**
* @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
* address.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy.
*/
function proxiableUUID() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)
pragma solidity ^0.8.2;
import "../beacon/IBeaconUpgradeable.sol";
import "../../interfaces/draft-IERC1822Upgradeable.sol";
import "../../utils/AddressUpgradeable.sol";
import "../../utils/StorageSlotUpgradeable.sol";
import "../utils/Initializable.sol";
/**
* @dev This abstract contract provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
*
* _Available since v4.1._
*
* @custom:oz-upgrades-unsafe-allow delegatecall
*/
abstract contract ERC1967UpgradeUpgradeable is Initializable {
function __ERC1967Upgrade_init() internal onlyInitializing {
}
function __ERC1967Upgrade_init_unchained() internal onlyInitializing {
}
// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Returns the current implementation address.
*/
function _getImplementation() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract");
StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
}
/**
* @dev Perform implementation upgrade
*
* Emits an {Upgraded} event.
*/
function _upgradeTo(address newImplementation) internal {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
/**
* @dev Perform implementation upgrade with additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCall(
address newImplementation,
bytes memory data,
bool forceCall
) internal {
_upgradeTo(newImplementation);
if (data.length > 0 || forceCall) {
_functionDelegateCall(newImplementation, data);
}
}
/**
* @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCallUUPS(
address newImplementation,
bytes memory data,
bool forceCall
) internal {
// Upgrades from old implementations will perform a rollback test. This test requires the new
// implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing
// this special case will break upgrade paths from old UUPS implementation to new ones.
if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {
_setImplementation(newImplementation);
} else {
try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {
require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID");
} catch {
revert("ERC1967Upgrade: new implementation is not UUPS");
}
_upgradeToAndCall(newImplementation, data, forceCall);
}
}
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Returns the current admin.
*/
function _getAdmin() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
require(newAdmin != address(0), "ERC1967: new admin is the zero address");
StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {AdminChanged} event.
*/
function _changeAdmin(address newAdmin) internal {
emit AdminChanged(_getAdmin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
*/
bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Emitted when the beacon is upgraded.
*/
event BeaconUpgraded(address indexed beacon);
/**
* @dev Returns the current beacon.
*/
function _getBeacon() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the EIP1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract");
require(
AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),
"ERC1967: beacon implementation is not a contract"
);
StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;
}
/**
* @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
* not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
*
* Emits a {BeaconUpgraded} event.
*/
function _upgradeBeaconToAndCall(
address newBeacon,
bytes memory data,
bool forceCall
) internal {
_setBeacon(newBeacon);
emit BeaconUpgraded(newBeacon);
if (data.length > 0 || forceCall) {
_functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);
}
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) {
require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed");
}
/**
* @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;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)
pragma solidity ^0.8.0;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeaconUpgradeable {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {BeaconProxy} will check that this address is a contract.
*/
function implementation() external view returns (address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)
pragma solidity ^0.8.0;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC1967 implementation slot:
* ```
* contract ERC1967 {
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._
*/
library StorageSlotUpgradeable {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
}// SPDX-License-Identifier: MIT
// ERC721A Contracts v3.3.0
// Creator: Chiru Labs
/** This is a modified version from original ERC721A v3.3.0
- ERC721ABurnable, burn() public function embedded
- TokenOwnership included transferCount
- AddressData added more fields
*/
pragma solidity ^0.8.4;
/**
* @dev Interface of an ERC721A compliant contract.
*/
interface IERC721AUpgradeable {
/**
* The caller must own the token or be an approved operator.
*/
error ApprovalCallerNotOwnerNorApproved();
/**
* The token does not exist.
*/
error ApprovalQueryForNonexistentToken();
/**
* The caller cannot approve to their own address.
*/
error ApproveToCaller();
/**
* The caller cannot approve to the current owner.
*/
error ApprovalToCurrentOwner();
/**
* Cannot query the balance for the zero address.
*/
error BalanceQueryForZeroAddress();
/**
* Cannot mint to the zero address.
*/
error MintToZeroAddress();
/**
* The quantity of tokens minted must be more than zero.
*/
error MintZeroQuantity();
/**
* The token does not exist.
*/
error OwnerQueryForNonexistentToken();
/**
* The caller must own the token or be an approved operator.
*/
error TransferCallerNotOwnerNorApproved();
/**
* The token must be owned by `from`.
*/
error TransferFromIncorrectOwner();
/**
* Cannot safely transfer to a contract that does not implement the ERC721Receiver interface.
*/
error TransferToNonERC721ReceiverImplementer();
/**
* Cannot transfer to the zero address.
*/
error TransferToZeroAddress();
/**
* The token does not exist.
*/
error URIQueryForNonexistentToken();
// Compiler will pack this into a single 256bit word.
struct TokenOwnership {
// The address of the owner.
address addr;
// Keeps track of the start time of ownership with minimal overhead for tokenomics.
uint64 startTimestamp;
// Keeps track of transfer counter
uint32 transferCount;
// Whether the token has been burned.
bool burned;
}
// Compiler will pack this into a single 256bit word.
struct AddressData {
// Realistically, 2**64-1 is more than enough.
uint64 balance;
// Keeps track of mint count with minimal overhead for tokenomics.
uint64 numberMinted;
// Keeps track of burn count with minimal overhead for tokenomics.
uint64 numberBurned;
// Mint quota
uint16 numberSoulIdFreeMinted;
// Mint quota
uint16 numberFreeMinted;
// Mint quota
uint16 numberPresaleMinted;
// Mint quota
uint16 numberPublicMinted;
}
/**
* @dev Returns the total amount of tokens stored by the contract.
*
* Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens.
*/
function totalSupply() external view returns (uint256);
// =============================================================
// IERC165
// =============================================================
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
* to learn more about how these ids are created.
*
* This function call must use less than 30000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
// =============================================================
// IERC721
// =============================================================
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables
* (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in `owner`'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`,
* checking first that contract recipients are aware of the ERC721 protocol
* to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be have been allowed to move
* this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement
* {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external payable;
/**
* @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external payable;
/**
* @dev Transfers `tokenId` from `from` to `to`.
*
* WARNING: Usage of this method is discouraged, use {safeTransferFrom}
* whenever possible.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token
* by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external payable;
/**
* @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 payable;
/**
* @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);
// =============================================================
// IERC721Metadata
// =============================================================
/**
* @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);
}// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;
interface IERC4907Upgradeable {
// Logged when the user of a token assigns a new user or updates expires
/// @notice Emitted when the `user` of an NFT or the `expires` of the `user` is changed
/// The zero address for user indicates that there is no user address
event UpdateUser(uint256 indexed tokenId, address indexed user, uint64 expires);
/// @notice set the user and expires of a NFT
/// @dev The zero address indicates there is no user
/// Throws if `tokenId` is not valid NFT
/// @param user The new user of the NFT
/// @param expires UNIX timestamp, The new user could use the NFT before expires
function setUser(uint256 tokenId, address user, uint64 expires) external ;
/// @notice Get the user address of an NFT
/// @dev The zero address indicates that there is no user or the user is expired
/// @param tokenId The NFT to get the user address for
/// @return The user address for this NFT
function userOf(uint256 tokenId) external view returns(address);
/// @notice Get the user expires of an NFT
/// @dev The zero value indicates that there is no user
/// @param tokenId The NFT to get the user expires for
/// @return The user expires for this NFT
function userExpires(uint256 tokenId) external view returns(uint256);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)
pragma solidity ^0.8.0;
import "../StringsUpgradeable.sol";
/**
* @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 ECDSAUpgradeable {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV
}
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");
} else if (error == RecoverError.InvalidSignatureV) {
revert("ECDSA: invalid signature 'v' 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) {
// Check the signature length
// - case 65: r,s,v signature (standard)
// - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
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 if (signature.length == 64) {
bytes32 r;
bytes32 vs;
// 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))
vs := mload(add(signature, 0x40))
}
return tryRecover(hash, r, vs);
} 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 (v != 27 && v != 28) {
return (address(0), RecoverError.InvalidSignatureV);
}
// 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", StringsUpgradeable.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));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library StringsUpgradeable {
bytes16 private constant _HEX_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) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
/**
* @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] = _HEX_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);
}
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"}],"name":"AdminCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"}],"name":"AdminRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"signer","type":"address"}],"name":"SetSigner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint64","name":"expires","type":"uint64"}],"name":"UpdateUser","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HASH_STRUCT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PROVENANCE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"addressDataOf","outputs":[{"components":[{"internalType":"uint64","name":"balance","type":"uint64"},{"internalType":"uint64","name":"numberMinted","type":"uint64"},{"internalType":"uint64","name":"numberBurned","type":"uint64"},{"internalType":"uint16","name":"numberSoulIdFreeMinted","type":"uint16"},{"internalType":"uint16","name":"numberFreeMinted","type":"uint16"},{"internalType":"uint16","name":"numberPresaleMinted","type":"uint16"},{"internalType":"uint16","name":"numberPublicMinted","type":"uint16"}],"internalType":"struct IERC721AUpgradeable.AddressData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseScore","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burnedSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkFreeMintTime","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkPresaleTime","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkPublicMintTime","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Signer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_qty","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"freeMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMintSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintConfig","outputs":[{"internalType":"uint32","name":"freeMintStartTime","type":"uint32"},{"internalType":"uint32","name":"freeMintEndTime","type":"uint32"},{"internalType":"uint16","name":"freeMintBySoulIdPerWallet","type":"uint16"},{"internalType":"uint16","name":"freeMintByWLPerWallet","type":"uint16"},{"internalType":"uint32","name":"presaleMintStartTime","type":"uint32"},{"internalType":"uint32","name":"presaleMintEndTime","type":"uint32"},{"internalType":"uint16","name":"presaleMintPerWallet","type":"uint16"},{"internalType":"uint32","name":"publicMintStartTime","type":"uint32"},{"internalType":"uint32","name":"publicMintEndTime","type":"uint32"},{"internalType":"uint16","name":"publicMintPerWallet","type":"uint16"},{"internalType":"uint256","name":"presaleMintPrice","type":"uint256"},{"internalType":"uint256","name":"publicMintPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_qty","type":"uint256"}],"name":"ownerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"ownershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"uint32","name":"transferCount","type":"uint32"},{"internalType":"bool","name":"burned","type":"bool"}],"internalType":"struct IERC721AUpgradeable.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_qty","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"presaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_qty","type":"uint256"}],"name":"publicMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"reduceMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"scoreByAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"scoreByToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_score","type":"uint256"}],"name":"setBaseScore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_startTime","type":"uint32"},{"internalType":"uint32","name":"_endTime","type":"uint32"},{"internalType":"uint16","name":"_soulIdMintPerWallet","type":"uint16"},{"internalType":"uint16","name":"_wlMintPerWallet","type":"uint16"}],"name":"setFreeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint32","name":"_startTime","type":"uint32"},{"internalType":"uint32","name":"_endTime","type":"uint32"},{"internalType":"uint16","name":"_maxPerWallet","type":"uint16"}],"name":"setPresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_hash","type":"string"}],"name":"setProvenance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint32","name":"_startTime","type":"uint32"},{"internalType":"uint32","name":"_endTime","type":"uint32"},{"internalType":"uint16","name":"_maxPerWallet","type":"uint16"}],"name":"setPublicMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"setSoulIdContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setUnrevealURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint64","name":"expires","type":"uint64"}],"name":"setUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"soulIdContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_qty","type":"uint256"}],"name":"soulIdMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"unrevealURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"userExpires","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"userOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"string","name":"_type","type":"string"}],"name":"verifySignature","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address payable","name":"_to","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60a06040523060805234801561001457600080fd5b5060805161493861005a600039600081816112e70152818161132701528181611672015281816116b20152818161183501528181611c860152611cc601526149386000f3fe6080604052600436106103c35760003560e01c806355f804b3116101f2578063b88d4fde1161010d578063dc33e681116100a0578063e985e9c51161006f578063e985e9c514610c6e578063ec02ef5714610c8e578063fd24a85414610cae578063ffe630b514610cc157600080fd5b8063dc33e68114610b13578063df33c86c14610b33578063e030565e14610b53578063e7cc724414610b7357600080fd5b8063cfb559ce116100dc578063cfb559ce14610ac0578063d0354b8214610ad6578063d547cfb714610ae9578063d89135cd14610afe57600080fd5b8063b88d4fde14610a39578063c2f1f14a14610a4c578063c87b56dd14610a6c578063cb29ed3814610a8c57600080fd5b80637cee62481161018557806395d89b411161015457806395d89b41146109cf57806397bc411c146109e4578063a22cb46514610a04578063b84d8aeb14610a2457600080fd5b80637cee62481461094a5780638129fc1c1461096a578063817415c41461097f5780638fc88c481461099257600080fd5b806364b207b6116101c157806364b207b6146108ca5780636c19e783146108ea57806370a082311461090a578063735328021461092a57600080fd5b806355f804b3146108555780635accb4f3146108755780636352211e146108955780636373a6b1146108b557600080fd5b806332cb6b0c116102e25780634f1ef2861161027557806352d1902d1161024457806352d1902d146107de57806354fd4d50146107f357806355d0a1d01461081d57806355d6a65e1461083457600080fd5b80634f1ef2861461076b5780634fb5334c1461077e5780634ff4e2441461079e57806351cff8d9146107be57600080fd5b806342842e0e116102b157806342842e0e146106f857806342966c681461070b578063484b973c1461072b5780634b0bddd21461074b57600080fd5b806332cb6b0c146106965780633644e515146106ac5780633659cfe6146106c3578063400ec069146106e357600080fd5b8063140364a11161035a57806323b872dd1161032957806323b872dd1461061757806324d7806c1461062a578063253676e7146106635780632db115441461068357600080fd5b8063140364a11461055857806318160ddd146105c55780631ad26603146105e25780632126ea811461060257600080fd5b806306fdde031161039657806306fdde03146104de578063081812fc14610500578063095ea7b3146105205780630fa5d7641461053557600080fd5b806301ffc9a7146103c857806302e84c14146103fd57806304a4c55e1461041257806304d4f96c1461044b575b600080fd5b3480156103d457600080fd5b506103e86103e3366004613da4565b610ce1565b60405190151581526020015b60405180910390f35b34801561040957600080fd5b506103e8610d0d565b34801561041e57600080fd5b5061017954610433906001600160a01b031681565b6040516001600160a01b0390911681526020016103f4565b34801561045757600080fd5b5061046b610466366004613dd6565b610d56565b6040516103f49190600060e0820190506001600160401b0380845116835280602085015116602084015280604085015116604084015250606083015161ffff80821660608501528060808601511660808501528060a08601511660a08501528060c08601511660c0850152505092915050565b3480156104ea57600080fd5b506104f3610e5e565b6040516103f49190613e4b565b34801561050c57600080fd5b5061043361051b366004613e5e565b610ef0565b61053361052e366004613e77565b610f34565b005b34801561054157600080fd5b5061054a610fba565b6040519081526020016103f4565b34801561056457600080fd5b50610578610573366004613e5e565b610fd2565b6040516103f4919081516001600160a01b031681526020808301516001600160401b03169082015260408083015163ffffffff169082015260609182015115159181019190915260800190565b3480156105d157600080fd5b50609854609754036000190161054a565b3480156105ee57600080fd5b5061054a6105fd366004613dd6565b610fff565b34801561060e57600080fd5b506104f3611018565b610533610625366004613ea3565b6110a7565b34801561063657600080fd5b506103e8610645366004613dd6565b6001600160a01b031660009081526065602052604090205460011490565b34801561066f57600080fd5b5061053361067e366004613f0a565b6110b2565b610533610691366004613e5e565b611143565b3480156106a257600080fd5b5061054a611e6181565b3480156106b857600080fd5b5061054a61012e5481565b3480156106cf57600080fd5b506105336106de366004613dd6565b6112dd565b3480156106ef57600080fd5b506103e86113a5565b610533610706366004613ea3565b6113f8565b34801561071757600080fd5b50610533610726366004613e5e565b611413565b34801561073757600080fd5b50610533610746366004613e77565b61141e565b34801561075757600080fd5b50610533610766366004613f57565b61148c565b610533610779366004614037565b611668565b34801561078a57600080fd5b50610533610799366004613e5e565b61171d565b3480156107aa57600080fd5b5061054a6107b9366004613e5e565b611748565b3480156107ca57600080fd5b506105336107d9366004613dd6565b61176e565b3480156107ea57600080fd5b5061054a611828565b3480156107ff57600080fd5b506040805180820190915260018152603160f81b60208201526104f3565b34801561082957600080fd5b5061054a6101765481565b34801561084057600080fd5b5061012d54610433906001600160a01b031681565b34801561086157600080fd5b506105336108703660046140c7565b6118db565b34801561088157600080fd5b50610533610890366004613f0a565b61190e565b3480156108a157600080fd5b506104336108b0366004613e5e565b611997565b3480156108c157600080fd5b506104f36119a9565b3480156108d657600080fd5b506105336108e5366004614108565b6119b7565b3480156108f657600080fd5b50610533610905366004613dd6565b611a42565b34801561091657600080fd5b5061054a610925366004613dd6565b611ab4565b34801561093657600080fd5b50610533610945366004613e5e565b611b02565b34801561095657600080fd5b506103e8610965366004614143565b611b93565b34801561097657600080fd5b50610533611bbc565b61053361098d3660046141ab565b611df8565b34801561099e57600080fd5b5061054a6109ad366004613e5e565b600090815260fb6020526040902054600160a01b90046001600160401b031690565b3480156109db57600080fd5b506104f3611fd5565b3480156109f057600080fd5b506105336109ff3660046140c7565b611fe4565b348015610a1057600080fd5b50610533610a1f366004613f57565b612017565b348015610a3057600080fd5b506103e86120ac565b610533610a473660046141f6565b6120ff565b348015610a5857600080fd5b50610433610a67366004613e5e565b612149565b348015610a7857600080fd5b506104f3610a87366004613e5e565b61218b565b348015610a9857600080fd5b5061054a7f37c6b9d7eb54fbea31a6c2906bc57f6f771960ad0d5c5abe7bb4d8044105429781565b348015610acc57600080fd5b5061017a5461054a565b610533610ae4366004613e5e565b61222a565b348015610af557600080fd5b506104f36123d3565b348015610b0a57600080fd5b5060985461054a565b348015610b1f57600080fd5b5061054a610b2e366004613dd6565b6123e1565b348015610b3f57600080fd5b50610533610b4e366004613dd6565b61240f565b348015610b5f57600080fd5b50610533610b6e366004614261565b612457565b348015610b7f57600080fd5b5061015f546101605461016154610bfb9263ffffffff80821693640100000000830482169361ffff600160401b8504811694600160501b8104821694600160601b8204811694600160801b8304821694600160a01b8404851694600160b01b8504841694600160d01b810490941693600160f01b90041691908c565b6040805163ffffffff9d8e1681529b8d1660208d015261ffff9a8b16908c015297891660608b0152958a1660808a015293891660a089015291861660c0880152871660e08701529590951661010085015291909316610120830152610140820152610160810191909152610180016103f4565b348015610c7a57600080fd5b506103e8610c893660046142af565b61258a565b348015610c9a57600080fd5b5061054a610ca9366004613e5e565b6125b8565b610533610cbc3660046141ab565b6125d3565b348015610ccd57600080fd5b50610533610cdc3660046142dd565b6127fe565b6000610cec82612830565b80610d0757506001600160e01b03198216639a93dd8960e01b145b92915050565b61015f54600090429063ffffffff1615801590610d33575061015f5463ffffffff168110155b8015610d50575061015f54640100000000900463ffffffff168111155b91505090565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810191909152610d07826040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810191909152506001600160a01b03166000908152609c6020908152604091829020825160e08101845290546001600160401b038082168352600160401b8204811693830193909352600160801b81049092169281019290925261ffff600160c01b820481166060840152600160d01b820481166080840152600160e01b8204811660a0840152600160f01b9091041660c082015290565b606060998054610e6d90614311565b80601f0160208091040260200160405190810160405280929190818152602001828054610e9990614311565b8015610ee65780601f10610ebb57610100808354040283529160200191610ee6565b820191906000526020600020905b815481529060010190602001808311610ec957829003601f168201915b5050505050905090565b6000610efb82612858565b610f18576040516333d1c03960e21b815260040160405180910390fd5b506000908152609d60205260409020546001600160a01b031690565b6000610f3f82611997565b9050806001600160a01b0316836001600160a01b031603610f735760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b03821614610faa57610f8d813361258a565b610faa576040516367d9dca160e11b815260040160405180910390fd5b610fb583838361288d565b505050565b600061017654611e61610fcd9190614361565b905090565b604080516080810182526000808252602082018190529181018290526060810191909152610d07826128e9565b600061017a5461100e83611ab4565b610d079190614378565b610178805461102690614311565b80601f016020809104026020016040519081016040528092919081815260200182805461105290614311565b801561109f5780601f106110745761010080835404028352916020019161109f565b820191906000526020600020905b81548152906001019060200180831161108257829003601f168201915b505050505081565b610fb5838383612a34565b6110bb33610645565b6110e05760405162461bcd60e51b81526004016110d790614397565b60405180910390fd5b6101609390935561015f805467ffffffffffffffff60601b1916600160601b63ffffffff9485160263ffffffff60801b191617600160801b92909316919091029190911761ffff60a01b1916600160a01b61ffff90931692909202919091179055565b3233146111625760405162461bcd60e51b81526004016110d7906143ce565b8061116b610fba565b816111796097546000190190565b6111839190614405565b11156111a15760405162461bcd60e51b81526004016110d79061441d565b6111a96120ac565b6111f55760405162461bcd60e51b815260206004820152601960248201527f5075626c6963206d696e74206973206e6f74206163746976650000000000000060448201526064016110d7565b61016154611204908390614378565b34101561124d5760405162461bcd60e51b81526020600482015260176024820152762732b2b2103a379039b2b7321036b7b9329032ba3432b960491b60448201526064016110d7565b61015f54336000908152609c602052604090205461ffff600160f01b928390048116928592041661127e9190614405565b111561129c5760405162461bcd60e51b81526004016110d790614461565b336000908152609c60205260409020805461ffff600160f01b80830482168601909116026001600160f01b039091161790555b6112d93383612c56565b5050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036113255760405162461bcd60e51b81526004016110d790614496565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611357612d90565b6001600160a01b03161461137d5760405162461bcd60e51b81526004016110d7906144e2565b61138681612dac565b604080516000808252602082019092526113a291839190612dd1565b50565b61015f546000904290600160601b900463ffffffff16158015906113d9575061015f54600160601b900463ffffffff168110155b8015610d50575061015f54600160801b900463ffffffff161015919050565b610fb5838383604051806020016040528060008152506120ff565b6113a2816001612f3c565b61142733610645565b6114435760405162461bcd60e51b81526004016110d790614397565b8061144c610fba565b8161145a6097546000190190565b6114649190614405565b11156114825760405162461bcd60e51b81526004016110d79061441d565b610fb58383612c56565b61149533610645565b6114b15760405162461bcd60e51b81526004016110d790614397565b6001600160a01b0382166115205760405162461bcd60e51b815260206004820152603060248201527f41646d696e61626c653a2063616e6e6f74207365742061646d696e20666f722060448201526f746865207a65726f206164647265737360801b60648201526084016110d7565b80156115c25761152f82610645565b1561157c5760405162461bcd60e51b815260206004820152601d60248201527f41646d696e61626c653a20616464206578697374696e672061646d696e00000060448201526064016110d7565b6001600160a01b03821660008181526065602052604080822060019055517f068138ab5baa0a8a7aadb0e73d78b0b40417344c7bba0f4387479260cc462d669190a25050565b6115cb82610645565b6116235760405162461bcd60e51b8152602060048201526024808201527f41646d696e61626c653a2072656d6f7665206e6f6e2d6578697374656e7420616044820152633236b4b760e11b60648201526084016110d7565b6001600160a01b038216600081815260656020526040808220829055517fa3b62bc36326052d97ea62d63c3d60308ed4c3ea8ac079dd8499f1e9c4f80c0f9190a25050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036116b05760405162461bcd60e51b81526004016110d790614496565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166116e2612d90565b6001600160a01b0316146117085760405162461bcd60e51b81526004016110d7906144e2565b61171182612dac565b6112d982826001612dd1565b61172633610645565b6117425760405162461bcd60e51b81526004016110d790614397565b61017a55565b600061175382612858565b1561176157505061017a5490565b506000919050565b919050565b61177733610645565b6117935760405162461bcd60e51b81526004016110d790614397565b60405147906000906001600160a01b0384169083908381818185875af1925050503d80600081146117e0576040519150601f19603f3d011682016040523d82523d6000602084013e6117e5565b606091505b5050905080610fb55760405162461bcd60e51b815260206004820152600f60248201526e15da5d1a191c985dc819985a5b1959608a1b60448201526064016110d7565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146118c85760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016110d7565b506000805160206148bc83398151915290565b6118e433610645565b6119005760405162461bcd60e51b81526004016110d790614397565b610177610fb582848361457c565b61191733610645565b6119335760405162461bcd60e51b81526004016110d790614397565b6101619390935561015f805467ffffffffffffffff60b01b1916600160b01b63ffffffff9485160263ffffffff60d01b191617600160d01b9290931691909102919091176001600160f01b0316600160f01b61ffff90931692909202919091179055565b60006119a2826128e9565b5192915050565b610175805461102690614311565b6119c033610645565b6119dc5760405162461bcd60e51b81526004016110d790614397565b61015f805463ffffffff95861667ffffffffffffffff19909116176401000000009490951693909302939093176bffffffff00000000000000001916600160401b61ffff9283160261ffff60501b191617600160501b9390911692909202919091179055565b611a4b33610645565b611a675760405162461bcd60e51b81526004016110d790614397565b61012d80546001600160a01b0319166001600160a01b03831690811790915560405133907f3271c8694494a7cc76cd185c743e9ee6b515a043ea98c0db7f5ca112f694add490600090a350565b60006001600160a01b038216611add576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152609c60205260409020546001600160401b031690565b611b0b33610645565b611b275760405162461bcd60e51b81526004016110d790614397565b61017654611b3790611e61614361565b60985460975403600019011115611b875760405162461bcd60e51b8152602060048201526014602482015273084eae4dc40c2dadeeadce840e8dede40daeac6d60631b60448201526064016110d7565b61017680549091019055565b6000611ba084848461310d565b61012d546001600160a01b0390811691161490505b9392505050565b600054610100900460ff1615808015611bdc5750600054600160ff909116105b80611bf65750303b158015611bf6575060005460ff166001145b611c595760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016110d7565b6000805460ff191660011790558015611c7c576000805461ff0019166101001790555b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003611cc45760405162461bcd60e51b81526004016110d790614496565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611cf6612d90565b6001600160a01b031614611d1c5760405162461bcd60e51b81526004016110d7906144e2565b611d2461326c565b611d736040518060400160405280600e81526020016d536861726b7a2047656e6573697360901b81525060405180604001604052806007815260200166534841524b5a4760c81b81525061329d565b611d7b6132ce565b611d836132fd565b61017980546001600160a01b0319167312deb1cb5732e40dd55b89abb6d5c31df13a6e38179055600161017a5580156113a2576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b323314611e175760405162461bcd60e51b81526004016110d7906143ce565b82611e20610fba565b81611e2e6097546000190190565b611e389190614405565b1115611e565760405162461bcd60e51b81526004016110d79061441d565b611e5e610d0d565b611ea45760405162461bcd60e51b815260206004820152601760248201527646726565206d696e74206973206e6f742061637469766560481b60448201526064016110d7565b828260405180604001604052806008815260200167199c99595b5a5b9d60c21b815250611ed283838361310d565b61012d546001600160a01b03908116911614611f2c5760405162461bcd60e51b81526020600482015260196024820152784549503731323a20496e76616c6964205369676e617475726560381b60448201526064016110d7565b61015f5461ffff600160501b9091041687611f68336001600160a01b03166000908152609c602052604090205461ffff600160d01b9091041690565b611f729190614405565b1115611f905760405162461bcd60e51b81526004016110d790614461565b336000908152609c60205260409020805461ffff600160d01b80830482168b019091160261ffff60d01b199091161790555b611fcc3388612c56565b50505050505050565b6060609a8054610e6d90614311565b611fed33610645565b6120095760405162461bcd60e51b81526004016110d790614397565b610178610fb582848361457c565b336001600160a01b038316036120405760405163b06307db60e01b815260040160405180910390fd5b336000818152609e602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61015f546000904290600160b01b900463ffffffff16158015906120e0575061015f54600160b01b900463ffffffff168110155b8015610d50575061015f54600160d01b900463ffffffff161015919050565b61210a848484612a34565b6001600160a01b0383163b15612143576121268484848461332c565b612143576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b600081815260fb602052604081205442600160a01b9091046001600160401b0316106117615750600090815260fb60205260409020546001600160a01b031690565b606061219682612858565b6121b357604051630a14c4b560e41b815260040160405180910390fd5b60006121bd613418565b905080516000036121f9576101786121d484613428565b6040516020016121e592919061463b565b604051602081830303815290604052611bb5565b8061220384613428565b6040516020016122149291906146c2565b6040516020818303038152906040529392505050565b3233146122495760405162461bcd60e51b81526004016110d7906143ce565b80612252610fba565b816122606097546000190190565b61226a9190614405565b11156122885760405162461bcd60e51b81526004016110d79061441d565b612290610d0d565b6122d65760405162461bcd60e51b815260206004820152601760248201527646726565206d696e74206973206e6f742061637469766560481b60448201526064016110d7565b610179546122ed906001600160a01b03163361346c565b6123395760405162461bcd60e51b815260206004820152601b60248201527f43616c6c6572206973206e6f7420536f756c204944206f776e6572000000000060448201526064016110d7565b61015f5461ffff600160401b9091041682612375336001600160a01b03166000908152609c602052604090205461ffff600160c01b9091041690565b61237f9190614405565b111561239d5760405162461bcd60e51b81526004016110d790614461565b336000908152609c60205260409020805461ffff600160c01b808304821686019091160261ffff60c01b199091161790556112cf565b610177805461102690614311565b6001600160a01b0381166000908152609c6020526040812054600160401b90046001600160401b0316610d07565b61241833610645565b6124345760405162461bcd60e51b81526004016110d790614397565b61017980546001600160a01b0319166001600160a01b0392909216919091179055565b6000612462846128e9565b5190506000336001600160a01b03831614806124835750612483823361258a565b8061249e57503361249386610ef0565b6001600160a01b0316145b9050806125085760405162461bcd60e51b815260206004820152603260248201527f455243343930373a207472616e736665722063616c6c6572206973206e6f74206044820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b60648201526084016110d7565b600085815260fb602090815260409182902080546001600160a01b0388166001600160e01b03199091168117600160a01b6001600160401b03891690810291909117835593519384529092909188917f4e06b4e7000e659094299b3533b47b6aa8ad048e95e872d23d1f4ee55af89cfe910160405180910390a3505050505050565b6001600160a01b039182166000908152609e6020908152604080832093909416825291909152205460ff1690565b60006125c3826128e9565b6040015163ffffffff1692915050565b3233146125f25760405162461bcd60e51b81526004016110d7906143ce565b826125fb610fba565b816126096097546000190190565b6126139190614405565b11156126315760405162461bcd60e51b81526004016110d79061441d565b6126396113a5565b6126855760405162461bcd60e51b815260206004820152601a60248201527f50726573616c65206d696e74206973206e6f742061637469766500000000000060448201526064016110d7565b82826040518060400160405280600781526020016670726573616c6560c81b8152506126b283838361310d565b61012d546001600160a01b0390811691161461270c5760405162461bcd60e51b81526020600482015260196024820152784549503731323a20496e76616c6964205369676e617475726560381b60448201526064016110d7565b6101605461271b908890614378565b3410156127645760405162461bcd60e51b81526020600482015260176024820152762732b2b2103a379039b2b7321036b7b9329032ba3432b960491b60448201526064016110d7565b61015f5461ffff600160a01b90910416876127a0336001600160a01b03166000908152609c602052604090205461ffff600160e01b9091041690565b6127aa9190614405565b11156127c85760405162461bcd60e51b81526004016110d790614461565b336000908152609c60205260409020805461ffff600160e01b80830482168b019091160261ffff60e01b19909116179055611fc2565b61280733610645565b6128235760405162461bcd60e51b81526004016110d790614397565b6101756112d982826146e8565b600061283b82613519565b80610d075750506001600160e01b031916632b424ad760e21b1490565b60008160011115801561286c575060975482105b8015610d075750506000908152609b602052604090206001015460ff161590565b6000828152609d602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6040805160808101825260008082526020820181905291810182905260608101919091528180600111612a1b57609754811015612a1b576000818152609b6020908152604091829020825160808101845281546001600160a01b0381168252600160a01b81046001600160401b031693820193909352600160e01b90920463ffffffff169282019290925260019091015460ff16151560608201819052612a195780516001600160a01b0316156129a1579392505050565b50600019016000818152609b6020908152604091829020825160808101845281546001600160a01b038116808352600160a01b82046001600160401b031694830194909452600160e01b900463ffffffff16938101939093526001015460ff161515606083015215612a14579392505050565b6129a1565b505b604051636f96cda160e11b815260040160405180910390fd5b6000612a3f826128e9565b9050836001600160a01b031681600001516001600160a01b031614612a765760405162a1148160e81b815260040160405180910390fd5b6000336001600160a01b0386161480612a945750612a94853361258a565b80612aaf575033612aa484610ef0565b6001600160a01b0316145b905080612acf57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038416612af657604051633a954ecd60e21b815260040160405180910390fd5b612b038585856001613567565b612b0f6000848761288d565b6001600160a01b038086166000908152609c6020908152604080832080546000196001600160401b0380831691909101811667ffffffffffffffff199283161790925589861680865283862080548085166001908101861691909416179055898652609b909452828520805463ffffffff600160e01b42909516600160a01b026001600160e01b031990921690961717838104861683019095169092026001600160e01b03909416939093178155918701808452922080549193909116612c0a576097548214612c0a57805460208601516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038a16171781555b50505082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b5050505050565b6097546001600160a01b038316612c7f57604051622e076360e81b815260040160405180910390fd5b81600003612ca05760405163b562e8dd60e01b815260040160405180910390fd5b612cad6000848385613567565b6001600160a01b0383166000818152609c6020908152604080832080546fffffffffffffffffffffffffffffffff1981166001600160401b038083168a018116918217600160401b67ffffffffffffffff1990941690921783900481168a01811690920217909155858452609b90925290912080546001600160e01b031916909217600160a01b4290921691909102179055808083015b6040516001830192906001600160a01b038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4808210612d445750609755505050565b6000805160206148bc833981519152546001600160a01b031690565b612db533610645565b6113a25760405162461bcd60e51b81526004016110d790614397565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612e0457610fb583613573565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612e5e575060408051601f3d908101601f19168201909252612e5b918101906147a7565b60015b612ec15760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016110d7565b6000805160206148bc8339815191528114612f305760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016110d7565b50610fb583838361360f565b6000612f47836128e9565b80519091508215612fad576000336001600160a01b0383161480612f705750612f70823361258a565b80612f8b575033612f8086610ef0565b6001600160a01b0316145b905080612fab57604051632ce44b5f60e11b815260040160405180910390fd5b505b612fbb816000866001613567565b612fc76000858361288d565b6001600160a01b038082166000818152609c602090815260408083208054600160801b6000196001600160401b0380841691909101811667ffffffffffffffff198416811783900482166001908101831690930277ffffffffffffffff0000000000000000ffffffffffffffff19909416179290921783558b8652609b909452828520805442909216600160a01b026001600160e01b0319909216909617178555848301805460ff1916841790559189018084529220805491949091166130c25760975482146130c257805460208701516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038716171781555b5050604051869250600091506001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a450506098805460010190555050565b61012d546000906001600160a01b03166131695760405162461bcd60e51b815260206004820152601d60248201527f4549503731323a2057686974656c697374206e6f7420656e61626c656400000060448201526064016110d7565b600061012e547f37c6b9d7eb54fbea31a6c2906bc57f6f771960ad0d5c5abe7bb4d804410542976131973390565b6131a0866147c0565b6040516020016131cc939291909283526001600160a01b03919091166020830152604082015260600190565b6040516020818303038152906040528051906020012060405160200161320992919061190160f01b81526002810192909252602282015260420190565b60405160208183030381529060405280519060200120905061326385858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506136349050565b95945050505050565b600054610100900460ff166132935760405162461bcd60e51b81526004016110d7906147e4565b61329b613658565b565b600054610100900460ff166132c45760405162461bcd60e51b81526004016110d7906147e4565b6112d98282613694565b600054610100900460ff166132f55760405162461bcd60e51b81526004016110d7906147e4565b61329b6136de565b600054610100900460ff166133245760405162461bcd60e51b81526004016110d7906147e4565b61329b6137e4565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a029061336190339089908890889060040161482f565b6020604051808303816000875af192505050801561339c575060408051601f3d908101601f191682019092526133999181019061486c565b60015b6133fa573d8080156133ca576040519150601f19603f3d011682016040523d82523d6000602084013e6133cf565b606091505b5080516000036133f2576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b60606101778054610e6d90614311565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a9004806134425750819003601f19909101908152919050565b6040516370a0823160e01b81526001600160a01b038281166004830152600091908416906370a0823190602401602060405180830381865afa9250505080156134d2575060408051601f3d908101601f191682019092526134cf918101906147a7565b60015b613510573d808015613500576040519150601f19603f3d011682016040523d82523d6000602084013e613505565b606091505b506000915050610d07565b15159050610d07565b60006301ffc9a760e01b6001600160e01b03198316148061354a57506380ac58cd60e01b6001600160e01b03198316145b80610d075750506001600160e01b031916635b5e139f60e01b1490565b61214384848484613849565b6001600160a01b0381163b6135e05760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016110d7565b6000805160206148bc83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b613618836138e0565b6000825111806136255750805b15610fb5576121438383613920565b60008060006136438585613a0b565b9150915061365081613a79565b509392505050565b600054610100900460ff1661367f5760405162461bcd60e51b81526004016110d7906147e4565b33600090815260656020526040902060019055565b600054610100900460ff166136bb5760405162461bcd60e51b81526004016110d7906147e4565b60996136c783826146e8565b50609a6136d482826146e8565b5060016097555050565b600054610100900460ff166137055760405162461bcd60e51b81526004016110d7906147e4565b604080518082018252600e81526d2bb434ba32b634b9ba2a37b5b2b760911b6020918201528151808301835260018152603160f81b9082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818301527fb31abde365a4931cba9a0ea66b4737a15e8eb9a0649f549f4857db08880a9049818401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a0808301919091528351808303909101815260c0909101909252815191012061012e5561329b33611a42565b600054610100900460ff1661380b5760405162461bcd60e51b81526004016110d7906147e4565b66470de4df8200006101605566b1a2bc2ec50000610161557e14634014c06336e148000a634014c06336e14800010001634014c06336da4061015f55565b8060010361214357816001600160a01b03858116908516148015906138845750600081815260fb60205260409020546001600160a01b031615155b15612c4f57600081815260fb6020908152604080832080546001600160e01b03191690555182815283917f4e06b4e7000e659094299b3533b47b6aa8ad048e95e872d23d1f4ee55af89cfe910160405180910390a35050505050565b6138e981613573565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6139885760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016110d7565b600080846001600160a01b0316846040516139a39190614889565b600060405180830381855af49150503d80600081146139de576040519150601f19603f3d011682016040523d82523d6000602084013e6139e3565b606091505b509150915061326382826040518060600160405280602781526020016148dc60279139613c2f565b6000808251604103613a415760208301516040840151606085015160001a613a3587828585613c68565b94509450505050613a72565b8251604003613a6a5760208301516040840151613a5f868383613d55565b935093505050613a72565b506000905060025b9250929050565b6000816004811115613a8d57613a8d6148a5565b03613a955750565b6001816004811115613aa957613aa96148a5565b03613af65760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016110d7565b6002816004811115613b0a57613b0a6148a5565b03613b575760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016110d7565b6003816004811115613b6b57613b6b6148a5565b03613bc35760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016110d7565b6004816004811115613bd757613bd76148a5565b036113a25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016110d7565b60608315613c3e575081611bb5565b825115613c4e5782518084602001fd5b8160405162461bcd60e51b81526004016110d79190613e4b565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613c9f5750600090506003613d4c565b8460ff16601b14158015613cb757508460ff16601c14155b15613cc85750600090506004613d4c565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613d1c573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116613d4557600060019250925050613d4c565b9150600090505b94509492505050565b6000806001600160ff1b03831681613d7260ff86901c601b614405565b9050613d8087828885613c68565b935093505050935093915050565b6001600160e01b0319811681146113a257600080fd5b600060208284031215613db657600080fd5b8135611bb581613d8e565b6001600160a01b03811681146113a257600080fd5b600060208284031215613de857600080fd5b8135611bb581613dc1565b60005b83811015613e0e578181015183820152602001613df6565b838111156121435750506000910152565b60008151808452613e37816020860160208601613df3565b601f01601f19169290920160200192915050565b602081526000611bb56020830184613e1f565b600060208284031215613e7057600080fd5b5035919050565b60008060408385031215613e8a57600080fd5b8235613e9581613dc1565b946020939093013593505050565b600080600060608486031215613eb857600080fd5b8335613ec381613dc1565b92506020840135613ed381613dc1565b929592945050506040919091013590565b803563ffffffff8116811461176957600080fd5b803561ffff8116811461176957600080fd5b60008060008060808587031215613f2057600080fd5b84359350613f3060208601613ee4565b9250613f3e60408601613ee4565b9150613f4c60608601613ef8565b905092959194509250565b60008060408385031215613f6a57600080fd5b8235613f7581613dc1565b915060208301358015158114613f8a57600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112613fbc57600080fd5b81356001600160401b0380821115613fd657613fd6613f95565b604051601f8301601f19908116603f01168101908282118183101715613ffe57613ffe613f95565b8160405283815286602085880101111561401757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806040838503121561404a57600080fd5b823561405581613dc1565b915060208301356001600160401b0381111561407057600080fd5b61407c85828601613fab565b9150509250929050565b60008083601f84011261409857600080fd5b5081356001600160401b038111156140af57600080fd5b602083019150836020828501011115613a7257600080fd5b600080602083850312156140da57600080fd5b82356001600160401b038111156140f057600080fd5b6140fc85828601614086565b90969095509350505050565b6000806000806080858703121561411e57600080fd5b61412785613ee4565b935061413560208601613ee4565b9250613f3e60408601613ef8565b60008060006040848603121561415857600080fd5b83356001600160401b038082111561416f57600080fd5b61417b87838801614086565b9095509350602086013591508082111561419457600080fd5b506141a186828701613fab565b9150509250925092565b6000806000604084860312156141c057600080fd5b8335925060208401356001600160401b038111156141dd57600080fd5b6141e986828701614086565b9497909650939450505050565b6000806000806080858703121561420c57600080fd5b843561421781613dc1565b9350602085013561422781613dc1565b92506040850135915060608501356001600160401b0381111561424957600080fd5b61425587828801613fab565b91505092959194509250565b60008060006060848603121561427657600080fd5b83359250602084013561428881613dc1565b915060408401356001600160401b03811681146142a457600080fd5b809150509250925092565b600080604083850312156142c257600080fd5b82356142cd81613dc1565b91506020830135613f8a81613dc1565b6000602082840312156142ef57600080fd5b81356001600160401b0381111561430557600080fd5b61341084828501613fab565b600181811c9082168061432557607f821691505b60208210810361434557634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6000828210156143735761437361434b565b500390565b60008160001904831182151516156143925761439261434b565b500290565b6020808252601e908201527f41646d696e61626c653a2063616c6c6572206973206e6f742061646d696e0000604082015260600190565b6020808252601e908201527f5468652063616c6c657220697320616e6f7468657220636f6e74726163740000604082015260600190565b600082198211156144185761441861434b565b500190565b60208082526024908201527f52656163686564206d617820737570706c79206f662074686520636f6c6c65636040820152633a34b7b760e11b606082015260800190565b6020808252818101527f52656163686564206d696e74696e67206c696d6974207065722077616c6c6574604082015260600190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b601f821115610fb557600081815260208120601f850160051c810160208610156145555750805b601f850160051c820191505b8181101561457457828155600101614561565b505050505050565b6001600160401b0383111561459357614593613f95565b6145a7836145a18354614311565b8361452e565b6000601f8411600181146145db57600085156145c35750838201355b600019600387901b1c1916600186901b178355612c4f565b600083815260209020601f19861690835b8281101561460c57868501358255602094850194600190920191016145ec565b50868210156146295760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b600080845461464981614311565b600182811680156146615760018114614676576146a5565b60ff19841687528215158302870194506146a5565b8860005260208060002060005b8581101561469c5781548a820152908401908201614683565b50505082870194505b5050505083516146b9818360208801613df3565b01949350505050565b600083516146d4818460208801613df3565b8351908301906146b9818360208801613df3565b81516001600160401b0381111561470157614701613f95565b6147158161470f8454614311565b8461452e565b602080601f83116001811461474a57600084156147325750858301515b600019600386901b1c1916600185901b178555614574565b600085815260208120601f198616915b828110156147795788860151825594840194600190910190840161475a565b50858210156147975787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602082840312156147b957600080fd5b5051919050565b805160208083015191908110156143455760001960209190910360031b1b16919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061486290830184613e1f565b9695505050505050565b60006020828403121561487e57600080fd5b8151611bb581613d8e565b6000825161489b818460208701613df3565b9190910192915050565b634e487b7160e01b600052602160045260246000fdfe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212200561269f0be6af66eeb5d81587b6aa579b10da315dffeda19bbb24b61c5a2f3064736f6c634300080f0033
Deployed Bytecode
0x6080604052600436106103c35760003560e01c806355f804b3116101f2578063b88d4fde1161010d578063dc33e681116100a0578063e985e9c51161006f578063e985e9c514610c6e578063ec02ef5714610c8e578063fd24a85414610cae578063ffe630b514610cc157600080fd5b8063dc33e68114610b13578063df33c86c14610b33578063e030565e14610b53578063e7cc724414610b7357600080fd5b8063cfb559ce116100dc578063cfb559ce14610ac0578063d0354b8214610ad6578063d547cfb714610ae9578063d89135cd14610afe57600080fd5b8063b88d4fde14610a39578063c2f1f14a14610a4c578063c87b56dd14610a6c578063cb29ed3814610a8c57600080fd5b80637cee62481161018557806395d89b411161015457806395d89b41146109cf57806397bc411c146109e4578063a22cb46514610a04578063b84d8aeb14610a2457600080fd5b80637cee62481461094a5780638129fc1c1461096a578063817415c41461097f5780638fc88c481461099257600080fd5b806364b207b6116101c157806364b207b6146108ca5780636c19e783146108ea57806370a082311461090a578063735328021461092a57600080fd5b806355f804b3146108555780635accb4f3146108755780636352211e146108955780636373a6b1146108b557600080fd5b806332cb6b0c116102e25780634f1ef2861161027557806352d1902d1161024457806352d1902d146107de57806354fd4d50146107f357806355d0a1d01461081d57806355d6a65e1461083457600080fd5b80634f1ef2861461076b5780634fb5334c1461077e5780634ff4e2441461079e57806351cff8d9146107be57600080fd5b806342842e0e116102b157806342842e0e146106f857806342966c681461070b578063484b973c1461072b5780634b0bddd21461074b57600080fd5b806332cb6b0c146106965780633644e515146106ac5780633659cfe6146106c3578063400ec069146106e357600080fd5b8063140364a11161035a57806323b872dd1161032957806323b872dd1461061757806324d7806c1461062a578063253676e7146106635780632db115441461068357600080fd5b8063140364a11461055857806318160ddd146105c55780631ad26603146105e25780632126ea811461060257600080fd5b806306fdde031161039657806306fdde03146104de578063081812fc14610500578063095ea7b3146105205780630fa5d7641461053557600080fd5b806301ffc9a7146103c857806302e84c14146103fd57806304a4c55e1461041257806304d4f96c1461044b575b600080fd5b3480156103d457600080fd5b506103e86103e3366004613da4565b610ce1565b60405190151581526020015b60405180910390f35b34801561040957600080fd5b506103e8610d0d565b34801561041e57600080fd5b5061017954610433906001600160a01b031681565b6040516001600160a01b0390911681526020016103f4565b34801561045757600080fd5b5061046b610466366004613dd6565b610d56565b6040516103f49190600060e0820190506001600160401b0380845116835280602085015116602084015280604085015116604084015250606083015161ffff80821660608501528060808601511660808501528060a08601511660a08501528060c08601511660c0850152505092915050565b3480156104ea57600080fd5b506104f3610e5e565b6040516103f49190613e4b565b34801561050c57600080fd5b5061043361051b366004613e5e565b610ef0565b61053361052e366004613e77565b610f34565b005b34801561054157600080fd5b5061054a610fba565b6040519081526020016103f4565b34801561056457600080fd5b50610578610573366004613e5e565b610fd2565b6040516103f4919081516001600160a01b031681526020808301516001600160401b03169082015260408083015163ffffffff169082015260609182015115159181019190915260800190565b3480156105d157600080fd5b50609854609754036000190161054a565b3480156105ee57600080fd5b5061054a6105fd366004613dd6565b610fff565b34801561060e57600080fd5b506104f3611018565b610533610625366004613ea3565b6110a7565b34801561063657600080fd5b506103e8610645366004613dd6565b6001600160a01b031660009081526065602052604090205460011490565b34801561066f57600080fd5b5061053361067e366004613f0a565b6110b2565b610533610691366004613e5e565b611143565b3480156106a257600080fd5b5061054a611e6181565b3480156106b857600080fd5b5061054a61012e5481565b3480156106cf57600080fd5b506105336106de366004613dd6565b6112dd565b3480156106ef57600080fd5b506103e86113a5565b610533610706366004613ea3565b6113f8565b34801561071757600080fd5b50610533610726366004613e5e565b611413565b34801561073757600080fd5b50610533610746366004613e77565b61141e565b34801561075757600080fd5b50610533610766366004613f57565b61148c565b610533610779366004614037565b611668565b34801561078a57600080fd5b50610533610799366004613e5e565b61171d565b3480156107aa57600080fd5b5061054a6107b9366004613e5e565b611748565b3480156107ca57600080fd5b506105336107d9366004613dd6565b61176e565b3480156107ea57600080fd5b5061054a611828565b3480156107ff57600080fd5b506040805180820190915260018152603160f81b60208201526104f3565b34801561082957600080fd5b5061054a6101765481565b34801561084057600080fd5b5061012d54610433906001600160a01b031681565b34801561086157600080fd5b506105336108703660046140c7565b6118db565b34801561088157600080fd5b50610533610890366004613f0a565b61190e565b3480156108a157600080fd5b506104336108b0366004613e5e565b611997565b3480156108c157600080fd5b506104f36119a9565b3480156108d657600080fd5b506105336108e5366004614108565b6119b7565b3480156108f657600080fd5b50610533610905366004613dd6565b611a42565b34801561091657600080fd5b5061054a610925366004613dd6565b611ab4565b34801561093657600080fd5b50610533610945366004613e5e565b611b02565b34801561095657600080fd5b506103e8610965366004614143565b611b93565b34801561097657600080fd5b50610533611bbc565b61053361098d3660046141ab565b611df8565b34801561099e57600080fd5b5061054a6109ad366004613e5e565b600090815260fb6020526040902054600160a01b90046001600160401b031690565b3480156109db57600080fd5b506104f3611fd5565b3480156109f057600080fd5b506105336109ff3660046140c7565b611fe4565b348015610a1057600080fd5b50610533610a1f366004613f57565b612017565b348015610a3057600080fd5b506103e86120ac565b610533610a473660046141f6565b6120ff565b348015610a5857600080fd5b50610433610a67366004613e5e565b612149565b348015610a7857600080fd5b506104f3610a87366004613e5e565b61218b565b348015610a9857600080fd5b5061054a7f37c6b9d7eb54fbea31a6c2906bc57f6f771960ad0d5c5abe7bb4d8044105429781565b348015610acc57600080fd5b5061017a5461054a565b610533610ae4366004613e5e565b61222a565b348015610af557600080fd5b506104f36123d3565b348015610b0a57600080fd5b5060985461054a565b348015610b1f57600080fd5b5061054a610b2e366004613dd6565b6123e1565b348015610b3f57600080fd5b50610533610b4e366004613dd6565b61240f565b348015610b5f57600080fd5b50610533610b6e366004614261565b612457565b348015610b7f57600080fd5b5061015f546101605461016154610bfb9263ffffffff80821693640100000000830482169361ffff600160401b8504811694600160501b8104821694600160601b8204811694600160801b8304821694600160a01b8404851694600160b01b8504841694600160d01b810490941693600160f01b90041691908c565b6040805163ffffffff9d8e1681529b8d1660208d015261ffff9a8b16908c015297891660608b0152958a1660808a015293891660a089015291861660c0880152871660e08701529590951661010085015291909316610120830152610140820152610160810191909152610180016103f4565b348015610c7a57600080fd5b506103e8610c893660046142af565b61258a565b348015610c9a57600080fd5b5061054a610ca9366004613e5e565b6125b8565b610533610cbc3660046141ab565b6125d3565b348015610ccd57600080fd5b50610533610cdc3660046142dd565b6127fe565b6000610cec82612830565b80610d0757506001600160e01b03198216639a93dd8960e01b145b92915050565b61015f54600090429063ffffffff1615801590610d33575061015f5463ffffffff168110155b8015610d50575061015f54640100000000900463ffffffff168111155b91505090565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810191909152610d07826040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810191909152506001600160a01b03166000908152609c6020908152604091829020825160e08101845290546001600160401b038082168352600160401b8204811693830193909352600160801b81049092169281019290925261ffff600160c01b820481166060840152600160d01b820481166080840152600160e01b8204811660a0840152600160f01b9091041660c082015290565b606060998054610e6d90614311565b80601f0160208091040260200160405190810160405280929190818152602001828054610e9990614311565b8015610ee65780601f10610ebb57610100808354040283529160200191610ee6565b820191906000526020600020905b815481529060010190602001808311610ec957829003601f168201915b5050505050905090565b6000610efb82612858565b610f18576040516333d1c03960e21b815260040160405180910390fd5b506000908152609d60205260409020546001600160a01b031690565b6000610f3f82611997565b9050806001600160a01b0316836001600160a01b031603610f735760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b03821614610faa57610f8d813361258a565b610faa576040516367d9dca160e11b815260040160405180910390fd5b610fb583838361288d565b505050565b600061017654611e61610fcd9190614361565b905090565b604080516080810182526000808252602082018190529181018290526060810191909152610d07826128e9565b600061017a5461100e83611ab4565b610d079190614378565b610178805461102690614311565b80601f016020809104026020016040519081016040528092919081815260200182805461105290614311565b801561109f5780601f106110745761010080835404028352916020019161109f565b820191906000526020600020905b81548152906001019060200180831161108257829003601f168201915b505050505081565b610fb5838383612a34565b6110bb33610645565b6110e05760405162461bcd60e51b81526004016110d790614397565b60405180910390fd5b6101609390935561015f805467ffffffffffffffff60601b1916600160601b63ffffffff9485160263ffffffff60801b191617600160801b92909316919091029190911761ffff60a01b1916600160a01b61ffff90931692909202919091179055565b3233146111625760405162461bcd60e51b81526004016110d7906143ce565b8061116b610fba565b816111796097546000190190565b6111839190614405565b11156111a15760405162461bcd60e51b81526004016110d79061441d565b6111a96120ac565b6111f55760405162461bcd60e51b815260206004820152601960248201527f5075626c6963206d696e74206973206e6f74206163746976650000000000000060448201526064016110d7565b61016154611204908390614378565b34101561124d5760405162461bcd60e51b81526020600482015260176024820152762732b2b2103a379039b2b7321036b7b9329032ba3432b960491b60448201526064016110d7565b61015f54336000908152609c602052604090205461ffff600160f01b928390048116928592041661127e9190614405565b111561129c5760405162461bcd60e51b81526004016110d790614461565b336000908152609c60205260409020805461ffff600160f01b80830482168601909116026001600160f01b039091161790555b6112d93383612c56565b5050565b6001600160a01b037f000000000000000000000000a190d11f937de97d1ebe5a2b2732d86689c97c151630036113255760405162461bcd60e51b81526004016110d790614496565b7f000000000000000000000000a190d11f937de97d1ebe5a2b2732d86689c97c156001600160a01b0316611357612d90565b6001600160a01b03161461137d5760405162461bcd60e51b81526004016110d7906144e2565b61138681612dac565b604080516000808252602082019092526113a291839190612dd1565b50565b61015f546000904290600160601b900463ffffffff16158015906113d9575061015f54600160601b900463ffffffff168110155b8015610d50575061015f54600160801b900463ffffffff161015919050565b610fb5838383604051806020016040528060008152506120ff565b6113a2816001612f3c565b61142733610645565b6114435760405162461bcd60e51b81526004016110d790614397565b8061144c610fba565b8161145a6097546000190190565b6114649190614405565b11156114825760405162461bcd60e51b81526004016110d79061441d565b610fb58383612c56565b61149533610645565b6114b15760405162461bcd60e51b81526004016110d790614397565b6001600160a01b0382166115205760405162461bcd60e51b815260206004820152603060248201527f41646d696e61626c653a2063616e6e6f74207365742061646d696e20666f722060448201526f746865207a65726f206164647265737360801b60648201526084016110d7565b80156115c25761152f82610645565b1561157c5760405162461bcd60e51b815260206004820152601d60248201527f41646d696e61626c653a20616464206578697374696e672061646d696e00000060448201526064016110d7565b6001600160a01b03821660008181526065602052604080822060019055517f068138ab5baa0a8a7aadb0e73d78b0b40417344c7bba0f4387479260cc462d669190a25050565b6115cb82610645565b6116235760405162461bcd60e51b8152602060048201526024808201527f41646d696e61626c653a2072656d6f7665206e6f6e2d6578697374656e7420616044820152633236b4b760e11b60648201526084016110d7565b6001600160a01b038216600081815260656020526040808220829055517fa3b62bc36326052d97ea62d63c3d60308ed4c3ea8ac079dd8499f1e9c4f80c0f9190a25050565b6001600160a01b037f000000000000000000000000a190d11f937de97d1ebe5a2b2732d86689c97c151630036116b05760405162461bcd60e51b81526004016110d790614496565b7f000000000000000000000000a190d11f937de97d1ebe5a2b2732d86689c97c156001600160a01b03166116e2612d90565b6001600160a01b0316146117085760405162461bcd60e51b81526004016110d7906144e2565b61171182612dac565b6112d982826001612dd1565b61172633610645565b6117425760405162461bcd60e51b81526004016110d790614397565b61017a55565b600061175382612858565b1561176157505061017a5490565b506000919050565b919050565b61177733610645565b6117935760405162461bcd60e51b81526004016110d790614397565b60405147906000906001600160a01b0384169083908381818185875af1925050503d80600081146117e0576040519150601f19603f3d011682016040523d82523d6000602084013e6117e5565b606091505b5050905080610fb55760405162461bcd60e51b815260206004820152600f60248201526e15da5d1a191c985dc819985a5b1959608a1b60448201526064016110d7565b6000306001600160a01b037f000000000000000000000000a190d11f937de97d1ebe5a2b2732d86689c97c1516146118c85760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016110d7565b506000805160206148bc83398151915290565b6118e433610645565b6119005760405162461bcd60e51b81526004016110d790614397565b610177610fb582848361457c565b61191733610645565b6119335760405162461bcd60e51b81526004016110d790614397565b6101619390935561015f805467ffffffffffffffff60b01b1916600160b01b63ffffffff9485160263ffffffff60d01b191617600160d01b9290931691909102919091176001600160f01b0316600160f01b61ffff90931692909202919091179055565b60006119a2826128e9565b5192915050565b610175805461102690614311565b6119c033610645565b6119dc5760405162461bcd60e51b81526004016110d790614397565b61015f805463ffffffff95861667ffffffffffffffff19909116176401000000009490951693909302939093176bffffffff00000000000000001916600160401b61ffff9283160261ffff60501b191617600160501b9390911692909202919091179055565b611a4b33610645565b611a675760405162461bcd60e51b81526004016110d790614397565b61012d80546001600160a01b0319166001600160a01b03831690811790915560405133907f3271c8694494a7cc76cd185c743e9ee6b515a043ea98c0db7f5ca112f694add490600090a350565b60006001600160a01b038216611add576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152609c60205260409020546001600160401b031690565b611b0b33610645565b611b275760405162461bcd60e51b81526004016110d790614397565b61017654611b3790611e61614361565b60985460975403600019011115611b875760405162461bcd60e51b8152602060048201526014602482015273084eae4dc40c2dadeeadce840e8dede40daeac6d60631b60448201526064016110d7565b61017680549091019055565b6000611ba084848461310d565b61012d546001600160a01b0390811691161490505b9392505050565b600054610100900460ff1615808015611bdc5750600054600160ff909116105b80611bf65750303b158015611bf6575060005460ff166001145b611c595760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016110d7565b6000805460ff191660011790558015611c7c576000805461ff0019166101001790555b6001600160a01b037f000000000000000000000000a190d11f937de97d1ebe5a2b2732d86689c97c15163003611cc45760405162461bcd60e51b81526004016110d790614496565b7f000000000000000000000000a190d11f937de97d1ebe5a2b2732d86689c97c156001600160a01b0316611cf6612d90565b6001600160a01b031614611d1c5760405162461bcd60e51b81526004016110d7906144e2565b611d2461326c565b611d736040518060400160405280600e81526020016d536861726b7a2047656e6573697360901b81525060405180604001604052806007815260200166534841524b5a4760c81b81525061329d565b611d7b6132ce565b611d836132fd565b61017980546001600160a01b0319167312deb1cb5732e40dd55b89abb6d5c31df13a6e38179055600161017a5580156113a2576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150565b323314611e175760405162461bcd60e51b81526004016110d7906143ce565b82611e20610fba565b81611e2e6097546000190190565b611e389190614405565b1115611e565760405162461bcd60e51b81526004016110d79061441d565b611e5e610d0d565b611ea45760405162461bcd60e51b815260206004820152601760248201527646726565206d696e74206973206e6f742061637469766560481b60448201526064016110d7565b828260405180604001604052806008815260200167199c99595b5a5b9d60c21b815250611ed283838361310d565b61012d546001600160a01b03908116911614611f2c5760405162461bcd60e51b81526020600482015260196024820152784549503731323a20496e76616c6964205369676e617475726560381b60448201526064016110d7565b61015f5461ffff600160501b9091041687611f68336001600160a01b03166000908152609c602052604090205461ffff600160d01b9091041690565b611f729190614405565b1115611f905760405162461bcd60e51b81526004016110d790614461565b336000908152609c60205260409020805461ffff600160d01b80830482168b019091160261ffff60d01b199091161790555b611fcc3388612c56565b50505050505050565b6060609a8054610e6d90614311565b611fed33610645565b6120095760405162461bcd60e51b81526004016110d790614397565b610178610fb582848361457c565b336001600160a01b038316036120405760405163b06307db60e01b815260040160405180910390fd5b336000818152609e602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61015f546000904290600160b01b900463ffffffff16158015906120e0575061015f54600160b01b900463ffffffff168110155b8015610d50575061015f54600160d01b900463ffffffff161015919050565b61210a848484612a34565b6001600160a01b0383163b15612143576121268484848461332c565b612143576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b600081815260fb602052604081205442600160a01b9091046001600160401b0316106117615750600090815260fb60205260409020546001600160a01b031690565b606061219682612858565b6121b357604051630a14c4b560e41b815260040160405180910390fd5b60006121bd613418565b905080516000036121f9576101786121d484613428565b6040516020016121e592919061463b565b604051602081830303815290604052611bb5565b8061220384613428565b6040516020016122149291906146c2565b6040516020818303038152906040529392505050565b3233146122495760405162461bcd60e51b81526004016110d7906143ce565b80612252610fba565b816122606097546000190190565b61226a9190614405565b11156122885760405162461bcd60e51b81526004016110d79061441d565b612290610d0d565b6122d65760405162461bcd60e51b815260206004820152601760248201527646726565206d696e74206973206e6f742061637469766560481b60448201526064016110d7565b610179546122ed906001600160a01b03163361346c565b6123395760405162461bcd60e51b815260206004820152601b60248201527f43616c6c6572206973206e6f7420536f756c204944206f776e6572000000000060448201526064016110d7565b61015f5461ffff600160401b9091041682612375336001600160a01b03166000908152609c602052604090205461ffff600160c01b9091041690565b61237f9190614405565b111561239d5760405162461bcd60e51b81526004016110d790614461565b336000908152609c60205260409020805461ffff600160c01b808304821686019091160261ffff60c01b199091161790556112cf565b610177805461102690614311565b6001600160a01b0381166000908152609c6020526040812054600160401b90046001600160401b0316610d07565b61241833610645565b6124345760405162461bcd60e51b81526004016110d790614397565b61017980546001600160a01b0319166001600160a01b0392909216919091179055565b6000612462846128e9565b5190506000336001600160a01b03831614806124835750612483823361258a565b8061249e57503361249386610ef0565b6001600160a01b0316145b9050806125085760405162461bcd60e51b815260206004820152603260248201527f455243343930373a207472616e736665722063616c6c6572206973206e6f74206044820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b60648201526084016110d7565b600085815260fb602090815260409182902080546001600160a01b0388166001600160e01b03199091168117600160a01b6001600160401b03891690810291909117835593519384529092909188917f4e06b4e7000e659094299b3533b47b6aa8ad048e95e872d23d1f4ee55af89cfe910160405180910390a3505050505050565b6001600160a01b039182166000908152609e6020908152604080832093909416825291909152205460ff1690565b60006125c3826128e9565b6040015163ffffffff1692915050565b3233146125f25760405162461bcd60e51b81526004016110d7906143ce565b826125fb610fba565b816126096097546000190190565b6126139190614405565b11156126315760405162461bcd60e51b81526004016110d79061441d565b6126396113a5565b6126855760405162461bcd60e51b815260206004820152601a60248201527f50726573616c65206d696e74206973206e6f742061637469766500000000000060448201526064016110d7565b82826040518060400160405280600781526020016670726573616c6560c81b8152506126b283838361310d565b61012d546001600160a01b0390811691161461270c5760405162461bcd60e51b81526020600482015260196024820152784549503731323a20496e76616c6964205369676e617475726560381b60448201526064016110d7565b6101605461271b908890614378565b3410156127645760405162461bcd60e51b81526020600482015260176024820152762732b2b2103a379039b2b7321036b7b9329032ba3432b960491b60448201526064016110d7565b61015f5461ffff600160a01b90910416876127a0336001600160a01b03166000908152609c602052604090205461ffff600160e01b9091041690565b6127aa9190614405565b11156127c85760405162461bcd60e51b81526004016110d790614461565b336000908152609c60205260409020805461ffff600160e01b80830482168b019091160261ffff60e01b19909116179055611fc2565b61280733610645565b6128235760405162461bcd60e51b81526004016110d790614397565b6101756112d982826146e8565b600061283b82613519565b80610d075750506001600160e01b031916632b424ad760e21b1490565b60008160011115801561286c575060975482105b8015610d075750506000908152609b602052604090206001015460ff161590565b6000828152609d602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6040805160808101825260008082526020820181905291810182905260608101919091528180600111612a1b57609754811015612a1b576000818152609b6020908152604091829020825160808101845281546001600160a01b0381168252600160a01b81046001600160401b031693820193909352600160e01b90920463ffffffff169282019290925260019091015460ff16151560608201819052612a195780516001600160a01b0316156129a1579392505050565b50600019016000818152609b6020908152604091829020825160808101845281546001600160a01b038116808352600160a01b82046001600160401b031694830194909452600160e01b900463ffffffff16938101939093526001015460ff161515606083015215612a14579392505050565b6129a1565b505b604051636f96cda160e11b815260040160405180910390fd5b6000612a3f826128e9565b9050836001600160a01b031681600001516001600160a01b031614612a765760405162a1148160e81b815260040160405180910390fd5b6000336001600160a01b0386161480612a945750612a94853361258a565b80612aaf575033612aa484610ef0565b6001600160a01b0316145b905080612acf57604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038416612af657604051633a954ecd60e21b815260040160405180910390fd5b612b038585856001613567565b612b0f6000848761288d565b6001600160a01b038086166000908152609c6020908152604080832080546000196001600160401b0380831691909101811667ffffffffffffffff199283161790925589861680865283862080548085166001908101861691909416179055898652609b909452828520805463ffffffff600160e01b42909516600160a01b026001600160e01b031990921690961717838104861683019095169092026001600160e01b03909416939093178155918701808452922080549193909116612c0a576097548214612c0a57805460208601516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038a16171781555b50505082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b5050505050565b6097546001600160a01b038316612c7f57604051622e076360e81b815260040160405180910390fd5b81600003612ca05760405163b562e8dd60e01b815260040160405180910390fd5b612cad6000848385613567565b6001600160a01b0383166000818152609c6020908152604080832080546fffffffffffffffffffffffffffffffff1981166001600160401b038083168a018116918217600160401b67ffffffffffffffff1990941690921783900481168a01811690920217909155858452609b90925290912080546001600160e01b031916909217600160a01b4290921691909102179055808083015b6040516001830192906001600160a01b038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4808210612d445750609755505050565b6000805160206148bc833981519152546001600160a01b031690565b612db533610645565b6113a25760405162461bcd60e51b81526004016110d790614397565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612e0457610fb583613573565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612e5e575060408051601f3d908101601f19168201909252612e5b918101906147a7565b60015b612ec15760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016110d7565b6000805160206148bc8339815191528114612f305760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016110d7565b50610fb583838361360f565b6000612f47836128e9565b80519091508215612fad576000336001600160a01b0383161480612f705750612f70823361258a565b80612f8b575033612f8086610ef0565b6001600160a01b0316145b905080612fab57604051632ce44b5f60e11b815260040160405180910390fd5b505b612fbb816000866001613567565b612fc76000858361288d565b6001600160a01b038082166000818152609c602090815260408083208054600160801b6000196001600160401b0380841691909101811667ffffffffffffffff198416811783900482166001908101831690930277ffffffffffffffff0000000000000000ffffffffffffffff19909416179290921783558b8652609b909452828520805442909216600160a01b026001600160e01b0319909216909617178555848301805460ff1916841790559189018084529220805491949091166130c25760975482146130c257805460208701516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038716171781555b5050604051869250600091506001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a450506098805460010190555050565b61012d546000906001600160a01b03166131695760405162461bcd60e51b815260206004820152601d60248201527f4549503731323a2057686974656c697374206e6f7420656e61626c656400000060448201526064016110d7565b600061012e547f37c6b9d7eb54fbea31a6c2906bc57f6f771960ad0d5c5abe7bb4d804410542976131973390565b6131a0866147c0565b6040516020016131cc939291909283526001600160a01b03919091166020830152604082015260600190565b6040516020818303038152906040528051906020012060405160200161320992919061190160f01b81526002810192909252602282015260420190565b60405160208183030381529060405280519060200120905061326385858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506136349050565b95945050505050565b600054610100900460ff166132935760405162461bcd60e51b81526004016110d7906147e4565b61329b613658565b565b600054610100900460ff166132c45760405162461bcd60e51b81526004016110d7906147e4565b6112d98282613694565b600054610100900460ff166132f55760405162461bcd60e51b81526004016110d7906147e4565b61329b6136de565b600054610100900460ff166133245760405162461bcd60e51b81526004016110d7906147e4565b61329b6137e4565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a029061336190339089908890889060040161482f565b6020604051808303816000875af192505050801561339c575060408051601f3d908101601f191682019092526133999181019061486c565b60015b6133fa573d8080156133ca576040519150601f19603f3d011682016040523d82523d6000602084013e6133cf565b606091505b5080516000036133f2576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b60606101778054610e6d90614311565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a9004806134425750819003601f19909101908152919050565b6040516370a0823160e01b81526001600160a01b038281166004830152600091908416906370a0823190602401602060405180830381865afa9250505080156134d2575060408051601f3d908101601f191682019092526134cf918101906147a7565b60015b613510573d808015613500576040519150601f19603f3d011682016040523d82523d6000602084013e613505565b606091505b506000915050610d07565b15159050610d07565b60006301ffc9a760e01b6001600160e01b03198316148061354a57506380ac58cd60e01b6001600160e01b03198316145b80610d075750506001600160e01b031916635b5e139f60e01b1490565b61214384848484613849565b6001600160a01b0381163b6135e05760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016110d7565b6000805160206148bc83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b613618836138e0565b6000825111806136255750805b15610fb5576121438383613920565b60008060006136438585613a0b565b9150915061365081613a79565b509392505050565b600054610100900460ff1661367f5760405162461bcd60e51b81526004016110d7906147e4565b33600090815260656020526040902060019055565b600054610100900460ff166136bb5760405162461bcd60e51b81526004016110d7906147e4565b60996136c783826146e8565b50609a6136d482826146e8565b5060016097555050565b600054610100900460ff166137055760405162461bcd60e51b81526004016110d7906147e4565b604080518082018252600e81526d2bb434ba32b634b9ba2a37b5b2b760911b6020918201528151808301835260018152603160f81b9082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818301527fb31abde365a4931cba9a0ea66b4737a15e8eb9a0649f549f4857db08880a9049818401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a0808301919091528351808303909101815260c0909101909252815191012061012e5561329b33611a42565b600054610100900460ff1661380b5760405162461bcd60e51b81526004016110d7906147e4565b66470de4df8200006101605566b1a2bc2ec50000610161557e14634014c06336e148000a634014c06336e14800010001634014c06336da4061015f55565b8060010361214357816001600160a01b03858116908516148015906138845750600081815260fb60205260409020546001600160a01b031615155b15612c4f57600081815260fb6020908152604080832080546001600160e01b03191690555182815283917f4e06b4e7000e659094299b3533b47b6aa8ad048e95e872d23d1f4ee55af89cfe910160405180910390a35050505050565b6138e981613573565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6139885760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016110d7565b600080846001600160a01b0316846040516139a39190614889565b600060405180830381855af49150503d80600081146139de576040519150601f19603f3d011682016040523d82523d6000602084013e6139e3565b606091505b509150915061326382826040518060600160405280602781526020016148dc60279139613c2f565b6000808251604103613a415760208301516040840151606085015160001a613a3587828585613c68565b94509450505050613a72565b8251604003613a6a5760208301516040840151613a5f868383613d55565b935093505050613a72565b506000905060025b9250929050565b6000816004811115613a8d57613a8d6148a5565b03613a955750565b6001816004811115613aa957613aa96148a5565b03613af65760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016110d7565b6002816004811115613b0a57613b0a6148a5565b03613b575760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016110d7565b6003816004811115613b6b57613b6b6148a5565b03613bc35760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016110d7565b6004816004811115613bd757613bd76148a5565b036113a25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016110d7565b60608315613c3e575081611bb5565b825115613c4e5782518084602001fd5b8160405162461bcd60e51b81526004016110d79190613e4b565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613c9f5750600090506003613d4c565b8460ff16601b14158015613cb757508460ff16601c14155b15613cc85750600090506004613d4c565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613d1c573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116613d4557600060019250925050613d4c565b9150600090505b94509492505050565b6000806001600160ff1b03831681613d7260ff86901c601b614405565b9050613d8087828885613c68565b935093505050935093915050565b6001600160e01b0319811681146113a257600080fd5b600060208284031215613db657600080fd5b8135611bb581613d8e565b6001600160a01b03811681146113a257600080fd5b600060208284031215613de857600080fd5b8135611bb581613dc1565b60005b83811015613e0e578181015183820152602001613df6565b838111156121435750506000910152565b60008151808452613e37816020860160208601613df3565b601f01601f19169290920160200192915050565b602081526000611bb56020830184613e1f565b600060208284031215613e7057600080fd5b5035919050565b60008060408385031215613e8a57600080fd5b8235613e9581613dc1565b946020939093013593505050565b600080600060608486031215613eb857600080fd5b8335613ec381613dc1565b92506020840135613ed381613dc1565b929592945050506040919091013590565b803563ffffffff8116811461176957600080fd5b803561ffff8116811461176957600080fd5b60008060008060808587031215613f2057600080fd5b84359350613f3060208601613ee4565b9250613f3e60408601613ee4565b9150613f4c60608601613ef8565b905092959194509250565b60008060408385031215613f6a57600080fd5b8235613f7581613dc1565b915060208301358015158114613f8a57600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112613fbc57600080fd5b81356001600160401b0380821115613fd657613fd6613f95565b604051601f8301601f19908116603f01168101908282118183101715613ffe57613ffe613f95565b8160405283815286602085880101111561401757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806040838503121561404a57600080fd5b823561405581613dc1565b915060208301356001600160401b0381111561407057600080fd5b61407c85828601613fab565b9150509250929050565b60008083601f84011261409857600080fd5b5081356001600160401b038111156140af57600080fd5b602083019150836020828501011115613a7257600080fd5b600080602083850312156140da57600080fd5b82356001600160401b038111156140f057600080fd5b6140fc85828601614086565b90969095509350505050565b6000806000806080858703121561411e57600080fd5b61412785613ee4565b935061413560208601613ee4565b9250613f3e60408601613ef8565b60008060006040848603121561415857600080fd5b83356001600160401b038082111561416f57600080fd5b61417b87838801614086565b9095509350602086013591508082111561419457600080fd5b506141a186828701613fab565b9150509250925092565b6000806000604084860312156141c057600080fd5b8335925060208401356001600160401b038111156141dd57600080fd5b6141e986828701614086565b9497909650939450505050565b6000806000806080858703121561420c57600080fd5b843561421781613dc1565b9350602085013561422781613dc1565b92506040850135915060608501356001600160401b0381111561424957600080fd5b61425587828801613fab565b91505092959194509250565b60008060006060848603121561427657600080fd5b83359250602084013561428881613dc1565b915060408401356001600160401b03811681146142a457600080fd5b809150509250925092565b600080604083850312156142c257600080fd5b82356142cd81613dc1565b91506020830135613f8a81613dc1565b6000602082840312156142ef57600080fd5b81356001600160401b0381111561430557600080fd5b61341084828501613fab565b600181811c9082168061432557607f821691505b60208210810361434557634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6000828210156143735761437361434b565b500390565b60008160001904831182151516156143925761439261434b565b500290565b6020808252601e908201527f41646d696e61626c653a2063616c6c6572206973206e6f742061646d696e0000604082015260600190565b6020808252601e908201527f5468652063616c6c657220697320616e6f7468657220636f6e74726163740000604082015260600190565b600082198211156144185761441861434b565b500190565b60208082526024908201527f52656163686564206d617820737570706c79206f662074686520636f6c6c65636040820152633a34b7b760e11b606082015260800190565b6020808252818101527f52656163686564206d696e74696e67206c696d6974207065722077616c6c6574604082015260600190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b601f821115610fb557600081815260208120601f850160051c810160208610156145555750805b601f850160051c820191505b8181101561457457828155600101614561565b505050505050565b6001600160401b0383111561459357614593613f95565b6145a7836145a18354614311565b8361452e565b6000601f8411600181146145db57600085156145c35750838201355b600019600387901b1c1916600186901b178355612c4f565b600083815260209020601f19861690835b8281101561460c57868501358255602094850194600190920191016145ec565b50868210156146295760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b600080845461464981614311565b600182811680156146615760018114614676576146a5565b60ff19841687528215158302870194506146a5565b8860005260208060002060005b8581101561469c5781548a820152908401908201614683565b50505082870194505b5050505083516146b9818360208801613df3565b01949350505050565b600083516146d4818460208801613df3565b8351908301906146b9818360208801613df3565b81516001600160401b0381111561470157614701613f95565b6147158161470f8454614311565b8461452e565b602080601f83116001811461474a57600084156147325750858301515b600019600386901b1c1916600185901b178555614574565b600085815260208120601f198616915b828110156147795788860151825594840194600190910190840161475a565b50858210156147975787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602082840312156147b957600080fd5b5051919050565b805160208083015191908110156143455760001960209190910360031b1b16919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061486290830184613e1f565b9695505050505050565b60006020828403121561487e57600080fd5b8151611bb581613d8e565b6000825161489b818460208701613df3565b9190910192915050565b634e487b7160e01b600052602160045260246000fdfe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212200561269f0be6af66eeb5d81587b6aa579b10da315dffeda19bbb24b61c5a2f3064736f6c634300080f0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.