Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00
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:
GenesisSale
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../../acl/access-controlled/AccessControlledUpgradeable.sol";
import "./IGenesisSale.sol";
import "../ZeeItems/IZeeItemCollection.sol";
import "../SoulShards/ISoulShards.sol";
import "../Vouchers/IVouchers.sol";
contract GenesisSale is
IGenesisSale,
UUPSUpgradeable,
EIP712Upgradeable,
AccessControlledUpgradeable
{
bytes32 public constant ADMIN_ROLE = keccak256("SALE_ADMIN_ROLE");
bytes32 public constant SIGNER_ROLE = keccak256("SALE_SIGNER_ROLE");
bytes32 public constant CLAIMREQUEST_TYPEHASH = keccak256("ClaimRequest(address minterAddress,uint256 beltId)");
bytes32 private constant _VAULT_SLOT = bytes32(uint256(keccak256("vault")));
bytes32 private constant _ZEE_ITEMS_SLOT = bytes32(uint256(keccak256("zee_items")));
bytes32 private constant _SOULBOUND_SLOT = bytes32(uint256(keccak256("soulbound")));
bytes32 private constant _VOUCHER_SLOT = bytes32(uint256(keccak256("voucher")));
mapping(uint256 => Price) internal _prices;
mapping(uint256 => bool) internal _usedBelts;
mapping(uint256 => bool) internal _claimableItems;
bool internal _lootpodSaleEnabled;
bool internal _soulBoundSaleEnabled;
uint256 internal _soulBoundPrice;
bytes32 public constant VOUCHER_SOUL_SHARD_TYPE = keccak256("VoucherSoulShardConfig");
bytes32 public constant VOUCHER_LOOTPOD_TYPE = keccak256("VoucherLootpodConfig");
uint256 internal _coolDownTime;
mapping(address => uint256) _coolDownMapping;
constructor() initializer {}
function initialize(address acl, address payable vault) external initializer {
__UUPSUpgradeable_init();
__AccessControlled_init(acl);
_setVault(vault);
__EIP712_init("GenesisSale", "V1");
}
function setPrice(uint256 itemId, uint256 ethPrice, uint256 price, address token) external onlyRole(ADMIN_ROLE) {
_prices[itemId].ethPrice = ethPrice;
_prices[itemId].price = price;
_prices[itemId].token = token;
emit PriceSet(itemId, price, ethPrice, token);
}
function removePrice(uint256 itemId) external onlyRole(ADMIN_ROLE) {
delete _prices[itemId];
emit PriceRemoved(itemId);
}
function setSoulBoundPrice(uint256 price) external onlyRole(ADMIN_ROLE) {
_soulBoundPrice = price;
emit SoulBoundPriceSet(price);
}
function getSoulBoundPrice() external view returns(uint256) {
return _soulBoundPrice;
}
function getPrice(uint256 itemId) external view returns(Price memory) {
return _prices[itemId];
}
function setVault(address payable vault) external onlyRole(ADMIN_ROLE) {
_setVault(vault);
}
function getVault() external view returns(address) {
return _getVault();
}
function setZeeItemsContract(address zeeItems) external onlyRole(ADMIN_ROLE) {
_setZeeItemsContract(zeeItems);
}
function getZeeItemsContract() external view returns(address) {
return _getZeeItemsContract();
}
function setSoulBoundContract(address soulbound) external onlyRole(ADMIN_ROLE) {
return _setSoulBoundContract(soulbound);
}
function getSoulBoundContract() external view returns(address) {
return _getSoulBoundContract();
}
function setVouchersContract(address vouchers) external onlyRole(ADMIN_ROLE) {
_setVouchersContract(vouchers);
}
function getVouchersContract() external view returns(address) {
return _getVoucherContract();
}
function setCoolDown(uint256 time) external onlyRole(ADMIN_ROLE){
_coolDownTime = time;
emit CoolDownSet(time);
}
// Get zee items contract address
function getCoolDown() external view returns(uint256) {
return _coolDownTime;
}
function getAddressCoolDown(address buyer) external view returns(uint256) {
return _coolDownMapping[buyer];
}
function overrideLevelConfig(uint256 voucherId, address level1, address level2) external {
}
function buyItems(uint256[] calldata itemIds, uint256[] calldata amounts, uint256 voucherId) external payable {
require(itemIds.length == amounts.length, "Invalid length");
require(itemIds.length != 0, "Invalid length");
require(_lootpodSaleEnabled, "Sale not enabled");
uint256 totalPrice = 0;
uint count = itemIds.length;
uint totalItems = 0;
for(uint i = 0; i < count; i++)
{
require(_prices[itemIds[i]].ethPrice > 0, "No price set for item");
totalPrice += _prices[itemIds[i]].ethPrice * amounts[i];
totalItems += amounts[i];
}
processReceivedFunds(totalPrice, VOUCHER_LOOTPOD_TYPE, voucherId, address(0x0));
uint256[] memory itemList = new uint256[](totalItems);
for(uint i = 0; i < count; i++)
{
IZeeItemCollection(_getZeeItemsContract()).mintMultiple(msg.sender, itemIds[i], amounts[i]);
emit ItemsSold(itemIds[i], msg.sender, amounts[i]);
}
}
function buyItemsUsingVee(uint256[] calldata itemIds, uint256[] calldata amounts, uint256 voucherId) external {
require(itemIds.length == amounts.length, "Invalid length");
require(itemIds.length != 0, "Invalid length");
require(_lootpodSaleEnabled, "Sale not enabled");
require(amounts[0] == 1, "Only 1 lootpod can be bought");
require(amounts.length == 1, "Only 1 lootpod can be bought");
require(_coolDownMapping[msg.sender] < block.timestamp, "Cannot buy using tokens, wait for some time to purchase again");
uint256 totalPrice = 0;
uint count = itemIds.length;
uint totalItems = 0;
for(uint i = 0; i < count; i++)
{
require(_prices[itemIds[i]].price > 0, "No price set for item");
totalPrice += _prices[itemIds[i]].price * amounts[i];
totalItems += amounts[i];
}
processReceivedFunds(totalPrice, VOUCHER_LOOTPOD_TYPE, voucherId, _prices[itemIds[0]].token);
_coolDownMapping[msg.sender] = block.timestamp + _coolDownTime;
uint256[] memory itemList = new uint256[](totalItems);
for(uint i = 0; i < count; i++)
{
emit ItemsSoldWithTokens(itemIds[i], msg.sender, amounts[i], _prices[itemIds[0]].token);
}
}
function buySoulBound(uint256 voucherId) external payable {
require(_soulBoundSaleEnabled, "Soul Bound sale not enabled");
processReceivedFunds(_soulBoundPrice, VOUCHER_SOUL_SHARD_TYPE, voucherId, address(0x0));
ISoulShards(_getSoulBoundContract()).mintType(msg.sender, 1);
emit SoulShardSold(msg.sender, 1);
}
function processReceivedFunds(uint256 originalPrice, bytes32 voucherConfigType, uint256 voucherId, address token) internal {
uint256 vouchers = voucherCount(msg.sender);
if (vouchers > 0) {
// Get discount for this specific purchase
DiscountConfiguration memory discountConfiguration = IVouchers(_getVoucherContract()).getConfiguration(voucherConfigType);
// Get overall information about this user/voucher
VoucherInfo memory userInfo = IVouchers(_getVoucherContract()).accountInfo(msg.sender);
// Check if user is indeed the owner of this voucher
checkOwnership(voucherId);
// Get discount based on voucher status
uint16 discount = discountConfiguration.discount;
if (userInfo.activated) {
discount = discountConfiguration.activatedDiscount;
}
uint256 price = originalPrice - calculatePercentage(originalPrice, discount);
uint256 feePrice = calculatePercentage(price, discountConfiguration.soulPercentage + discountConfiguration.shamanPercentage);
if (token == address(0x0)) {
require(msg.value == price, "Invalid discounted value provided");
(bool sent1, bytes memory data1) = payable(_getVault()).call{value: price - feePrice}("");
require(sent1, "Failed to send funds to vault");
IVouchers(_getVoucherContract()).payFees{value: feePrice}(price, voucherConfigType, userInfo.activated ? userInfo.tokenId : voucherId);
} else {
require(IERC20(token).transferFrom(msg.sender, _getVault(), price - feePrice), "Failed to send ERC20 funds to vault");
IVouchers(_getVoucherContract()).payFeesErc20(price, voucherConfigType, userInfo.activated ? userInfo.tokenId : voucherId, token);
}
} else {
if (token == address(0x0)) {
require(msg.value == originalPrice, "Invalid value provided");
(bool sent, bytes memory data) = payable(_getVault()).call{value: msg.value}("");
require(sent, "Failed to send funds");
} else {
require(IERC20(token).transferFrom(msg.sender, _getVault(), originalPrice), "Failed to send ERC20 funds to vault");
}
}
}
function calculatePrice(uint256[] calldata itemIds, uint256[] calldata amounts) external view returns(uint256) {
uint256 totalPrice = 0;
uint count = itemIds.length;
for(uint i = 0; i < count; i++)
{
require(_prices[itemIds[i]].ethPrice > 0, "No price set for item");
totalPrice += _prices[itemIds[i]].ethPrice * amounts[i];
}
return totalPrice;
}
function hasActivatedVoucher(address wallet) internal returns(bool) {
return IVouchers(_getVoucherContract()).accountInfo(wallet).activated;
}
function voucherCount(address wallet) internal returns(uint256) {
return ERC721Upgradeable(_getVoucherContract()).balanceOf(wallet);
}
function checkOwnership(uint256 voucherId) internal {
require(ERC721Upgradeable(_getVoucherContract()).ownerOf(voucherId) == msg.sender, "You are not an owner of this voucher");
}
function calculatePercentage(uint256 standardPrice, uint16 bps) internal returns(uint256) {
if (bps > 0 || bps <= 10_000) {
require((standardPrice * bps) >= 10_000, "percentage calculation failed");
return standardPrice * bps / 10_000;
}
return standardPrice;
}
function claimLootPods(uint256[] calldata itemIds, uint256[] calldata beltIds, bytes[] calldata signatures) external {
require(_lootpodSaleEnabled, "Lootpod sale not enabled");
require(itemIds.length == beltIds.length, "invalid parameters length");
// bool soulShardExists = _isSoulBoundClaimed(msg.sender);
// require(soulShardExists, "Soul shard required");
uint count = itemIds.length;
for(uint i = 0; i < count; i++)
{
uint256 itemId = itemIds[i];
uint256 beltId = beltIds[i];
require(_usedBelts[beltId] == false, "Belt already claimed");
require(_claimableItems[itemId], "Item is not claimable");
bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(CLAIMREQUEST_TYPEHASH, msg.sender, beltId)));
address signer = ECDSAUpgradeable.recover(digest, signatures[i]);
require(_getAcl().hasRole(SIGNER_ROLE, signer), "Invalid signature");
_usedBelts[beltId] = true;
emit ItemClaimed(itemId, beltId, msg.sender, false);
}
}
// function claimSoulShard(uint256 beltId, bytes calldata signature) external {
// require(_soulBoundSaleEnabled, "Sale not enabled");
// require(_usedBelts[beltId] == false, "Belt already claimed");
//
// bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(CLAIMREQUEST_TYPEHASH, msg.sender, beltId)));
// address signer = ECDSAUpgradeable.recover(digest, signature);
// require(_getAcl().hasRole(SIGNER_ROLE, signer), "Invalid signature");
//
// uint soulBoundCount = ERC721Upgradeable(_getSoulBoundContract()).balanceOf(msg.sender);
//
// _usedBelts[beltId] = true;
// // Mint lootpod by users choice
// ISoulShards(_getSoulBoundContract()).mint(msg.sender);
//
// emit ItemClaimed(0, beltId, msg.sender, true);
// }
function setLootpodSaleState(bool enabled) external onlyRole(ADMIN_ROLE) {
_lootpodSaleEnabled = enabled;
emit LootpodSaleStateChanged(enabled);
}
function getLootpodSaleState() external view returns(bool) {
return _lootpodSaleEnabled;
}
function setSoulBoundSaleState(bool enabled) external onlyRole(ADMIN_ROLE) {
_soulBoundSaleEnabled = enabled;
emit SoulBoundSaleStateChanged(enabled);
}
function getSoulBoundSaleState() external view returns(bool) {
return _soulBoundSaleEnabled;
}
function setClaimableItems(uint256[] calldata itemIds, bool claimable) external onlyRole(ADMIN_ROLE) {
uint count = itemIds.length;
for(uint i = 0; i < count; i++)
{
_claimableItems[itemIds[i]] = claimable;
}
emit ClaimableItemsConfigured(itemIds, claimable);
}
function _setVault(address payable vault) internal {
StorageSlotUpgradeable.getAddressSlot(_VAULT_SLOT).value = vault;
emit VaultSet(vault);
}
function _setZeeItemsContract(address zeeItems) internal {
// TODO: maybe add some sort of validation if the contract is correct
StorageSlotUpgradeable.getAddressSlot(_ZEE_ITEMS_SLOT).value = zeeItems;
emit ZeeItemsContractSet(zeeItems);
}
function _setSoulBoundContract(address soulBound) internal {
StorageSlotUpgradeable.getAddressSlot(_SOULBOUND_SLOT).value = soulBound;
emit SoulBoundContractSet(soulBound);
}
function _setVouchersContract(address voucher) internal {
StorageSlotUpgradeable.getAddressSlot(_VOUCHER_SLOT).value = voucher;
emit VoucherContractSet(voucher);
}
function _getZeeItemsContract() internal view returns(address) {
address value = StorageSlotUpgradeable.getAddressSlot(_ZEE_ITEMS_SLOT).value;
require(value != address(0), "Zee Items contract not set");
return value;
}
function _getSoulBoundContract() internal view returns(address) {
address value = StorageSlotUpgradeable.getAddressSlot(_SOULBOUND_SLOT).value;
require(value != address(0), "SoulBound contract not set");
return value;
}
function _getVoucherContract() internal view returns(address) {
address value = StorageSlotUpgradeable.getAddressSlot(_VOUCHER_SLOT).value;
require(value != address(0), "Vouchers contract not set");
return value;
}
function _getVault() internal view returns(address) {
return StorageSlotUpgradeable.getAddressSlot(_VAULT_SLOT).value;
}
function isSoulBoundClaimed(address wallet) external view returns(bool) {
return _isSoulBoundClaimed(wallet);
}
function clearCooldown(address wallet) external onlyRole(ADMIN_ROLE) {
_coolDownMapping[wallet] = block.timestamp;
}
function _isSoulBoundClaimed(address wallet) internal view returns(bool) {
uint soulBoundCount = ERC721Upgradeable(_getSoulBoundContract()).balanceOf(wallet);
return soulBoundCount > 0;
}
}// 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
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
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);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)
pragma solidity ^0.8.0;
import "./ECDSAUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
*
* The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
* thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
* they need in their contracts using a combination of `abi.encode` and `keccak256`.
*
* This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
* scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
* ({_hashTypedDataV4}).
*
* The implementation of the domain separator was designed to be as efficient as possible while still properly updating
* the chain id to protect against replay attacks on an eventual fork of the chain.
*
* NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
* https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
*
* _Available since v3.4._
*
* @custom:storage-size 52
*/
abstract contract EIP712Upgradeable is Initializable {
/* solhint-disable var-name-mixedcase */
bytes32 private _HASHED_NAME;
bytes32 private _HASHED_VERSION;
bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
/* solhint-enable var-name-mixedcase */
/**
* @dev Initializes the domain separator and parameter caches.
*
* The meaning of `name` and `version` is specified in
* https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
*
* - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
* - `version`: the current major version of the signing domain.
*
* NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
* contract upgrade].
*/
function __EIP712_init(string memory name, string memory version) internal onlyInitializing {
__EIP712_init_unchained(name, version);
}
function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {
bytes32 hashedName = keccak256(bytes(name));
bytes32 hashedVersion = keccak256(bytes(version));
_HASHED_NAME = hashedName;
_HASHED_VERSION = hashedVersion;
}
/**
* @dev Returns the domain separator for the current chain.
*/
function _domainSeparatorV4() internal view returns (bytes32) {
return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());
}
function _buildDomainSeparator(
bytes32 typeHash,
bytes32 nameHash,
bytes32 versionHash
) private view returns (bytes32) {
return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));
}
/**
* @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
* function returns the hash of the fully encoded EIP712 message for this domain.
*
* This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
*
* ```solidity
* bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
* keccak256("Mail(address to,string contents)"),
* mailTo,
* keccak256(bytes(mailContents))
* )));
* address signer = ECDSA.recover(digest, signature);
* ```
*/
function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);
}
/**
* @dev The hash of the name parameter for the EIP712 domain.
*
* NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
* are a concern.
*/
function _EIP712NameHash() internal virtual view returns (bytes32) {
return _HASHED_NAME;
}
/**
* @dev The hash of the version parameter for the EIP712 domain.
*
* NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs
* are a concern.
*/
function _EIP712VersionHash() internal virtual view returns (bytes32) {
return _HASHED_VERSION;
}
/**
* @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 (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
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)
pragma solidity ^0.8.0;
import "./IERC721Upgradeable.sol";
import "./IERC721ReceiverUpgradeable.sol";
import "./extensions/IERC721MetadataUpgradeable.sol";
import "../../utils/AddressUpgradeable.sol";
import "../../utils/ContextUpgradeable.sol";
import "../../utils/StringsUpgradeable.sol";
import "../../utils/introspection/ERC165Upgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata extension, but not including the Enumerable extension, which is available separately as
* {ERC721Enumerable}.
*/
contract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {
using AddressUpgradeable for address;
using StringsUpgradeable for uint256;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to owner address
mapping(uint256 => address) private _owners;
// Mapping owner address to token count
mapping(address => uint256) private _balances;
// Mapping from token ID to approved address
mapping(uint256 => address) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {
__ERC721_init_unchained(name_, symbol_);
}
function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {
_name = name_;
_symbol = symbol_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {
return
interfaceId == type(IERC721Upgradeable).interfaceId ||
interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721-balanceOf}.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: address zero is not a valid owner");
return _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "ERC721: invalid token ID");
return owner;
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
_requireMinted(tokenId);
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overridden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return "";
}
/**
* @dev See {IERC721-approve}.
*/
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721Upgradeable.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not token owner nor approved for all"
);
_approve(to, tokenId);
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
_requireMinted(tokenId);
return _tokenApprovals[tokenId];
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory data
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");
_safeTransfer(from, to, tokenId, data);
}
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* `data` is additional data, it has no specified format and it is sent in call to `to`.
*
* This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory data
) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Returns whether `tokenId` exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted (`_mint`),
* and stop existing when they are burned (`_burn`).
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
/**
* @dev Returns whether `spender` is allowed to manage `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
address owner = ERC721Upgradeable.ownerOf(tokenId);
return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
}
/**
* @dev Safely mints `tokenId` and transfers it to `to`.
*
* Requirements:
*
* - `tokenId` must not exist.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeMint(
address to,
uint256 tokenId,
bytes memory data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
/**
* @dev Mints `tokenId` and transfers it to `to`.
*
* WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
*
* Requirements:
*
* - `tokenId` must not exist.
* - `to` cannot be the zero address.
*
* Emits a {Transfer} event.
*/
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
_afterTokenTransfer(address(0), to, tokenId);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721Upgradeable.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
// Clear approvals
_approve(address(0), tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
_afterTokenTransfer(owner, address(0), tokenId);
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721Upgradeable.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
// Clear approvals from the previous owner
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
_afterTokenTransfer(from, to, tokenId);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits an {Approval} event.
*/
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId);
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits an {ApprovalForAll} event.
*/
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC721: approve to caller");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Reverts if the `tokenId` has not been minted yet.
*/
function _requireMinted(uint256 tokenId) internal view virtual {
require(_exists(tokenId), "ERC721: invalid token ID");
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param data bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory data
) private returns (bool) {
if (to.isContract()) {
try IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
/// @solidity memory-safe-assembly
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, ``from``'s `tokenId` will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[44] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "./IAccessControlled.sol";
import "../Roles.sol";
import "../IACL.sol";
/// @notice Modifier provider for contracts that want to interact with the ACL contract.
abstract contract AccessControlledUpgradeable is
IAccessControlled,
UUPSUpgradeable,
ContextUpgradeable,
ERC165Upgradeable
{
bytes32 private constant _ACL_SLOT = bytes32(uint256(keccak256("zee-game.acl.slot")) - 1);
modifier onlyRole(bytes32 role) {
_getAcl().checkRole(role, _msgSender());
_;
}
/// @dev Modifier to make a function callable by the admin account.
modifier onlyAdmin() {
_getAcl().checkRole(Roles.ADMIN, _msgSender());
_;
}
/// @dev Modifier to make a function callable by a supervisor account.
modifier onlyMaintainer() {
_getAcl().checkRole(Roles.MAINTAINER, _msgSender());
_;
}
function __AccessControlled_init(address acl) internal onlyInitializing {
// solhint-disable-previous-line func-name-mixedcase
_setACL(acl);
}
/// @inheritdoc IAccessControlled
function getACL() external view returns (address) {
// solhint-disable-previous-line ordering
return address(_getAcl());
}
/// @inheritdoc IAccessControlled
function setACL(address acl) external onlyAdmin {
_setACL(acl);
}
/// @inheritdoc ERC165Upgradeable
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControlled).interfaceId || super.supportsInterface(interfaceId);
}
function _setACL(address acl) internal {
if (!IERC165Upgradeable(acl).supportsInterface(type(IACL).interfaceId)) revert InvalidACLAddress(acl);
StorageSlotUpgradeable.getAddressSlot(_ACL_SLOT).value = acl;
emit ACLSet(acl);
}
/// @dev return the IACL address
function _getAcl() internal view returns (IACL) {
return IACL(StorageSlotUpgradeable.getAddressSlot(_ACL_SLOT).value);
}
/// @inheritdoc UUPSUpgradeable
function _authorizeUpgrade(address) internal virtual override onlyAdmin {
// solhint-disable-previous-line no-empty-blocks
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
struct Price {
uint256 price;
uint256 ethPrice;
address token;
}
interface IGenesisSale {
event ItemsSold(uint256 itemId, address buyer, uint256 amount);
event ItemsSoldWithTokens(uint256 itemId, address buyer, uint256 amount, address token);
event SoulShardSold(address buyer, uint256 nftType);
event ItemClaimed(uint256 itemId, uint256 beltId, address claimer, bool soulBound);
event VaultSet(address vault);
event ZeeItemsContractSet(address zeeItems);
event SoulBoundContractSet(address soulBound);
event PriceSet(uint256 itemId, uint256 price, uint256 ethPrice, address token);
event SoulBoundPriceSet(uint256 price);
event PriceRemoved(uint256 itemId);
event LootpodSaleStateChanged(bool enabled);
event SoulBoundSaleStateChanged(bool enabled);
event ClaimableItemsConfigured(uint256[] itemIds, bool claimable);
event VoucherContractSet(address voucher);
event CoolDownSet(uint256 time);
// Set price for buyable items
function setPrice(uint256 itemId, uint256 ethPrice, uint256 price, address token) external;
// Remove price for item making it non buyable
function removePrice(uint256 itemId) external;
// Get price for specific item
function getPrice(uint256 itemId) external view returns(Price memory);
// Set SoulShard mint price
function setSoulBoundPrice(uint256 price) external;
// Get SoulShard mint price
function getSoulBoundPrice() external view returns(uint256);
// Address for which to send funds to
function setVault(address payable vault) external;
// Get vault address
function getVault() external view returns(address);
// Set address for zee items contract
function setZeeItemsContract(address zeeItems) external;
// Get zee items contract address
function getZeeItemsContract() external view returns(address);
// Set address for soulbound contract
function setSoulBoundContract(address soulBound) external;
// Get soulbound contract address
function getSoulBoundContract() external view returns(address);
// Set address for vouchers contract
function setVouchersContract(address vouchers) external;
// Get vouchers contract address
function getVouchersContract() external view returns(address);
// Set cooldown for VEE purchases
function setCoolDown(uint256 time) external;
// Get set cooldown value
function getCoolDown() external view returns(uint256);
// Get cooldown time for specific wallet
function getAddressCoolDown(address buyer) external view returns(uint256);
// Buy items using native currency
function buyItems(uint256[] calldata itemIds, uint256[] calldata amounts, uint256 voucherId) external payable;
function buyItemsUsingVee(uint256[] calldata itemIds, uint256[] calldata amounts, uint256 voucherId) external;
// Buy soul bound using native currency
function buySoulBound(uint256 voucherId) external payable;
// Calculate price
function calculatePrice(uint256[] calldata itemIds, uint256[] calldata amounts) external view returns(uint256);
// Claim items using belts
function claimLootPods(uint256[] calldata itemIds, uint256[] calldata beltIds, bytes[] calldata signatures) external;
// Claim soul shard
// function claimSoulShard(uint256 beltId, bytes calldata signature) external;
// Set Sale state
function setLootpodSaleState(bool enabled) external;
// Get Sale state
function getLootpodSaleState() external view returns(bool);
// Set Sale state
function setSoulBoundSaleState(bool enabled) external;
// Get Sale state
function getSoulBoundSaleState() external view returns(bool);
// Set items that can be claimable with signatures
function setClaimableItems(uint256[] calldata itemIds, bool claimable) external;
// Return wheter wallet already contains soul bound
function isSoulBoundClaimed(address wallet) external view returns(bool);
function clearCooldown(address wallet) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
struct AirdropConfig {
address wallet;
uint256[] tokenIds;
uint256[] amounts;
}
struct ItemBalance {
uint256 tokenId;
uint256 amount;
}
interface IZeeItemCollection {
event UriSet(string newUri);
event BatchAirdropped(AirdropConfig[] recipients, string reason);
event SoulBoundSet(uint256 tokenId, bool soulbound);
event BatchBurnCompleted(uint256[] tokenIds, uint256[] amounts, uint256 requiredAmount, string reason, address operator, uint256 actionId, string externalId);
event SupplyLimitSet(uint256 tokenId, uint256 limit);
event SupplySet(uint256 tokenId, uint256 amount);
function setBaseURI(string calldata baseUri) external;
function airdropTokens(address[] calldata recipients, uint256 tokenId) external;
function sendBatch(address recipient, uint256[] calldata tokenIds) external;
function mintMultiple(address recipient, uint256 tokenId, uint256 amount) external;
function airdropBatch(AirdropConfig[] calldata recipients) external;
function airdropBatchSafe(AirdropConfig[] calldata recipients, uint256 requestId) external;
function airdropBatchWithReason(AirdropConfig[] calldata recipients, string calldata reason) external;
function airdropBatchFromMinted(AirdropConfig[] calldata recipients) external;
function setSoulBoundTokens(uint256[] calldata tokenIds, bool soulbound) external;
function setTokenLimits(uint256[] calldata tokenIds, uint256[] calldata limits) external;
function setTokenCounts(uint256[] calldata tokenIds, uint256[] calldata counts) external;
function burnWithReason(uint256[] calldata tokenIds, uint256[] calldata amounts, uint256 requiredAmount, string calldata reason) external;
function burnWithReasonAndId(uint256[] calldata tokenIds, uint256[] calldata amounts, uint256 requiredAmount, string calldata reason, string calldata externalId) external;
function multipleBalanceOf(address owner, uint256[] calldata tokenIds) external view returns(ItemBalance[] memory);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
interface ISoulShards {
event UriSet(string newUri);
event SoulBoundMinted(uint256 tokenId, address owner, uint256 nftType);
function setBaseURI(string calldata baseUri) external;
function mint(address recipient) external;
// Mint specific token type
function mintType(address recipient, uint256 nftType) external;
// Get type of token id
function getType(uint256 tokenId) external view returns(uint256);
// Manually set which recipient already has which nft
function configureMinted(address[] calldata recipients, uint256 nftType) external;
// Does the owner has this type of token
function isMinted(address owner, uint256 nftType) external view returns(bool);
// Get the first minted token time for specific owner
function getMintTime(address owner) external view returns(uint256);
// Set all token owner mint times to the current block
function resetMintTimes(uint256 from, uint256 to) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
struct VoucherInfo {
bool activated;
uint256 tokenId;
address soul;
address shaman;
address owner;
}
struct DiscountConfiguration {
bytes32 discountType;
uint16 discount;
uint16 soulPercentage;
uint16 shamanPercentage;
uint16 activatedDiscount;
}
interface IVouchers {
event UriSet(string newUri);
event VoucherMinted(uint256 tokenId, address soul, address shaman);
event VoucherActivated(uint256 tokenId, address owner, address soul, address shaman);
event DiscountConfigured(bytes32 discountType, uint16 discount, uint16 activatedDiscount, uint16 soulPercentage, uint16 shamanPercentage);
event VoucherFee(uint256 voucherId, address from, uint256 value, address level1, uint256 level1Fee, address level2, uint256 level2Fee, bytes32 configType, address token);
event BanConfigured(uint256 tokenId, bool banned);
event VaultSet(address vault);
event SoulShardsContractSet(address soulShard);
event NewOwnerBlockSet(uint256 block);
event RewardClaimed(address claimer, uint256 amount, uint256 requestId);
event SoulShardRequirementSet(bool enabled);
function setBaseURI(string calldata baseUri) external;
// Return original minter for specific token
function getMinter(uint256 tokenId) external view returns(address);
// Return whether specific voucher is activated
function isActivated(uint256 tokenId) external view returns(bool);
// Get tokenId of the activated voucher
function getAccountActivatedVoucher(address wallet) external view returns(uint256);
// Activate vouchers
function activate(uint256 tokenId) external;
// Airdrop vouchers to wallets
function airdropVouchers(address[] calldata recipients) external;
// Mint vouchers on own wallet
function mintVouchers(uint256 amount) external;
// Mint vouchers for admin
function adminMint(address recipient, uint256 amount) external;
// Set ban for specific voucher
function setBan(uint256 tokenId, bool banned) external;
// Get ban status for voucher
function isBanned(uint256 tokenId) external view returns(bool);
// Account info
function accountInfo(address wallet) external view returns(VoucherInfo memory);
function voucherInfo(uint256 voucherId) external view returns(VoucherInfo memory);
// Add new discount configuration
function configureDiscounts(bytes32 discountType, uint16 discount, uint16 activatedDiscount, uint16 soulPercentage, uint16 shamanPercentage) external;
// Get configuration
function getConfiguration(bytes32 discountType) external view returns(DiscountConfiguration memory);
function overrideConfig(address owner, uint256 voucherId, address level1, address level2) external;
function payFees(uint256 price, bytes32 voucherConfigType, uint256 voucherId) external payable;
function payFeesErc20(uint256 price, bytes32 voucherConfigType, uint256 voucherId, address tokenContract) external payable;
// Address for which to send funds to
function setVault(address payable vault) external;
// Get vault address
function getVault() external view returns(address);
// Set address for soulbound contract
function setSoulShardContract(address soulShards) external;
// Get soulbound contract address
function getSoulShardContract() external view returns(address);
function setNewOwnerBlock(uint256 block) external;
function getNewOwnerBlock() external view returns(uint256);
function claim(uint256[] calldata amounts, uint256[] calldata requestIds, bytes[] calldata signatures) external;
function setSoulShardRequirement(bool enabled) external;
function getSoulShardRequirement() external view returns(bool);
}// 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 (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 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/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.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);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165Upgradeable.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721Upgradeable is IERC165Upgradeable {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev 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);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721ReceiverUpgradeable {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC721Upgradeable.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721MetadataUpgradeable is IERC721Upgradeable {
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165Upgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {
function __ERC165_init() internal onlyInitializing {
}
function __ERC165_init_unchained() internal onlyInitializing {
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165Upgradeable).interfaceId;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165Upgradeable {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
/// @notice Access Control List contract interface.
interface IAccessControlled {
/// @notice Thrown when the acl address does not implement the IACL interface.
error InvalidACLAddress(address acl);
/// @notice Emitted when the ACL contract gets set.
event ACLSet(address indexed acl);
/// @notice set the ACL contract
/// @param acl The ACL contract address.
function setACL(address acl) external;
/// @notice Get the ACL contract address.
/// @return The ACL contract address.
function getACL() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
/// @notice Different role definitions used by the ACL contract.
library Roles {
/// @dev This maps directly to the OpenZeppelins AccessControl DEFAULT_ADMIN
bytes32 public constant ADMIN = 0x00;
/// @dev The Maintainer role. Can execute Maintainer-only tasks.
bytes32 public constant MAINTAINER = keccak256("MAINTAINER_ROLE");
/// @dev The NFT owner role. Can execute NFT-only tasks.
bytes32 public constant NFT_OWNER = keccak256("NFT_OWNER");
/// @dev The auxiliary contracts that can perform cross-calls with one another.
// TODO: segregate these into a smaller roles.
bytes32 public constant AUXILIARY_CONTRACTS = keccak256("AUXILIARY_CONTRACTS");
/// @dev The Fragment mini-game burn permission
bytes32 public constant FRAGMENT_MINI_GAME_BURN = keccak256("FRAGMENT_MINI_GAME_BURN");
/// @dev The Zee NFT mint permission
bytes32 public constant ZEE_NFT_MINT = keccak256("ZEE_NFT_MINT");
/// @dev The Zee NFT burn permission
bytes32 public constant ZEE_NFT_BURN = keccak256("ZEE_NFT_BURN");
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
import "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol";
/// @notice Access Control List contract interface.
interface IACL is IAccessControlEnumerableUpgradeable {
/// @notice Thrown when the ACL roles do not match AccessControlEnumerable
error RolesContractIncorrectlyConfigured();
error CannotHaveMoreThanOneAddressInRole();
error CannotRemoveLastAdmin();
/// @notice Tevert if the `account` does not have the specified role.
/// @param role The role identifier.
/// @param account The address to check the role for.
function checkRole(bytes32 role, address account) external view;
/// @notice Get the admin role describing bytes.
/// @return role bytes.
function getAdminRole() external pure returns (bytes32);
/// @notice Get the maintainer role describing bytes.
/// @return role bytes.
function getMaintainerRole() external pure returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)
pragma solidity ^0.8.0;
import "./IAccessControlUpgradeable.sol";
/**
* @dev External interface of AccessControlEnumerable declared to support ERC165 detection.
*/
interface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/
function getRoleMember(bytes32 role, uint256 index) external view returns (address);
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/
function getRoleMemberCount(bytes32 role) external view returns (uint256);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)
pragma solidity ^0.8.0;
/**
* @dev External interface of AccessControl declared to support ERC165 detection.
*/
interface IAccessControlUpgradeable {
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {AccessControl-_setupRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) external;
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"acl","type":"address"}],"name":"InvalidACLAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"acl","type":"address"}],"name":"ACLSet","type":"event"},{"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":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"itemIds","type":"uint256[]"},{"indexed":false,"internalType":"bool","name":"claimable","type":"bool"}],"name":"ClaimableItemsConfigured","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"CoolDownSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"itemId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"beltId","type":"uint256"},{"indexed":false,"internalType":"address","name":"claimer","type":"address"},{"indexed":false,"internalType":"bool","name":"soulBound","type":"bool"}],"name":"ItemClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"itemId","type":"uint256"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ItemsSold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"itemId","type":"uint256"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"ItemsSoldWithTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"LootpodSaleStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"PriceRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"itemId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethPrice","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"PriceSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"soulBound","type":"address"}],"name":"SoulBoundContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"SoulBoundPriceSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"SoulBoundSaleStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"nftType","type":"uint256"}],"name":"SoulShardSold","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"vault","type":"address"}],"name":"VaultSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"voucher","type":"address"}],"name":"VoucherContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"zeeItems","type":"address"}],"name":"ZeeItemsContractSet","type":"event"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CLAIMREQUEST_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SIGNER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VOUCHER_LOOTPOD_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VOUCHER_SOUL_SHARD_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"itemIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256","name":"voucherId","type":"uint256"}],"name":"buyItems","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"itemIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256","name":"voucherId","type":"uint256"}],"name":"buyItemsUsingVee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"voucherId","type":"uint256"}],"name":"buySoulBound","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"itemIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"calculatePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"itemIds","type":"uint256[]"},{"internalType":"uint256[]","name":"beltIds","type":"uint256[]"},{"internalType":"bytes[]","name":"signatures","type":"bytes[]"}],"name":"claimLootPods","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"clearCooldown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getACL","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"buyer","type":"address"}],"name":"getAddressCoolDown","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCoolDown","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLootpodSaleState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"getPrice","outputs":[{"components":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"ethPrice","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"internalType":"struct Price","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSoulBoundContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSoulBoundPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSoulBoundSaleState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVouchersContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getZeeItemsContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"acl","type":"address"},{"internalType":"address payable","name":"vault","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"isSoulBoundClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"voucherId","type":"uint256"},{"internalType":"address","name":"level1","type":"address"},{"internalType":"address","name":"level2","type":"address"}],"name":"overrideLevelConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"removePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"acl","type":"address"}],"name":"setACL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"itemIds","type":"uint256[]"},{"internalType":"bool","name":"claimable","type":"bool"}],"name":"setClaimableItems","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"name":"setCoolDown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setLootpodSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint256","name":"ethPrice","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"soulbound","type":"address"}],"name":"setSoulBoundContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"name":"setSoulBoundPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setSoulBoundSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"vault","type":"address"}],"name":"setVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vouchers","type":"address"}],"name":"setVouchersContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"zeeItems","type":"address"}],"name":"setZeeItemsContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"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"}]Contract Creation Code
60a0604052306080523480156200001557600080fd5b50600054610100900460ff1615808015620000375750600054600160ff909116105b8062000067575062000054306200014160201b620023201760201c565b15801562000067575060005460ff166001145b620000cf5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000f3576000805461ff0019166101001790555b80156200013a576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5062000150565b6001600160a01b03163b151590565b60805161432d62000188600039600081816108c50152818161090e015281816111460152818161118601526111fe015261432d6000f3fe6080604052600436106102465760003560e01c80636f0eb78211610139578063a222ef1c116100b6578063c225db0c1161007a578063c225db0c146106eb578063d64a13b21461070b578063e75722301461072b578063e7675f3c14610776578063efd148d91461078b578063fa3b703d146107a057600080fd5b8063a222ef1c14610649578063ad1751fb1461065c578063ad85d1651461067c578063b1cf9fe614610697578063c11c7d5e146106b757600080fd5b80637c56687a116100fd5780637c56687a146105a05780637d3142c2146105c05780638d928af8146105e05780639cd0726a146105f5578063a1ebf35d1461061557600080fd5b80636f0eb782146104fe578063701eb1d51461051e57806374d3578a1461053e57806375b238fc1461055e57806376aad6051461058057600080fd5b8063485cc955116101c757806352d1902d1161018b57806352d1902d1461047e57806359facd4014610493578063647a9b57146104b357806366822364146104c85780636817031b146104de57600080fd5b8063485cc955146103f25780634c10e340146104125780634cd30fb0146104325780634ec424c81461044b5780634f1ef2861461046b57600080fd5b8063319333161161020e578063319333161461032a5780633659cfe61461035e5780633b1c85c51461037e5780633d00eae6146103b257806343110989146103d257600080fd5b806301ffc9a71461024b578063087376951461028057806309345900146102ad5780630e7e2143146102f25780631b6a7ada14610308575b600080fd5b34801561025757600080fd5b5061026b61026636600461398d565b6107b3565b60405190151581526020015b60405180910390f35b34801561028c57600080fd5b506102956107ea565b6040516001600160a01b039091168152602001610277565b3480156102b957600080fd5b506102e46102c83660046139cc565b6001600160a01b03166000908152610103602052604090205490565b604051908152602001610277565b3480156102fe57600080fd5b50610102546102e4565b34801561031457600080fd5b506103286103233660046139e9565b6107f9565b005b34801561033657600080fd5b506102e47f53493370b49bd36e0cf5c523d80e01079b16a5bec9214eb451f6eb45641692df81565b34801561036a57600080fd5b506103286103793660046139cc565b6108bb565b34801561038a57600080fd5b506102e47fab8a4f513e6a481f3215fb978a0f924f181acdf5128ea12a9606ddb771cc8f4981565b3480156103be57600080fd5b506103286103cd366004613a10565b61098c565b3480156103de57600080fd5b506103286103ed3660046139cc565b610a58565b3480156103fe57600080fd5b5061032861040d366004613a2d565b610ae9565b34801561041e57600080fd5b5061032861042d366004613aab565b610c54565b34801561043e57600080fd5b506101005460ff1661026b565b34801561045757600080fd5b50610328610466366004613b02565b610d7f565b610328610479366004613c0c565b61113c565b34801561048a57600080fd5b506102e46111f1565b34801561049f57600080fd5b506103286104ae3660046139cc565b6112a4565b3480156104bf57600080fd5b50610295611348565b3480156104d457600080fd5b50610101546102e4565b3480156104ea57600080fd5b506103286104f93660046139cc565b611352565b34801561050a57600080fd5b506103286105193660046139cc565b6113df565b34801561052a57600080fd5b50610328610539366004613a10565b61146c565b34801561054a57600080fd5b50610328610559366004613cb4565b611533565b34801561056a57600080fd5b506102e460008051602061429183398151915281565b34801561058c57600080fd5b5061032861059b3660046139cc565b611635565b3480156105ac57600080fd5b506103286105bb3660046139e9565b6116b4565b3480156105cc57600080fd5b5061026b6105db3660046139cc565b61176e565b3480156105ec57600080fd5b50610295611779565b34801561060157600080fd5b506103286106103660046139e9565b611783565b34801561062157600080fd5b506102e47fd9b7bfff425ebe71c13e899500acb373e0f7bdf204974be3d97a691fece7351b81565b610328610657366004613cf5565b611864565b34801561066857600080fd5b506102e4610677366004613d69565b611baf565b34801561068857600080fd5b5061010080540460ff1661026b565b3480156106a357600080fd5b506103286106b23660046139cc565b611c87565b3480156106c357600080fd5b506102e47f608c225644debd22bef24a74f42af7b8d92fb931cb66c105e1aa304bca6fdcfe81565b3480156106f757600080fd5b50610328610706366004613dd5565b505050565b34801561071757600080fd5b50610328610726366004613cf5565b611d14565b34801561073757600080fd5b5061074b6107463660046139e9565b612170565b604080518251815260208084015190820152918101516001600160a01b031690820152606001610277565b34801561078257600080fd5b506102956121df565b34801561079757600080fd5b506102956121e9565b6103286107ae3660046139e9565b6121f3565b60006001600160e01b031982166307ed9a0960e41b14806107e457506301ffc9a760e01b6001600160e01b03198316145b92915050565b60006107f461232f565b905090565b60008051602061429183398151915261081061232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b15801561086557600080fd5b505afa158015610879573d6000803e3d6000fd5b505050610101839055506040518281527f5f600a3bbf106c270c7e13f3d2fa7ed1f9f75d5f243620b850c6785cacd50b8b906020015b60405180910390a15050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361090c5760405162461bcd60e51b815260040161090390613e0c565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661093e612371565b6001600160a01b0316146109645760405162461bcd60e51b815260040161090390613e58565b61096d81612387565b6040805160008082526020820190925261098991839190612400565b50565b6000805160206142918339815191526109a361232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b1580156109f857600080fd5b505afa158015610a0c573d6000803e3d6000fd5b50506101008054851515820261ff001990911617905550506040517f404eef42c444205f06ce56f8872275ef40b7785e208692ca5be199df99b1bfe0906108af90841515815260200190565b600080516020614291833981519152610a6f61232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b158015610ac457600080fd5b505afa158015610ad8573d6000803e3d6000fd5b50505050610ae58261256b565b5050565b600054610100900460ff1615808015610b095750600054600160ff909116105b80610b235750303b158015610b23575060005460ff166001145b610b865760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610903565b6000805460ff191660011790558015610ba9576000805461ff0019166101001790555b610bb16125d9565b610bba83612602565b610bc382612632565b610c0a6040518060400160405280600b81526020016a47656e6573697353616c6560a81b81525060405180604001604052806002815260200161563160f01b8152506126a0565b8015610706576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b600080516020614291833981519152610c6b61232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b158015610cc057600080fd5b505afa158015610cd4573d6000803e3d6000fd5b5085925060009150505b81811015610d3c578360ff6000888885818110610cfd57610cfd613ea4565b90506020020135815260200190815260200160002060006101000a81548160ff0219169083151502179055508080610d3490613ed0565b915050610cde565b507f8ef0446324837e5426e8f0377caef5207fb6d6038e6d49d2b243c66769995cff858585604051610d7093929190613ee9565b60405180910390a15050505050565b6101005460ff16610dd25760405162461bcd60e51b815260206004820152601860248201527f4c6f6f74706f642073616c65206e6f7420656e61626c656400000000000000006044820152606401610903565b848314610e215760405162461bcd60e51b815260206004820152601960248201527f696e76616c696420706172616d6574657273206c656e677468000000000000006044820152606401610903565b8460005b81811015611132576000888883818110610e4157610e41613ea4565b9050602002013590506000878784818110610e5e57610e5e613ea4565b60209081029290920135600081815260fe9093526040909220549192505060ff1615610ec35760405162461bcd60e51b815260206004820152601460248201527310995b1d08185b1c9958591e4818db185a5b595960621b6044820152606401610903565b600082815260ff602081905260409091205416610f1a5760405162461bcd60e51b81526020600482015260156024820152744974656d206973206e6f7420636c61696d61626c6560581b6044820152606401610903565b604080517f608c225644debd22bef24a74f42af7b8d92fb931cb66c105e1aa304bca6fdcfe6020820152339181019190915260608101829052600090610f7890608001604051602081830303815290604052805190602001206126d1565b90506000610fde82898988818110610f9257610f92613ea4565b9050602002810190610fa49190613f27565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061271f92505050565b9050610fe861232f565b604051632474521560e21b81527fd9b7bfff425ebe71c13e899500acb373e0f7bdf204974be3d97a691fece7351b60048201526001600160a01b03838116602483015291909116906391d1485490604401602060405180830381865afa158015611056573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107a9190613f6e565b6110ba5760405162461bcd60e51b8152602060048201526011602482015270496e76616c6964207369676e617475726560781b6044820152606401610903565b600083815260fe60209081526040808320805460ff191660011790558051878152918201869052339082015260608101919091527f1117f8770e2aa7674429688435f29ac4abc16c8c06255d27b16307e5775e47119060800160405180910390a150505050808061112a90613ed0565b915050610e25565b5050505050505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036111845760405162461bcd60e51b815260040161090390613e0c565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166111b6612371565b6001600160a01b0316146111dc5760405162461bcd60e51b815260040161090390613e58565b6111e582612387565b610ae582826001612400565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146112915760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610903565b506000805160206142b183398151915290565b6000805160206142918339815191526112bb61232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b15801561131057600080fd5b505afa158015611324573d6000803e3d6000fd5b5050506001600160a01b039092166000908152610103602052604090204290555050565b60006107f4612743565b60008051602061429183398151915261136961232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b1580156113be57600080fd5b505afa1580156113d2573d6000803e3d6000fd5b50505050610ae582612632565b6000805160206142918339815191526113f661232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b15801561144b57600080fd5b505afa15801561145f573d6000803e3d6000fd5b50505050610ae5826127c3565b60008051602061429183398151915261148361232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b1580156114d857600080fd5b505afa1580156114ec573d6000803e3d6000fd5b5050610100805460ff19168515159081179091556040519081527f069bb4dc6c4d8bf8cf7d51d8a89a63e1736a0636c1c0141a74130af93b8083a9925060200190506108af565b60008051602061429183398151915261154a61232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b15801561159f57600080fd5b505afa1580156115b3573d6000803e3d6000fd5b505050600086815260fd60209081526040918290206001810188905586815560020180546001600160a01b0319166001600160a01b038716908117909155825189815291820187905291810187905260608101919091527f7215058c17123344067beaefa49b02a046f6bf181d953e7a53c063cf8cd7f7e49150608001610d70565b61163d61232f565b6001600160a01b03166312d9a6ad6000336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b15801561169357600080fd5b505afa1580156116a7573d6000803e3d6000fd5b5050505061098981612831565b6000805160206142918339815191526116cb61232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b15801561172057600080fd5b505afa158015611734573d6000803e3d6000fd5b505050610102839055506040518281527faf4f803c8a8c9e52547c2ef4a4f56fd34c3b7c188c8a60b9e84b868f16b8fa87906020016108af565b60006107e482612941565b60006107f46129c1565b60008051602061429183398151915261179a61232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b1580156117ef57600080fd5b505afa158015611803573d6000803e3d6000fd5b505050600083815260fd60205260408082208281556001810192909255600290910180546001600160a01b0319169055517fe2a3f0357b0d99e00c1a37b07b32568f2b89ff1cc900f08006835a663ba91c2e91506108af9084815260200190565b8382146118835760405162461bcd60e51b815260040161090390613f8b565b60008490036118a45760405162461bcd60e51b815260040161090390613f8b565b6101005460ff166118ea5760405162461bcd60e51b815260206004820152601060248201526f14d85b19481b9bdd08195b98589b195960821b6044820152606401610903565b60008481805b828110156119dc57600060fd60008b8b8581811061191057611910613ea4565b90506020020135815260200190815260200160002060010154116119465760405162461bcd60e51b815260040161090390613fb3565b86868281811061195857611958613ea4565b9050602002013560fd60008b8b8581811061197557611975613ea4565b905060200201358152602001908152602001600020600101546119989190613fe2565b6119a29085613ff9565b93508686828181106119b6576119b6613ea4565b90506020020135826119c89190613ff9565b9150806119d481613ed0565b9150506118f0565b50611a0a837f53493370b49bd36e0cf5c523d80e01079b16a5bec9214eb451f6eb45641692df8660006129e9565b60008167ffffffffffffffff811115611a2557611a25613b9c565b604051908082528060200260200182016040528015611a4e578160200160208202803683370190505b50905060005b83811015611ba357611a64612ff3565b6001600160a01b0316638b394ad4338c8c85818110611a8557611a85613ea4565b905060200201358b8b86818110611a9e57611a9e613ea4565b6040516001600160e01b031960e088901b1681526001600160a01b039095166004860152602485019390935250602090910201356044820152606401600060405180830381600087803b158015611af457600080fd5b505af1158015611b08573d6000803e3d6000fd5b505050507ff7edfdcea1e97865d938e0392e5eee3c3c9212f358fa65c204256be46d9efa7e8a8a83818110611b3f57611b3f613ea4565b90506020020135338a8a85818110611b5957611b59613ea4565b90506020020135604051611b89939291909283526001600160a01b03919091166020830152604082015260600190565b60405180910390a180611b9b81613ed0565b915050611a54565b50505050505050505050565b60008084815b81811015611c7b57600060fd60008a8a85818110611bd557611bd5613ea4565b9050602002013581526020019081526020016000206001015411611c0b5760405162461bcd60e51b815260040161090390613fb3565b858582818110611c1d57611c1d613ea4565b9050602002013560fd60008a8a85818110611c3a57611c3a613ea4565b90506020020135815260200190815260200160002060010154611c5d9190613fe2565b611c679084613ff9565b925080611c7381613ed0565b915050611bb5565b50909695505050505050565b600080516020614291833981519152611c9e61232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b158015611cf357600080fd5b505afa158015611d07573d6000803e3d6000fd5b50505050610ae58261306e565b838214611d335760405162461bcd60e51b815260040161090390613f8b565b6000849003611d545760405162461bcd60e51b815260040161090390613f8b565b6101005460ff16611d9a5760405162461bcd60e51b815260206004820152601060248201526f14d85b19481b9bdd08195b98589b195960821b6044820152606401610903565b82826000818110611dad57611dad613ea4565b90506020020135600114611e035760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c792031206c6f6f74706f642063616e20626520626f75676874000000006044820152606401610903565b60018214611e535760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c792031206c6f6f74706f642063616e20626520626f75676874000000006044820152606401610903565b33600090815261010360205260409020544211611ed85760405162461bcd60e51b815260206004820152603d60248201527f43616e6e6f7420627579207573696e6720746f6b656e732c207761697420666f60448201527f7220736f6d652074696d6520746f20707572636861736520616761696e0000006064820152608401610903565b60008481805b82811015611fca57600060fd60008b8b85818110611efe57611efe613ea4565b9050602002013581526020019081526020016000206000015411611f345760405162461bcd60e51b815260040161090390613fb3565b868682818110611f4657611f46613ea4565b9050602002013560fd60008b8b85818110611f6357611f63613ea4565b90506020020135815260200190815260200160002060000154611f869190613fe2565b611f909085613ff9565b9350868682818110611fa457611fa4613ea4565b9050602002013582611fb69190613ff9565b915080611fc281613ed0565b915050611ede565b50612033837f53493370b49bd36e0cf5c523d80e01079b16a5bec9214eb451f6eb45641692df8660fd60008d8d600081811061200857612008613ea4565b60209081029290920135835250810191909152604001600020600201546001600160a01b03166129e9565b610102546120419042613ff9565b33600090815261010360205260408120919091558167ffffffffffffffff81111561206e5761206e613b9c565b604051908082528060200260200182016040528015612097578160200160208202803683370190505b50905060005b83811015611ba3577f278584b9bf84c7beecbe370cb3512b6e21f0fc071872e3a56d11f385978757308a8a838181106120d8576120d8613ea4565b90506020020135338a8a858181106120f2576120f2613ea4565b9050602002013560fd60008f8f600081811061211057612110613ea4565b602090810292909201358352508181019290925260409081016000206002015481519586526001600160a01b039485169286019290925284019190915216606082015260800160405180910390a18061216881613ed0565b91505061209d565b61219d6040518060600160405280600081526020016000815260200160006001600160a01b031681525090565b50600090815260fd6020908152604091829020825160608101845281548152600182015492810192909252600201546001600160a01b03169181019190915290565b60006107f46130dc565b60006107f4612ff3565b61010080540460ff166122485760405162461bcd60e51b815260206004820152601b60248201527f536f756c20426f756e642073616c65206e6f7420656e61626c656400000000006044820152606401610903565b612278610101547fab8a4f513e6a481f3215fb978a0f924f181acdf5128ea12a9606ddb771cc8f498360006129e9565b612280612743565b6040516330c5170360e21b8152336004820152600160248201526001600160a01b03919091169063c3145c0c90604401600060405180830381600087803b1580156122ca57600080fd5b505af11580156122de573d6000803e3d6000fd5b505060408051338152600160208201527f1446213f6d0d6629c8891e1ebfa20ac35daf9feeedfde363d7226a363b1ab13493500190505b60405180910390a150565b6001600160a01b03163b151590565b600061236261235f60017f2f94117d2c26dd889e3bde9cad610be6ea59faa34cc016c7267596f75c87e37661400c565b90565b546001600160a01b0316919050565b60006000805160206142b1833981519152612362565b61238f61232f565b6001600160a01b03166312d9a6ad6000336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b1580156123e557600080fd5b505afa1580156123f9573d6000803e3d6000fd5b5050505050565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156124335761070683613157565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561248d575060408051601f3d908101601f1916820190925261248a9181019061401f565b60015b6124f05760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610903565b6000805160206142b1833981519152811461255f5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610903565b506107068383836131f3565b807f9e7ed7f8e6dcd193d98e2fd5ebd44790ad3072ac13a6c8399c17d661a1faa4bd80546001600160a01b0319166001600160a01b0392831617905560405190821681527fdc80e5c99445c4b953979db282beb930a03398b133c8702956af485b76ebe8e190602001612315565b600054610100900460ff166126005760405162461bcd60e51b815260040161090390614038565b565b600054610100900460ff166126295760405162461bcd60e51b815260040161090390614038565b61098981612831565b807f23c14fceac7676b670aa56866076586ea1ce15ddcf19208ec6346cf748dffbee80546001600160a01b0319166001600160a01b0392831617905560405190821681527fe7ae49f883c825b05681b3e00e8be6fdea9ed2a8a45e4c6ecb9390fc44cce61590602001612315565b600054610100900460ff166126c75760405162461bcd60e51b815260040161090390614038565b610ae5828261321e565b60006107e46126de61325f565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b600080600061272e8585613296565b9150915061273b81613304565b509392505050565b7f9e7ed7f8e6dcd193d98e2fd5ebd44790ad3072ac13a6c8399c17d661a1faa4bd546000906001600160a01b0316806127be5760405162461bcd60e51b815260206004820152601a60248201527f536f756c426f756e6420636f6e7472616374206e6f74207365740000000000006044820152606401610903565b919050565b807f11638ba6e1563078b2a29922612cadeb254e197f0e8a708c5e69a2c8091a1ae380546001600160a01b0319166001600160a01b0392831617905560405190821681527fc97c95bbbb76c791f0fcd4e4fe4fb58c666fa8f43231a02d0cdc514f2a205b7890602001612315565b6040516301ffc9a760e01b815263d432a77560e01b60048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa15801561287c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128a09190613f6e565b6128c8576040516320d2869360e11b81526001600160a01b0382166004820152602401610903565b806128f761235f60017f2f94117d2c26dd889e3bde9cad610be6ea59faa34cc016c7267596f75c87e37661400c565b80546001600160a01b0319166001600160a01b03928316179055604051908216907fb682c047807b0e34dd5e7ec89aa8d43386ff4e25dbd12c98e2fbfd44b99936f990600090a250565b60008061294c612743565b6040516370a0823160e01b81526001600160a01b03858116600483015291909116906370a0823190602401602060405180830381865afa158015612994573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129b8919061401f565b15159392505050565b60007f23c14fceac7676b670aa56866076586ea1ce15ddcf19208ec6346cf748dffbee612362565b60006129f4336134ba565b90508015612e47576000612a066130dc565b6001600160a01b0316639283ae3a866040518263ffffffff1660e01b8152600401612a3391815260200190565b60a060405180830381865afa158015612a50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a749190614095565b90506000612a806130dc565b6040516314e6216b60e31b81523360048201526001600160a01b03919091169063a7310b589060240160a060405180830381865afa158015612ac6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aea91906140fe565b9050612af585613530565b6020820151815115612b08575060808201515b6000612b148983613609565b612b1e908a61400c565b90506000612b3f8286606001518760400151612b3a9190614163565b613609565b90506001600160a01b038716612cec57813414612ba85760405162461bcd60e51b815260206004820152602160248201527f496e76616c696420646973636f756e7465642076616c75652070726f766964656044820152601960fa1b6064820152608401610903565b600080612bb36129c1565b6001600160a01b0316612bc6848661400c565b604051600081818185875af1925050503d8060008114612c02576040519150601f19603f3d011682016040523d82523d6000602084013e612c07565b606091505b509150915081612c595760405162461bcd60e51b815260206004820152601d60248201527f4661696c656420746f2073656e642066756e647320746f207661756c740000006044820152606401610903565b612c616130dc565b6001600160a01b0316632779258384868e8a60000151612c81578e612c87565b8a602001515b6040516001600160e01b031960e087901b1681526004810193909352602483019190915260448201526064016000604051808303818588803b158015612ccc57600080fd5b505af1158015612ce0573d6000803e3d6000fd5b50505050505050612e3d565b866001600160a01b03166323b872dd33612d046129c1565b612d0e858761400c565b6040516001600160e01b031960e086901b1681526001600160a01b03938416600482015292909116602483015260448201526064016020604051808303816000875af1158015612d62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d869190613f6e565b612da25760405162461bcd60e51b815260040161090390614185565b612daa6130dc565b6001600160a01b031663a7881053838b8760000151612dc9578b612dcf565b87602001515b6040516001600160e01b031960e086901b1681526004810193909352602483019190915260448201526001600160a01b038a166064820152608401600060405180830381600087803b158015612e2457600080fd5b505af1158015612e38573d6000803e3d6000fd5b505050505b50505050506123f9565b6001600160a01b038216612f4757843414612e9d5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d985b1d59481c1c9bdd9a59195960521b6044820152606401610903565b600080612ea86129c1565b6001600160a01b03163460405160006040518083038185875af1925050503d8060008114612ef2576040519150601f19603f3d011682016040523d82523d6000602084013e612ef7565b606091505b509150915081612f405760405162461bcd60e51b81526020600482015260146024820152734661696c656420746f2073656e642066756e647360601b6044820152606401610903565b50506123f9565b816001600160a01b03166323b872dd33612f5f6129c1565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604481018890526064016020604051808303816000875af1158015612fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd79190613f6e565b6123f95760405162461bcd60e51b815260040161090390614185565b7f9a004a100fc3d4a01d976e5a71581546937a4d363ba890e0031e799b616714ec546000906001600160a01b0316806127be5760405162461bcd60e51b815260206004820152601a60248201527f5a6565204974656d7320636f6e7472616374206e6f74207365740000000000006044820152606401610903565b807f9a004a100fc3d4a01d976e5a71581546937a4d363ba890e0031e799b616714ec80546001600160a01b0319166001600160a01b0392831617905560405190821681527fc5ea82483f6885918abaa0d3f55638f577f3a9ec2e50879dc57550552ce1c31690602001612315565b7f11638ba6e1563078b2a29922612cadeb254e197f0e8a708c5e69a2c8091a1ae3546000906001600160a01b0316806127be5760405162461bcd60e51b815260206004820152601960248201527f566f75636865727320636f6e7472616374206e6f7420736574000000000000006044820152606401610903565b6001600160a01b0381163b6131c45760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610903565b6000805160206142b183398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6131fc836136b0565b6000825111806132095750805b156107065761321883836136f0565b50505050565b600054610100900460ff166132455760405162461bcd60e51b815260040161090390614038565b815160209283012081519190920120606591909155606655565b60006107f47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61328e60655490565b6066546137e4565b60008082516041036132cc5760208301516040840151606085015160001a6132c08782858561382e565b945094505050506132fd565b82516040036132f557602083015160408401516132ea86838361391b565b9350935050506132fd565b506000905060025b9250929050565b6000816004811115613318576133186141c8565b036133205750565b6001816004811115613334576133346141c8565b036133815760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610903565b6002816004811115613395576133956141c8565b036133e25760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610903565b60038160048111156133f6576133f66141c8565b0361344e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610903565b6004816004811115613462576134626141c8565b036109895760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610903565b60006134c46130dc565b6040516370a0823160e01b81526001600160a01b03848116600483015291909116906370a0823190602401602060405180830381865afa15801561350c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e4919061401f565b336135396130dc565b6001600160a01b0316636352211e836040518263ffffffff1660e01b815260040161356691815260200190565b602060405180830381865afa158015613583573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135a791906141de565b6001600160a01b0316146109895760405162461bcd60e51b8152602060048201526024808201527f596f7520617265206e6f7420616e206f776e6572206f66207468697320766f7560448201526331b432b960e11b6064820152608401610903565b6000808261ffff16118061362357506127108261ffff1611155b156136a95761271061363961ffff841685613fe2565b10156136875760405162461bcd60e51b815260206004820152601d60248201527f70657263656e746167652063616c63756c6174696f6e206661696c65640000006044820152606401610903565b61271061369861ffff841685613fe2565b6136a291906141fb565b90506107e4565b5090919050565b6136b981613157565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6137585760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610903565b600080846001600160a01b0316846040516137739190614241565b600060405180830381855af49150503d80600081146137ae576040519150601f19603f3d011682016040523d82523d6000602084013e6137b3565b606091505b50915091506137db82826040518060600160405280602781526020016142d160279139613954565b95945050505050565b6040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090505b9392505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156138655750600090506003613912565b8460ff16601b1415801561387d57508460ff16601c14155b1561388e5750600090506004613912565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156138e2573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661390b57600060019250925050613912565b9150600090505b94509492505050565b6000806001600160ff1b0383168161393860ff86901c601b613ff9565b90506139468782888561382e565b935093505050935093915050565b60608315613963575081613827565b8251156139735782518084602001fd5b8160405162461bcd60e51b8152600401610903919061425d565b60006020828403121561399f57600080fd5b81356001600160e01b03198116811461382757600080fd5b6001600160a01b038116811461098957600080fd5b6000602082840312156139de57600080fd5b8135613827816139b7565b6000602082840312156139fb57600080fd5b5035919050565b801515811461098957600080fd5b600060208284031215613a2257600080fd5b813561382781613a02565b60008060408385031215613a4057600080fd5b8235613a4b816139b7565b91506020830135613a5b816139b7565b809150509250929050565b60008083601f840112613a7857600080fd5b50813567ffffffffffffffff811115613a9057600080fd5b6020830191508360208260051b85010111156132fd57600080fd5b600080600060408486031215613ac057600080fd5b833567ffffffffffffffff811115613ad757600080fd5b613ae386828701613a66565b9094509250506020840135613af781613a02565b809150509250925092565b60008060008060008060608789031215613b1b57600080fd5b863567ffffffffffffffff80821115613b3357600080fd5b613b3f8a838b01613a66565b90985096506020890135915080821115613b5857600080fd5b613b648a838b01613a66565b90965094506040890135915080821115613b7d57600080fd5b50613b8a89828a01613a66565b979a9699509497509295939492505050565b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715613bd557613bd5613b9c565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715613c0457613c04613b9c565b604052919050565b60008060408385031215613c1f57600080fd5b8235613c2a816139b7565b915060208381013567ffffffffffffffff80821115613c4857600080fd5b818601915086601f830112613c5c57600080fd5b813581811115613c6e57613c6e613b9c565b613c80601f8201601f19168501613bdb565b91508082528784828501011115613c9657600080fd5b80848401858401376000848284010152508093505050509250929050565b60008060008060808587031215613cca57600080fd5b8435935060208501359250604085013591506060850135613cea816139b7565b939692955090935050565b600080600080600060608688031215613d0d57600080fd5b853567ffffffffffffffff80821115613d2557600080fd5b613d3189838a01613a66565b90975095506020880135915080821115613d4a57600080fd5b50613d5788828901613a66565b96999598509660400135949350505050565b60008060008060408587031215613d7f57600080fd5b843567ffffffffffffffff80821115613d9757600080fd5b613da388838901613a66565b90965094506020870135915080821115613dbc57600080fd5b50613dc987828801613a66565b95989497509550505050565b600080600060608486031215613dea57600080fd5b833592506020840135613dfc816139b7565b91506040840135613af7816139b7565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201613ee257613ee2613eba565b5060010190565b6040808252810183905260006001600160fb1b03841115613f0957600080fd5b8360051b808660608501379215156020830152500160600192915050565b6000808335601e19843603018112613f3e57600080fd5b83018035915067ffffffffffffffff821115613f5957600080fd5b6020019150368190038213156132fd57600080fd5b600060208284031215613f8057600080fd5b815161382781613a02565b6020808252600e908201526d092dcecc2d8d2c840d8cadccee8d60931b604082015260600190565b6020808252601590820152744e6f2070726963652073657420666f72206974656d60581b604082015260600190565b80820281158282048414176107e4576107e4613eba565b808201808211156107e4576107e4613eba565b818103818111156107e4576107e4613eba565b60006020828403121561403157600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b805161ffff811681146127be57600080fd5b600060a082840312156140a757600080fd5b6140af613bb2565b825181526140bf60208401614083565b60208201526140d060408401614083565b60408201526140e160608401614083565b60608201526140f260808401614083565b60808201529392505050565b600060a0828403121561411057600080fd5b614118613bb2565b825161412381613a02565b815260208381015190820152604083015161413d816139b7565b60408201526060830151614150816139b7565b606082015260808301516140f2816139b7565b61ffff81811683821601908082111561417e5761417e613eba565b5092915050565b60208082526023908201527f4661696c656420746f2073656e642045524332302066756e647320746f2076616040820152621d5b1d60ea1b606082015260800190565b634e487b7160e01b600052602160045260246000fd5b6000602082840312156141f057600080fd5b8151613827816139b7565b60008261421857634e487b7160e01b600052601260045260246000fd5b500490565b60005b83811015614238578181015183820152602001614220565b50506000910152565b6000825161425381846020870161421d565b9190910192915050565b602081526000825180602084015261427c81604085016020870161421d565b601f01601f1916919091016040019291505056fe27a0624e64a794e52337524177801654db9a21fcd4c18d902036cf6ff01b0159360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220dde0bc999764264da12da19b1779c2ae5facfdc8a7db5d32cb940ab8a6e58ea164736f6c63430008110033
Deployed Bytecode
0x6080604052600436106102465760003560e01c80636f0eb78211610139578063a222ef1c116100b6578063c225db0c1161007a578063c225db0c146106eb578063d64a13b21461070b578063e75722301461072b578063e7675f3c14610776578063efd148d91461078b578063fa3b703d146107a057600080fd5b8063a222ef1c14610649578063ad1751fb1461065c578063ad85d1651461067c578063b1cf9fe614610697578063c11c7d5e146106b757600080fd5b80637c56687a116100fd5780637c56687a146105a05780637d3142c2146105c05780638d928af8146105e05780639cd0726a146105f5578063a1ebf35d1461061557600080fd5b80636f0eb782146104fe578063701eb1d51461051e57806374d3578a1461053e57806375b238fc1461055e57806376aad6051461058057600080fd5b8063485cc955116101c757806352d1902d1161018b57806352d1902d1461047e57806359facd4014610493578063647a9b57146104b357806366822364146104c85780636817031b146104de57600080fd5b8063485cc955146103f25780634c10e340146104125780634cd30fb0146104325780634ec424c81461044b5780634f1ef2861461046b57600080fd5b8063319333161161020e578063319333161461032a5780633659cfe61461035e5780633b1c85c51461037e5780633d00eae6146103b257806343110989146103d257600080fd5b806301ffc9a71461024b578063087376951461028057806309345900146102ad5780630e7e2143146102f25780631b6a7ada14610308575b600080fd5b34801561025757600080fd5b5061026b61026636600461398d565b6107b3565b60405190151581526020015b60405180910390f35b34801561028c57600080fd5b506102956107ea565b6040516001600160a01b039091168152602001610277565b3480156102b957600080fd5b506102e46102c83660046139cc565b6001600160a01b03166000908152610103602052604090205490565b604051908152602001610277565b3480156102fe57600080fd5b50610102546102e4565b34801561031457600080fd5b506103286103233660046139e9565b6107f9565b005b34801561033657600080fd5b506102e47f53493370b49bd36e0cf5c523d80e01079b16a5bec9214eb451f6eb45641692df81565b34801561036a57600080fd5b506103286103793660046139cc565b6108bb565b34801561038a57600080fd5b506102e47fab8a4f513e6a481f3215fb978a0f924f181acdf5128ea12a9606ddb771cc8f4981565b3480156103be57600080fd5b506103286103cd366004613a10565b61098c565b3480156103de57600080fd5b506103286103ed3660046139cc565b610a58565b3480156103fe57600080fd5b5061032861040d366004613a2d565b610ae9565b34801561041e57600080fd5b5061032861042d366004613aab565b610c54565b34801561043e57600080fd5b506101005460ff1661026b565b34801561045757600080fd5b50610328610466366004613b02565b610d7f565b610328610479366004613c0c565b61113c565b34801561048a57600080fd5b506102e46111f1565b34801561049f57600080fd5b506103286104ae3660046139cc565b6112a4565b3480156104bf57600080fd5b50610295611348565b3480156104d457600080fd5b50610101546102e4565b3480156104ea57600080fd5b506103286104f93660046139cc565b611352565b34801561050a57600080fd5b506103286105193660046139cc565b6113df565b34801561052a57600080fd5b50610328610539366004613a10565b61146c565b34801561054a57600080fd5b50610328610559366004613cb4565b611533565b34801561056a57600080fd5b506102e460008051602061429183398151915281565b34801561058c57600080fd5b5061032861059b3660046139cc565b611635565b3480156105ac57600080fd5b506103286105bb3660046139e9565b6116b4565b3480156105cc57600080fd5b5061026b6105db3660046139cc565b61176e565b3480156105ec57600080fd5b50610295611779565b34801561060157600080fd5b506103286106103660046139e9565b611783565b34801561062157600080fd5b506102e47fd9b7bfff425ebe71c13e899500acb373e0f7bdf204974be3d97a691fece7351b81565b610328610657366004613cf5565b611864565b34801561066857600080fd5b506102e4610677366004613d69565b611baf565b34801561068857600080fd5b5061010080540460ff1661026b565b3480156106a357600080fd5b506103286106b23660046139cc565b611c87565b3480156106c357600080fd5b506102e47f608c225644debd22bef24a74f42af7b8d92fb931cb66c105e1aa304bca6fdcfe81565b3480156106f757600080fd5b50610328610706366004613dd5565b505050565b34801561071757600080fd5b50610328610726366004613cf5565b611d14565b34801561073757600080fd5b5061074b6107463660046139e9565b612170565b604080518251815260208084015190820152918101516001600160a01b031690820152606001610277565b34801561078257600080fd5b506102956121df565b34801561079757600080fd5b506102956121e9565b6103286107ae3660046139e9565b6121f3565b60006001600160e01b031982166307ed9a0960e41b14806107e457506301ffc9a760e01b6001600160e01b03198316145b92915050565b60006107f461232f565b905090565b60008051602061429183398151915261081061232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b15801561086557600080fd5b505afa158015610879573d6000803e3d6000fd5b505050610101839055506040518281527f5f600a3bbf106c270c7e13f3d2fa7ed1f9f75d5f243620b850c6785cacd50b8b906020015b60405180910390a15050565b6001600160a01b037f00000000000000000000000026c9007a2612644fb7f7e6d98a860d3f75128e6a16300361090c5760405162461bcd60e51b815260040161090390613e0c565b60405180910390fd5b7f00000000000000000000000026c9007a2612644fb7f7e6d98a860d3f75128e6a6001600160a01b031661093e612371565b6001600160a01b0316146109645760405162461bcd60e51b815260040161090390613e58565b61096d81612387565b6040805160008082526020820190925261098991839190612400565b50565b6000805160206142918339815191526109a361232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b1580156109f857600080fd5b505afa158015610a0c573d6000803e3d6000fd5b50506101008054851515820261ff001990911617905550506040517f404eef42c444205f06ce56f8872275ef40b7785e208692ca5be199df99b1bfe0906108af90841515815260200190565b600080516020614291833981519152610a6f61232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b158015610ac457600080fd5b505afa158015610ad8573d6000803e3d6000fd5b50505050610ae58261256b565b5050565b600054610100900460ff1615808015610b095750600054600160ff909116105b80610b235750303b158015610b23575060005460ff166001145b610b865760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610903565b6000805460ff191660011790558015610ba9576000805461ff0019166101001790555b610bb16125d9565b610bba83612602565b610bc382612632565b610c0a6040518060400160405280600b81526020016a47656e6573697353616c6560a81b81525060405180604001604052806002815260200161563160f01b8152506126a0565b8015610706576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b600080516020614291833981519152610c6b61232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b158015610cc057600080fd5b505afa158015610cd4573d6000803e3d6000fd5b5085925060009150505b81811015610d3c578360ff6000888885818110610cfd57610cfd613ea4565b90506020020135815260200190815260200160002060006101000a81548160ff0219169083151502179055508080610d3490613ed0565b915050610cde565b507f8ef0446324837e5426e8f0377caef5207fb6d6038e6d49d2b243c66769995cff858585604051610d7093929190613ee9565b60405180910390a15050505050565b6101005460ff16610dd25760405162461bcd60e51b815260206004820152601860248201527f4c6f6f74706f642073616c65206e6f7420656e61626c656400000000000000006044820152606401610903565b848314610e215760405162461bcd60e51b815260206004820152601960248201527f696e76616c696420706172616d6574657273206c656e677468000000000000006044820152606401610903565b8460005b81811015611132576000888883818110610e4157610e41613ea4565b9050602002013590506000878784818110610e5e57610e5e613ea4565b60209081029290920135600081815260fe9093526040909220549192505060ff1615610ec35760405162461bcd60e51b815260206004820152601460248201527310995b1d08185b1c9958591e4818db185a5b595960621b6044820152606401610903565b600082815260ff602081905260409091205416610f1a5760405162461bcd60e51b81526020600482015260156024820152744974656d206973206e6f7420636c61696d61626c6560581b6044820152606401610903565b604080517f608c225644debd22bef24a74f42af7b8d92fb931cb66c105e1aa304bca6fdcfe6020820152339181019190915260608101829052600090610f7890608001604051602081830303815290604052805190602001206126d1565b90506000610fde82898988818110610f9257610f92613ea4565b9050602002810190610fa49190613f27565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061271f92505050565b9050610fe861232f565b604051632474521560e21b81527fd9b7bfff425ebe71c13e899500acb373e0f7bdf204974be3d97a691fece7351b60048201526001600160a01b03838116602483015291909116906391d1485490604401602060405180830381865afa158015611056573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107a9190613f6e565b6110ba5760405162461bcd60e51b8152602060048201526011602482015270496e76616c6964207369676e617475726560781b6044820152606401610903565b600083815260fe60209081526040808320805460ff191660011790558051878152918201869052339082015260608101919091527f1117f8770e2aa7674429688435f29ac4abc16c8c06255d27b16307e5775e47119060800160405180910390a150505050808061112a90613ed0565b915050610e25565b5050505050505050565b6001600160a01b037f00000000000000000000000026c9007a2612644fb7f7e6d98a860d3f75128e6a1630036111845760405162461bcd60e51b815260040161090390613e0c565b7f00000000000000000000000026c9007a2612644fb7f7e6d98a860d3f75128e6a6001600160a01b03166111b6612371565b6001600160a01b0316146111dc5760405162461bcd60e51b815260040161090390613e58565b6111e582612387565b610ae582826001612400565b6000306001600160a01b037f00000000000000000000000026c9007a2612644fb7f7e6d98a860d3f75128e6a16146112915760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610903565b506000805160206142b183398151915290565b6000805160206142918339815191526112bb61232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b15801561131057600080fd5b505afa158015611324573d6000803e3d6000fd5b5050506001600160a01b039092166000908152610103602052604090204290555050565b60006107f4612743565b60008051602061429183398151915261136961232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b1580156113be57600080fd5b505afa1580156113d2573d6000803e3d6000fd5b50505050610ae582612632565b6000805160206142918339815191526113f661232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b15801561144b57600080fd5b505afa15801561145f573d6000803e3d6000fd5b50505050610ae5826127c3565b60008051602061429183398151915261148361232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b1580156114d857600080fd5b505afa1580156114ec573d6000803e3d6000fd5b5050610100805460ff19168515159081179091556040519081527f069bb4dc6c4d8bf8cf7d51d8a89a63e1736a0636c1c0141a74130af93b8083a9925060200190506108af565b60008051602061429183398151915261154a61232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b15801561159f57600080fd5b505afa1580156115b3573d6000803e3d6000fd5b505050600086815260fd60209081526040918290206001810188905586815560020180546001600160a01b0319166001600160a01b038716908117909155825189815291820187905291810187905260608101919091527f7215058c17123344067beaefa49b02a046f6bf181d953e7a53c063cf8cd7f7e49150608001610d70565b61163d61232f565b6001600160a01b03166312d9a6ad6000336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b15801561169357600080fd5b505afa1580156116a7573d6000803e3d6000fd5b5050505061098981612831565b6000805160206142918339815191526116cb61232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b15801561172057600080fd5b505afa158015611734573d6000803e3d6000fd5b505050610102839055506040518281527faf4f803c8a8c9e52547c2ef4a4f56fd34c3b7c188c8a60b9e84b868f16b8fa87906020016108af565b60006107e482612941565b60006107f46129c1565b60008051602061429183398151915261179a61232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b1580156117ef57600080fd5b505afa158015611803573d6000803e3d6000fd5b505050600083815260fd60205260408082208281556001810192909255600290910180546001600160a01b0319169055517fe2a3f0357b0d99e00c1a37b07b32568f2b89ff1cc900f08006835a663ba91c2e91506108af9084815260200190565b8382146118835760405162461bcd60e51b815260040161090390613f8b565b60008490036118a45760405162461bcd60e51b815260040161090390613f8b565b6101005460ff166118ea5760405162461bcd60e51b815260206004820152601060248201526f14d85b19481b9bdd08195b98589b195960821b6044820152606401610903565b60008481805b828110156119dc57600060fd60008b8b8581811061191057611910613ea4565b90506020020135815260200190815260200160002060010154116119465760405162461bcd60e51b815260040161090390613fb3565b86868281811061195857611958613ea4565b9050602002013560fd60008b8b8581811061197557611975613ea4565b905060200201358152602001908152602001600020600101546119989190613fe2565b6119a29085613ff9565b93508686828181106119b6576119b6613ea4565b90506020020135826119c89190613ff9565b9150806119d481613ed0565b9150506118f0565b50611a0a837f53493370b49bd36e0cf5c523d80e01079b16a5bec9214eb451f6eb45641692df8660006129e9565b60008167ffffffffffffffff811115611a2557611a25613b9c565b604051908082528060200260200182016040528015611a4e578160200160208202803683370190505b50905060005b83811015611ba357611a64612ff3565b6001600160a01b0316638b394ad4338c8c85818110611a8557611a85613ea4565b905060200201358b8b86818110611a9e57611a9e613ea4565b6040516001600160e01b031960e088901b1681526001600160a01b039095166004860152602485019390935250602090910201356044820152606401600060405180830381600087803b158015611af457600080fd5b505af1158015611b08573d6000803e3d6000fd5b505050507ff7edfdcea1e97865d938e0392e5eee3c3c9212f358fa65c204256be46d9efa7e8a8a83818110611b3f57611b3f613ea4565b90506020020135338a8a85818110611b5957611b59613ea4565b90506020020135604051611b89939291909283526001600160a01b03919091166020830152604082015260600190565b60405180910390a180611b9b81613ed0565b915050611a54565b50505050505050505050565b60008084815b81811015611c7b57600060fd60008a8a85818110611bd557611bd5613ea4565b9050602002013581526020019081526020016000206001015411611c0b5760405162461bcd60e51b815260040161090390613fb3565b858582818110611c1d57611c1d613ea4565b9050602002013560fd60008a8a85818110611c3a57611c3a613ea4565b90506020020135815260200190815260200160002060010154611c5d9190613fe2565b611c679084613ff9565b925080611c7381613ed0565b915050611bb5565b50909695505050505050565b600080516020614291833981519152611c9e61232f565b6001600160a01b03166312d9a6ad82336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b158015611cf357600080fd5b505afa158015611d07573d6000803e3d6000fd5b50505050610ae58261306e565b838214611d335760405162461bcd60e51b815260040161090390613f8b565b6000849003611d545760405162461bcd60e51b815260040161090390613f8b565b6101005460ff16611d9a5760405162461bcd60e51b815260206004820152601060248201526f14d85b19481b9bdd08195b98589b195960821b6044820152606401610903565b82826000818110611dad57611dad613ea4565b90506020020135600114611e035760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c792031206c6f6f74706f642063616e20626520626f75676874000000006044820152606401610903565b60018214611e535760405162461bcd60e51b815260206004820152601c60248201527f4f6e6c792031206c6f6f74706f642063616e20626520626f75676874000000006044820152606401610903565b33600090815261010360205260409020544211611ed85760405162461bcd60e51b815260206004820152603d60248201527f43616e6e6f7420627579207573696e6720746f6b656e732c207761697420666f60448201527f7220736f6d652074696d6520746f20707572636861736520616761696e0000006064820152608401610903565b60008481805b82811015611fca57600060fd60008b8b85818110611efe57611efe613ea4565b9050602002013581526020019081526020016000206000015411611f345760405162461bcd60e51b815260040161090390613fb3565b868682818110611f4657611f46613ea4565b9050602002013560fd60008b8b85818110611f6357611f63613ea4565b90506020020135815260200190815260200160002060000154611f869190613fe2565b611f909085613ff9565b9350868682818110611fa457611fa4613ea4565b9050602002013582611fb69190613ff9565b915080611fc281613ed0565b915050611ede565b50612033837f53493370b49bd36e0cf5c523d80e01079b16a5bec9214eb451f6eb45641692df8660fd60008d8d600081811061200857612008613ea4565b60209081029290920135835250810191909152604001600020600201546001600160a01b03166129e9565b610102546120419042613ff9565b33600090815261010360205260408120919091558167ffffffffffffffff81111561206e5761206e613b9c565b604051908082528060200260200182016040528015612097578160200160208202803683370190505b50905060005b83811015611ba3577f278584b9bf84c7beecbe370cb3512b6e21f0fc071872e3a56d11f385978757308a8a838181106120d8576120d8613ea4565b90506020020135338a8a858181106120f2576120f2613ea4565b9050602002013560fd60008f8f600081811061211057612110613ea4565b602090810292909201358352508181019290925260409081016000206002015481519586526001600160a01b039485169286019290925284019190915216606082015260800160405180910390a18061216881613ed0565b91505061209d565b61219d6040518060600160405280600081526020016000815260200160006001600160a01b031681525090565b50600090815260fd6020908152604091829020825160608101845281548152600182015492810192909252600201546001600160a01b03169181019190915290565b60006107f46130dc565b60006107f4612ff3565b61010080540460ff166122485760405162461bcd60e51b815260206004820152601b60248201527f536f756c20426f756e642073616c65206e6f7420656e61626c656400000000006044820152606401610903565b612278610101547fab8a4f513e6a481f3215fb978a0f924f181acdf5128ea12a9606ddb771cc8f498360006129e9565b612280612743565b6040516330c5170360e21b8152336004820152600160248201526001600160a01b03919091169063c3145c0c90604401600060405180830381600087803b1580156122ca57600080fd5b505af11580156122de573d6000803e3d6000fd5b505060408051338152600160208201527f1446213f6d0d6629c8891e1ebfa20ac35daf9feeedfde363d7226a363b1ab13493500190505b60405180910390a150565b6001600160a01b03163b151590565b600061236261235f60017f2f94117d2c26dd889e3bde9cad610be6ea59faa34cc016c7267596f75c87e37661400c565b90565b546001600160a01b0316919050565b60006000805160206142b1833981519152612362565b61238f61232f565b6001600160a01b03166312d9a6ad6000336040516001600160e01b031960e085901b16815260048101929092526001600160a01b0316602482015260440160006040518083038186803b1580156123e557600080fd5b505afa1580156123f9573d6000803e3d6000fd5b5050505050565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156124335761070683613157565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561248d575060408051601f3d908101601f1916820190925261248a9181019061401f565b60015b6124f05760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610903565b6000805160206142b1833981519152811461255f5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610903565b506107068383836131f3565b807f9e7ed7f8e6dcd193d98e2fd5ebd44790ad3072ac13a6c8399c17d661a1faa4bd80546001600160a01b0319166001600160a01b0392831617905560405190821681527fdc80e5c99445c4b953979db282beb930a03398b133c8702956af485b76ebe8e190602001612315565b600054610100900460ff166126005760405162461bcd60e51b815260040161090390614038565b565b600054610100900460ff166126295760405162461bcd60e51b815260040161090390614038565b61098981612831565b807f23c14fceac7676b670aa56866076586ea1ce15ddcf19208ec6346cf748dffbee80546001600160a01b0319166001600160a01b0392831617905560405190821681527fe7ae49f883c825b05681b3e00e8be6fdea9ed2a8a45e4c6ecb9390fc44cce61590602001612315565b600054610100900460ff166126c75760405162461bcd60e51b815260040161090390614038565b610ae5828261321e565b60006107e46126de61325f565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b600080600061272e8585613296565b9150915061273b81613304565b509392505050565b7f9e7ed7f8e6dcd193d98e2fd5ebd44790ad3072ac13a6c8399c17d661a1faa4bd546000906001600160a01b0316806127be5760405162461bcd60e51b815260206004820152601a60248201527f536f756c426f756e6420636f6e7472616374206e6f74207365740000000000006044820152606401610903565b919050565b807f11638ba6e1563078b2a29922612cadeb254e197f0e8a708c5e69a2c8091a1ae380546001600160a01b0319166001600160a01b0392831617905560405190821681527fc97c95bbbb76c791f0fcd4e4fe4fb58c666fa8f43231a02d0cdc514f2a205b7890602001612315565b6040516301ffc9a760e01b815263d432a77560e01b60048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa15801561287c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128a09190613f6e565b6128c8576040516320d2869360e11b81526001600160a01b0382166004820152602401610903565b806128f761235f60017f2f94117d2c26dd889e3bde9cad610be6ea59faa34cc016c7267596f75c87e37661400c565b80546001600160a01b0319166001600160a01b03928316179055604051908216907fb682c047807b0e34dd5e7ec89aa8d43386ff4e25dbd12c98e2fbfd44b99936f990600090a250565b60008061294c612743565b6040516370a0823160e01b81526001600160a01b03858116600483015291909116906370a0823190602401602060405180830381865afa158015612994573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129b8919061401f565b15159392505050565b60007f23c14fceac7676b670aa56866076586ea1ce15ddcf19208ec6346cf748dffbee612362565b60006129f4336134ba565b90508015612e47576000612a066130dc565b6001600160a01b0316639283ae3a866040518263ffffffff1660e01b8152600401612a3391815260200190565b60a060405180830381865afa158015612a50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a749190614095565b90506000612a806130dc565b6040516314e6216b60e31b81523360048201526001600160a01b03919091169063a7310b589060240160a060405180830381865afa158015612ac6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aea91906140fe565b9050612af585613530565b6020820151815115612b08575060808201515b6000612b148983613609565b612b1e908a61400c565b90506000612b3f8286606001518760400151612b3a9190614163565b613609565b90506001600160a01b038716612cec57813414612ba85760405162461bcd60e51b815260206004820152602160248201527f496e76616c696420646973636f756e7465642076616c75652070726f766964656044820152601960fa1b6064820152608401610903565b600080612bb36129c1565b6001600160a01b0316612bc6848661400c565b604051600081818185875af1925050503d8060008114612c02576040519150601f19603f3d011682016040523d82523d6000602084013e612c07565b606091505b509150915081612c595760405162461bcd60e51b815260206004820152601d60248201527f4661696c656420746f2073656e642066756e647320746f207661756c740000006044820152606401610903565b612c616130dc565b6001600160a01b0316632779258384868e8a60000151612c81578e612c87565b8a602001515b6040516001600160e01b031960e087901b1681526004810193909352602483019190915260448201526064016000604051808303818588803b158015612ccc57600080fd5b505af1158015612ce0573d6000803e3d6000fd5b50505050505050612e3d565b866001600160a01b03166323b872dd33612d046129c1565b612d0e858761400c565b6040516001600160e01b031960e086901b1681526001600160a01b03938416600482015292909116602483015260448201526064016020604051808303816000875af1158015612d62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d869190613f6e565b612da25760405162461bcd60e51b815260040161090390614185565b612daa6130dc565b6001600160a01b031663a7881053838b8760000151612dc9578b612dcf565b87602001515b6040516001600160e01b031960e086901b1681526004810193909352602483019190915260448201526001600160a01b038a166064820152608401600060405180830381600087803b158015612e2457600080fd5b505af1158015612e38573d6000803e3d6000fd5b505050505b50505050506123f9565b6001600160a01b038216612f4757843414612e9d5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d985b1d59481c1c9bdd9a59195960521b6044820152606401610903565b600080612ea86129c1565b6001600160a01b03163460405160006040518083038185875af1925050503d8060008114612ef2576040519150601f19603f3d011682016040523d82523d6000602084013e612ef7565b606091505b509150915081612f405760405162461bcd60e51b81526020600482015260146024820152734661696c656420746f2073656e642066756e647360601b6044820152606401610903565b50506123f9565b816001600160a01b03166323b872dd33612f5f6129c1565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604481018890526064016020604051808303816000875af1158015612fb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd79190613f6e565b6123f95760405162461bcd60e51b815260040161090390614185565b7f9a004a100fc3d4a01d976e5a71581546937a4d363ba890e0031e799b616714ec546000906001600160a01b0316806127be5760405162461bcd60e51b815260206004820152601a60248201527f5a6565204974656d7320636f6e7472616374206e6f74207365740000000000006044820152606401610903565b807f9a004a100fc3d4a01d976e5a71581546937a4d363ba890e0031e799b616714ec80546001600160a01b0319166001600160a01b0392831617905560405190821681527fc5ea82483f6885918abaa0d3f55638f577f3a9ec2e50879dc57550552ce1c31690602001612315565b7f11638ba6e1563078b2a29922612cadeb254e197f0e8a708c5e69a2c8091a1ae3546000906001600160a01b0316806127be5760405162461bcd60e51b815260206004820152601960248201527f566f75636865727320636f6e7472616374206e6f7420736574000000000000006044820152606401610903565b6001600160a01b0381163b6131c45760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610903565b6000805160206142b183398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6131fc836136b0565b6000825111806132095750805b156107065761321883836136f0565b50505050565b600054610100900460ff166132455760405162461bcd60e51b815260040161090390614038565b815160209283012081519190920120606591909155606655565b60006107f47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61328e60655490565b6066546137e4565b60008082516041036132cc5760208301516040840151606085015160001a6132c08782858561382e565b945094505050506132fd565b82516040036132f557602083015160408401516132ea86838361391b565b9350935050506132fd565b506000905060025b9250929050565b6000816004811115613318576133186141c8565b036133205750565b6001816004811115613334576133346141c8565b036133815760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610903565b6002816004811115613395576133956141c8565b036133e25760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610903565b60038160048111156133f6576133f66141c8565b0361344e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610903565b6004816004811115613462576134626141c8565b036109895760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610903565b60006134c46130dc565b6040516370a0823160e01b81526001600160a01b03848116600483015291909116906370a0823190602401602060405180830381865afa15801561350c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e4919061401f565b336135396130dc565b6001600160a01b0316636352211e836040518263ffffffff1660e01b815260040161356691815260200190565b602060405180830381865afa158015613583573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135a791906141de565b6001600160a01b0316146109895760405162461bcd60e51b8152602060048201526024808201527f596f7520617265206e6f7420616e206f776e6572206f66207468697320766f7560448201526331b432b960e11b6064820152608401610903565b6000808261ffff16118061362357506127108261ffff1611155b156136a95761271061363961ffff841685613fe2565b10156136875760405162461bcd60e51b815260206004820152601d60248201527f70657263656e746167652063616c63756c6174696f6e206661696c65640000006044820152606401610903565b61271061369861ffff841685613fe2565b6136a291906141fb565b90506107e4565b5090919050565b6136b981613157565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6137585760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610903565b600080846001600160a01b0316846040516137739190614241565b600060405180830381855af49150503d80600081146137ae576040519150601f19603f3d011682016040523d82523d6000602084013e6137b3565b606091505b50915091506137db82826040518060600160405280602781526020016142d160279139613954565b95945050505050565b6040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090505b9392505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156138655750600090506003613912565b8460ff16601b1415801561387d57508460ff16601c14155b1561388e5750600090506004613912565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156138e2573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661390b57600060019250925050613912565b9150600090505b94509492505050565b6000806001600160ff1b0383168161393860ff86901c601b613ff9565b90506139468782888561382e565b935093505050935093915050565b60608315613963575081613827565b8251156139735782518084602001fd5b8160405162461bcd60e51b8152600401610903919061425d565b60006020828403121561399f57600080fd5b81356001600160e01b03198116811461382757600080fd5b6001600160a01b038116811461098957600080fd5b6000602082840312156139de57600080fd5b8135613827816139b7565b6000602082840312156139fb57600080fd5b5035919050565b801515811461098957600080fd5b600060208284031215613a2257600080fd5b813561382781613a02565b60008060408385031215613a4057600080fd5b8235613a4b816139b7565b91506020830135613a5b816139b7565b809150509250929050565b60008083601f840112613a7857600080fd5b50813567ffffffffffffffff811115613a9057600080fd5b6020830191508360208260051b85010111156132fd57600080fd5b600080600060408486031215613ac057600080fd5b833567ffffffffffffffff811115613ad757600080fd5b613ae386828701613a66565b9094509250506020840135613af781613a02565b809150509250925092565b60008060008060008060608789031215613b1b57600080fd5b863567ffffffffffffffff80821115613b3357600080fd5b613b3f8a838b01613a66565b90985096506020890135915080821115613b5857600080fd5b613b648a838b01613a66565b90965094506040890135915080821115613b7d57600080fd5b50613b8a89828a01613a66565b979a9699509497509295939492505050565b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715613bd557613bd5613b9c565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715613c0457613c04613b9c565b604052919050565b60008060408385031215613c1f57600080fd5b8235613c2a816139b7565b915060208381013567ffffffffffffffff80821115613c4857600080fd5b818601915086601f830112613c5c57600080fd5b813581811115613c6e57613c6e613b9c565b613c80601f8201601f19168501613bdb565b91508082528784828501011115613c9657600080fd5b80848401858401376000848284010152508093505050509250929050565b60008060008060808587031215613cca57600080fd5b8435935060208501359250604085013591506060850135613cea816139b7565b939692955090935050565b600080600080600060608688031215613d0d57600080fd5b853567ffffffffffffffff80821115613d2557600080fd5b613d3189838a01613a66565b90975095506020880135915080821115613d4a57600080fd5b50613d5788828901613a66565b96999598509660400135949350505050565b60008060008060408587031215613d7f57600080fd5b843567ffffffffffffffff80821115613d9757600080fd5b613da388838901613a66565b90965094506020870135915080821115613dbc57600080fd5b50613dc987828801613a66565b95989497509550505050565b600080600060608486031215613dea57600080fd5b833592506020840135613dfc816139b7565b91506040840135613af7816139b7565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201613ee257613ee2613eba565b5060010190565b6040808252810183905260006001600160fb1b03841115613f0957600080fd5b8360051b808660608501379215156020830152500160600192915050565b6000808335601e19843603018112613f3e57600080fd5b83018035915067ffffffffffffffff821115613f5957600080fd5b6020019150368190038213156132fd57600080fd5b600060208284031215613f8057600080fd5b815161382781613a02565b6020808252600e908201526d092dcecc2d8d2c840d8cadccee8d60931b604082015260600190565b6020808252601590820152744e6f2070726963652073657420666f72206974656d60581b604082015260600190565b80820281158282048414176107e4576107e4613eba565b808201808211156107e4576107e4613eba565b818103818111156107e4576107e4613eba565b60006020828403121561403157600080fd5b5051919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b805161ffff811681146127be57600080fd5b600060a082840312156140a757600080fd5b6140af613bb2565b825181526140bf60208401614083565b60208201526140d060408401614083565b60408201526140e160608401614083565b60608201526140f260808401614083565b60808201529392505050565b600060a0828403121561411057600080fd5b614118613bb2565b825161412381613a02565b815260208381015190820152604083015161413d816139b7565b60408201526060830151614150816139b7565b606082015260808301516140f2816139b7565b61ffff81811683821601908082111561417e5761417e613eba565b5092915050565b60208082526023908201527f4661696c656420746f2073656e642045524332302066756e647320746f2076616040820152621d5b1d60ea1b606082015260800190565b634e487b7160e01b600052602160045260246000fd5b6000602082840312156141f057600080fd5b8151613827816139b7565b60008261421857634e487b7160e01b600052601260045260246000fd5b500490565b60005b83811015614238578181015183820152602001614220565b50506000910152565b6000825161425381846020870161421d565b9190910192915050565b602081526000825180602084015261427c81604085016020870161421d565b601f01601f1916919091016040019291505056fe27a0624e64a794e52337524177801654db9a21fcd4c18d902036cf6ff01b0159360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220dde0bc999764264da12da19b1779c2ae5facfdc8a7db5d32cb940ab8a6e58ea164736f6c63430008110033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 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.