Source Code
Overview
GLMR Balance
GLMR Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 11095569 | 240 days ago | 0 GLMR | ||||
| 11095569 | 240 days ago | 0 GLMR | ||||
| 11095569 | 240 days ago | 0 GLMR | ||||
| 10782834 | 262 days ago | 0 GLMR | ||||
| 10782834 | 262 days ago | 0 GLMR | ||||
| 10782834 | 262 days ago | 0 GLMR | ||||
| 10782834 | 262 days ago | 0 GLMR | ||||
| 10782834 | 262 days ago | 0 GLMR | ||||
| 8939826 | 393 days ago | 0 GLMR | ||||
| 8939826 | 393 days ago | 0 GLMR | ||||
| 8939826 | 393 days ago | 0 GLMR | ||||
| 8939826 | 393 days ago | 0 GLMR | ||||
| 8939826 | 393 days ago | 0 GLMR | ||||
| 8939826 | 393 days ago | 0 GLMR | ||||
| 8939826 | 393 days ago | 0 GLMR | ||||
| 8939826 | 393 days ago | 0 GLMR | ||||
| 8939826 | 393 days ago | 0 GLMR | ||||
| 8939811 | 393 days ago | 0 GLMR | ||||
| 8939113 | 393 days ago | 0 GLMR | ||||
| 8939113 | 393 days ago | 0 GLMR | ||||
| 8939113 | 393 days ago | 0 GLMR | ||||
| 8939113 | 393 days ago | 0 GLMR | ||||
| 8939113 | 393 days ago | 0 GLMR | ||||
| 8939113 | 393 days ago | 0 GLMR | ||||
| 8939113 | 393 days ago | 0 GLMR |
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:
RMRKRegistry
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 1 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@rmrk-team/evm-contracts/contracts/RMRK/extension/soulbound/IERC6454.sol";
import "@rmrk-team/evm-contracts/contracts/RMRK/equippable/IERC6220.sol";
import "@rmrk-team/evm-contracts/contracts/RMRK/nestable/IERC7401.sol";
import "@rmrk-team/evm-contracts/contracts/RMRK/multiasset/IERC5773.sol";
import "../interfaces/IOwnable.sol";
import "../interfaces/IRMRKRegistry.sol";
import "../interfaces/IRMRKImplementationBase.sol";
import "../upgradeable/PausableUpgradeable.sol";
import "../upgradeable/OwnableUpgradeable.sol";
contract RMRKRegistry is
OwnableUpgradeable,
PausableUpgradeable,
UUPSUpgradeable,
IRMRKRegistry
{
uint256 public collectionVerificationFee;
uint256 public totalCollectionsCounter;
mapping(address => bool) public factories;
address[] public factoryList;
IERC20 public rmrkToken;
address private metaFactoryAddress;
Collection[] private _collections;
mapping(address => uint256) private _collectionByAddressIndex;
uint256 private _collectionsDepositBalance;
uint256 private _blacklistedCollectionsDepositBalance;
CollectionConfig private _defaultCollectionConfig;
CollectionConfig private _defaultCollectionConfigForExternalCollections;
uint8 public constant CUSTOM_MINTING_TYPE_FOR_EXTERNAL_COLLECTIONS =
2 ** 8 - 1;
bool private _isProduction;
mapping(address issuer => mapping(string collectionSymbol => bool allowed))
private _collectionsAllowedPerIssuer;
string private constant _ALL_COLLECTIONS_ALLOWED = "*";
function initialize(
address rmrkToken_,
uint256 collectionVerificationFee_
) public initializer {
__OwnableUpgradeable_init();
totalCollectionsCounter = 1;
rmrkToken = IERC20(rmrkToken_);
collectionVerificationFee = collectionVerificationFee_;
_defaultCollectionConfig = CollectionConfig(
true,
false,
true,
true,
true,
true,
true,
true,
true,
0,
0,
0x0
);
_defaultCollectionConfigForExternalCollections = CollectionConfig(
true,
false,
false,
false,
false,
false,
false,
false,
false,
0,
CUSTOM_MINTING_TYPE_FOR_EXTERNAL_COLLECTIONS,
0x0
);
}
function addExternalCollection(
address collection,
string memory collectionMetadata
) external {
if (IOwnable(collection).owner() != _msgSender())
revert OnlyCollectionOwnerCanAddCollection();
string memory symbol = IRMRKImplementationBase(collection).symbol();
if (!isCollectionAllowedForIssuer(msg.sender, symbol))
revert CollectionNotAllowedForIssuer();
LegoCombination legoCombination;
bool supportsEquippable = IERC165(collection).supportsInterface(
type(IERC6220).interfaceId
);
if (supportsEquippable) legoCombination = LegoCombination.Equippable;
else {
bool supportsNestable = IERC165(collection).supportsInterface(
type(IERC7401).interfaceId
);
bool supportsMultiAsset = IERC165(collection).supportsInterface(
type(IERC5773).interfaceId
);
if (supportsNestable && supportsMultiAsset)
legoCombination = LegoCombination.NestableMultiAsset;
else if (supportsNestable)
legoCombination = LegoCombination.Nestable;
else if (supportsMultiAsset)
legoCombination = LegoCombination.MultiAsset;
else revert UnsupportedCollection();
}
if (IRMRKImplementationBase(collection).totalSupply() > 0)
revert CannotAddCollectionWithMintedTokens();
_addCollection(
collection,
_msgSender(),
IRMRKImplementationBase(collection).maxSupply(),
legoCombination,
MintingType.Custom,
IERC165(collection).supportsInterface(type(IERC6454).interfaceId),
_defaultCollectionConfigForExternalCollections,
collectionMetadata
);
}
function addCollectionFromFactories(
address collection,
address deployer,
uint256 maxSupply,
LegoCombination legoCombination,
MintingType mintingType,
bool isSoulbound
) external {
if (!factories[_msgSender()]) revert NotFactory();
_addCollection(
collection,
deployer,
maxSupply,
legoCombination,
mintingType,
isSoulbound,
_defaultCollectionConfig,
""
);
}
function addCollection(
address collection,
address deployer,
uint256 maxSupply,
LegoCombination legoCombination,
MintingType mintingType,
bool isSoulbound,
CollectionConfig memory config,
string memory collectionMetadata
) public whenNotPaused onlyOwnerOrContributor {
_addCollection(
collection,
deployer,
maxSupply,
legoCombination,
mintingType,
isSoulbound,
config,
collectionMetadata
);
}
function _addCollection(
address collection,
address deployer,
uint256 maxSupply,
LegoCombination legoCombination,
MintingType mintingType,
bool isSoulbound,
CollectionConfig memory config,
string memory collectionMetadata
) private whenNotPaused {
if (collection == address(0)) revert CollectionAddressCannotBeZero();
if (_collectionByAddressIndex[collection] != 0) {
revert CollectionAlreadyExists();
}
Collection memory newCollection = Collection({
collection: collection,
verificationSponsor: 0x0000000000000000000000000000000000000000,
verificationFeeBalance: 0,
legoCombination: legoCombination,
mintingType: mintingType,
isSoulbound: isSoulbound,
config: config,
visible: true,
verified: false
});
string memory name = IRMRKImplementationBase(collection).name();
string memory symbol = IRMRKImplementationBase(collection).symbol();
string memory finalCollectionMetadata;
if (bytes(collectionMetadata).length > 0) {
finalCollectionMetadata = collectionMetadata;
} else {
try IRMRKImplementationBase(collection).contractURI() returns (
string memory collectionMeta
) {
finalCollectionMetadata = collectionMeta;
} catch {
try
IRMRKImplementationBase(collection).collectionMetadata()
returns (string memory contractURI) {
finalCollectionMetadata = contractURI;
} catch {
revert CollectionMetadataNotAvailable();
}
}
}
_collections.push(newCollection);
_collectionByAddressIndex[collection] = totalCollectionsCounter;
totalCollectionsCounter++;
emit CollectionAdded(
collection,
deployer,
name,
symbol,
maxSupply,
finalCollectionMetadata,
legoCombination,
mintingType,
isSoulbound,
config
);
}
function sponsorVerification(
address collectionAddress
) public whenNotPaused {
if (
rmrkToken.allowance(_msgSender(), address(this)) <
collectionVerificationFee
) revert NotEnoughAllowance();
if (rmrkToken.balanceOf(_msgSender()) < collectionVerificationFee)
revert NotEnoughBalance();
uint256 index = _collectionByAddressIndex[collectionAddress];
if (index == 0) {
revert CollectionDoesNotExist(collectionAddress);
}
_collectionsDepositBalance += collectionVerificationFee;
Collection storage collection = _collections[index - 1];
if (collection.verificationSponsor != address(0)) {
revert CollectionAlreadySponsored();
}
collection.verificationFeeBalance = collectionVerificationFee;
collection.verificationSponsor = _msgSender();
rmrkToken.transferFrom(
_msgSender(),
address(this),
collectionVerificationFee
);
emit CollectionSponsored(collectionAddress, _msgSender());
}
function cancelSponsorship(address collectionAddress) public whenNotPaused {
uint256 index = _collectionByAddressIndex[collectionAddress];
if (index == 0) {
revert CollectionDoesNotExist(collectionAddress);
}
Collection storage collection = _collections[index - 1];
if (collection.verificationSponsor != _msgSender()) {
revert CollectionNotSponsoredBySender();
}
if (collection.verified) revert CollectionAlreadyVerified();
uint256 verificationFeeBalance = collection.verificationFeeBalance;
_collectionsDepositBalance -= verificationFeeBalance;
collection.verificationFeeBalance = 0;
collection.verificationSponsor = address(0);
rmrkToken.transfer(_msgSender(), verificationFeeBalance);
emit CollectionSponsorshipCancelled(collectionAddress);
}
function verifyCollection(
address collectionAddress
) external onlyOwnerOrContributor {
uint256 index = _collectionByAddressIndex[collectionAddress];
if (index == 0) {
revert CollectionDoesNotExist(collectionAddress);
}
Collection storage collection = _collections[index - 1];
if (collection.verificationFeeBalance == 0)
revert CollectionNotSponsored();
collection.verified = true;
emit CollectionVerified(collectionAddress);
}
function unverifyCollection(
address collectionAddress
) external onlyOwnerOrContributor {
uint256 index = _collectionByAddressIndex[collectionAddress];
if (index == 0) {
revert CollectionDoesNotExist(collectionAddress);
}
_collections[index - 1].verified = false;
emit CollectionUnverified(collectionAddress);
}
function declineVerification(
address collectionAddress
) external onlyOwnerOrContributor {
Collection storage collection = _collections[
_collectionByAddressIndex[collectionAddress] - 1
];
_blacklistedCollectionsDepositBalance += collection
.verificationFeeBalance;
_collectionsDepositBalance -= collection.verificationFeeBalance;
collection.verificationFeeBalance = 0;
collection
.verificationSponsor = 0x0000000000000000000000000000000000000000;
}
function getCollectionByIndex(
uint256 index
) public view returns (Collection memory) {
return _collections[index];
}
function getCollectionAddressByIndex(
uint256 index
) public view returns (address) {
return _collections[index].collection;
}
function getCollectionByAddress(
address collectionAddress
) public view returns (Collection memory) {
uint256 index = _collectionByAddressIndex[collectionAddress];
if (index == 0) {
revert CollectionDoesNotExist(collectionAddress);
}
return _collections[index - 1];
}
function isCollectionInRegistry(
address collection
) external view returns (bool) {
return _collectionByAddressIndex[collection] != 0;
}
function updateRMRKTokenAddress(
address rmrkToken_
) external onlyOwnerOrContributor {
rmrkToken = IERC20(rmrkToken_);
}
function updateCollectionVerificationFee(
uint256 collectionVerificationFee_
) external onlyOwnerOrContributor {
collectionVerificationFee = collectionVerificationFee_;
}
function addFactory(address factory) external onlyOwnerOrContributor {
factories[factory] = true;
factoryList.push(factory);
}
function setMetaFactory(
address metaFactory
) external onlyOwnerOrContributor {
metaFactoryAddress = metaFactory;
}
function removeFactory(
address factory,
uint256 factoryIndex
) external onlyOwnerOrContributor {
delete factories[factory];
delete factoryList[factoryIndex];
}
function blackListCollection(
address collectionAddress
) external onlyOwnerOrContributor {
Collection storage collection = _collections[
_collectionByAddressIndex[collectionAddress] - 1
];
_blacklistedCollectionsDepositBalance += collection
.verificationFeeBalance;
_collectionsDepositBalance -= collection.verificationFeeBalance;
collection.visible = false;
collection.verified = false;
emit CollectionBlacklisted(collectionAddress);
}
function removeCollection(
address collectionAddress
) external whenNotPaused {
uint256 index = _collectionByAddressIndex[collectionAddress];
if (index == 0) {
revert CollectionDoesNotExist(collectionAddress);
}
index -= 1;
Collection memory collection = _collections[index];
if (IOwnable(collection.collection).owner() != _msgSender())
revert OnlyCollectionOwnerCanRemoveCollection();
if (collection.legoCombination != LegoCombination.ERC1155) {
if (IRMRKImplementationBase(collectionAddress).totalSupply() > 0) {
revert CollectionHasMintedTokens();
}
}
// TODO: Check for ERC1155
_removeCollection(collectionAddress, index);
}
function forceRemoveCollection(
address collectionAddress
) external onlyOwnerOrContributor {
uint256 index = _collectionByAddressIndex[collectionAddress];
if (index == 0) {
revert CollectionDoesNotExist(collectionAddress);
}
index -= 1;
_removeCollection(collectionAddress, index);
}
function _removeCollection(
address collectionAddress,
uint256 index
) private {
Collection memory collection = _collections[index];
delete _collections[index];
delete _collectionByAddressIndex[collectionAddress];
if (collection.verificationFeeBalance > 0) {
uint256 refundBalance = collection.verificationFeeBalance;
_collectionsDepositBalance -= refundBalance;
rmrkToken.transfer(collection.verificationSponsor, refundBalance);
}
emit CollectionRemoved(collectionAddress);
}
function unblackListCollection(
address collectionAddress
) external onlyOwnerOrContributor {
Collection storage collection = _collections[
_collectionByAddressIndex[collectionAddress] - 1
];
collection.visible = true;
}
function withdrawFees(address to) external onlyOwner {
uint256 feeAmount = _blacklistedCollectionsDepositBalance;
_blacklistedCollectionsDepositBalance = 0;
rmrkToken.transfer(to, feeAmount);
}
function getCollectionVerificationFee() external view returns (uint256) {
return collectionVerificationFee;
}
function getRmrkTokenAddress() external view returns (address) {
return address(rmrkToken);
}
function getTotalCollectionCount() external view returns (uint256) {
return _collections.length;
}
function getMetaFactoryAddress() external view returns (address) {
return metaFactoryAddress;
}
function _authorizeUpgrade(address) internal override onlyOwner {}
function pauseRegistry(bool pause) external onlyOwnerOrContributor {
_pause(pause);
}
// External collections
function setCollectionAllowedPerIssuer(
address issuer,
string memory collectionSymbol,
bool allowed
) external onlyOwnerOrContributor {
if (bytes(collectionSymbol).length == 0) {
revert CollectionSymbolCannotBeEmpty();
}
if (allowed) {
_collectionsAllowedPerIssuer[issuer][collectionSymbol] = true;
} else {
delete _collectionsAllowedPerIssuer[issuer][collectionSymbol];
}
}
function isCollectionAllowedForIssuer(
address issuer,
string memory collectionSymbol
) public view returns (bool) {
if (bytes(collectionSymbol).length == 0) {
revert CollectionSymbolCannotBeEmpty();
}
return
!_isProduction ||
_collectionsAllowedPerIssuer[issuer][_ALL_COLLECTIONS_ALLOWED] ||
_collectionsAllowedPerIssuer[issuer][collectionSymbol];
}
function setProduction(bool isProduction_) external onlyOwnerOrContributor {
_isProduction = isProduction_;
}
function isProduction() external view returns (bool) {
return _isProduction;
}
}// 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.9.0) (interfaces/IERC1967.sol)
pragma solidity ^0.8.0;
/**
* @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.
*
* _Available since v4.8.3._
*/
interface IERC1967Upgradeable {
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Emitted when the beacon is changed.
*/
event BeaconUpgraded(address indexed beacon);
}// 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.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)
pragma solidity ^0.8.2;
import "../beacon/IBeaconUpgradeable.sol";
import "../../interfaces/IERC1967Upgradeable.sol";
import "../../interfaces/draft-IERC1822Upgradeable.sol";
import "../../utils/AddressUpgradeable.sol";
import "../../utils/StorageSlotUpgradeable.sol";
import {Initializable} from "../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._
*/
abstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {
// 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;
function __ERC1967Upgrade_init() internal onlyInitializing {
}
function __ERC1967Upgrade_init_unchained() internal onlyInitializing {
}
/**
* @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) {
AddressUpgradeable.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 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 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) {
AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), 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 (last updated v4.9.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]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: setting the version to 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized != type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)
pragma solidity ^0.8.0;
import "../../interfaces/draft-IERC1822Upgradeable.sol";
import "../ERC1967/ERC1967UpgradeUpgradeable.sol";
import {Initializable} from "./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 {
/// @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");
_;
}
function __UUPSUpgradeable_init() internal onlyInitializing {
}
function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
}
/**
* @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
* implementation. It is used to validate the implementation's compatibility when performing 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.
*
* @custom:oz-upgrades-unsafe-allow-reachable delegatecall
*/
function upgradeTo(address newImplementation) public 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.
*
* @custom:oz-upgrades-unsafe-allow-reachable delegatecall
*/
function upgradeToAndCall(address newImplementation, bytes memory data) public 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.9.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
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [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://consensys.net/diligence/blog/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.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @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,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
pragma solidity ^0.8.0;
import {Initializable} from "../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;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
/**
* @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.9.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
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:
* ```solidity
* 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`, `uint256`._
* _Available since v4.9 for `string`, `bytes`._
*/
library StorageSlotUpgradeable {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes 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
}
}
/**
* @dev Returns an `StringSlot` with member `value` located at `slot`.
*/
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` representation of the string storage pointer `store`.
*/
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
/**
* @dev Returns an `BytesSlot` with member `value` located at `slot`.
*/
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
*/
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @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 value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` 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 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.21;
import {IERC5773} from "../multiasset/IERC5773.sol";
/**
* @title IERC6220
* @author RMRK team
* @notice Interface smart contract of the RMRK equippable module.
*/
interface IERC6220 is IERC5773 {
/**
* @notice Used to store the core structure of the `Equippable` RMRK lego.
* @return assetId The ID of the asset equipping a child
* @return childAssetId The ID of the asset used as equipment
* @return childId The ID of token that is equipped
* @return childEquippableAddress Address of the collection to which the child asset belongs to
*/
struct Equipment {
uint64 assetId;
uint64 childAssetId;
uint256 childId;
address childEquippableAddress;
}
/**
* @notice Used to provide a struct for inputing equip data.
* @dev Only used for input and not storage of data.
* @return tokenId ID of the token we are managing
* @return childIndex Index of a child in the list of token's active children
* @return assetId ID of the asset that we are equipping into
* @return slotPartId ID of the slot part that we are using to equip
* @return childAssetId ID of the asset that we are equipping
*/
struct IntakeEquip {
uint256 tokenId;
uint256 childIndex;
uint64 assetId;
uint64 slotPartId;
uint64 childAssetId;
}
/**
* @notice Used to notify listeners that a child's asset has been equipped into one of its parent assets.
* @param tokenId ID of the token that had an asset equipped
* @param assetId ID of the asset associated with the token we are equipping into
* @param slotPartId ID of the slot we are using to equip
* @param childId ID of the child token we are equipping into the slot
* @param childAddress Address of the child token's collection
* @param childAssetId ID of the asset associated with the token we are equipping
*/
event ChildAssetEquipped(
uint256 indexed tokenId,
uint64 indexed assetId,
uint64 indexed slotPartId,
uint256 childId,
address childAddress,
uint64 childAssetId
);
/**
* @notice Used to notify listeners that a child's asset has been unequipped from one of its parent assets.
* @param tokenId ID of the token that had an asset unequipped
* @param assetId ID of the asset associated with the token we are unequipping out of
* @param slotPartId ID of the slot we are unequipping from
* @param childId ID of the token being unequipped
* @param childAddress Address of the collection that a token that is being unequipped belongs to
* @param childAssetId ID of the asset associated with the token we are unequipping
*/
event ChildAssetUnequipped(
uint256 indexed tokenId,
uint64 indexed assetId,
uint64 indexed slotPartId,
uint256 childId,
address childAddress,
uint64 childAssetId
);
/**
* @notice Used to notify listeners that the assets belonging to a `equippableGroupId` have been marked as
* equippable into a given slot and parent
* @param equippableGroupId ID of the equippable group being marked as equippable into the slot associated with
* `slotPartId` of the `parentAddress` collection
* @param slotPartId ID of the slot part of the catalog into which the parts belonging to the equippable group
* associated with `equippableGroupId` can be equipped
* @param parentAddress Address of the collection into which the parts belonging to `equippableGroupId` can be
* equipped
*/
event ValidParentEquippableGroupIdSet(
uint64 indexed equippableGroupId,
uint64 indexed slotPartId,
address parentAddress
);
/**
* @notice Used to equip a child into a token.
* @dev The `IntakeEquip` stuct contains the following data:
* [
* tokenId,
* childIndex,
* assetId,
* slotPartId,
* childAssetId
* ]
* @param data An `IntakeEquip` struct specifying the equip data
*/
function equip(IntakeEquip memory data) external;
/**
* @notice Used to unequip child from parent token.
* @dev This can only be called by the owner of the token or by an account that has been granted permission to
* manage the given token by the current owner.
* @param tokenId ID of the parent from which the child is being unequipped
* @param assetId ID of the parent's asset that contains the `Slot` into which the child is equipped
* @param slotPartId ID of the `Slot` from which to unequip the child
*/
function unequip(
uint256 tokenId,
uint64 assetId,
uint64 slotPartId
) external;
/**
* @notice Used to check whether the token has a given child equipped.
* @dev This is used to prevent from transferring a child that is equipped.
* @param tokenId ID of the parent token for which we are querying for
* @param childAddress Address of the child token's smart contract
* @param childId ID of the child token
* @return isEquipped A boolean value indicating whether the child token is equipped into the given token or not
*/
function isChildEquipped(
uint256 tokenId,
address childAddress,
uint256 childId
) external view returns (bool isEquipped);
/**
* @notice Used to verify whether a token can be equipped into a given parent's slot.
* @param parent Address of the parent token's smart contract
* @param tokenId ID of the token we want to equip
* @param assetId ID of the asset associated with the token we want to equip
* @param slotId ID of the slot that we want to equip the token into
* @return canBeEquipped A boolean indicating whether the token with the given asset can be equipped into the desired slot
*/
function canTokenBeEquippedWithAssetIntoSlot(
address parent,
uint256 tokenId,
uint64 assetId,
uint64 slotId
) external view returns (bool canBeEquipped);
/**
* @notice Used to get the Equipment object equipped into the specified slot of the desired token.
* @dev The `Equipment` struct consists of the following data:
* [
* assetId,
* childAssetId,
* childId,
* childEquippableAddress
* ]
* @param tokenId ID of the token for which we are retrieving the equipped object
* @param targetCatalogAddress Address of the `Catalog` associated with the `Slot` part of the token
* @param slotPartId ID of the `Slot` part that we are checking for equipped objects
* @return equipment The `Equipment` struct containing data about the equipped object
*/
function getEquipment(
uint256 tokenId,
address targetCatalogAddress,
uint64 slotPartId
) external view returns (Equipment memory equipment);
/**
* @notice Used to get the asset and equippable data associated with given `assetId`.
* @param tokenId ID of the token for which to retrieve the asset
* @param assetId ID of the asset of which we are retrieving
* @return metadataURI The metadata URI of the asset
* @return equippableGroupId ID of the equippable group this asset belongs to
* @return catalogAddress The address of the catalog the part belongs to
* @return partIds An array of IDs of parts included in the asset
*/
function getAssetAndEquippableData(
uint256 tokenId,
uint64 assetId
)
external
view
returns (
string memory metadataURI,
uint64 equippableGroupId,
address catalogAddress,
uint64[] memory partIds
);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.21;
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/**
* @title IERC6454
* @author RMRK team
* @notice A minimal extension to identify the transferability of Non-Fungible Tokens.
*/
interface IERC6454 is IERC165 {
/**
* @notice Used to check whether the given token is transferable or not.
* @dev If this function returns `false`, the transfer of the token MUST revert execution.
* @dev If the tokenId does not exist, this method MUST revert execution, unless the token is being checked for
* minting.
* @param tokenId ID of the token being checked
* @param from Address from which the token is being transferred
* @param to Address to which the token is being transferred
* @return isTransferable_ Boolean value indicating whether the given token is transferable
*/
function isTransferable(
uint256 tokenId,
address from,
address to
) external view returns (bool isTransferable_);
}// SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.21; /// @title RMRKErrors /// @author RMRK team /// @notice A collection of errors used in the RMRK suite /// @dev Errors are kept in a centralised file in order to provide a central point of reference and to avoid error /// naming collisions due to inheritance /// Attempting to grant the token to 0x0 address error ERC721AddressZeroIsNotaValidOwner(); /// Attempting to grant approval to the current owner of the token error ERC721ApprovalToCurrentOwner(); /// Attempting to grant approval when not being owner or approved for all should not be permitted error ERC721ApproveCallerIsNotOwnerNorApprovedForAll(); /// Attempting to grant approval to self error ERC721ApproveToCaller(); /// Attempting to use an invalid token ID error ERC721InvalidTokenId(); /// Attempting to mint to 0x0 address error ERC721MintToTheZeroAddress(); /// Attempting to manage a token without being its owner or approved by the owner error ERC721NotApprovedOrOwner(); /// Attempting to mint an already minted token error ERC721TokenAlreadyMinted(); /// Attempting to transfer the token from an address that is not the owner error ERC721TransferFromIncorrectOwner(); /// Attempting to safe transfer to an address that is unable to receive the token error ERC721TransferToNonReceiverImplementer(); /// Attempting to transfer the token to a 0x0 address error ERC721TransferToTheZeroAddress(); /// Attempting to grant approval of assets to their current owner error RMRKApprovalForAssetsToCurrentOwner(); /// Attempting to grant approval of assets without being the caller or approved for all error RMRKApproveForAssetsCallerIsNotOwnerNorApprovedForAll(); /// Attempting to incorrectly configue a Catalog item error RMRKBadConfig(); /// Attempting to set the priorities with an array of length that doesn't match the length of active assets array error RMRKBadPriorityListLength(); /// Attempting to add an asset entry with `Part`s, without setting the `Catalog` address error RMRKCatalogRequiredForParts(); /// Attempting to transfer a soulbound (non-transferrable) token error RMRKCannotTransferSoulbound(); /// Attempting to accept a child that has already been accepted error RMRKChildAlreadyExists(); /// Attempting to interact with a child, using index that is higher than the number of children error RMRKChildIndexOutOfRange(); /// Attempting to find the index of a child token on a parent which does not own it. error RMRKChildNotFoundInParent(); /// Attempting to equip a `Part` with a child not approved by the Catalog error RMRKEquippableEquipNotAllowedByCatalog(); /// Attempting to use ID 0, which is not supported /// @dev The ID 0 in RMRK suite is reserved for empty values. Guarding against its use ensures the expected operation error RMRKIdZeroForbidden(); /// Attempting to interact with an asset, using index greater than number of assets error RMRKIndexOutOfRange(); /// Attempting to reclaim a child that can't be reclaimed error RMRKInvalidChildReclaim(); /// Attempting to interact with an end-user account when the contract account is expected error RMRKIsNotContract(); /// Attempting to interact with a contract that had its operation locked error RMRKLocked(); /// Attempting to add a pending child after the number of pending children has reached the limit (default limit is 128) error RMRKMaxPendingChildrenReached(); /// Attempting to add a pending asset after the number of pending assets has reached the limit (default limit is /// 128) error RMRKMaxPendingAssetsReached(); /// Attempting to burn a total number of recursive children higher than maximum set /// @param childContract Address of the collection smart contract in which the maximum number of recursive burns was reached /// @param childId ID of the child token at which the maximum number of recursive burns was reached error RMRKMaxRecursiveBurnsReached(address childContract, uint256 childId); /// Attempting to mint a number of tokens that would cause the total supply to be greater than maximum supply error RMRKMintOverMax(); /// Attempting to mint zero tokens error RMRKMintZero(); /// Attempting to pass complementary arrays of different lengths error RMRKMismachedArrayLength(); /// Attempting to transfer a child before it is unequipped error RMRKMustUnequipFirst(); /// Attempting to nest a child over the nestable limit (current limit is 100 levels of nesting) error RMRKNestableTooDeep(); /// Attempting to nest the token to own descendant, which would create a loop and leave the looped tokens in limbo error RMRKNestableTransferToDescendant(); /// Attempting to nest the token to a smart contract that doesn't support nesting error RMRKNestableTransferToNonRMRKNestableImplementer(); /// Attempting to nest the token into itself error RMRKNestableTransferToSelf(); /// Attempting to interact with an asset that can not be found error RMRKNoAssetMatchingId(); /// Attempting to manage an asset without owning it or having been granted permission by the owner to do so error RMRKNotApprovedForAssetsOrOwner(); /// Attempting to interact with a token without being its owner or having been granted permission by the /// owner to do so /// @dev When a token is nested, only the direct owner (NFT parent) can mange it. In that case, approved addresses are /// not allowed to manage it, in order to ensure the expected behaviour error RMRKNotApprovedOrDirectOwner(); /// Attempting to compose an asset wihtout having an associated Catalog error RMRKNotComposableAsset(); /// Attempting to unequip an item that isn't equipped error RMRKNotEquipped(); /// Attempting to interact with a management function without being the smart contract's owner error RMRKNotOwner(); /// Attempting to interact with a function without being the owner or contributor of the collection error RMRKNotOwnerOrContributor(); /// Attempting to transfer the ownership to the 0x0 address error RMRKNewOwnerIsZeroAddress(); /// Attempting to assign a 0x0 address as a contributor error RMRKNewContributorIsZeroAddress(); /// Attempting an operation requiring the token being nested, while it is not error RMRKParentIsNotNFT(); /// Attempting to add a `Part` with an ID that is already used error RMRKPartAlreadyExists(); /// Attempting to use a `Part` that doesn't exist error RMRKPartDoesNotExist(); /// Attempting to use a `Part` that is `Fixed` when `Slot` kind of `Part` should be used error RMRKPartIsNotSlot(); /// Attempting to interact with a pending child using an index greater than the size of pending array error RMRKPendingChildIndexOutOfRange(); /// Attempting to add an asset using an ID that has already been used error RMRKAssetAlreadyExists(); /// Attempting to equip an item into a slot that already has an item equipped error RMRKSlotAlreadyUsed(); /// Attempting to equip an item into a `Slot` that the target asset does not implement error RMRKTargetAssetCannotReceiveSlot(); /// Attempting to equip a child into a `Slot` and parent that the child's collection doesn't support error RMRKTokenCannotBeEquippedWithAssetIntoSlot(); /// Attempting to compose a NFT of a token without active assets error RMRKTokenDoesNotHaveAsset(); /// Attempting to determine the asset with the top priority on a token without assets error RMRKTokenHasNoAssets(); /// Attempting to accept or transfer a child which does not match the one at the specified index error RMRKUnexpectedChildId(); /// Attempting to reject all pending assets but more assets than expected are pending error RMRKUnexpectedNumberOfAssets(); /// Attempting to reject all pending children but children assets than expected are pending error RMRKUnexpectedNumberOfChildren(); /// Attempting to accept or reject an asset which does not match the one at the specified index error RMRKUnexpectedAssetId(); /// Attempting an operation expecting a parent to the token which is not the actual one error RMRKUnexpectedParent(); /// Attempting not to pass an empty array of equippable addresses when adding or setting the equippable addresses error RMRKZeroLengthIdsPassed(); /// Attempting to set the royalties to a value higher than 100% (10000 in basis points) error RMRKRoyaltiesTooHigh(); /// Attempting to do a bulk operation on a token that is not owned by the caller error RMRKCanOnlyDoBulkOperationsOnOwnedTokens(); /// Attempting to do a bulk operation with multiple tokens at a time error RMRKCanOnlyDoBulkOperationsWithOneTokenAtATime(); /// Attempting to pay with native token with a value different than expected error RMRKWrongValueSent(); // Attempting to send native token to a recipient that is unable to receive it error TransferFailed();
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.21;
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/**
* @title IERC5773
* @author RMRK team
* @notice Interface smart contract of the RMRK multi asset module.
*/
interface IERC5773 is IERC165 {
/**
* @notice Used to notify listeners that an asset object is initialized at `assetId`.
* @param assetId ID of the asset that was initialized
*/
event AssetSet(uint64 indexed assetId);
/**
* @notice Used to notify listeners that an asset object at `assetId` is added to token's pending asset
* array.
* @param tokenIds An array of token IDs that received a new pending asset
* @param assetId ID of the asset that has been added to the token's pending assets array
* @param replacesId ID of the asset that would be replaced
*/
event AssetAddedToTokens(
uint256[] tokenIds,
uint64 indexed assetId,
uint64 indexed replacesId
);
/**
* @notice Used to notify listeners that an asset object at `assetId` is accepted by the token and migrated
* from token's pending assets array to active assets array of the token.
* @param tokenId ID of the token that had a new asset accepted
* @param assetId ID of the asset that was accepted
* @param replacesId ID of the asset that was replaced
*/
event AssetAccepted(
uint256 indexed tokenId,
uint64 indexed assetId,
uint64 indexed replacesId
);
/**
* @notice Used to notify listeners that an asset object at `assetId` is rejected from token and is dropped
* from the pending assets array of the token.
* @param tokenId ID of the token that had an asset rejected
* @param assetId ID of the asset that was rejected
*/
event AssetRejected(uint256 indexed tokenId, uint64 indexed assetId);
/**
* @notice Used to notify listeners that token's prioritiy array is reordered.
* @param tokenId ID of the token that had the asset priority array updated
*/
event AssetPrioritySet(uint256 indexed tokenId);
/**
* @notice Used to notify listeners that owner has granted an approval to the user to manage the assets of a
* given token.
* @dev Approvals must be cleared on transfer
* @param owner Address of the account that has granted the approval for all token's assets
* @param approved Address of the account that has been granted approval to manage the token's assets
* @param tokenId ID of the token on which the approval was granted
*/
event ApprovalForAssets(
address indexed owner,
address indexed approved,
uint256 indexed tokenId
);
/**
* @notice Used to notify listeners that owner has granted approval to the user to manage assets of all of their
* tokens.
* @param owner Address of the account that has granted the approval for all assets on all of their tokens
* @param operator Address of the account that has been granted the approval to manage the token's assets on all of
* the tokens
* @param approved Boolean value signifying whether the permission has been granted (`true`) or revoked (`false`)
*/
event ApprovalForAllForAssets(
address indexed owner,
address indexed operator,
bool approved
);
/**
* @notice Accepts an asset at from the pending array of given token.
* @dev Migrates the asset from the token's pending asset array to the token's active asset array.
* @dev Active assets cannot be removed by anyone, but can be replaced by a new asset.
* @dev Requirements:
*
* - The caller must own the token or be approved to manage the token's assets
* - `tokenId` must exist.
* - `index` must be in range of the length of the pending asset array.
* @dev Emits an {AssetAccepted} event.
* @param tokenId ID of the token for which to accept the pending asset
* @param index Index of the asset in the pending array to accept
* @param assetId ID of the asset expected to be in the index
*/
function acceptAsset(
uint256 tokenId,
uint256 index,
uint64 assetId
) external;
/**
* @notice Rejects an asset from the pending array of given token.
* @dev Removes the asset from the token's pending asset array.
* @dev Requirements:
*
* - The caller must own the token or be approved to manage the token's assets
* - `tokenId` must exist.
* - `index` must be in range of the length of the pending asset array.
* @dev Emits a {AssetRejected} event.
* @param tokenId ID of the token that the asset is being rejected from
* @param index Index of the asset in the pending array to be rejected
* @param assetId ID of the asset expected to be in the index
*/
function rejectAsset(
uint256 tokenId,
uint256 index,
uint64 assetId
) external;
/**
* @notice Rejects all assets from the pending array of a given token.
* @dev Effecitvely deletes the pending array.
* @dev Requirements:
*
* - The caller must own the token or be approved to manage the token's assets
* - `tokenId` must exist.
* @dev Emits a {AssetRejected} event with assetId = 0.
* @param tokenId ID of the token of which to clear the pending array.
* @param maxRejections Maximum number of expected assets to reject, used to prevent from rejecting assets which
* arrive just before this operation.
*/
function rejectAllAssets(uint256 tokenId, uint256 maxRejections) external;
/**
* @notice Sets a new priority array for a given token.
* @dev The priority array is a non-sequential list of `uint64`s, where the lowest value is considered highest
* priority.
* @dev Value `0` of a priority is a special case equivalent to unitialized.
* @dev Requirements:
*
* - The caller must own the token or be approved to manage the token's assets
* - `tokenId` must exist.
* - The length of `priorities` must be equal the length of the active assets array.
* @dev Emits a {AssetPrioritySet} event.
* @param tokenId ID of the token to set the priorities for
* @param priorities An array of priorities of active assets. The succesion of items in the priorities array
* matches that of the succesion of items in the active array
*/
function setPriority(
uint256 tokenId,
uint64[] calldata priorities
) external;
/**
* @notice Used to retrieve IDs of the active assets of given token.
* @dev Asset data is stored by reference, in order to access the data corresponding to the ID, call
* `getAssetMetadata(tokenId, assetId)`.
* @dev You can safely get 10k
* @param tokenId ID of the token to retrieve the IDs of the active assets
* @return assetIds An array of active asset IDs of the given token
*/
function getActiveAssets(
uint256 tokenId
) external view returns (uint64[] memory assetIds);
/**
* @notice Used to retrieve IDs of the pending assets of given token.
* @dev Asset data is stored by reference, in order to access the data corresponding to the ID, call
* `getAssetMetadata(tokenId, assetId)`.
* @param tokenId ID of the token to retrieve the IDs of the pending assets
* @return assetIds An array of pending asset IDs of the given token
*/
function getPendingAssets(
uint256 tokenId
) external view returns (uint64[] memory assetIds);
/**
* @notice Used to retrieve the priorities of the active resoources of a given token.
* @dev Asset priorities are a non-sequential array of uint64 values with an array size equal to active asset
* priorites.
* @param tokenId ID of the token for which to retrieve the priorities of the active assets
* @return priorities An array of priorities of the active assets of the given token
*/
function getActiveAssetPriorities(
uint256 tokenId
) external view returns (uint64[] memory priorities);
/**
* @notice Used to retrieve the asset that will be replaced if a given asset from the token's pending array
* is accepted.
* @dev Asset data is stored by reference, in order to access the data corresponding to the ID, call
* `getAssetMetadata(tokenId, assetId)`.
* @param tokenId ID of the token to check
* @param newAssetId ID of the pending asset which will be accepted
* @return replacesAssetWithId ID of the asset which will be replaced
*/
function getAssetReplacements(
uint256 tokenId,
uint64 newAssetId
) external view returns (uint64 replacesAssetWithId);
/**
* @notice Used to fetch the asset metadata of the specified token's active asset with the given index.
* @dev Assets are stored by reference mapping `_assets[assetId]`.
* @dev Can be overriden to implement enumerate, fallback or other custom logic.
* @param tokenId ID of the token from which to retrieve the asset metadata
* @param assetId Asset Id, must be in the active assets array
* @return metadata The metadata of the asset belonging to the specified index in the token's active assets
* array
*/
function getAssetMetadata(
uint256 tokenId,
uint64 assetId
) external view returns (string memory metadata);
// Approvals
/**
* @notice Used to grant permission to the user to manage token's assets.
* @dev This differs from transfer approvals, as approvals are not cleared when the approved party accepts or
* rejects an asset, or sets asset priorities. This approval is cleared on token transfer.
* @dev Only a single account can be approved at a time, so approving the `0x0` address clears previous approvals.
* @dev Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
* @dev Emits an {ApprovalForAssets} event.
* @param to Address of the account to grant the approval to
* @param tokenId ID of the token for which the approval to manage the assets is granted
*/
function approveForAssets(address to, uint256 tokenId) external;
/**
* @notice Used to retrieve the address of the account approved to manage assets of a given token.
* @dev Requirements:
*
* - `tokenId` must exist.
* @param tokenId ID of the token for which to retrieve the approved address
* @return approved Address of the account that is approved to manage the specified token's assets
*/
function getApprovedForAssets(
uint256 tokenId
) external view returns (address approved);
/**
* @notice Used to add or remove an operator of assets for the caller.
* @dev Operators can call {acceptAsset}, {rejectAsset}, {rejectAllAssets} or {setPriority} for any token
* owned by the caller.
* @dev Requirements:
*
* - The `operator` cannot be the caller.
* @dev Emits an {ApprovalForAllForAssets} event.
* @param operator Address of the account to which the operator role is granted or revoked from
* @param approved The boolean value indicating whether the operator role is being granted (`true`) or revoked
* (`false`)
*/
function setApprovalForAllForAssets(
address operator,
bool approved
) external;
/**
* @notice Used to check whether the address has been granted the operator role by a given address or not.
* @dev See {setApprovalForAllForAssets}.
* @param owner Address of the account that we are checking for whether it has granted the operator role
* @param operator Address of the account that we are checking whether it has the operator role or not
* @return isApproved A boolean value indicating whether the account we are checking has been granted the operator role
*/
function isApprovedForAllForAssets(
address owner,
address operator
) external view returns (bool isApproved);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.21;
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/**
* @title IERC7401
* @author RMRK team
* @notice Interface smart contract of the RMRK nestable module.
*/
interface IERC7401 is IERC165 {
/**
* @notice The core struct of RMRK ownership.
* @dev The `DirectOwner` struct is used to store information of the next immediate owner, be it the parent token or
* the externally owned account.
* @dev If the token is owned by the externally owned account, the `tokenId` should equal `0`.
* @param tokenId ID of the parent token
* @param ownerAddress Address of the owner of the token. If the owner is another token, then the address should be
* the one of the parent token's collection smart contract. If the owner is externally owned account, the address
* should be the address of this account
* @param isNft A boolean value signifying whether the token is owned by another token (`true`) or by an externally
* owned account (`false`)
*/
struct DirectOwner {
uint256 tokenId;
address ownerAddress;
}
/**
* @notice Used to notify listeners that the token is being transferred.
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
* @param from Address of the previous immediate owner, which is a smart contract if the token was nested.
* @param to Address of the new immediate owner, which is a smart contract if the token is being nested.
* @param fromTokenId ID of the previous parent token. If the token was not nested before, the value should be `0`
* @param toTokenId ID of the new parent token. If the token is not being nested, the value should be `0`
* @param tokenId ID of the token being transferred
*/
event NestTransfer(
address indexed from,
address indexed to,
uint256 fromTokenId,
uint256 toTokenId,
uint256 indexed tokenId
);
/**
* @notice Used to notify listeners that a new token has been added to a given token's pending children array.
* @dev Emitted when a child NFT is added to a token's pending array.
* @param tokenId ID of the token that received a new pending child token
* @param childIndex Index of the proposed child token in the parent token's pending children array
* @param childAddress Address of the proposed child token's collection smart contract
* @param childId ID of the child token in the child token's collection smart contract
*/
event ChildProposed(
uint256 indexed tokenId,
uint256 childIndex,
address indexed childAddress,
uint256 indexed childId
);
/**
* @notice Used to notify listeners that a new child token was accepted by the parent token.
* @dev Emitted when a parent token accepts a token from its pending array, migrating it to the active array.
* @param tokenId ID of the token that accepted a new child token
* @param childIndex Index of the newly accepted child token in the parent token's active children array
* @param childAddress Address of the child token's collection smart contract
* @param childId ID of the child token in the child token's collection smart contract
*/
event ChildAccepted(
uint256 indexed tokenId,
uint256 childIndex,
address indexed childAddress,
uint256 indexed childId
);
/**
* @notice Used to notify listeners that all pending child tokens of a given token have been rejected.
* @dev Emitted when a token removes all a child tokens from its pending array.
* @param tokenId ID of the token that rejected all of the pending children
*/
event AllChildrenRejected(uint256 indexed tokenId);
/**
* @notice Used to notify listeners a child token has been transferred from parent token.
* @dev Emitted when a token transfers a child from itself, transferring ownership to the root owner.
* @param tokenId ID of the token that transferred a child token
* @param childIndex Index of a child in the array from which it is being transferred
* @param childAddress Address of the child token's collection smart contract
* @param childId ID of the child token in the child token's collection smart contract
* @param fromPending A boolean value signifying whether the token was in the pending child tokens array (`true`) or
* in the active child tokens array (`false`)
* @param toZero A boolean value signifying whether the token is being transferred to the `0x0` address (`true`) or
* not (`false`)
*/
event ChildTransferred(
uint256 indexed tokenId,
uint256 childIndex,
address indexed childAddress,
uint256 indexed childId,
bool fromPending,
bool toZero
);
/**
* @notice The core child token struct, holding the information about the child tokens.
* @return tokenId ID of the child token in the child token's collection smart contract
* @return contractAddress Address of the child token's smart contract
*/
struct Child {
uint256 tokenId;
address contractAddress;
}
/**
* @notice Used to retrieve the *root* owner of a given token.
* @dev The *root* owner of the token is an externally owned account (EOA). If the given token is child of another
* NFT, this will return an EOA address. Otherwise, if the token is owned by an EOA, this EOA will be returned.
* @param tokenId ID of the token for which the *root* owner has been retrieved
* @return owner_ The *root* owner of the token
*/
function ownerOf(uint256 tokenId) external view returns (address owner_);
/**
* @notice Used to retrieve the immediate owner of the given token.
* @dev If the immediate owner is another token, the address returned will be the parent token's collection address.
* @param tokenId ID of the token for which the RMRK owner is being retrieved
* @return owner Address of the given token's owner
* @return parentId The ID of the parent token. Should be `0` if the owner is an externally owned account
* @return isNFT The boolean value signifying whether the owner is an NFT or not
*/
function directOwnerOf(
uint256 tokenId
) external view returns (address owner, uint256 parentId, bool isNFT);
/**
* @notice Used to burn a given token.
* @dev When a token is burned, all of its child tokens are recursively burned as well.
* @dev When specifying the maximum recursive burns, the execution will be reverted if there are more children to be
* burned.
* @dev Setting the `maxRecursiveBurn` value to 0 will only attempt to burn the specified token and revert if there
* are any child tokens present.
* @dev The approvals are cleared when the token is burned.
* @dev Requirements:
*
* - `tokenId` must exist.
* @dev Emits a {Transfer} event.
* @param tokenId ID of the token to burn
* @param maxRecursiveBurns Maximum number of tokens to recursively burn
* @return burnedChildren Number of recursively burned children
*/
function burn(
uint256 tokenId,
uint256 maxRecursiveBurns
) external returns (uint256 burnedChildren);
/**
* @notice Used to add a child token to a given parent token.
* @dev This adds the child token into the given parent token's pending child tokens array.
* @dev Requirements:
*
* - `directOwnerOf` on the child contract must resolve to the called contract.
* - the pending array of the parent contract must not be full.
* @param parentId ID of the parent token to receive the new child token
* @param childId ID of the new proposed child token
* @param data Additional data with no specified format
*/
function addChild(
uint256 parentId,
uint256 childId,
bytes memory data
) external;
/**
* @notice Used to accept a pending child token for a given parent token.
* @dev This moves the child token from parent token's pending child tokens array into the active child tokens
* array.
* @param parentId ID of the parent token for which the child token is being accepted
* @param childIndex Index of a child tokem in the given parent's pending children array
* @param childAddress Address of the collection smart contract of the child token expected to be located at the
* specified index of the given parent token's pending children array
* @param childId ID of the child token expected to be located at the specified index of the given parent token's
* pending children array
*/
function acceptChild(
uint256 parentId,
uint256 childIndex,
address childAddress,
uint256 childId
) external;
/**
* @notice Used to reject all pending children of a given parent token.
* @dev Removes the children from the pending array mapping.
* @dev This does not update the ownership storage data on children. If necessary, ownership can be reclaimed by the
* rootOwner of the previous parent.
* @dev Requirements:
*
* Requirements:
*
* - `parentId` must exist
* @param parentId ID of the parent token for which to reject all of the pending tokens.
* @param maxRejections Maximum number of expected children to reject, used to prevent from rejecting children which
* arrive just before this operation.
*/
function rejectAllChildren(
uint256 parentId,
uint256 maxRejections
) external;
/**
* @notice Used to transfer a child token from a given parent token.
* @dev When transferring a child token, the owner of the token is set to `to`, or is not updated in the event of
* `to` being the `0x0` address.
* @param tokenId ID of the parent token from which the child token is being transferred
* @param to Address to which to transfer the token to
* @param destinationId ID of the token to receive this child token (MUST be 0 if the destination is not a token)
* @param childIndex Index of a token we are transferring, in the array it belongs to (can be either active array or
* pending array)
* @param childAddress Address of the child token's collection smart contract.
* @param childId ID of the child token in its own collection smart contract.
* @param isPending A boolean value indicating whether the child token being transferred is in the pending array of
* the parent token (`true`) or in the active array (`false`)
* @param data Additional data with no specified format, sent in call to `_to`
*/
function transferChild(
uint256 tokenId,
address to,
uint256 destinationId,
uint256 childIndex,
address childAddress,
uint256 childId,
bool isPending,
bytes memory data
) external;
/**
* @notice Used to retrieve the active child tokens of a given parent token.
* @dev Returns array of Child structs existing for parent token.
* @dev The Child struct consists of the following values:
* [
* tokenId,
* contractAddress
* ]
* @param parentId ID of the parent token for which to retrieve the active child tokens
* @return children An array of Child structs containing the parent token's active child tokens
*/
function childrenOf(
uint256 parentId
) external view returns (Child[] memory children);
/**
* @notice Used to retrieve the pending child tokens of a given parent token.
* @dev Returns array of pending Child structs existing for given parent.
* @dev The Child struct consists of the following values:
* [
* tokenId,
* contractAddress
* ]
* @param parentId ID of the parent token for which to retrieve the pending child tokens
* @return children An array of Child structs containing the parent token's pending child tokens
*/
function pendingChildrenOf(
uint256 parentId
) external view returns (Child[] memory children);
/**
* @notice Used to retrieve a specific active child token for a given parent token.
* @dev Returns a single Child struct locating at `index` of parent token's active child tokens array.
* @dev The Child struct consists of the following values:
* [
* tokenId,
* contractAddress
* ]
* @param parentId ID of the parent token for which the child is being retrieved
* @param index Index of the child token in the parent token's active child tokens array
* @return child A Child struct containing data about the specified child
*/
function childOf(
uint256 parentId,
uint256 index
) external view returns (Child memory child);
/**
* @notice Used to retrieve a specific pending child token from a given parent token.
* @dev Returns a single Child struct locating at `index` of parent token's active child tokens array.
* @dev The Child struct consists of the following values:
* [
* tokenId,
* contractAddress
* ]
* @param parentId ID of the parent token for which the pending child token is being retrieved
* @param index Index of the child token in the parent token's pending child tokens array
* @return child A Child struct containting data about the specified child
*/
function pendingChildOf(
uint256 parentId,
uint256 index
) external view returns (Child memory child);
/**
* @notice Used to transfer the token into another token.
* @param from Address of the direct owner of the token to be transferred
* @param to Address of the receiving token's collection smart contract
* @param tokenId ID of the token being transferred
* @param destinationId ID of the token to receive the token being transferred
* @param data Additional data with no specified format, sent in the addChild call
*/
function nestTransferFrom(
address from,
address to,
uint256 tokenId,
uint256 destinationId,
bytes memory data
) external;
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.21;
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
interface IOwnable {
/**
* @dev Returns owner
*/
function owner() external view returns (address ownerAddress);
/**
* @dev Allows the current owner to relinquish control of the contract.
*/
function renounceOwnership() external;
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) external;
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.21;
interface IRMRKImplementationBase {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function totalSupply() external view returns (uint256);
function maxSupply() external view returns (uint256);
function collectionMetadata() external view returns (string memory);
function contractURI() external view returns (string memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
error CannotAddCollectionWithMintedTokens();
error CollectionAddressCannotBeZero();
error CollectionAlreadyExists();
error CollectionAlreadySponsored();
error CollectionAlreadyVerified();
error CollectionDoesNotExist(address collection);
error CollectionHasMintedTokens();
error CollectionMetadataNotAvailable();
error CollectionNotAllowedForIssuer();
error CollectionNotSponsored();
error CollectionNotSponsoredBySender();
error CollectionSymbolCannotBeEmpty();
error NotEnoughAllowance();
error NotEnoughBalance();
error OnlyCollectionOwnerCanAddCollection();
error OnlyCollectionOwnerCanRemoveCollection();
error NotFactory();
error UnsupportedCollection();
interface IRMRKRegistry {
enum LegoCombination {
None,
MultiAsset,
Nestable,
NestableMultiAsset,
Equippable,
ERC721,
ERC1155,
Custom
}
enum MintingType {
None,
RMRKPreMint,
RMRKLazyMintNativeToken,
RMRKLazyMintERC20,
Custom
}
struct CollectionConfig {
bool usesOwnable;
bool usesAccessControl;
bool usesRMRKContributor;
bool usesRMRKMintingUtils;
bool usesRMRKLockable;
bool hasStandardAssetManagement; // has addAssetEntry, addEquippableAssetEntry, addAssetToToken, etc
bool hasStandardMinting; // has mint(address to, uint256 numToMint)
bool hasStandardNestMinting; // has nestMint(address to, uint256 numToMint, uint256 destinationId)
bool autoAcceptsFirstAsset;
uint8 customLegoCombination;
uint8 customMintingType;
bytes32 adminRole; // Only for AccessControl users
}
struct Collection {
address collection;
address verificationSponsor;
uint256 verificationFeeBalance;
LegoCombination legoCombination;
MintingType mintingType;
bool isSoulbound;
bool visible;
bool verified;
CollectionConfig config;
}
event CollectionAdded(
address collection,
address deployer,
string name,
string symbol,
uint256 maxSupply,
string collectionMetadata,
LegoCombination legoCombination,
MintingType mintingType,
bool isSoulbound,
CollectionConfig config
);
event CollectionBlacklisted(address collection);
event CollectionRemoved(address collection);
event CollectionSponsorshipCancelled(address collection);
event CollectionSponsored(address collection, address sponsor);
event CollectionUnverified(address collection);
event CollectionVerified(address collection);
function addCollectionFromFactories(
address collection,
address deployer,
uint256 maxSupply,
LegoCombination legoCombination,
MintingType mintingType,
bool isSoulbound
) external;
function addCollection(
address collection,
address deployer,
uint256 maxSupply,
LegoCombination legoCombination,
MintingType mintingType,
bool isSoulbound,
CollectionConfig memory config,
string memory collectionMetadata
) external;
function getMetaFactoryAddress() external view returns (address);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.21;
import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
// import "./ContextUpgradeable.sol";
import "@rmrk-team/evm-contracts/contracts/RMRK/library/RMRKErrors.sol";
/**
* @title OwnableUpgradeable
* @author RMRK team
* @notice A minimal upgradeable ownable smart contractf or owner and contributors.
* @dev This smart contract is based on "openzeppelin's access/Ownable.sol".
*/
contract OwnableUpgradeable is ContextUpgradeable {
address private _owner;
mapping(address => uint256) private _contributors;
/**
* @notice Used to anounce the transfer of ownership.
* @param previousOwner Address of the account that transferred their ownership role
* @param newOwner Address of the account receiving the ownership role
*/
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/**
* @notice Event that signifies that an address was granted contributor role or that the permission has been
* revoked.
* @dev This can only be triggered by a current owner, so there is no need to include that information in the event.
* @param contributor Address of the account that had contributor role status updated
* @param isContributor A boolean value signifying whether the role has been granted (`true`) or revoked (`false`)
*/
event ContributorUpdate(address indexed contributor, bool isContributor);
/**
* @dev Reverts if called by any account other than the owner or an approved contributor.
*/
modifier onlyOwnerOrContributor() {
_onlyOwnerOrContributor();
_;
}
/**
* @dev Reverts if called by any account other than the owner.
*/
modifier onlyOwner() {
_onlyOwner();
_;
}
/**
* @dev Initializes the contract by setting the deployer as the initial owner.
*/
function __OwnableUpgradeable_init() internal onlyInitializing {
__OwnableUpgradeable_init_unchained();
__Context_init();
}
/**
* @dev Initializes the contract by setting the deployer as the initial owner.
*/
function __OwnableUpgradeable_init_unchained() internal onlyInitializing {
_transferOwnership(_msgSender());
}
/**
* @notice Returns the address of the current owner.
* @return Address of the current owner
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @notice Leaves the contract without owner. Functions using the `onlyOwner` modifier will be disabled.
* @dev Can only be called by the current owner.
* @dev Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is
* only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @notice Transfers ownership of the contract to a new owner.
* @dev Can only be called by the current owner.
* @param newOwner Address of the new owner's account
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) revert RMRKNewOwnerIsZeroAddress();
_transferOwnership(newOwner);
}
/**
* @notice Transfers ownership of the contract to a new owner.
* @dev Internal function without access restriction.
* @dev Emits ***OwnershipTransferred*** event.
* @param newOwner Address of the new owner's account
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
/**
* @notice Adds or removes a contributor to the smart contract.
* @dev Can only be called by the owner.
* @dev Emits ***ContributorUpdate*** event.
* @param contributor Address of the contributor's account
* @param grantRole A boolean value signifying whether the contributor role is being granted (`true`) or revoked
* (`false`)
*/
function manageContributor(
address contributor,
bool grantRole
) external onlyOwner {
if (contributor == address(0)) revert RMRKNewContributorIsZeroAddress();
grantRole
? _contributors[contributor] = 1
: _contributors[contributor] = 0;
emit ContributorUpdate(contributor, grantRole);
}
/**
* @notice Used to check if the address is one of the contributors.
* @param contributor Address of the contributor whose status we are checking
* @return Boolean value indicating whether the address is a contributor or not
*/
function isContributor(address contributor) public view returns (bool) {
return _contributors[contributor] == 1;
}
/**
* @notice Used to verify that the caller is either the owner or a contributor.
* @dev If the caller is not the owner or a contributor, the execution will be reverted.
*/
function _onlyOwnerOrContributor() private view {
if (owner() != _msgSender() && !isContributor(_msgSender()))
revert RMRKNotOwnerOrContributor();
}
/**
* @notice Used to verify that the caller is the owner.
* @dev If the caller is not the owner, the execution will be reverted.
*/
function _onlyOwner() private view {
if (owner() != _msgSender()) revert RMRKNotOwner();
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)
pragma solidity ^0.8.0;
// import "./ContextUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract PausableUpgradeable is ContextUpgradeable {
error ContractPaused();
error ContractNotPaused();
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(bool pauseState, address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
function __Pausable_init() internal onlyInitializing {
__Pausable_init_unchained();
}
/**
* @dev Initializes the contract in unpaused state.
*/
function __Pausable_init_unchained() internal onlyInitializing {
_paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
if (paused()) {
revert ContractPaused();
}
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
if (!paused()) {
revert ContractNotPaused();
}
}
/**
* @dev Called by a pauser to pause, toggles paused state.
*/
function _pause(bool pauseState) internal virtual {
_paused = pauseState;
emit Paused(_paused, _msgSender());
}
}{
"evmVersion": "london",
"optimizer": {
"enabled": true,
"runs": 1
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"CannotAddCollectionWithMintedTokens","type":"error"},{"inputs":[],"name":"CollectionAddressCannotBeZero","type":"error"},{"inputs":[],"name":"CollectionAlreadyExists","type":"error"},{"inputs":[],"name":"CollectionAlreadySponsored","type":"error"},{"inputs":[],"name":"CollectionAlreadyVerified","type":"error"},{"inputs":[{"internalType":"address","name":"collection","type":"address"}],"name":"CollectionDoesNotExist","type":"error"},{"inputs":[],"name":"CollectionHasMintedTokens","type":"error"},{"inputs":[],"name":"CollectionMetadataNotAvailable","type":"error"},{"inputs":[],"name":"CollectionNotAllowedForIssuer","type":"error"},{"inputs":[],"name":"CollectionNotSponsored","type":"error"},{"inputs":[],"name":"CollectionNotSponsoredBySender","type":"error"},{"inputs":[],"name":"CollectionSymbolCannotBeEmpty","type":"error"},{"inputs":[],"name":"ContractNotPaused","type":"error"},{"inputs":[],"name":"ContractPaused","type":"error"},{"inputs":[],"name":"NotEnoughAllowance","type":"error"},{"inputs":[],"name":"NotEnoughBalance","type":"error"},{"inputs":[],"name":"NotFactory","type":"error"},{"inputs":[],"name":"OnlyCollectionOwnerCanAddCollection","type":"error"},{"inputs":[],"name":"OnlyCollectionOwnerCanRemoveCollection","type":"error"},{"inputs":[],"name":"RMRKNewContributorIsZeroAddress","type":"error"},{"inputs":[],"name":"RMRKNewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"RMRKNotOwner","type":"error"},{"inputs":[],"name":"RMRKNotOwnerOrContributor","type":"error"},{"inputs":[],"name":"UnsupportedCollection","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"collection","type":"address"},{"indexed":false,"internalType":"address","name":"deployer","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"maxSupply","type":"uint256"},{"indexed":false,"internalType":"string","name":"collectionMetadata","type":"string"},{"indexed":false,"internalType":"enum IRMRKRegistry.LegoCombination","name":"legoCombination","type":"uint8"},{"indexed":false,"internalType":"enum IRMRKRegistry.MintingType","name":"mintingType","type":"uint8"},{"indexed":false,"internalType":"bool","name":"isSoulbound","type":"bool"},{"components":[{"internalType":"bool","name":"usesOwnable","type":"bool"},{"internalType":"bool","name":"usesAccessControl","type":"bool"},{"internalType":"bool","name":"usesRMRKContributor","type":"bool"},{"internalType":"bool","name":"usesRMRKMintingUtils","type":"bool"},{"internalType":"bool","name":"usesRMRKLockable","type":"bool"},{"internalType":"bool","name":"hasStandardAssetManagement","type":"bool"},{"internalType":"bool","name":"hasStandardMinting","type":"bool"},{"internalType":"bool","name":"hasStandardNestMinting","type":"bool"},{"internalType":"bool","name":"autoAcceptsFirstAsset","type":"bool"},{"internalType":"uint8","name":"customLegoCombination","type":"uint8"},{"internalType":"uint8","name":"customMintingType","type":"uint8"},{"internalType":"bytes32","name":"adminRole","type":"bytes32"}],"indexed":false,"internalType":"struct IRMRKRegistry.CollectionConfig","name":"config","type":"tuple"}],"name":"CollectionAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"collection","type":"address"}],"name":"CollectionBlacklisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"collection","type":"address"}],"name":"CollectionRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"collection","type":"address"},{"indexed":false,"internalType":"address","name":"sponsor","type":"address"}],"name":"CollectionSponsored","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"collection","type":"address"}],"name":"CollectionSponsorshipCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"collection","type":"address"}],"name":"CollectionUnverified","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"collection","type":"address"}],"name":"CollectionVerified","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"contributor","type":"address"},{"indexed":false,"internalType":"bool","name":"isContributor","type":"bool"}],"name":"ContributorUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"pauseState","type":"bool"},{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"CUSTOM_MINTING_TYPE_FOR_EXTERNAL_COLLECTIONS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"deployer","type":"address"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"enum IRMRKRegistry.LegoCombination","name":"legoCombination","type":"uint8"},{"internalType":"enum IRMRKRegistry.MintingType","name":"mintingType","type":"uint8"},{"internalType":"bool","name":"isSoulbound","type":"bool"},{"components":[{"internalType":"bool","name":"usesOwnable","type":"bool"},{"internalType":"bool","name":"usesAccessControl","type":"bool"},{"internalType":"bool","name":"usesRMRKContributor","type":"bool"},{"internalType":"bool","name":"usesRMRKMintingUtils","type":"bool"},{"internalType":"bool","name":"usesRMRKLockable","type":"bool"},{"internalType":"bool","name":"hasStandardAssetManagement","type":"bool"},{"internalType":"bool","name":"hasStandardMinting","type":"bool"},{"internalType":"bool","name":"hasStandardNestMinting","type":"bool"},{"internalType":"bool","name":"autoAcceptsFirstAsset","type":"bool"},{"internalType":"uint8","name":"customLegoCombination","type":"uint8"},{"internalType":"uint8","name":"customMintingType","type":"uint8"},{"internalType":"bytes32","name":"adminRole","type":"bytes32"}],"internalType":"struct IRMRKRegistry.CollectionConfig","name":"config","type":"tuple"},{"internalType":"string","name":"collectionMetadata","type":"string"}],"name":"addCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"deployer","type":"address"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"enum IRMRKRegistry.LegoCombination","name":"legoCombination","type":"uint8"},{"internalType":"enum IRMRKRegistry.MintingType","name":"mintingType","type":"uint8"},{"internalType":"bool","name":"isSoulbound","type":"bool"}],"name":"addCollectionFromFactories","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"string","name":"collectionMetadata","type":"string"}],"name":"addExternalCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"factory","type":"address"}],"name":"addFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collectionAddress","type":"address"}],"name":"blackListCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collectionAddress","type":"address"}],"name":"cancelSponsorship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectionVerificationFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collectionAddress","type":"address"}],"name":"declineVerification","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"factories","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"factoryList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collectionAddress","type":"address"}],"name":"forceRemoveCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getCollectionAddressByIndex","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collectionAddress","type":"address"}],"name":"getCollectionByAddress","outputs":[{"components":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"verificationSponsor","type":"address"},{"internalType":"uint256","name":"verificationFeeBalance","type":"uint256"},{"internalType":"enum IRMRKRegistry.LegoCombination","name":"legoCombination","type":"uint8"},{"internalType":"enum IRMRKRegistry.MintingType","name":"mintingType","type":"uint8"},{"internalType":"bool","name":"isSoulbound","type":"bool"},{"internalType":"bool","name":"visible","type":"bool"},{"internalType":"bool","name":"verified","type":"bool"},{"components":[{"internalType":"bool","name":"usesOwnable","type":"bool"},{"internalType":"bool","name":"usesAccessControl","type":"bool"},{"internalType":"bool","name":"usesRMRKContributor","type":"bool"},{"internalType":"bool","name":"usesRMRKMintingUtils","type":"bool"},{"internalType":"bool","name":"usesRMRKLockable","type":"bool"},{"internalType":"bool","name":"hasStandardAssetManagement","type":"bool"},{"internalType":"bool","name":"hasStandardMinting","type":"bool"},{"internalType":"bool","name":"hasStandardNestMinting","type":"bool"},{"internalType":"bool","name":"autoAcceptsFirstAsset","type":"bool"},{"internalType":"uint8","name":"customLegoCombination","type":"uint8"},{"internalType":"uint8","name":"customMintingType","type":"uint8"},{"internalType":"bytes32","name":"adminRole","type":"bytes32"}],"internalType":"struct IRMRKRegistry.CollectionConfig","name":"config","type":"tuple"}],"internalType":"struct IRMRKRegistry.Collection","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getCollectionByIndex","outputs":[{"components":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"verificationSponsor","type":"address"},{"internalType":"uint256","name":"verificationFeeBalance","type":"uint256"},{"internalType":"enum IRMRKRegistry.LegoCombination","name":"legoCombination","type":"uint8"},{"internalType":"enum IRMRKRegistry.MintingType","name":"mintingType","type":"uint8"},{"internalType":"bool","name":"isSoulbound","type":"bool"},{"internalType":"bool","name":"visible","type":"bool"},{"internalType":"bool","name":"verified","type":"bool"},{"components":[{"internalType":"bool","name":"usesOwnable","type":"bool"},{"internalType":"bool","name":"usesAccessControl","type":"bool"},{"internalType":"bool","name":"usesRMRKContributor","type":"bool"},{"internalType":"bool","name":"usesRMRKMintingUtils","type":"bool"},{"internalType":"bool","name":"usesRMRKLockable","type":"bool"},{"internalType":"bool","name":"hasStandardAssetManagement","type":"bool"},{"internalType":"bool","name":"hasStandardMinting","type":"bool"},{"internalType":"bool","name":"hasStandardNestMinting","type":"bool"},{"internalType":"bool","name":"autoAcceptsFirstAsset","type":"bool"},{"internalType":"uint8","name":"customLegoCombination","type":"uint8"},{"internalType":"uint8","name":"customMintingType","type":"uint8"},{"internalType":"bytes32","name":"adminRole","type":"bytes32"}],"internalType":"struct IRMRKRegistry.CollectionConfig","name":"config","type":"tuple"}],"internalType":"struct IRMRKRegistry.Collection","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCollectionVerificationFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMetaFactoryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRmrkTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalCollectionCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"rmrkToken_","type":"address"},{"internalType":"uint256","name":"collectionVerificationFee_","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"string","name":"collectionSymbol","type":"string"}],"name":"isCollectionAllowedForIssuer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"}],"name":"isCollectionInRegistry","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributor","type":"address"}],"name":"isContributor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isProduction","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributor","type":"address"},{"internalType":"bool","name":"grantRole","type":"bool"}],"name":"manageContributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"pause","type":"bool"}],"name":"pauseRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collectionAddress","type":"address"}],"name":"removeCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"factory","type":"address"},{"internalType":"uint256","name":"factoryIndex","type":"uint256"}],"name":"removeFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rmrkToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"string","name":"collectionSymbol","type":"string"},{"internalType":"bool","name":"allowed","type":"bool"}],"name":"setCollectionAllowedPerIssuer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"metaFactory","type":"address"}],"name":"setMetaFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isProduction_","type":"bool"}],"name":"setProduction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collectionAddress","type":"address"}],"name":"sponsorVerification","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalCollectionsCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collectionAddress","type":"address"}],"name":"unblackListCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collectionAddress","type":"address"}],"name":"unverifyCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"collectionVerificationFee_","type":"uint256"}],"name":"updateCollectionVerificationFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"rmrkToken_","type":"address"}],"name":"updateRMRKTokenAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"collectionAddress","type":"address"}],"name":"verifyCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"withdrawFees","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60a06040523060805234801561001457600080fd5b5060805161424361004c60003960008181610c4e01528181610c9701528181610e5a01528181610e9a015261127701526142436000f3fe6080604052600436106102185760003560e01c80630184e8211461021d5780630c44218b1461024d5780630cb42c701461026f5780630d252c1014610293578063164e68de146102b357806319a49e3a146102d35780631d0d35f514610300578063213acdeb1461033957806329ce1ec5146103595780633659cfe6146103795780633707b630146103995780633711c363146103b95780633908cc93146103f157806339d10cc3146104115780633abd0651146104315780634a56644a146104515780634f1ef286146104715780635028d05a1461048457806352d1902d146104a4578063540834e3146104c75780635701df44146104e75780635c975abb146104fc5780636083f65514610514578063646286011461053457806364e32c4c1461055b578063715018a61461057b578063749dab031461059057806377c40550146105b057806379e8ca9e146105d05780637cceb15f146105f0578063845ac611146106105780638da5cb5b146106255780638ffca83e1461063a578063923e77161461065a5780639c4ba8361461067a578063a7b65d021461069a578063ad738ef4146106ba578063aea53d4e146106da578063b718a42c146106fa578063cc4c24aa14610718578063cd6dc68714610738578063dddfd61614610758578063f002804a1461076e578063f0090e571461078e578063f25c0635146107ae578063f2fde38b146107c4578063fab52689146107e4575b600080fd5b34801561022957600080fd5b50609f546001600160a01b03165b6040516102449190613762565b60405180910390f35b34801561025957600080fd5b5061026d61026836600461378b565b610814565b005b34801561027b57600080fd5b5060a85460ff165b6040519015158152602001610244565b34801561029f57600080fd5b506102836102ae3660046138ab565b61086d565b3480156102bf57600080fd5b5061026d6102ce3660046138fa565b610948565b3480156102df57600080fd5b506102f36102ee36600461391e565b6109d3565b6040516102449190613a3d565b34801561030c57600080fd5b5061028361031b3660046138fa565b6001600160a01b031660009081526034602052604090205460011490565b34801561034557600080fd5b5061023761035436600461391e565b610bac565b34801561036557600080fd5b5061026d6103743660046138fa565b610bd6565b34801561038557600080fd5b5061026d6103943660046138fa565b610c44565b3480156103a557600080fd5b5061026d6103b4366004613b04565b610d15565b3480156103c557600080fd5b506102836103d43660046138fa565b6001600160a01b0316600090815260a16020526040902054151590565b3480156103fd57600080fd5b5061026d61040c3660046138fa565b610d30565b34801561041d57600080fd5b5061026d61042c36600461391e565b610e19565b34801561043d57600080fd5b50609e54610237906001600160a01b031681565b34801561045d57600080fd5b5061026d61046c3660046138fa565b610e26565b61026d61047f366004613b21565b610e50565b34801561049057600080fd5b5061026d61049f3660046138fa565b610f09565b3480156104b057600080fd5b506104b961126a565b604051908152602001610244565b3480156104d357600080fd5b5061026d6104e2366004613b98565b611318565b3480156104f357600080fd5b50609a546104b9565b34801561050857600080fd5b5060355460ff16610283565b34801561052057600080fd5b5061026d61052f366004613b04565b611432565b34801561054057600080fd5b5061054960ff81565b60405160ff9091168152602001610244565b34801561056757600080fd5b5061026d6105763660046138fa565b611443565b34801561058757600080fd5b5061026d6116fe565b34801561059c57600080fd5b5061026d6105ab3660046138fa565b611712565b3480156105bc57600080fd5b5061026d6105cb3660046138fa565b61176d565b3480156105dc57600080fd5b5061026d6105eb366004613c0d565b6117d5565b3480156105fc57600080fd5b5061026d61060b3660046138fa565b611892565b34801561061c57600080fd5b5060a0546104b9565b34801561063157600080fd5b50610237611965565b34801561064657600080fd5b5061026d6106553660046138fa565b611974565b34801561066657600080fd5b5061026d6106753660046138fa565b611b35565b34801561068657600080fd5b5061026d610695366004613c46565b611bd7565b3480156106a657600080fd5b5061026d6106b53660046138ab565b611c9a565b3480156106c657600080fd5b5061026d6106d5366004613cba565b6121b8565b3480156106e657600080fd5b5061026d6106f53660046138fa565b6121e2565b34801561070657600080fd5b50609e546001600160a01b0316610237565b34801561072457600080fd5b5061023761073336600461391e565b61229c565b34801561074457600080fd5b5061026d61075336600461378b565b6122d1565b34801561076457600080fd5b506104b9609b5481565b34801561077a57600080fd5b506102f36107893660046138fa565b6124f7565b34801561079a57600080fd5b5061026d6107a93660046138fa565b612717565b3480156107ba57600080fd5b506104b9609a5481565b3480156107d057600080fd5b5061026d6107df3660046138fa565b612741565b3480156107f057600080fd5b506102836107ff3660046138fa565b609c6020526000908152604090205460ff1681565b61081c612779565b6001600160a01b0382166000908152609c60205260409020805460ff19169055609d80548290811061085057610850613e4e565b600091825260209091200180546001600160a01b03191690555050565b6000815160000361089157604051638398b93760e01b815260040160405180910390fd5b60a85460ff1615806108fe575060a96000846001600160a01b03166001600160a01b03168152602001908152602001600020604051806040016040528060018152602001601560f91b8152506040516108ea9190613e88565b9081526040519081900360200190205460ff165b8061093f57506001600160a01b038316600090815260a9602052604090819020905161092b908490613e88565b9081526040519081900360200190205460ff165b90505b92915050565b6109506127bd565b60a380546000909155609e5460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061098b9085908590600401613ea4565b6020604051808303816000875af11580156109aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ce9190613ebd565b505050565b6109db6136bb565b60a082815481106109ee576109ee613e4e565b60009182526020918290206040805161012081018252600690930290910180546001600160a01b039081168452600182015416938301939093526002830154908201526003820154909190606083019060ff166007811115610a5257610a52613937565b6007811115610a6357610a63613937565b81526020016003820160019054906101000a900460ff166004811115610a8b57610a8b613937565b6004811115610a9c57610a9c613937565b815260038201546201000080820460ff9081161515602080860191909152630100000080850483161515604080880191909152600160201b958690048416151560608089019190915281516101808101835260048a01548087161515825261010080820488161515968301969096529687048616151592810192909252918504841615159181019190915293830482161515608080860191909152600160281b84048316151560a0860152600160301b84048316151560c0860152600160381b84048316151560e0860152600160401b84048316151591850191909152600160481b83048216610120850152600160501b9092041661014083015260059093015461016082015291015292915050565b609d8181548110610bbc57600080fd5b6000918252602090912001546001600160a01b0316905081565b610bde612779565b6001600160a01b03166000818152609c60205260408120805460ff19166001908117909155609d805491820181559091527fd26e832454299e9fabb89e0e5fffdc046d4e14431bc1bf607ffb2e8a1ddecf7b0180546001600160a01b0319169091179055565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610c955760405162461bcd60e51b8152600401610c8c90613eda565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610cc76127ed565b6001600160a01b031614610ced5760405162461bcd60e51b8152600401610c8c90613f14565b610cf681612809565b60408051600080825260208201909252610d1291839190612811565b50565b610d1d612779565b60a8805460ff1916911515919091179055565b610d38612779565b6001600160a01b038116600090815260a1602052604081205490819003610d745781604051634580ccc360e11b8152600401610c8c9190613762565b600060a0610d83600184613f64565b81548110610d9357610d93613e4e565b906000526020600020906006020190508060020154600003610dc75760405162e5804760e31b815260040160405180910390fd5b60038101805460ff60201b1916600160201b1790556040517f5e0a07f8a1b8fe74cef346cd40f37e962e499bb7fbbb3ca3e0527d2948f6984790610e0c908590613762565b60405180910390a1505050565b610e21612779565b609a55565b610e2e612779565b609f80546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610e985760405162461bcd60e51b8152600401610c8c90613eda565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610eca6127ed565b6001600160a01b031614610ef05760405162461bcd60e51b8152600401610c8c90613f14565b610ef982612809565b610f0582826001612811565b5050565b610f1161297c565b6001600160a01b038116600090815260a1602052604081205490819003610f4d5781604051634580ccc360e11b8152600401610c8c9190613762565b610f58600182613f64565b9050600060a08281548110610f6f57610f6f613e4e565b60009182526020918290206040805161012081018252600690930290910180546001600160a01b039081168452600182015416938301939093526002830154908201526003820154909190606083019060ff166007811115610fd357610fd3613937565b6007811115610fe457610fe4613937565b81526020016003820160019054906101000a900460ff16600481111561100c5761100c613937565b600481111561101d5761101d613937565b815260038201546201000080820460ff9081161515602080860191909152630100000080850483161515604080880191909152600160201b958690048416151560608089019190915281516101808101835260048a01548087161515825261010080820488161515968301969096529687048616151592810192909252918504841615159181019190915293830482161515608080860191909152600160281b84048316151560a0860152600160301b84048316151560c0860152600160381b84048316151560e0860152600160401b84048316151591850191909152600160481b83048216610120850152600160501b909204166101408301526005909301546101608201529101529050336001600160a01b031681600001516001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611175573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111999190613f77565b6001600160a01b0316146111c057604051638f16e9eb60e01b815260040160405180910390fd5b6006816060015160078111156111d8576111d8613937565b14611260576000836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561121d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112419190613f94565b11156112605760405163c1c59d5360e01b815260040160405180910390fd5b6109ce83836129a0565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146113055760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c6044820152771b1959081d1a1c9bdd59da0819195b1959d85d1958d85b1b60421b6064820152608401610c8c565b506000805160206141c783398151915290565b336000908152609c602052604090205460ff1661134857604051631966391b60e11b815260040160405180910390fd5b604080516101808101825260a45460ff8082161515835261010080830482161515602080860191909152620100008404831615158587015263010000008404831615156060860152600160201b8404831615156080860152600160281b84048316151560a0860152600160301b84048316151560c0860152600160381b84048316151560e0860152600160401b84048316151591850191909152600160481b83048216610120850152600160501b9092041661014083015260a55461016083015282519081019092526000825261142a91889188918891889188918891612cd1565b505050505050565b61143a612779565b610d128161332a565b61144b61297c565b609a54609e546001600160a01b031663dd62ed3e33306040518363ffffffff1660e01b815260040161147e929190613fad565b602060405180830381865afa15801561149b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114bf9190613f94565b10156114de57604051634fd3af0760e01b815260040160405180910390fd5b609a54609e546001600160a01b03166370a08231336040518263ffffffff1660e01b815260040161150f9190613762565b602060405180830381865afa15801561152c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115509190613f94565b101561156f5760405163569d45cf60e11b815260040160405180910390fd5b6001600160a01b038116600090815260a16020526040812054908190036115ab5781604051634580ccc360e11b8152600401610c8c9190613762565b609a5460a260008282546115bf9190613fc7565b909155506000905060a06115d4600184613f64565b815481106115e4576115e4613e4e565b6000918252602090912060069091020160018101549091506001600160a01b031615611623576040516343e17fbb60e11b815260040160405180910390fd5b609a546002820155336001820180546001600160a01b0319166001600160a01b03928316179055609e54166323b872dd33609a546040516001600160e01b031960e085901b1681526001600160a01b03909216600483015230602483015260448201526064016020604051808303816000875af11580156116a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116cc9190613ebd565b507f8ae43f03c3a864e23098f158c34506280d61ac9fd8816f6557962c6cea7221d68333604051610e0c929190613fad565b6117066127bd565b6117106000613386565b565b61171a612779565b6001600160a01b038116600090815260a16020526040812054908190036117565781604051634580ccc360e11b8152600401610c8c9190613762565b611761600182613f64565b9050610f0582826129a0565b611775612779565b6001600160a01b038116600090815260a1602052604081205460a09061179d90600190613f64565b815481106117ad576117ad613e4e565b60009182526020909120600360069092020101805463ff000000191663010000001790555050565b6117dd6127bd565b6001600160a01b0382166118045760405163016b812760e71b815260040160405180910390fd5b80611829576001600160a01b0382166000908152603460205260408120819055611848565b6001600160a01b03821660009081526034602052604090206001908190555b50816001600160a01b03167f4b5657e84cf8a17ac5587bbeb3cc2bab9826c4c67b8bad81b4849de49d37aac282604051611886911515815260200190565b60405180910390a25050565b61189a612779565b6001600160a01b038116600090815260a1602052604081205460a0906118c290600190613f64565b815481106118d2576118d2613e4e565b90600052602060002090600602019050806002015460a360008282546118f89190613fc7565b9091555050600281015460a28054600090611914908490613f64565b909155505060038101805464ffff000000191690556040517f98b341583efd5a371b2e3094e23f9d87c5e4ec187739d33fa26fe6bc08ef4ec790611959908490613762565b60405180910390a15050565b6033546001600160a01b031690565b61197c61297c565b6001600160a01b038116600090815260a16020526040812054908190036119b85781604051634580ccc360e11b8152600401610c8c9190613762565b600060a06119c7600184613f64565b815481106119d7576119d7613e4e565b906000526020600020906006020190506119ee3390565b60018201546001600160a01b03908116911614611a1e5760405163fc43687560e01b815260040160405180910390fd5b6003810154600160201b900460ff1615611a4b57604051638d8f77f160e01b815260040160405180910390fd5b6000816002015490508060a26000828254611a669190613f64565b9091555050600060028301556001820180546001600160a01b0319169055609e546001600160a01b031663a9059cbb33836040518363ffffffff1660e01b8152600401611ab4929190613ea4565b6020604051808303816000875af1158015611ad3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af79190613ebd565b507f615de186fe6672ad36b495ca50ef1b79c75da6ed1606bba009c81a780e16474084604051611b279190613762565b60405180910390a150505050565b611b3d612779565b6001600160a01b038116600090815260a1602052604081205460a090611b6590600190613f64565b81548110611b7557611b75613e4e565b90600052602060002090600602019050806002015460a36000828254611b9b9190613fc7565b9091555050600281015460a28054600090611bb7908490613f64565b90915550506000600282015560010180546001600160a01b031916905550565b611bdf612779565b8151600003611c0157604051638398b93760e01b815260040160405180910390fd5b8015611c57576001600160a01b038316600090815260a9602052604090819020905160019190611c32908590613e88565b908152604051908190036020019020805491151560ff19909216919091179055505050565b6001600160a01b038316600090815260a96020526040908190209051611c7e908490613e88565b908152604051908190036020019020805460ff19169055505050565b336001600160a01b0316826001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ce2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d069190613f77565b6001600160a01b031614611d2d5760405163070adab760e01b815260040160405180910390fd5b6000826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611d6d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611d959190810190613fda565b9050611da1338261086d565b611dbe5760405163103e123160e11b815260040160405180910390fd5b600080846001600160a01b03166301ffc9a7630a2f26b960e21b6040518263ffffffff1660e01b8152600401611df49190614050565b602060405180830381865afa158015611e11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e359190613ebd565b90508015611e465760049150611f89565b6040516301ffc9a760e01b81526000906001600160a01b038716906301ffc9a790611e7c906342b0e56f60e01b90600401614050565b602060405180830381865afa158015611e99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ebd9190613ebd565b90506000866001600160a01b03166301ffc9a763035a194d60e11b6040518263ffffffff1660e01b8152600401611ef49190614050565b602060405180830381865afa158015611f11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f359190613ebd565b9050818015611f415750805b15611f4f5760039350611f86565b8115611f5e5760029350611f86565b8015611f6d5760019350611f86565b604051630179a91760e01b815260040160405180910390fd5b50505b6000856001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fed9190613f94565b111561200c57604051636483cdd960e11b815260040160405180910390fd5b6121b18533876001600160a01b031663d5abeb016040518163ffffffff1660e01b8152600401602060405180830381865afa15801561204f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120739190613f94565b8560048a6001600160a01b03166301ffc9a76391a6262f60e01b6040518263ffffffff1660e01b81526004016120a99190614050565b602060405180830381865afa1580156120c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ea9190613ebd565b604080516101808101825260a65460ff80821615158352610100808304821615156020850152620100008304821615159484019490945263010000008204811615156060840152600160201b8204811615156080840152600160281b82048116151560a0840152600160301b82048116151560c0840152600160381b82048116151560e0840152600160401b82048116151593830193909352600160481b81048316610120830152600160501b900490911661014082015260a7546101608201528b612cd1565b5050505050565b6121c061297c565b6121c8612779565b6121d88888888888888888612cd1565b5050505050505050565b6121ea612779565b6001600160a01b038116600090815260a16020526040812054908190036122265781604051634580ccc360e11b8152600401610c8c9190613762565b600060a0612235600184613f64565b8154811061224557612245613e4e565b906000526020600020906006020160030160046101000a81548160ff0219169083151502179055507f7403a0e4f4850762f1201c07ff352e8cb5cacb21e1cdb51424f685ca60ce3818826040516119599190613762565b600060a082815481106122b1576122b1613e4e565b60009182526020909120600690910201546001600160a01b031692915050565b600054610100900460ff16158080156122f15750600054600160ff909116105b806123125750612300306133d8565b158015612312575060005460ff166001145b6123755760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610c8c565b6000805460ff191660011790558015612398576000805461ff0019166101001790555b6123a06133e7565b6001609b819055609e80546001600160a01b0319166001600160a01b038616179055609a839055604080516101808082018352838252600060208084018290528385018690526060808501879052608080860188905260a080870189905260c08088018a905260e08089018b9052610100808a018c9052610120808b01899052610140808c018a90526101609b8c018a905260a48054680101010101010100016001600160581b03199182161790915560a58b90558d519b8c018e529d8b52978a018990529a890188905294880187905292870186905290860185905285018490528401839052830182905293820181905260ff938201939093520181905260a68054909216600160ff60501b011790915560a75580156109ce576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602001610e0c565b6124ff6136bb565b6001600160a01b038216600090815260a160205260408120549081900361253b5782604051634580ccc360e11b8152600401610c8c9190613762565b60a0612548600183613f64565b8154811061255857612558613e4e565b60009182526020918290206040805161012081018252600690930290910180546001600160a01b039081168452600182015416938301939093526002830154908201526003820154909190606083019060ff1660078111156125bc576125bc613937565b60078111156125cd576125cd613937565b81526020016003820160019054906101000a900460ff1660048111156125f5576125f5613937565b600481111561260657612606613937565b815260038201546201000080820460ff9081161515602080860191909152630100000080850483161515604080880191909152600160201b958690048416151560608089019190915281516101808101835260048a01548087161515825261010080820488161515968301969096529687048616151592810192909252918504841615159181019190915293830482161515608080860191909152600160281b84048316151560a0860152600160301b84048316151560c0860152600160381b84048316151560e0860152600160401b84048316151591850191909152600160481b83048216610120850152600160501b909204166101408301526005909301546101608201529101529392505050565b61271f612779565b609e80546001600160a01b0319166001600160a01b0392909216919091179055565b6127496127bd565b6001600160a01b03811661277057604051634ece6ecf60e01b815260040160405180910390fd5b610d1281613386565b33612782611965565b6001600160a01b03161415801561279f575061279d3361031b565b155b15611710576040516301eca16760e41b815260040160405180910390fd5b336127c6611965565b6001600160a01b03161461171057604051631c62d58f60e11b815260040160405180910390fd5b6000805160206141c7833981519152546001600160a01b031690565b610d126127bd565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612844576109ce8361341e565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561289e575060408051601f3d908101601f1916820190925261289b91810190613f94565b60015b6129015760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610c8c565b6000805160206141c783398151915281146129705760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610c8c565b506109ce8383836134b8565b60355460ff16156117105760405163ab35696f60e01b815260040160405180910390fd5b600060a082815481106129b5576129b5613e4e565b60009182526020918290206040805161012081018252600690930290910180546001600160a01b039081168452600182015416938301939093526002830154908201526003820154909190606083019060ff166007811115612a1957612a19613937565b6007811115612a2a57612a2a613937565b81526020016003820160019054906101000a900460ff166004811115612a5257612a52613937565b6004811115612a6357612a63613937565b8152600382015460ff6201000080830482161515602080860191909152630100000080850484161515604080880191909152600160201b958690048516151560608089019190915281516101808101835260048a01548088161515825261010080820489161515968301969096529586048716151592810192909252918404851615159181019190915293820483161515608085810191909152600160281b83048416151560a080870191909152600160301b84048516151560c0870152600160381b84048516151560e0870152600160401b84048516151592860192909252600160481b83048416610120860152600160501b909204909216610140840152600590940154610160830152929091015280549192509083908110612b8a57612b8a613e4e565b60009182526020808320600690920290910180546001600160a01b0319908116825560018201805490911690556002810183905560038101805464ffffffffff191690556004810180546001600160581b03191690556005018290556001600160a01b038516825260a1905260408082209190915581015115612ca2576000816040015190508060a26000828254612c229190613f64565b9091555050609e54602083015160405163a9059cbb60e01b81526001600160a01b039092169163a9059cbb91612c5c918590600401613ea4565b6020604051808303816000875af1158015612c7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c9f9190613ebd565b50505b7fa0691bd707b2f65c33c8343d61c274df72c6b5007937dcfbc31aa5a0d0f6fe3c83604051610e0c9190613762565b612cd961297c565b6001600160a01b038816612cff5760405162db1a2360e21b815260040160405180910390fd5b6001600160a01b038816600090815260a1602052604090205415612d365760405163d7feb16d60e01b815260040160405180910390fd5b60006040518061012001604052808a6001600160a01b0316815260200160006001600160a01b0316815260200160008152602001876007811115612d7c57612d7c613937565b8152602001866004811115612d9357612d93613937565b815260200185151581526020016001151581526020016000151581526020018481525090506000896001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015612df8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e209190810190613fda565b905060008a6001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612e62573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e8a9190810190613fda565b90506060600085511115612e9f575083612f88565b8b6001600160a01b031663e8a3d4856040518163ffffffff1660e01b8152600401600060405180830381865afa925050508015612efe57506040513d6000823e601f3d908101601f19168201604052612efb9190810190613fda565b60015b612f85578b6001600160a01b03166389ed2edf6040518163ffffffff1660e01b8152600401600060405180830381865afa925050508015612f6157506040513d6000823e601f3d908101601f19168201604052612f5e9190810190613fda565b60015b612f7e5760405163fd590a4360e01b815260040160405180910390fd5b9050612f88565b90505b60a0805460018181018355600092909252855160069091027f78fdc8d422c49ced035a9edf18d00d3c6a8d81df210f3e5e448e045e77b41e88810180546001600160a01b039384166001600160a01b031991821617825560208901517f78fdc8d422c49ced035a9edf18d00d3c6a8d81df210f3e5e448e045e77b41e89840180549190951691161790925560408701517f78fdc8d422c49ced035a9edf18d00d3c6a8d81df210f3e5e448e045e77b41e8a82015560608701517f78fdc8d422c49ced035a9edf18d00d3c6a8d81df210f3e5e448e045e77b41e8b9091018054889460ff199091169083600781111561308257613082613937565b0217905550608082015160038201805461ff0019166101008360048111156130ac576130ac613937565b021790555060a08201518160030160026101000a81548160ff02191690831515021790555060c08201518160030160036101000a81548160ff02191690831515021790555060e08201518160030160046101000a81548160ff0219169083151502179055506101008201518160040160008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548160ff02191690831515021790555060608201518160000160036101000a81548160ff02191690831515021790555060808201518160000160046101000a81548160ff02191690831515021790555060a08201518160000160056101000a81548160ff02191690831515021790555060c08201518160000160066101000a81548160ff02191690831515021790555060e08201518160000160076101000a81548160ff0219169083151502179055506101008201518160000160086101000a81548160ff0219169083151502179055506101208201518160000160096101000a81548160ff021916908360ff16021790555061014082015181600001600a6101000a81548160ff021916908360ff160217905550610160820151816001015550505050609b5460a160008e6001600160a01b03166001600160a01b0316815260200190815260200160002081905550609b60008154809291906132ce90614065565b91905055507f24b61a8776b1bd6b79fc5eebad6e8b2887706c95e63dcba08a8ac0423f22cd878c8c85858e868f8f8f8f6040516133149a999897969594939291906140aa565b60405180910390a1505050505050505050505050565b6035805460ff19168215159081179091557fbe7c303f209cd18ec0555e186104232ac132a445e860bb535d9d28b9f76ad1fa9060ff16336040805192151583526001600160a01b0390911660208301520160405180910390a150565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03163b151590565b600054610100900460ff1661340e5760405162461bcd60e51b8152600401610c8c90614148565b6134166134e3565b611710613513565b613427816133d8565b6134895760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610c8c565b6000805160206141c783398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6134c18361353a565b6000825111806134ce5750805b156109ce576134dd838361357a565b50505050565b600054610100900460ff1661350a5760405162461bcd60e51b8152600401610c8c90614148565b61171033613386565b600054610100900460ff166117105760405162461bcd60e51b8152600401610c8c90614148565b6135438161341e565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b606061093f83836040518060600160405280602781526020016141e7602791396060600080856001600160a01b0316856040516135b79190613e88565b600060405180830381855af49150503d80600081146135f2576040519150601f19603f3d011682016040523d82523d6000602084013e6135f7565b606091505b509150915061360886838387613612565b9695505050505050565b6060831561367f5782516000036136785761362c856133d8565b6136785760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c8c565b5081613689565b6136898383613691565b949350505050565b8151156136a15781518083602001fd5b8060405162461bcd60e51b8152600401610c8c9190614193565b604080516101208101825260008082526020820181905291810182905290606082019081526020016000815260006020808301829052604080840183905260608085018490528151610180810183528481529283018490529082018390528101829052608081810183905260a0820183905260c0820183905260e0820183905261010082018390526101208201839052610140820183905261016082019290925291015290565b6001600160a01b0391909116815260200190565b6001600160a01b0381168114610d1257600080fd5b6000806040838503121561379e57600080fd5b82356137a981613776565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b60405161018081016001600160401b03811182821017156137f0576137f06137b7565b60405290565b604051601f8201601f191681016001600160401b038111828210171561381e5761381e6137b7565b604052919050565b60006001600160401b0382111561383f5761383f6137b7565b50601f01601f191660200190565b600061386061385b84613826565b6137f6565b905082815283838301111561387457600080fd5b828260208301376000602084830101529392505050565b600082601f83011261389c57600080fd5b61093f8383356020850161384d565b600080604083850312156138be57600080fd5b82356138c981613776565b915060208301356001600160401b038111156138e457600080fd5b6138f08582860161388b565b9150509250929050565b60006020828403121561390c57600080fd5b813561391781613776565b9392505050565b60006020828403121561393057600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b6008811061395d5761395d613937565b9052565b6005811061395d5761395d613937565b805115158252602081015161398a602084018215159052565b50604081015161399e604084018215159052565b5060608101516139b2606084018215159052565b5060808101516139c6608084018215159052565b5060a08101516139da60a084018215159052565b5060c08101516139ee60c084018215159052565b5060e0810151613a0260e084018215159052565b50610100818101511515908301526101208082015160ff90811691840191909152610140808301519091169083015261016090810151910152565b81516001600160a01b0390811682526020808401519091169082015260408083015190820152606080830151610280830191613a7b9084018261394d565b506080830151613a8e6080840182613961565b5060a0830151613aa260a084018215159052565b5060c0830151613ab660c084018215159052565b5060e0830151613aca60e084018215159052565b5061010080840151613ade82850182613971565b505092915050565b8015158114610d1257600080fd5b8035613aff81613ae6565b919050565b600060208284031215613b1657600080fd5b813561391781613ae6565b60008060408385031215613b3457600080fd5b8235613b3f81613776565b915060208301356001600160401b03811115613b5a57600080fd5b8301601f81018513613b6b57600080fd5b6138f08582356020840161384d565b803560088110613aff57600080fd5b803560058110613aff57600080fd5b60008060008060008060c08789031215613bb157600080fd5b8635613bbc81613776565b95506020870135613bcc81613776565b945060408701359350613be160608801613b7a565b9250613bef60808801613b89565b915060a0870135613bff81613ae6565b809150509295509295509295565b60008060408385031215613c2057600080fd5b8235613c2b81613776565b91506020830135613c3b81613ae6565b809150509250929050565b600080600060608486031215613c5b57600080fd5b8335613c6681613776565b925060208401356001600160401b03811115613c8157600080fd5b613c8d8682870161388b565b9250506040840135613c9e81613ae6565b809150509250925092565b803560ff81168114613aff57600080fd5b600080600080600080600080888a03610260811215613cd857600080fd5b8935613ce381613776565b985060208a0135613cf381613776565b975060408a01359650613d0860608b01613b7a565b9550613d1660808b01613b89565b945060a08a0135613d2681613ae6565b935061018060bf1982011215613d3b57600080fd5b50613d446137cd565b613d5060c08b01613af4565b8152613d5e60e08b01613af4565b6020820152610100613d71818c01613af4565b6040830152610120613d84818d01613af4565b6060840152610140613d97818e01613af4565b6080850152610160613daa818f01613af4565b60a0860152613dbc6101808f01613af4565b60c0860152613dce6101a08f01613af4565b60e0860152613de06101c08f01613af4565b84860152613df16101e08f01613ca9565b83860152613e026102008f01613ca9565b918501919091526102208d01359084015250909250506102408901356001600160401b03811115613e3257600080fd5b613e3e8b828c0161388b565b9150509295985092959890939650565b634e487b7160e01b600052603260045260246000fd5b60005b83811015613e7f578181015183820152602001613e67565b50506000910152565b60008251613e9a818460208701613e64565b9190910192915050565b6001600160a01b03929092168252602082015260400190565b600060208284031215613ecf57600080fd5b815161391781613ae6565b6020808252602c908201526000805160206141a783398151915260408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201526000805160206141a783398151915260408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b8181038181111561094257610942613f4e565b600060208284031215613f8957600080fd5b815161391781613776565b600060208284031215613fa657600080fd5b5051919050565b6001600160a01b0392831681529116602082015260400190565b8082018082111561094257610942613f4e565b600060208284031215613fec57600080fd5b81516001600160401b0381111561400257600080fd5b8201601f8101841361401357600080fd5b805161402161385b82613826565b81815285602083850101111561403657600080fd5b614047826020830160208601613e64565b95945050505050565b6001600160e01b031991909116815260200190565b60006001820161407757614077613f4e565b5060010190565b60008151808452614096816020860160208601613e64565b601f01601f19169290920160200192915050565b6001600160a01b038b811682528a1660208201526102a0604082018190526000906140d78382018c61407e565b905082810360608401526140eb818b61407e565b905088608084015282810360a0840152614105818961407e565b91505061411560c083018761394d565b61412260e0830186613961565b831515610100830152614139610120830184613971565b9b9a5050505050505050505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60208152600061093f602083018461407e56fe46756e6374696f6e206d7573742062652063616c6c6564207468726f75676820360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212201b179803e03d0f5795e80162f0392563842663dae9b85553ee9bde41d97a3e2d64736f6c63430008150033
Deployed Bytecode
0x6080604052600436106102185760003560e01c80630184e8211461021d5780630c44218b1461024d5780630cb42c701461026f5780630d252c1014610293578063164e68de146102b357806319a49e3a146102d35780631d0d35f514610300578063213acdeb1461033957806329ce1ec5146103595780633659cfe6146103795780633707b630146103995780633711c363146103b95780633908cc93146103f157806339d10cc3146104115780633abd0651146104315780634a56644a146104515780634f1ef286146104715780635028d05a1461048457806352d1902d146104a4578063540834e3146104c75780635701df44146104e75780635c975abb146104fc5780636083f65514610514578063646286011461053457806364e32c4c1461055b578063715018a61461057b578063749dab031461059057806377c40550146105b057806379e8ca9e146105d05780637cceb15f146105f0578063845ac611146106105780638da5cb5b146106255780638ffca83e1461063a578063923e77161461065a5780639c4ba8361461067a578063a7b65d021461069a578063ad738ef4146106ba578063aea53d4e146106da578063b718a42c146106fa578063cc4c24aa14610718578063cd6dc68714610738578063dddfd61614610758578063f002804a1461076e578063f0090e571461078e578063f25c0635146107ae578063f2fde38b146107c4578063fab52689146107e4575b600080fd5b34801561022957600080fd5b50609f546001600160a01b03165b6040516102449190613762565b60405180910390f35b34801561025957600080fd5b5061026d61026836600461378b565b610814565b005b34801561027b57600080fd5b5060a85460ff165b6040519015158152602001610244565b34801561029f57600080fd5b506102836102ae3660046138ab565b61086d565b3480156102bf57600080fd5b5061026d6102ce3660046138fa565b610948565b3480156102df57600080fd5b506102f36102ee36600461391e565b6109d3565b6040516102449190613a3d565b34801561030c57600080fd5b5061028361031b3660046138fa565b6001600160a01b031660009081526034602052604090205460011490565b34801561034557600080fd5b5061023761035436600461391e565b610bac565b34801561036557600080fd5b5061026d6103743660046138fa565b610bd6565b34801561038557600080fd5b5061026d6103943660046138fa565b610c44565b3480156103a557600080fd5b5061026d6103b4366004613b04565b610d15565b3480156103c557600080fd5b506102836103d43660046138fa565b6001600160a01b0316600090815260a16020526040902054151590565b3480156103fd57600080fd5b5061026d61040c3660046138fa565b610d30565b34801561041d57600080fd5b5061026d61042c36600461391e565b610e19565b34801561043d57600080fd5b50609e54610237906001600160a01b031681565b34801561045d57600080fd5b5061026d61046c3660046138fa565b610e26565b61026d61047f366004613b21565b610e50565b34801561049057600080fd5b5061026d61049f3660046138fa565b610f09565b3480156104b057600080fd5b506104b961126a565b604051908152602001610244565b3480156104d357600080fd5b5061026d6104e2366004613b98565b611318565b3480156104f357600080fd5b50609a546104b9565b34801561050857600080fd5b5060355460ff16610283565b34801561052057600080fd5b5061026d61052f366004613b04565b611432565b34801561054057600080fd5b5061054960ff81565b60405160ff9091168152602001610244565b34801561056757600080fd5b5061026d6105763660046138fa565b611443565b34801561058757600080fd5b5061026d6116fe565b34801561059c57600080fd5b5061026d6105ab3660046138fa565b611712565b3480156105bc57600080fd5b5061026d6105cb3660046138fa565b61176d565b3480156105dc57600080fd5b5061026d6105eb366004613c0d565b6117d5565b3480156105fc57600080fd5b5061026d61060b3660046138fa565b611892565b34801561061c57600080fd5b5060a0546104b9565b34801561063157600080fd5b50610237611965565b34801561064657600080fd5b5061026d6106553660046138fa565b611974565b34801561066657600080fd5b5061026d6106753660046138fa565b611b35565b34801561068657600080fd5b5061026d610695366004613c46565b611bd7565b3480156106a657600080fd5b5061026d6106b53660046138ab565b611c9a565b3480156106c657600080fd5b5061026d6106d5366004613cba565b6121b8565b3480156106e657600080fd5b5061026d6106f53660046138fa565b6121e2565b34801561070657600080fd5b50609e546001600160a01b0316610237565b34801561072457600080fd5b5061023761073336600461391e565b61229c565b34801561074457600080fd5b5061026d61075336600461378b565b6122d1565b34801561076457600080fd5b506104b9609b5481565b34801561077a57600080fd5b506102f36107893660046138fa565b6124f7565b34801561079a57600080fd5b5061026d6107a93660046138fa565b612717565b3480156107ba57600080fd5b506104b9609a5481565b3480156107d057600080fd5b5061026d6107df3660046138fa565b612741565b3480156107f057600080fd5b506102836107ff3660046138fa565b609c6020526000908152604090205460ff1681565b61081c612779565b6001600160a01b0382166000908152609c60205260409020805460ff19169055609d80548290811061085057610850613e4e565b600091825260209091200180546001600160a01b03191690555050565b6000815160000361089157604051638398b93760e01b815260040160405180910390fd5b60a85460ff1615806108fe575060a96000846001600160a01b03166001600160a01b03168152602001908152602001600020604051806040016040528060018152602001601560f91b8152506040516108ea9190613e88565b9081526040519081900360200190205460ff165b8061093f57506001600160a01b038316600090815260a9602052604090819020905161092b908490613e88565b9081526040519081900360200190205460ff165b90505b92915050565b6109506127bd565b60a380546000909155609e5460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061098b9085908590600401613ea4565b6020604051808303816000875af11580156109aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ce9190613ebd565b505050565b6109db6136bb565b60a082815481106109ee576109ee613e4e565b60009182526020918290206040805161012081018252600690930290910180546001600160a01b039081168452600182015416938301939093526002830154908201526003820154909190606083019060ff166007811115610a5257610a52613937565b6007811115610a6357610a63613937565b81526020016003820160019054906101000a900460ff166004811115610a8b57610a8b613937565b6004811115610a9c57610a9c613937565b815260038201546201000080820460ff9081161515602080860191909152630100000080850483161515604080880191909152600160201b958690048416151560608089019190915281516101808101835260048a01548087161515825261010080820488161515968301969096529687048616151592810192909252918504841615159181019190915293830482161515608080860191909152600160281b84048316151560a0860152600160301b84048316151560c0860152600160381b84048316151560e0860152600160401b84048316151591850191909152600160481b83048216610120850152600160501b9092041661014083015260059093015461016082015291015292915050565b609d8181548110610bbc57600080fd5b6000918252602090912001546001600160a01b0316905081565b610bde612779565b6001600160a01b03166000818152609c60205260408120805460ff19166001908117909155609d805491820181559091527fd26e832454299e9fabb89e0e5fffdc046d4e14431bc1bf607ffb2e8a1ddecf7b0180546001600160a01b0319169091179055565b6001600160a01b037f00000000000000000000000094b0144bdd5e876cd362957adf624e35c8ca8f68163003610c955760405162461bcd60e51b8152600401610c8c90613eda565b60405180910390fd5b7f00000000000000000000000094b0144bdd5e876cd362957adf624e35c8ca8f686001600160a01b0316610cc76127ed565b6001600160a01b031614610ced5760405162461bcd60e51b8152600401610c8c90613f14565b610cf681612809565b60408051600080825260208201909252610d1291839190612811565b50565b610d1d612779565b60a8805460ff1916911515919091179055565b610d38612779565b6001600160a01b038116600090815260a1602052604081205490819003610d745781604051634580ccc360e11b8152600401610c8c9190613762565b600060a0610d83600184613f64565b81548110610d9357610d93613e4e565b906000526020600020906006020190508060020154600003610dc75760405162e5804760e31b815260040160405180910390fd5b60038101805460ff60201b1916600160201b1790556040517f5e0a07f8a1b8fe74cef346cd40f37e962e499bb7fbbb3ca3e0527d2948f6984790610e0c908590613762565b60405180910390a1505050565b610e21612779565b609a55565b610e2e612779565b609f80546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b037f00000000000000000000000094b0144bdd5e876cd362957adf624e35c8ca8f68163003610e985760405162461bcd60e51b8152600401610c8c90613eda565b7f00000000000000000000000094b0144bdd5e876cd362957adf624e35c8ca8f686001600160a01b0316610eca6127ed565b6001600160a01b031614610ef05760405162461bcd60e51b8152600401610c8c90613f14565b610ef982612809565b610f0582826001612811565b5050565b610f1161297c565b6001600160a01b038116600090815260a1602052604081205490819003610f4d5781604051634580ccc360e11b8152600401610c8c9190613762565b610f58600182613f64565b9050600060a08281548110610f6f57610f6f613e4e565b60009182526020918290206040805161012081018252600690930290910180546001600160a01b039081168452600182015416938301939093526002830154908201526003820154909190606083019060ff166007811115610fd357610fd3613937565b6007811115610fe457610fe4613937565b81526020016003820160019054906101000a900460ff16600481111561100c5761100c613937565b600481111561101d5761101d613937565b815260038201546201000080820460ff9081161515602080860191909152630100000080850483161515604080880191909152600160201b958690048416151560608089019190915281516101808101835260048a01548087161515825261010080820488161515968301969096529687048616151592810192909252918504841615159181019190915293830482161515608080860191909152600160281b84048316151560a0860152600160301b84048316151560c0860152600160381b84048316151560e0860152600160401b84048316151591850191909152600160481b83048216610120850152600160501b909204166101408301526005909301546101608201529101529050336001600160a01b031681600001516001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611175573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111999190613f77565b6001600160a01b0316146111c057604051638f16e9eb60e01b815260040160405180910390fd5b6006816060015160078111156111d8576111d8613937565b14611260576000836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561121d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112419190613f94565b11156112605760405163c1c59d5360e01b815260040160405180910390fd5b6109ce83836129a0565b6000306001600160a01b037f00000000000000000000000094b0144bdd5e876cd362957adf624e35c8ca8f6816146113055760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c6044820152771b1959081d1a1c9bdd59da0819195b1959d85d1958d85b1b60421b6064820152608401610c8c565b506000805160206141c783398151915290565b336000908152609c602052604090205460ff1661134857604051631966391b60e11b815260040160405180910390fd5b604080516101808101825260a45460ff8082161515835261010080830482161515602080860191909152620100008404831615158587015263010000008404831615156060860152600160201b8404831615156080860152600160281b84048316151560a0860152600160301b84048316151560c0860152600160381b84048316151560e0860152600160401b84048316151591850191909152600160481b83048216610120850152600160501b9092041661014083015260a55461016083015282519081019092526000825261142a91889188918891889188918891612cd1565b505050505050565b61143a612779565b610d128161332a565b61144b61297c565b609a54609e546001600160a01b031663dd62ed3e33306040518363ffffffff1660e01b815260040161147e929190613fad565b602060405180830381865afa15801561149b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114bf9190613f94565b10156114de57604051634fd3af0760e01b815260040160405180910390fd5b609a54609e546001600160a01b03166370a08231336040518263ffffffff1660e01b815260040161150f9190613762565b602060405180830381865afa15801561152c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115509190613f94565b101561156f5760405163569d45cf60e11b815260040160405180910390fd5b6001600160a01b038116600090815260a16020526040812054908190036115ab5781604051634580ccc360e11b8152600401610c8c9190613762565b609a5460a260008282546115bf9190613fc7565b909155506000905060a06115d4600184613f64565b815481106115e4576115e4613e4e565b6000918252602090912060069091020160018101549091506001600160a01b031615611623576040516343e17fbb60e11b815260040160405180910390fd5b609a546002820155336001820180546001600160a01b0319166001600160a01b03928316179055609e54166323b872dd33609a546040516001600160e01b031960e085901b1681526001600160a01b03909216600483015230602483015260448201526064016020604051808303816000875af11580156116a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116cc9190613ebd565b507f8ae43f03c3a864e23098f158c34506280d61ac9fd8816f6557962c6cea7221d68333604051610e0c929190613fad565b6117066127bd565b6117106000613386565b565b61171a612779565b6001600160a01b038116600090815260a16020526040812054908190036117565781604051634580ccc360e11b8152600401610c8c9190613762565b611761600182613f64565b9050610f0582826129a0565b611775612779565b6001600160a01b038116600090815260a1602052604081205460a09061179d90600190613f64565b815481106117ad576117ad613e4e565b60009182526020909120600360069092020101805463ff000000191663010000001790555050565b6117dd6127bd565b6001600160a01b0382166118045760405163016b812760e71b815260040160405180910390fd5b80611829576001600160a01b0382166000908152603460205260408120819055611848565b6001600160a01b03821660009081526034602052604090206001908190555b50816001600160a01b03167f4b5657e84cf8a17ac5587bbeb3cc2bab9826c4c67b8bad81b4849de49d37aac282604051611886911515815260200190565b60405180910390a25050565b61189a612779565b6001600160a01b038116600090815260a1602052604081205460a0906118c290600190613f64565b815481106118d2576118d2613e4e565b90600052602060002090600602019050806002015460a360008282546118f89190613fc7565b9091555050600281015460a28054600090611914908490613f64565b909155505060038101805464ffff000000191690556040517f98b341583efd5a371b2e3094e23f9d87c5e4ec187739d33fa26fe6bc08ef4ec790611959908490613762565b60405180910390a15050565b6033546001600160a01b031690565b61197c61297c565b6001600160a01b038116600090815260a16020526040812054908190036119b85781604051634580ccc360e11b8152600401610c8c9190613762565b600060a06119c7600184613f64565b815481106119d7576119d7613e4e565b906000526020600020906006020190506119ee3390565b60018201546001600160a01b03908116911614611a1e5760405163fc43687560e01b815260040160405180910390fd5b6003810154600160201b900460ff1615611a4b57604051638d8f77f160e01b815260040160405180910390fd5b6000816002015490508060a26000828254611a669190613f64565b9091555050600060028301556001820180546001600160a01b0319169055609e546001600160a01b031663a9059cbb33836040518363ffffffff1660e01b8152600401611ab4929190613ea4565b6020604051808303816000875af1158015611ad3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af79190613ebd565b507f615de186fe6672ad36b495ca50ef1b79c75da6ed1606bba009c81a780e16474084604051611b279190613762565b60405180910390a150505050565b611b3d612779565b6001600160a01b038116600090815260a1602052604081205460a090611b6590600190613f64565b81548110611b7557611b75613e4e565b90600052602060002090600602019050806002015460a36000828254611b9b9190613fc7565b9091555050600281015460a28054600090611bb7908490613f64565b90915550506000600282015560010180546001600160a01b031916905550565b611bdf612779565b8151600003611c0157604051638398b93760e01b815260040160405180910390fd5b8015611c57576001600160a01b038316600090815260a9602052604090819020905160019190611c32908590613e88565b908152604051908190036020019020805491151560ff19909216919091179055505050565b6001600160a01b038316600090815260a96020526040908190209051611c7e908490613e88565b908152604051908190036020019020805460ff19169055505050565b336001600160a01b0316826001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ce2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d069190613f77565b6001600160a01b031614611d2d5760405163070adab760e01b815260040160405180910390fd5b6000826001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611d6d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611d959190810190613fda565b9050611da1338261086d565b611dbe5760405163103e123160e11b815260040160405180910390fd5b600080846001600160a01b03166301ffc9a7630a2f26b960e21b6040518263ffffffff1660e01b8152600401611df49190614050565b602060405180830381865afa158015611e11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e359190613ebd565b90508015611e465760049150611f89565b6040516301ffc9a760e01b81526000906001600160a01b038716906301ffc9a790611e7c906342b0e56f60e01b90600401614050565b602060405180830381865afa158015611e99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ebd9190613ebd565b90506000866001600160a01b03166301ffc9a763035a194d60e11b6040518263ffffffff1660e01b8152600401611ef49190614050565b602060405180830381865afa158015611f11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f359190613ebd565b9050818015611f415750805b15611f4f5760039350611f86565b8115611f5e5760029350611f86565b8015611f6d5760019350611f86565b604051630179a91760e01b815260040160405180910390fd5b50505b6000856001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fed9190613f94565b111561200c57604051636483cdd960e11b815260040160405180910390fd5b6121b18533876001600160a01b031663d5abeb016040518163ffffffff1660e01b8152600401602060405180830381865afa15801561204f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120739190613f94565b8560048a6001600160a01b03166301ffc9a76391a6262f60e01b6040518263ffffffff1660e01b81526004016120a99190614050565b602060405180830381865afa1580156120c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ea9190613ebd565b604080516101808101825260a65460ff80821615158352610100808304821615156020850152620100008304821615159484019490945263010000008204811615156060840152600160201b8204811615156080840152600160281b82048116151560a0840152600160301b82048116151560c0840152600160381b82048116151560e0840152600160401b82048116151593830193909352600160481b81048316610120830152600160501b900490911661014082015260a7546101608201528b612cd1565b5050505050565b6121c061297c565b6121c8612779565b6121d88888888888888888612cd1565b5050505050505050565b6121ea612779565b6001600160a01b038116600090815260a16020526040812054908190036122265781604051634580ccc360e11b8152600401610c8c9190613762565b600060a0612235600184613f64565b8154811061224557612245613e4e565b906000526020600020906006020160030160046101000a81548160ff0219169083151502179055507f7403a0e4f4850762f1201c07ff352e8cb5cacb21e1cdb51424f685ca60ce3818826040516119599190613762565b600060a082815481106122b1576122b1613e4e565b60009182526020909120600690910201546001600160a01b031692915050565b600054610100900460ff16158080156122f15750600054600160ff909116105b806123125750612300306133d8565b158015612312575060005460ff166001145b6123755760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610c8c565b6000805460ff191660011790558015612398576000805461ff0019166101001790555b6123a06133e7565b6001609b819055609e80546001600160a01b0319166001600160a01b038616179055609a839055604080516101808082018352838252600060208084018290528385018690526060808501879052608080860188905260a080870189905260c08088018a905260e08089018b9052610100808a018c9052610120808b01899052610140808c018a90526101609b8c018a905260a48054680101010101010100016001600160581b03199182161790915560a58b90558d519b8c018e529d8b52978a018990529a890188905294880187905292870186905290860185905285018490528401839052830182905293820181905260ff938201939093520181905260a68054909216600160ff60501b011790915560a75580156109ce576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602001610e0c565b6124ff6136bb565b6001600160a01b038216600090815260a160205260408120549081900361253b5782604051634580ccc360e11b8152600401610c8c9190613762565b60a0612548600183613f64565b8154811061255857612558613e4e565b60009182526020918290206040805161012081018252600690930290910180546001600160a01b039081168452600182015416938301939093526002830154908201526003820154909190606083019060ff1660078111156125bc576125bc613937565b60078111156125cd576125cd613937565b81526020016003820160019054906101000a900460ff1660048111156125f5576125f5613937565b600481111561260657612606613937565b815260038201546201000080820460ff9081161515602080860191909152630100000080850483161515604080880191909152600160201b958690048416151560608089019190915281516101808101835260048a01548087161515825261010080820488161515968301969096529687048616151592810192909252918504841615159181019190915293830482161515608080860191909152600160281b84048316151560a0860152600160301b84048316151560c0860152600160381b84048316151560e0860152600160401b84048316151591850191909152600160481b83048216610120850152600160501b909204166101408301526005909301546101608201529101529392505050565b61271f612779565b609e80546001600160a01b0319166001600160a01b0392909216919091179055565b6127496127bd565b6001600160a01b03811661277057604051634ece6ecf60e01b815260040160405180910390fd5b610d1281613386565b33612782611965565b6001600160a01b03161415801561279f575061279d3361031b565b155b15611710576040516301eca16760e41b815260040160405180910390fd5b336127c6611965565b6001600160a01b03161461171057604051631c62d58f60e11b815260040160405180910390fd5b6000805160206141c7833981519152546001600160a01b031690565b610d126127bd565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612844576109ce8361341e565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561289e575060408051601f3d908101601f1916820190925261289b91810190613f94565b60015b6129015760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610c8c565b6000805160206141c783398151915281146129705760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610c8c565b506109ce8383836134b8565b60355460ff16156117105760405163ab35696f60e01b815260040160405180910390fd5b600060a082815481106129b5576129b5613e4e565b60009182526020918290206040805161012081018252600690930290910180546001600160a01b039081168452600182015416938301939093526002830154908201526003820154909190606083019060ff166007811115612a1957612a19613937565b6007811115612a2a57612a2a613937565b81526020016003820160019054906101000a900460ff166004811115612a5257612a52613937565b6004811115612a6357612a63613937565b8152600382015460ff6201000080830482161515602080860191909152630100000080850484161515604080880191909152600160201b958690048516151560608089019190915281516101808101835260048a01548088161515825261010080820489161515968301969096529586048716151592810192909252918404851615159181019190915293820483161515608085810191909152600160281b83048416151560a080870191909152600160301b84048516151560c0870152600160381b84048516151560e0870152600160401b84048516151592860192909252600160481b83048416610120860152600160501b909204909216610140840152600590940154610160830152929091015280549192509083908110612b8a57612b8a613e4e565b60009182526020808320600690920290910180546001600160a01b0319908116825560018201805490911690556002810183905560038101805464ffffffffff191690556004810180546001600160581b03191690556005018290556001600160a01b038516825260a1905260408082209190915581015115612ca2576000816040015190508060a26000828254612c229190613f64565b9091555050609e54602083015160405163a9059cbb60e01b81526001600160a01b039092169163a9059cbb91612c5c918590600401613ea4565b6020604051808303816000875af1158015612c7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c9f9190613ebd565b50505b7fa0691bd707b2f65c33c8343d61c274df72c6b5007937dcfbc31aa5a0d0f6fe3c83604051610e0c9190613762565b612cd961297c565b6001600160a01b038816612cff5760405162db1a2360e21b815260040160405180910390fd5b6001600160a01b038816600090815260a1602052604090205415612d365760405163d7feb16d60e01b815260040160405180910390fd5b60006040518061012001604052808a6001600160a01b0316815260200160006001600160a01b0316815260200160008152602001876007811115612d7c57612d7c613937565b8152602001866004811115612d9357612d93613937565b815260200185151581526020016001151581526020016000151581526020018481525090506000896001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015612df8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e209190810190613fda565b905060008a6001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015612e62573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e8a9190810190613fda565b90506060600085511115612e9f575083612f88565b8b6001600160a01b031663e8a3d4856040518163ffffffff1660e01b8152600401600060405180830381865afa925050508015612efe57506040513d6000823e601f3d908101601f19168201604052612efb9190810190613fda565b60015b612f85578b6001600160a01b03166389ed2edf6040518163ffffffff1660e01b8152600401600060405180830381865afa925050508015612f6157506040513d6000823e601f3d908101601f19168201604052612f5e9190810190613fda565b60015b612f7e5760405163fd590a4360e01b815260040160405180910390fd5b9050612f88565b90505b60a0805460018181018355600092909252855160069091027f78fdc8d422c49ced035a9edf18d00d3c6a8d81df210f3e5e448e045e77b41e88810180546001600160a01b039384166001600160a01b031991821617825560208901517f78fdc8d422c49ced035a9edf18d00d3c6a8d81df210f3e5e448e045e77b41e89840180549190951691161790925560408701517f78fdc8d422c49ced035a9edf18d00d3c6a8d81df210f3e5e448e045e77b41e8a82015560608701517f78fdc8d422c49ced035a9edf18d00d3c6a8d81df210f3e5e448e045e77b41e8b9091018054889460ff199091169083600781111561308257613082613937565b0217905550608082015160038201805461ff0019166101008360048111156130ac576130ac613937565b021790555060a08201518160030160026101000a81548160ff02191690831515021790555060c08201518160030160036101000a81548160ff02191690831515021790555060e08201518160030160046101000a81548160ff0219169083151502179055506101008201518160040160008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548160ff02191690831515021790555060608201518160000160036101000a81548160ff02191690831515021790555060808201518160000160046101000a81548160ff02191690831515021790555060a08201518160000160056101000a81548160ff02191690831515021790555060c08201518160000160066101000a81548160ff02191690831515021790555060e08201518160000160076101000a81548160ff0219169083151502179055506101008201518160000160086101000a81548160ff0219169083151502179055506101208201518160000160096101000a81548160ff021916908360ff16021790555061014082015181600001600a6101000a81548160ff021916908360ff160217905550610160820151816001015550505050609b5460a160008e6001600160a01b03166001600160a01b0316815260200190815260200160002081905550609b60008154809291906132ce90614065565b91905055507f24b61a8776b1bd6b79fc5eebad6e8b2887706c95e63dcba08a8ac0423f22cd878c8c85858e868f8f8f8f6040516133149a999897969594939291906140aa565b60405180910390a1505050505050505050505050565b6035805460ff19168215159081179091557fbe7c303f209cd18ec0555e186104232ac132a445e860bb535d9d28b9f76ad1fa9060ff16336040805192151583526001600160a01b0390911660208301520160405180910390a150565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03163b151590565b600054610100900460ff1661340e5760405162461bcd60e51b8152600401610c8c90614148565b6134166134e3565b611710613513565b613427816133d8565b6134895760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610c8c565b6000805160206141c783398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6134c18361353a565b6000825111806134ce5750805b156109ce576134dd838361357a565b50505050565b600054610100900460ff1661350a5760405162461bcd60e51b8152600401610c8c90614148565b61171033613386565b600054610100900460ff166117105760405162461bcd60e51b8152600401610c8c90614148565b6135438161341e565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b606061093f83836040518060600160405280602781526020016141e7602791396060600080856001600160a01b0316856040516135b79190613e88565b600060405180830381855af49150503d80600081146135f2576040519150601f19603f3d011682016040523d82523d6000602084013e6135f7565b606091505b509150915061360886838387613612565b9695505050505050565b6060831561367f5782516000036136785761362c856133d8565b6136785760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c8c565b5081613689565b6136898383613691565b949350505050565b8151156136a15781518083602001fd5b8060405162461bcd60e51b8152600401610c8c9190614193565b604080516101208101825260008082526020820181905291810182905290606082019081526020016000815260006020808301829052604080840183905260608085018490528151610180810183528481529283018490529082018390528101829052608081810183905260a0820183905260c0820183905260e0820183905261010082018390526101208201839052610140820183905261016082019290925291015290565b6001600160a01b0391909116815260200190565b6001600160a01b0381168114610d1257600080fd5b6000806040838503121561379e57600080fd5b82356137a981613776565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b60405161018081016001600160401b03811182821017156137f0576137f06137b7565b60405290565b604051601f8201601f191681016001600160401b038111828210171561381e5761381e6137b7565b604052919050565b60006001600160401b0382111561383f5761383f6137b7565b50601f01601f191660200190565b600061386061385b84613826565b6137f6565b905082815283838301111561387457600080fd5b828260208301376000602084830101529392505050565b600082601f83011261389c57600080fd5b61093f8383356020850161384d565b600080604083850312156138be57600080fd5b82356138c981613776565b915060208301356001600160401b038111156138e457600080fd5b6138f08582860161388b565b9150509250929050565b60006020828403121561390c57600080fd5b813561391781613776565b9392505050565b60006020828403121561393057600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b6008811061395d5761395d613937565b9052565b6005811061395d5761395d613937565b805115158252602081015161398a602084018215159052565b50604081015161399e604084018215159052565b5060608101516139b2606084018215159052565b5060808101516139c6608084018215159052565b5060a08101516139da60a084018215159052565b5060c08101516139ee60c084018215159052565b5060e0810151613a0260e084018215159052565b50610100818101511515908301526101208082015160ff90811691840191909152610140808301519091169083015261016090810151910152565b81516001600160a01b0390811682526020808401519091169082015260408083015190820152606080830151610280830191613a7b9084018261394d565b506080830151613a8e6080840182613961565b5060a0830151613aa260a084018215159052565b5060c0830151613ab660c084018215159052565b5060e0830151613aca60e084018215159052565b5061010080840151613ade82850182613971565b505092915050565b8015158114610d1257600080fd5b8035613aff81613ae6565b919050565b600060208284031215613b1657600080fd5b813561391781613ae6565b60008060408385031215613b3457600080fd5b8235613b3f81613776565b915060208301356001600160401b03811115613b5a57600080fd5b8301601f81018513613b6b57600080fd5b6138f08582356020840161384d565b803560088110613aff57600080fd5b803560058110613aff57600080fd5b60008060008060008060c08789031215613bb157600080fd5b8635613bbc81613776565b95506020870135613bcc81613776565b945060408701359350613be160608801613b7a565b9250613bef60808801613b89565b915060a0870135613bff81613ae6565b809150509295509295509295565b60008060408385031215613c2057600080fd5b8235613c2b81613776565b91506020830135613c3b81613ae6565b809150509250929050565b600080600060608486031215613c5b57600080fd5b8335613c6681613776565b925060208401356001600160401b03811115613c8157600080fd5b613c8d8682870161388b565b9250506040840135613c9e81613ae6565b809150509250925092565b803560ff81168114613aff57600080fd5b600080600080600080600080888a03610260811215613cd857600080fd5b8935613ce381613776565b985060208a0135613cf381613776565b975060408a01359650613d0860608b01613b7a565b9550613d1660808b01613b89565b945060a08a0135613d2681613ae6565b935061018060bf1982011215613d3b57600080fd5b50613d446137cd565b613d5060c08b01613af4565b8152613d5e60e08b01613af4565b6020820152610100613d71818c01613af4565b6040830152610120613d84818d01613af4565b6060840152610140613d97818e01613af4565b6080850152610160613daa818f01613af4565b60a0860152613dbc6101808f01613af4565b60c0860152613dce6101a08f01613af4565b60e0860152613de06101c08f01613af4565b84860152613df16101e08f01613ca9565b83860152613e026102008f01613ca9565b918501919091526102208d01359084015250909250506102408901356001600160401b03811115613e3257600080fd5b613e3e8b828c0161388b565b9150509295985092959890939650565b634e487b7160e01b600052603260045260246000fd5b60005b83811015613e7f578181015183820152602001613e67565b50506000910152565b60008251613e9a818460208701613e64565b9190910192915050565b6001600160a01b03929092168252602082015260400190565b600060208284031215613ecf57600080fd5b815161391781613ae6565b6020808252602c908201526000805160206141a783398151915260408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201526000805160206141a783398151915260408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b8181038181111561094257610942613f4e565b600060208284031215613f8957600080fd5b815161391781613776565b600060208284031215613fa657600080fd5b5051919050565b6001600160a01b0392831681529116602082015260400190565b8082018082111561094257610942613f4e565b600060208284031215613fec57600080fd5b81516001600160401b0381111561400257600080fd5b8201601f8101841361401357600080fd5b805161402161385b82613826565b81815285602083850101111561403657600080fd5b614047826020830160208601613e64565b95945050505050565b6001600160e01b031991909116815260200190565b60006001820161407757614077613f4e565b5060010190565b60008151808452614096816020860160208601613e64565b601f01601f19169290920160200192915050565b6001600160a01b038b811682528a1660208201526102a0604082018190526000906140d78382018c61407e565b905082810360608401526140eb818b61407e565b905088608084015282810360a0840152614105818961407e565b91505061411560c083018761394d565b61412260e0830186613961565b831515610100830152614139610120830184613971565b9b9a5050505050505050505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60208152600061093f602083018461407e56fe46756e6374696f6e206d7573742062652063616c6c6564207468726f75676820360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212201b179803e03d0f5795e80162f0392563842663dae9b85553ee9bde41d97a3e2d64736f6c63430008150033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in GLMR
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.