Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00
Cross-Chain Transactions
Loading...
Loading
Contract Name:
RMRKCatalogUtils
Compiler Version
v0.8.21+commit.d9974bed
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.21;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IRMRKCatalog} from "../catalog/IRMRKCatalog.sol";
import {IERC6220} from "../equippable/IERC6220.sol";
import {IERC5773} from "../multiasset/IERC5773.sol";
import {IERC7401} from "../nestable/IERC7401.sol";
import {RMRKLib} from "../library/RMRKLib.sol";
import "../library/RMRKErrors.sol";
/**
* @title RMRKCatalogUtils
* @author RMRK team
* @notice Smart contract of the RMRK Catalog utils module.
* @dev Extra utility functions for RMRK contracts.
*/
contract RMRKCatalogUtils {
using RMRKLib for uint64[];
/**
* @notice Used to store the core structure of the `Equippable` RMRK lego.
* @return parentAssetId The ID of the parent asset equipping a child
* @return slotId The ID of the slot part
* @return childAddress Address of the collection to which the child asset belongs to
* @return childId The ID of token that is equipped
* @return childAssetId The ID of the asset used as equipment
*/
struct ExtendedEquipment {
uint64 parentAssetId;
uint64 slotId;
address childAddress;
uint256 childId;
uint64 childAssetId;
}
/**
* @notice Structure used to represent the extended part data.
* @return partId The part ID
* @return itemType The item type
* @return z The z index
* @return equippable The array of equippable IDs
* @return equippableToAll Whether the part is equippable to all, that is, any NFT can be equipped into it.
* @return metadataURI The metadata URI
*/
struct ExtendedPart {
uint64 partId;
IRMRKCatalog.ItemType itemType;
uint8 z;
address[] equippable;
bool equippableToAll;
string metadataURI;
}
/**
* @notice Used to get the catalog data of a specified catalog in a single call.
* @dev The owner might be address 0 if the catalog does not implement the `Ownable` interface.
* @param catalog Address of the catalog to get the data from
* @return owner The address of the owner of the catalog
* @return type_ The type of the catalog
* @return metadataURI The metadata URI of the catalog
*/
function getCatalogData(
address catalog
)
public
view
returns (address owner, string memory type_, string memory metadataURI)
{
IRMRKCatalog target = IRMRKCatalog(catalog);
type_ = target.getType();
metadataURI = target.getMetadataURI();
try Ownable(catalog).owner() returns (address catalogOwner) {
owner = catalogOwner;
} catch {}
}
/**
* @notice Used to get the extended part data of many parts from the specified catalog in a single call.
* @param catalog Address of the catalog to get the data from
* @param partIds Array of part IDs to get the data from
* @return parts Array of extended part data structs containing the part data
*/
function getExtendedParts(
address catalog,
uint64[] memory partIds
) public view returns (ExtendedPart[] memory parts) {
uint256 length = partIds.length;
IRMRKCatalog target = IRMRKCatalog(catalog);
parts = new ExtendedPart[](length);
for (uint256 i = 0; i < length; ) {
uint64 partId = partIds[i];
bool isEquippableToAll = target.checkIsEquippableToAll(partId);
IRMRKCatalog.Part memory part = target.getPart(partId);
parts[i] = ExtendedPart({
partId: partId,
itemType: part.itemType,
z: part.z,
equippable: part.equippable,
equippableToAll: isEquippableToAll,
metadataURI: part.metadataURI
});
unchecked {
++i;
}
}
}
/**
* @notice Used to get the catalog data and the extended part data of many parts from the specified catalog in a single call.
* @param catalog Address of the catalog to get the data from
* @param partIds Array of part IDs to get the data from
* @return owner The address of the owner of the catalog
* @return type_ The type of the catalog
* @return metadataURI The metadata URI of the catalog
* @return parts Array of extended part data structs containing the part data
*/
function getCatalogDataAndExtendedParts(
address catalog,
uint64[] memory partIds
)
public
view
returns (
address owner,
string memory type_,
string memory metadataURI,
ExtendedPart[] memory parts
)
{
(owner, type_, metadataURI) = getCatalogData(catalog);
parts = getExtendedParts(catalog, partIds);
}
/**
* @notice Used to get data about children equipped to a specified token, where the parent asset has been replaced.
* @param parentAddress Address of the collection smart contract of parent token
* @param parentId ID of the parent token
* @param catalogAddress Address of the catalog the slot part Ids belong to
* @param slotPartIds Array of slot part IDs of the parent token's assets to search for orphan equipments
* @return equipments Array of extended equipment data structs containing the equipment data, including the slot part ID
*/
function getOrphanEquipmentsFromParentAsset(
address parentAddress,
uint256 parentId,
address catalogAddress,
uint64[] memory slotPartIds
) public view returns (ExtendedEquipment[] memory equipments) {
uint256 length = slotPartIds.length;
ExtendedEquipment[] memory tempEquipments = new ExtendedEquipment[](
length
);
uint64[] memory parentAssetIds = IERC5773(parentAddress)
.getActiveAssets(parentId);
uint256 orphansFound;
for (uint256 i; i < length; ) {
uint64 slotPartId = slotPartIds[i];
IERC6220.Equipment memory equipment = IERC6220(parentAddress)
.getEquipment(parentId, catalogAddress, slotPartId);
if (equipment.assetId != 0) {
(, bool assetFound) = parentAssetIds.indexOf(equipment.assetId);
if (!assetFound) {
tempEquipments[orphansFound] = ExtendedEquipment({
parentAssetId: equipment.assetId,
slotId: slotPartId,
childAddress: equipment.childEquippableAddress,
childId: equipment.childId,
childAssetId: equipment.childAssetId
});
unchecked {
++orphansFound;
}
}
}
unchecked {
++i;
}
}
equipments = new ExtendedEquipment[](orphansFound);
for (uint256 i; i < orphansFound; ) {
equipments[i] = tempEquipments[i];
unchecked {
++i;
}
}
}
/**
* @notice Used to get data about children equipped to a specified token, where the child asset has been replaced.
* @param parentAddress Address of the collection smart contract of parent token
* @param parentId ID of the parent token
* @return equipments Array of extended equipment data structs containing the equipment data, including the slot part ID
*/
function getOrphanEquipmentsFromChildAsset(
address parentAddress,
uint256 parentId
) public view returns (ExtendedEquipment[] memory equipments) {
uint64[] memory parentAssetIds = IERC5773(parentAddress)
.getActiveAssets(parentId);
// In practice, there could be more equips than children, but this is a decent approximate since the real number cannot be known, also we do not expect a lot of orphans
uint256 totalChildren = IERC7401(parentAddress)
.childrenOf(parentId)
.length;
ExtendedEquipment[] memory tempEquipments = new ExtendedEquipment[](
totalChildren
);
uint256 orphansFound;
uint256 totalParentAssets = parentAssetIds.length;
for (uint256 i; i < totalParentAssets; ) {
(
uint64[] memory parentSlotPartIds,
address catalogAddress
) = getSlotPartsAndCatalog(
parentAddress,
parentId,
parentAssetIds[i]
);
uint256 totalSlots = parentSlotPartIds.length;
for (uint256 j; j < totalSlots; ) {
IERC6220.Equipment memory equipment = IERC6220(parentAddress)
.getEquipment(
parentId,
catalogAddress,
parentSlotPartIds[j]
);
if (equipment.assetId != 0) {
uint64[] memory childAssetIds = IERC5773(
equipment.childEquippableAddress
).getActiveAssets(equipment.childId);
(, bool assetFound) = childAssetIds.indexOf(
equipment.childAssetId
);
if (!assetFound) {
tempEquipments[orphansFound] = ExtendedEquipment({
parentAssetId: equipment.assetId,
slotId: parentSlotPartIds[j],
childAddress: equipment.childEquippableAddress,
childId: equipment.childId,
childAssetId: equipment.childAssetId
});
unchecked {
++orphansFound;
}
}
}
unchecked {
++j;
}
}
unchecked {
++i;
}
}
equipments = new ExtendedEquipment[](orphansFound);
for (uint256 i; i < orphansFound; ) {
equipments[i] = tempEquipments[i];
unchecked {
++i;
}
}
}
/**
* @notice Used to retrieve the parent address and its slot part IDs for a given target child, and the catalog of the parent asset.
* @param tokenAddress Address of the collection smart contract of parent token
* @param tokenId ID of the parent token
* @param assetId ID of the parent asset from which to get the slot parts
* @return parentSlotPartIds Array of slot part IDs of the parent token's asset
* @return catalogAddress Address of the catalog the parent asset belongs to
*/
function getSlotPartsAndCatalog(
address tokenAddress,
uint256 tokenId,
uint64 assetId
)
public
view
returns (uint64[] memory parentSlotPartIds, address catalogAddress)
{
uint64[] memory parentPartIds;
(, , catalogAddress, parentPartIds) = IERC6220(tokenAddress)
.getAssetAndEquippableData(tokenId, assetId);
if (catalogAddress == address(0)) revert RMRKNotComposableAsset();
(parentSlotPartIds, ) = splitSlotAndFixedParts(
parentPartIds,
catalogAddress
);
}
/**
* @notice Used to split slot and fixed parts.
* @param allPartIds[] An array of `Part` IDs containing both, `Slot` and `Fixed` parts
* @param catalogAddress An address of the catalog to which the given `Part`s belong to
* @return slotPartIds An array of IDs of the `Slot` parts included in the `allPartIds`
* @return fixedPartIds An array of IDs of the `Fixed` parts included in the `allPartIds`
*/
function splitSlotAndFixedParts(
uint64[] memory allPartIds,
address catalogAddress
)
public
view
returns (uint64[] memory slotPartIds, uint64[] memory fixedPartIds)
{
IRMRKCatalog.Part[] memory allParts = IRMRKCatalog(catalogAddress)
.getParts(allPartIds);
uint256 numFixedParts;
uint256 numSlotParts;
uint256 numParts = allPartIds.length;
// This for loop is just to discover the right size of the split arrays, since we can't create them dynamically
for (uint256 i; i < numParts; ) {
if (allParts[i].itemType == IRMRKCatalog.ItemType.Fixed)
numFixedParts += 1;
// We could just take the numParts - numFixedParts, but it doesn't hurt to double check it's not an uninitialized part:
else if (allParts[i].itemType == IRMRKCatalog.ItemType.Slot)
numSlotParts += 1;
unchecked {
++i;
}
}
slotPartIds = new uint64[](numSlotParts);
fixedPartIds = new uint64[](numFixedParts);
uint256 slotPartsIndex;
uint256 fixedPartsIndex;
// This for loop is to actually fill the split arrays
for (uint256 i; i < numParts; ) {
if (allParts[i].itemType == IRMRKCatalog.ItemType.Fixed) {
fixedPartIds[fixedPartsIndex] = allPartIds[i];
unchecked {
++fixedPartsIndex;
}
} else if (allParts[i].itemType == IRMRKCatalog.ItemType.Slot) {
slotPartIds[slotPartsIndex] = allPartIds[i];
unchecked {
++slotPartsIndex;
}
}
unchecked {
++i;
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.21;
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/**
* @title IRMRKCatalog
* @author RMRK team
* @notice An interface Catalog for RMRK equippable module.
*/
interface IRMRKCatalog is IERC165 {
/**
* @notice Event to announce addition of a new part.
* @dev It is emitted when a new part is added.
* @param partId ID of the part that was added
* @param itemType Enum value specifying whether the part is `None`, `Slot` and `Fixed`
* @param zIndex An uint specifying the z value of the part. It is used to specify the depth which the part should
* be rendered at
* @param equippableAddresses An array of addresses that can equip this part
* @param metadataURI The metadata URI of the part
*/
event AddedPart(
uint64 indexed partId,
ItemType indexed itemType,
uint8 zIndex,
address[] equippableAddresses,
string metadataURI
);
/**
* @notice Event to announce new equippables to the part.
* @dev It is emitted when new addresses are marked as equippable for `partId`.
* @param partId ID of the part that had new equippable addresses added
* @param equippableAddresses An array of the new addresses that can equip this part
*/
event AddedEquippables(
uint64 indexed partId,
address[] equippableAddresses
);
/**
* @notice Event to announce the overriding of equippable addresses of the part.
* @dev It is emitted when the existing list of addresses marked as equippable for `partId` is overwritten by a new one.
* @param partId ID of the part whose list of equippable addresses was overwritten
* @param equippableAddresses The new, full, list of addresses that can equip this part
*/
event SetEquippables(uint64 indexed partId, address[] equippableAddresses);
/**
* @notice Event to announce that a given part can be equipped by any address.
* @dev It is emitted when a given part is marked as equippable by any.
* @param partId ID of the part marked as equippable by any address
*/
event SetEquippableToAll(uint64 indexed partId);
/**
* @notice Used to define a type of the item. Possible values are `None`, `Slot` or `Fixed`.
* @dev Used for fixed and slot parts.
*/
enum ItemType {
None,
Slot,
Fixed
}
/**
* @notice The integral structure of a standard RMRK catalog item defining it.
* @dev Requires a minimum of 3 storage slots per catalog item, equivalent to roughly 60,000 gas as of Berlin hard
* fork (April 14, 2021), though 5-7 storage slots is more realistic, given the standard length of an IPFS URI.
* This will result in between 25,000,000 and 35,000,000 gas per 250 assets--the maximum block size of Ethereum
* mainnet is 30M at peak usage.
* @return itemType The item type of the part
* @return z The z value of the part defining how it should be rendered when presenting the full NFT
* @return equippable The array of addresses allowed to be equipped in this part
* @return metadataURI The metadata URI of the part
*/
struct Part {
ItemType itemType; //1 byte
uint8 z; //1 byte
address[] equippable; //n Collections that can be equipped into this slot
string metadataURI; //n bytes 32+
}
/**
* @notice The structure used to add a new `Part`.
* @dev The part is added with specified ID, so you have to make sure that you are using an unused `partId`,
* otherwise the addition of the part vill be reverted.
* @dev The full `IntakeStruct` looks like this:
* [
* partID,
* [
* itemType,
* z,
* [
* permittedCollectionAddress0,
* permittedCollectionAddress1,
* permittedCollectionAddress2
* ],
* metadataURI
* ]
* ]
* @return partId ID to be assigned to the `Part`
* @return part A `Part` to be added
*/
struct IntakeStruct {
uint64 partId;
Part part;
}
/**
* @notice Used to return the metadata URI of the associated Catalog.
* @return Catalog metadata URI
*/
function getMetadataURI() external view returns (string memory);
/**
* @notice Used to return the `itemType` of the associated Catalog
* @return `itemType` of the associated Catalog
*/
function getType() external view returns (string memory);
/**
* @notice Used to check whether the given address is allowed to equip the desired `Part`.
* @dev Returns true if a collection may equip asset with `partId`.
* @param partId The ID of the part that we are checking
* @param targetAddress The address that we are checking for whether the part can be equipped into it or not
* @return isEquippable The status indicating whether the `targetAddress` can be equipped into `Part` with `partId` or not
*/
function checkIsEquippable(
uint64 partId,
address targetAddress
) external view returns (bool isEquippable);
/**
* @notice Used to check if the part is equippable by all addresses.
* @dev Returns true if part is equippable to all.
* @param partId ID of the part that we are checking
* @return isEquippableToAll The status indicating whether the part with `partId` can be equipped by any address or not
*/
function checkIsEquippableToAll(
uint64 partId
) external view returns (bool isEquippableToAll);
/**
* @notice Used to retrieve a `Part` with id `partId`
* @param partId ID of the part that we are retrieving
* @return part The `Part` struct associated with given `partId`
*/
function getPart(uint64 partId) external view returns (Part memory part);
/**
* @notice Used to retrieve multiple parts at the same time.
* @param partIds An array of part IDs that we want to retrieve
* @return part An array of `Part` structs associated with given `partIds`
*/
function getParts(
uint64[] memory partIds
) external view returns (Part[] memory part);
}// 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 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 RMRKLib
* @author RMRK team
* @notice RMRK library smart contract.
*/
library RMRKLib {
error IndexOutOfBounds();
/**
* @notice Used to remove an item from the array using the specified index.
* @dev The item is removed by replacing it with the last item and removing the last element.
* @param array An array of items containing the item to be removed
* @param index Index of the item to remove
*/
function removeItemByIndex(uint64[] storage array, uint256 index) internal {
//Check to see if this is already gated by require in all calls
if (index >= array.length) revert IndexOutOfBounds();
array[index] = array[array.length - 1];
array.pop();
}
/**
* @notice Used to determine the index of the item in the array by spedifying its value.
* @dev This was adapted from Cryptofin-Solidity `arrayUtils`.
* @dev If the item is not found the index returned will equal `0`.
* @param A The array containing the item to be found
* @param a The value of the item to find the index of
* @return The index of the item in the array
* @return A boolean value specifying whether the item was found
*/
function indexOf(
uint64[] memory A,
uint64 a
) internal pure returns (uint256, bool) {
uint256 length = A.length;
for (uint256 i; i < length; ) {
if (A[i] == a) {
return (i, true);
}
unchecked {
++i;
}
}
return (0, false);
}
}// 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: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// 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);
}{
"remappings": [
"@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
"@rmrk-team/evm-contracts/=contracts/",
"hardhat/=node_modules/hardhat/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"evmVersion": "london",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"RMRKNotComposableAsset","type":"error"},{"inputs":[{"internalType":"address","name":"catalog","type":"address"}],"name":"getCatalogData","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"type_","type":"string"},{"internalType":"string","name":"metadataURI","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"catalog","type":"address"},{"internalType":"uint64[]","name":"partIds","type":"uint64[]"}],"name":"getCatalogDataAndExtendedParts","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"type_","type":"string"},{"internalType":"string","name":"metadataURI","type":"string"},{"components":[{"internalType":"uint64","name":"partId","type":"uint64"},{"internalType":"enum IRMRKCatalog.ItemType","name":"itemType","type":"uint8"},{"internalType":"uint8","name":"z","type":"uint8"},{"internalType":"address[]","name":"equippable","type":"address[]"},{"internalType":"bool","name":"equippableToAll","type":"bool"},{"internalType":"string","name":"metadataURI","type":"string"}],"internalType":"struct RMRKCatalogUtils.ExtendedPart[]","name":"parts","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"catalog","type":"address"},{"internalType":"uint64[]","name":"partIds","type":"uint64[]"}],"name":"getExtendedParts","outputs":[{"components":[{"internalType":"uint64","name":"partId","type":"uint64"},{"internalType":"enum IRMRKCatalog.ItemType","name":"itemType","type":"uint8"},{"internalType":"uint8","name":"z","type":"uint8"},{"internalType":"address[]","name":"equippable","type":"address[]"},{"internalType":"bool","name":"equippableToAll","type":"bool"},{"internalType":"string","name":"metadataURI","type":"string"}],"internalType":"struct RMRKCatalogUtils.ExtendedPart[]","name":"parts","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"parentAddress","type":"address"},{"internalType":"uint256","name":"parentId","type":"uint256"}],"name":"getOrphanEquipmentsFromChildAsset","outputs":[{"components":[{"internalType":"uint64","name":"parentAssetId","type":"uint64"},{"internalType":"uint64","name":"slotId","type":"uint64"},{"internalType":"address","name":"childAddress","type":"address"},{"internalType":"uint256","name":"childId","type":"uint256"},{"internalType":"uint64","name":"childAssetId","type":"uint64"}],"internalType":"struct RMRKCatalogUtils.ExtendedEquipment[]","name":"equipments","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"parentAddress","type":"address"},{"internalType":"uint256","name":"parentId","type":"uint256"},{"internalType":"address","name":"catalogAddress","type":"address"},{"internalType":"uint64[]","name":"slotPartIds","type":"uint64[]"}],"name":"getOrphanEquipmentsFromParentAsset","outputs":[{"components":[{"internalType":"uint64","name":"parentAssetId","type":"uint64"},{"internalType":"uint64","name":"slotId","type":"uint64"},{"internalType":"address","name":"childAddress","type":"address"},{"internalType":"uint256","name":"childId","type":"uint256"},{"internalType":"uint64","name":"childAssetId","type":"uint64"}],"internalType":"struct RMRKCatalogUtils.ExtendedEquipment[]","name":"equipments","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint64","name":"assetId","type":"uint64"}],"name":"getSlotPartsAndCatalog","outputs":[{"internalType":"uint64[]","name":"parentSlotPartIds","type":"uint64[]"},{"internalType":"address","name":"catalogAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64[]","name":"allPartIds","type":"uint64[]"},{"internalType":"address","name":"catalogAddress","type":"address"}],"name":"splitSlotAndFixedParts","outputs":[{"internalType":"uint64[]","name":"slotPartIds","type":"uint64[]"},{"internalType":"uint64[]","name":"fixedPartIds","type":"uint64[]"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50611c2a806100206000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063b57d646d1161005b578063b57d646d146100f0578063d95d068714610111578063ef7f5e6f14610131578063f385a6421461015257600080fd5b806330f8808514610082578063496f228d146100ae5780635076b89f146100d0575b600080fd5b6100956100903660046111d5565b610165565b6040516100a594939291906113ac565b60405180910390f35b6100c16100bc366004611401565b610191565b6040516100a593929190611425565b6100e36100de366004611465565b6102d5565b6040516100a591906114d0565b6101036100fe366004611555565b6105b6565b6040516100a59291906115df565b61012461011f3660046111d5565b610899565b6040516100a5919061160d565b61014461013f366004611620565b610ad8565b6040516100a5929190611662565b6100e361016036600461168c565b610ba2565b6000606080606061017586610191565b919550935091506101868686610899565b905092959194509250565b60006060806000849050806001600160a01b03166315dae03e6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156101d9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102019190810190611723565b9250806001600160a01b03166386a92af76040518163ffffffff1660e01b8152600401600060405180830381865afa158015610241573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102699190810190611723565b9150846001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156102c5575060408051601f3d908101601f191682019092526102c291810190611757565b60015b156102cd5793505b509193909250565b80516060906000816001600160401b038111156102f4576102f4611099565b60405190808252806020026020018201604052801561032d57816020015b61031a611053565b8152602001906001900390816103125790505b50604051633940140f60e11b8152600481018890529091506000906001600160a01b03891690637280281e90602401600060405180830381865afa158015610379573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526103a191908101906117d8565b90506000805b8481101561050a5760008782815181106103c3576103c361180c565b6020908102919091010151604051633a83f15760e11b8152600481018c90526001600160a01b038b811660248301526001600160401b03831660448301529192506000918d1690637507e2ae90606401608060405180830381865afa158015610430573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104549190611822565b80519091506001600160401b031615610500578051600090610477908790610fea565b915050806104fe576040518060a0016040528083600001516001600160401b03168152602001846001600160401b0316815260200183606001516001600160a01b031681526020018360400151815260200183602001516001600160401b03168152508786815181106104ec576104ec61180c565b60200260200101819052508460010194505b505b50506001016103a7565b50806001600160401b0381111561052357610523611099565b60405190808252806020026020018201604052801561055c57816020015b610549611053565b8152602001906001900390816105415790505b50945060005b818110156105a95783818151811061057c5761057c61180c565b60200260200101518682815181106105965761059661180c565b6020908102919091010152600101610562565b5050505050949350505050565b6060806000836001600160a01b0316639806c6ec866040518263ffffffff1660e01b81526004016105e79190611880565b600060405180830381865afa158015610604573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261062c9190810190611995565b905060008060008751905060005b818110156106d65760028582815181106106565761065661180c565b602002602001015160000151600281111561067357610673611274565b0361068a57610683600185611a45565b93506106ce565b600185828151811061069e5761069e61180c565b60200260200101516000015160028111156106bb576106bb611274565b036106ce576106cb600184611a45565b92505b60010161063a565b50816001600160401b038111156106ef576106ef611099565b604051908082528060200260200182016040528015610718578160200160208202803683370190505b509550826001600160401b0381111561073357610733611099565b60405190808252806020026020018201604052801561075c578160200160208202803683370190505b50945060008060005b8381101561088b5760028782815181106107815761078161180c565b602002602001015160000151600281111561079e5761079e611274565b036107fa578a81815181106107b5576107b561180c565b60200260200101518883815181106107cf576107cf61180c565b60200260200101906001600160401b031690816001600160401b031681525050816001019150610883565b600187828151811061080e5761080e61180c565b602002602001015160000151600281111561082b5761082b611274565b03610883578a81815181106108425761084261180c565b602002602001015189848151811061085c5761085c61180c565b60200260200101906001600160401b031690816001600160401b0316815250508260010192505b600101610765565b505050505050509250929050565b805160609083816001600160401b038111156108b7576108b7611099565b60405190808252806020026020018201604052801561092757816020015b6109146040805160c08101909152600080825260208201908152602001600060ff16815260200160608152602001600015158152602001606081525090565b8152602001906001900390816108d55790505b50925060005b82811015610acf5760008582815181106109495761094961180c565b602090810291909101015160405163dc477d2f60e01b81526001600160401b03821660048201529091506000906001600160a01b0385169063dc477d2f90602401602060405180830381865afa1580156109a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109cb9190611a6c565b60405163d297ac4360e01b81526001600160401b03841660048201529091506000906001600160a01b0386169063d297ac4390602401600060405180830381865afa158015610a1e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a469190810190611a8e565b90506040518060c00160405280846001600160401b0316815260200182600001516002811115610a7857610a78611274565b8152602001826020015160ff1681526020018260400151815260200183151581526020018260600151815250878581518110610ab657610ab661180c565b602002602001018190525083600101935050505061092d565b50505092915050565b60405163273076dd60e11b8152600481018390526001600160401b038216602482015260609060009082906001600160a01b03871690634e60edba90604401600060405180830381865afa158015610b34573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b5c9190810190611ac2565b9094509250506001600160a01b0383169050610b8b57604051630f40c4af60e31b815260040160405180910390fd5b610b9581836105b6565b5096919550909350505050565b604051633940140f60e11b8152600481018290526060906000906001600160a01b03851690637280281e90602401600060405180830381865afa158015610bed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c1591908101906117d8565b604051631bc6654760e21b8152600481018590529091506000906001600160a01b03861690636f19951c90602401600060405180830381865afa158015610c60573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c889190810190611b40565b5190506000816001600160401b03811115610ca557610ca5611099565b604051908082528060200260200182016040528015610cde57816020015b610ccb611053565b815260200190600190039081610cc35790505b508351909150600090815b81811015610f3f57600080610d188b8b8a8681518110610d0b57610d0b61180c565b6020026020010151610ad8565b8151919350915060005b81811015610f305760008d6001600160a01b0316637507e2ae8e86888681518110610d4f57610d4f61180c565b60200260200101516040518463ffffffff1660e01b8152600401610d98939291909283526001600160a01b039190911660208301526001600160401b0316604082015260600190565b608060405180830381865afa158015610db5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd99190611822565b80519091506001600160401b031615610f2757600081606001516001600160a01b0316637280281e83604001516040518263ffffffff1660e01b8152600401610e2491815260200190565b600060405180830381865afa158015610e41573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e6991908101906117d8565b90506000610e84836020015183610fea90919063ffffffff16565b91505080610f24576040518060a0016040528084600001516001600160401b03168152602001888681518110610ebc57610ebc61180c565b60200260200101516001600160401b0316815260200184606001516001600160a01b031681526020018460400151815260200184602001516001600160401b03168152508b8b81518110610f1257610f1261180c565b60200260200101819052508960010199505b50505b50600101610d22565b50836001019350505050610ce9565b50816001600160401b03811115610f5857610f58611099565b604051908082528060200260200182016040528015610f9157816020015b610f7e611053565b815260200190600190039081610f765790505b50955060005b82811015610fde57838181518110610fb157610fb161180c565b6020026020010151878281518110610fcb57610fcb61180c565b6020908102919091010152600101610f97565b50505050505092915050565b81516000908190815b8181101561104257846001600160401b03168682815181106110175761101761180c565b60200260200101516001600160401b03160361103a5792506001915061104c9050565b600101610ff3565b5060008092509250505b9250929050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b6001600160a01b038116811461109657600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156110d1576110d1611099565b60405290565b604080519081016001600160401b03811182821017156110d1576110d1611099565b604051601f8201601f191681016001600160401b038111828210171561112157611121611099565b604052919050565b60006001600160401b0382111561114257611142611099565b5060051b60200190565b6001600160401b038116811461109657600080fd5b600082601f83011261117257600080fd5b8135602061118761118283611129565b6110f9565b82815260059290921b840181019181810190868411156111a657600080fd5b8286015b848110156111ca5780356111bd8161114c565b83529183019183016111aa565b509695505050505050565b600080604083850312156111e857600080fd5b82356111f381611081565b915060208301356001600160401b0381111561120e57600080fd5b61121a85828601611161565b9150509250929050565b60005b8381101561123f578181015183820152602001611227565b50506000910152565b60008151808452611260816020860160208601611224565b601f01601f19169290920160200192915050565b634e487b7160e01b600052602160045260246000fd5b600081518084526020808501945080840160005b838110156112c35781516001600160a01b03168752958201959082019060010161129e565b509495945050505050565b600082825180855260208086019550808260051b8401018186016000805b8581101561139e57601f19878503018a52825160c06001600160401b038251168652868201516003811061132e57634e487b7160e01b85526021600452602485fd5b8688015260408281015160ff16908701526060808301518188018390526113578389018261128a565b9250505060808083015161136e8289018215159052565b505060a0808301519250868203818801525061138a8183611248565b9b87019b95505050918401916001016112ec565b509198975050505050505050565b6001600160a01b03851681526080602082018190526000906113d090830186611248565b82810360408401526113e28186611248565b905082810360608401526113f681856112ce565b979650505050505050565b60006020828403121561141357600080fd5b813561141e81611081565b9392505050565b6001600160a01b038416815260606020820181905260009061144990830185611248565b828103604084015261145b8185611248565b9695505050505050565b6000806000806080858703121561147b57600080fd5b843561148681611081565b935060208501359250604085013561149d81611081565b915060608501356001600160401b038111156114b857600080fd5b6114c487828801611161565b91505092959194509250565b602080825282518282018190526000919060409081850190868401855b8281101561154857815180516001600160401b03908116865287820151811688870152868201516001600160a01b03168787015260608083015190870152608091820151169085015260a090930192908501906001016114ed565b5091979650505050505050565b6000806040838503121561156857600080fd5b82356001600160401b0381111561157e57600080fd5b61158a85828601611161565b925050602083013561159b81611081565b809150509250929050565b600081518084526020808501945080840160005b838110156112c35781516001600160401b0316875295820195908201906001016115ba565b6040815260006115f260408301856115a6565b828103602084015261160481856115a6565b95945050505050565b60208152600061141e60208301846112ce565b60008060006060848603121561163557600080fd5b833561164081611081565b92506020840135915060408401356116578161114c565b809150509250925092565b60408152600061167560408301856115a6565b905060018060a01b03831660208301529392505050565b6000806040838503121561169f57600080fd5b82356116aa81611081565b946020939093013593505050565b600082601f8301126116c957600080fd5b81516001600160401b038111156116e2576116e2611099565b6116f5601f8201601f19166020016110f9565b81815284602083860101111561170a57600080fd5b61171b826020830160208701611224565b949350505050565b60006020828403121561173557600080fd5b81516001600160401b0381111561174b57600080fd5b61171b848285016116b8565b60006020828403121561176957600080fd5b815161141e81611081565b600082601f83011261178557600080fd5b8151602061179561118283611129565b82815260059290921b840181019181810190868411156117b457600080fd5b8286015b848110156111ca5780516117cb8161114c565b83529183019183016117b8565b6000602082840312156117ea57600080fd5b81516001600160401b0381111561180057600080fd5b61171b84828501611774565b634e487b7160e01b600052603260045260246000fd5b60006080828403121561183457600080fd5b61183c6110af565b82516118478161114c565b815260208301516118578161114c565b602082015260408381015190820152606083015161187481611081565b60608201529392505050565b60208152600061141e60208301846115a6565b600082601f8301126118a457600080fd5b815160206118b461118283611129565b82815260059290921b840181019181810190868411156118d357600080fd5b8286015b848110156111ca5780516118ea81611081565b83529183019183016118d7565b60006080828403121561190957600080fd5b6119116110af565b905081516003811061192257600080fd5b8152602082015160ff8116811461193857600080fd5b602082015260408201516001600160401b038082111561195757600080fd5b61196385838601611893565b6040840152606084015191508082111561197c57600080fd5b50611989848285016116b8565b60608301525092915050565b600060208083850312156119a857600080fd5b82516001600160401b03808211156119bf57600080fd5b818501915085601f8301126119d357600080fd5b81516119e161118282611129565b81815260059190911b83018401908481019088831115611a0057600080fd5b8585015b83811015611a3857805185811115611a1c5760008081fd5b611a2a8b89838a01016118f7565b845250918601918601611a04565b5098975050505050505050565b80820180821115611a6657634e487b7160e01b600052601160045260246000fd5b92915050565b600060208284031215611a7e57600080fd5b8151801515811461141e57600080fd5b600060208284031215611aa057600080fd5b81516001600160401b03811115611ab657600080fd5b61171b848285016118f7565b60008060008060808587031215611ad857600080fd5b84516001600160401b0380821115611aef57600080fd5b611afb888389016116b8565b955060208701519150611b0d8261114c565b6040870151919450611b1e82611081565b606087015191935080821115611b3357600080fd5b506114c487828801611774565b60006020808385031215611b5357600080fd5b82516001600160401b03811115611b6957600080fd5b8301601f81018513611b7a57600080fd5b8051611b8861118282611129565b81815260069190911b82018301908381019087831115611ba757600080fd5b928401925b828410156113f65760408489031215611bc55760008081fd5b611bcd6110d7565b8451815285850151611bde81611081565b8187015282526040939093019290840190611bac56fea264697066735822122062d12355ff8924d59c1555d26558ca2301b98d0f1b9eae53268002f4ee4c2ebe64736f6c63430008150033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061007d5760003560e01c8063b57d646d1161005b578063b57d646d146100f0578063d95d068714610111578063ef7f5e6f14610131578063f385a6421461015257600080fd5b806330f8808514610082578063496f228d146100ae5780635076b89f146100d0575b600080fd5b6100956100903660046111d5565b610165565b6040516100a594939291906113ac565b60405180910390f35b6100c16100bc366004611401565b610191565b6040516100a593929190611425565b6100e36100de366004611465565b6102d5565b6040516100a591906114d0565b6101036100fe366004611555565b6105b6565b6040516100a59291906115df565b61012461011f3660046111d5565b610899565b6040516100a5919061160d565b61014461013f366004611620565b610ad8565b6040516100a5929190611662565b6100e361016036600461168c565b610ba2565b6000606080606061017586610191565b919550935091506101868686610899565b905092959194509250565b60006060806000849050806001600160a01b03166315dae03e6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156101d9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102019190810190611723565b9250806001600160a01b03166386a92af76040518163ffffffff1660e01b8152600401600060405180830381865afa158015610241573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102699190810190611723565b9150846001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156102c5575060408051601f3d908101601f191682019092526102c291810190611757565b60015b156102cd5793505b509193909250565b80516060906000816001600160401b038111156102f4576102f4611099565b60405190808252806020026020018201604052801561032d57816020015b61031a611053565b8152602001906001900390816103125790505b50604051633940140f60e11b8152600481018890529091506000906001600160a01b03891690637280281e90602401600060405180830381865afa158015610379573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526103a191908101906117d8565b90506000805b8481101561050a5760008782815181106103c3576103c361180c565b6020908102919091010151604051633a83f15760e11b8152600481018c90526001600160a01b038b811660248301526001600160401b03831660448301529192506000918d1690637507e2ae90606401608060405180830381865afa158015610430573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104549190611822565b80519091506001600160401b031615610500578051600090610477908790610fea565b915050806104fe576040518060a0016040528083600001516001600160401b03168152602001846001600160401b0316815260200183606001516001600160a01b031681526020018360400151815260200183602001516001600160401b03168152508786815181106104ec576104ec61180c565b60200260200101819052508460010194505b505b50506001016103a7565b50806001600160401b0381111561052357610523611099565b60405190808252806020026020018201604052801561055c57816020015b610549611053565b8152602001906001900390816105415790505b50945060005b818110156105a95783818151811061057c5761057c61180c565b60200260200101518682815181106105965761059661180c565b6020908102919091010152600101610562565b5050505050949350505050565b6060806000836001600160a01b0316639806c6ec866040518263ffffffff1660e01b81526004016105e79190611880565b600060405180830381865afa158015610604573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261062c9190810190611995565b905060008060008751905060005b818110156106d65760028582815181106106565761065661180c565b602002602001015160000151600281111561067357610673611274565b0361068a57610683600185611a45565b93506106ce565b600185828151811061069e5761069e61180c565b60200260200101516000015160028111156106bb576106bb611274565b036106ce576106cb600184611a45565b92505b60010161063a565b50816001600160401b038111156106ef576106ef611099565b604051908082528060200260200182016040528015610718578160200160208202803683370190505b509550826001600160401b0381111561073357610733611099565b60405190808252806020026020018201604052801561075c578160200160208202803683370190505b50945060008060005b8381101561088b5760028782815181106107815761078161180c565b602002602001015160000151600281111561079e5761079e611274565b036107fa578a81815181106107b5576107b561180c565b60200260200101518883815181106107cf576107cf61180c565b60200260200101906001600160401b031690816001600160401b031681525050816001019150610883565b600187828151811061080e5761080e61180c565b602002602001015160000151600281111561082b5761082b611274565b03610883578a81815181106108425761084261180c565b602002602001015189848151811061085c5761085c61180c565b60200260200101906001600160401b031690816001600160401b0316815250508260010192505b600101610765565b505050505050509250929050565b805160609083816001600160401b038111156108b7576108b7611099565b60405190808252806020026020018201604052801561092757816020015b6109146040805160c08101909152600080825260208201908152602001600060ff16815260200160608152602001600015158152602001606081525090565b8152602001906001900390816108d55790505b50925060005b82811015610acf5760008582815181106109495761094961180c565b602090810291909101015160405163dc477d2f60e01b81526001600160401b03821660048201529091506000906001600160a01b0385169063dc477d2f90602401602060405180830381865afa1580156109a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109cb9190611a6c565b60405163d297ac4360e01b81526001600160401b03841660048201529091506000906001600160a01b0386169063d297ac4390602401600060405180830381865afa158015610a1e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a469190810190611a8e565b90506040518060c00160405280846001600160401b0316815260200182600001516002811115610a7857610a78611274565b8152602001826020015160ff1681526020018260400151815260200183151581526020018260600151815250878581518110610ab657610ab661180c565b602002602001018190525083600101935050505061092d565b50505092915050565b60405163273076dd60e11b8152600481018390526001600160401b038216602482015260609060009082906001600160a01b03871690634e60edba90604401600060405180830381865afa158015610b34573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b5c9190810190611ac2565b9094509250506001600160a01b0383169050610b8b57604051630f40c4af60e31b815260040160405180910390fd5b610b9581836105b6565b5096919550909350505050565b604051633940140f60e11b8152600481018290526060906000906001600160a01b03851690637280281e90602401600060405180830381865afa158015610bed573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c1591908101906117d8565b604051631bc6654760e21b8152600481018590529091506000906001600160a01b03861690636f19951c90602401600060405180830381865afa158015610c60573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c889190810190611b40565b5190506000816001600160401b03811115610ca557610ca5611099565b604051908082528060200260200182016040528015610cde57816020015b610ccb611053565b815260200190600190039081610cc35790505b508351909150600090815b81811015610f3f57600080610d188b8b8a8681518110610d0b57610d0b61180c565b6020026020010151610ad8565b8151919350915060005b81811015610f305760008d6001600160a01b0316637507e2ae8e86888681518110610d4f57610d4f61180c565b60200260200101516040518463ffffffff1660e01b8152600401610d98939291909283526001600160a01b039190911660208301526001600160401b0316604082015260600190565b608060405180830381865afa158015610db5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd99190611822565b80519091506001600160401b031615610f2757600081606001516001600160a01b0316637280281e83604001516040518263ffffffff1660e01b8152600401610e2491815260200190565b600060405180830381865afa158015610e41573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e6991908101906117d8565b90506000610e84836020015183610fea90919063ffffffff16565b91505080610f24576040518060a0016040528084600001516001600160401b03168152602001888681518110610ebc57610ebc61180c565b60200260200101516001600160401b0316815260200184606001516001600160a01b031681526020018460400151815260200184602001516001600160401b03168152508b8b81518110610f1257610f1261180c565b60200260200101819052508960010199505b50505b50600101610d22565b50836001019350505050610ce9565b50816001600160401b03811115610f5857610f58611099565b604051908082528060200260200182016040528015610f9157816020015b610f7e611053565b815260200190600190039081610f765790505b50955060005b82811015610fde57838181518110610fb157610fb161180c565b6020026020010151878281518110610fcb57610fcb61180c565b6020908102919091010152600101610f97565b50505050505092915050565b81516000908190815b8181101561104257846001600160401b03168682815181106110175761101761180c565b60200260200101516001600160401b03160361103a5792506001915061104c9050565b600101610ff3565b5060008092509250505b9250929050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b6001600160a01b038116811461109657600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156110d1576110d1611099565b60405290565b604080519081016001600160401b03811182821017156110d1576110d1611099565b604051601f8201601f191681016001600160401b038111828210171561112157611121611099565b604052919050565b60006001600160401b0382111561114257611142611099565b5060051b60200190565b6001600160401b038116811461109657600080fd5b600082601f83011261117257600080fd5b8135602061118761118283611129565b6110f9565b82815260059290921b840181019181810190868411156111a657600080fd5b8286015b848110156111ca5780356111bd8161114c565b83529183019183016111aa565b509695505050505050565b600080604083850312156111e857600080fd5b82356111f381611081565b915060208301356001600160401b0381111561120e57600080fd5b61121a85828601611161565b9150509250929050565b60005b8381101561123f578181015183820152602001611227565b50506000910152565b60008151808452611260816020860160208601611224565b601f01601f19169290920160200192915050565b634e487b7160e01b600052602160045260246000fd5b600081518084526020808501945080840160005b838110156112c35781516001600160a01b03168752958201959082019060010161129e565b509495945050505050565b600082825180855260208086019550808260051b8401018186016000805b8581101561139e57601f19878503018a52825160c06001600160401b038251168652868201516003811061132e57634e487b7160e01b85526021600452602485fd5b8688015260408281015160ff16908701526060808301518188018390526113578389018261128a565b9250505060808083015161136e8289018215159052565b505060a0808301519250868203818801525061138a8183611248565b9b87019b95505050918401916001016112ec565b509198975050505050505050565b6001600160a01b03851681526080602082018190526000906113d090830186611248565b82810360408401526113e28186611248565b905082810360608401526113f681856112ce565b979650505050505050565b60006020828403121561141357600080fd5b813561141e81611081565b9392505050565b6001600160a01b038416815260606020820181905260009061144990830185611248565b828103604084015261145b8185611248565b9695505050505050565b6000806000806080858703121561147b57600080fd5b843561148681611081565b935060208501359250604085013561149d81611081565b915060608501356001600160401b038111156114b857600080fd5b6114c487828801611161565b91505092959194509250565b602080825282518282018190526000919060409081850190868401855b8281101561154857815180516001600160401b03908116865287820151811688870152868201516001600160a01b03168787015260608083015190870152608091820151169085015260a090930192908501906001016114ed565b5091979650505050505050565b6000806040838503121561156857600080fd5b82356001600160401b0381111561157e57600080fd5b61158a85828601611161565b925050602083013561159b81611081565b809150509250929050565b600081518084526020808501945080840160005b838110156112c35781516001600160401b0316875295820195908201906001016115ba565b6040815260006115f260408301856115a6565b828103602084015261160481856115a6565b95945050505050565b60208152600061141e60208301846112ce565b60008060006060848603121561163557600080fd5b833561164081611081565b92506020840135915060408401356116578161114c565b809150509250925092565b60408152600061167560408301856115a6565b905060018060a01b03831660208301529392505050565b6000806040838503121561169f57600080fd5b82356116aa81611081565b946020939093013593505050565b600082601f8301126116c957600080fd5b81516001600160401b038111156116e2576116e2611099565b6116f5601f8201601f19166020016110f9565b81815284602083860101111561170a57600080fd5b61171b826020830160208701611224565b949350505050565b60006020828403121561173557600080fd5b81516001600160401b0381111561174b57600080fd5b61171b848285016116b8565b60006020828403121561176957600080fd5b815161141e81611081565b600082601f83011261178557600080fd5b8151602061179561118283611129565b82815260059290921b840181019181810190868411156117b457600080fd5b8286015b848110156111ca5780516117cb8161114c565b83529183019183016117b8565b6000602082840312156117ea57600080fd5b81516001600160401b0381111561180057600080fd5b61171b84828501611774565b634e487b7160e01b600052603260045260246000fd5b60006080828403121561183457600080fd5b61183c6110af565b82516118478161114c565b815260208301516118578161114c565b602082015260408381015190820152606083015161187481611081565b60608201529392505050565b60208152600061141e60208301846115a6565b600082601f8301126118a457600080fd5b815160206118b461118283611129565b82815260059290921b840181019181810190868411156118d357600080fd5b8286015b848110156111ca5780516118ea81611081565b83529183019183016118d7565b60006080828403121561190957600080fd5b6119116110af565b905081516003811061192257600080fd5b8152602082015160ff8116811461193857600080fd5b602082015260408201516001600160401b038082111561195757600080fd5b61196385838601611893565b6040840152606084015191508082111561197c57600080fd5b50611989848285016116b8565b60608301525092915050565b600060208083850312156119a857600080fd5b82516001600160401b03808211156119bf57600080fd5b818501915085601f8301126119d357600080fd5b81516119e161118282611129565b81815260059190911b83018401908481019088831115611a0057600080fd5b8585015b83811015611a3857805185811115611a1c5760008081fd5b611a2a8b89838a01016118f7565b845250918601918601611a04565b5098975050505050505050565b80820180821115611a6657634e487b7160e01b600052601160045260246000fd5b92915050565b600060208284031215611a7e57600080fd5b8151801515811461141e57600080fd5b600060208284031215611aa057600080fd5b81516001600160401b03811115611ab657600080fd5b61171b848285016118f7565b60008060008060808587031215611ad857600080fd5b84516001600160401b0380821115611aef57600080fd5b611afb888389016116b8565b955060208701519150611b0d8261114c565b6040870151919450611b1e82611081565b606087015191935080821115611b3357600080fd5b506114c487828801611774565b60006020808385031215611b5357600080fd5b82516001600160401b03811115611b6957600080fd5b8301601f81018513611b7a57600080fd5b8051611b8861118282611129565b81815260069190911b82018301908381019087831115611ba757600080fd5b928401925b828410156113f65760408489031215611bc55760008081fd5b611bcd6110d7565b8451815285850151611bde81611081565b8187015282526040939093019290840190611bac56fea264697066735822122062d12355ff8924d59c1555d26558ca2301b98d0f1b9eae53268002f4ee4c2ebe64736f6c63430008150033
Deployed Bytecode Sourcemap
602:13178:6:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4474:425;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;2296:433;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;5487:1720::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;11962:1816::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;3069:879::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;10924:595::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;7604:2790::-;;;;;;:::i;:::-;;:::i;4474:425::-;4636:13;4663:19;4696:25;4735:27;4817:23;4832:7;4817:14;:23::i;:::-;4787:53;;-1:-1:-1;4787:53:6;-1:-1:-1;4787:53:6;-1:-1:-1;4858:34:6;4875:7;4884;4858:16;:34::i;:::-;4850:42;;4474:425;;;;;;;:::o;2296:433::-;2396:13;2411:19;2432:25;2473:19;2508:7;2473:43;;2535:6;-1:-1:-1;;;;;2535:14:6;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2535:16:6;;;;;;;;;;;;:::i;:::-;2527:24;;2575:6;-1:-1:-1;;;;;2575:21:6;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2575:23:6;;;;;;;;;;;;:::i;:::-;2561:37;;2621:7;-1:-1:-1;;;;;2613:22:6;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2613:24:6;;;;;;;;-1:-1:-1;;2613:24:6;;;;;;;;;;;;:::i;:::-;;;2609:114;;;2691:12;-1:-1:-1;2609:114:6;2463:266;2296:433;;;;;:::o;5487:1720::-;5750:18;;5684:37;;5733:14;5750:18;-1:-1:-1;;;;;5822:53:6;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;5918:62:6;;-1:-1:-1;;;5918:62:6;;;;;13056:25:10;;;5778:97:6;;-1:-1:-1;5885:30:6;;-1:-1:-1;;;;;5918:52:6;;;;;13029:18:10;;5918:62:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5918:62:6;;;;;;;;;;;;:::i;:::-;5885:95;;5990:20;6026:9;6021:957;6041:6;6037:1;:10;6021:957;;;6065:17;6085:11;6097:1;6085:14;;;;;;;;:::i;:::-;;;;;;;;;;;6151:91;;-1:-1:-1;;;6151:91:6;;;;;14526:25:10;;;-1:-1:-1;;;;;14587:32:10;;;14567:18;;;14560:60;-1:-1:-1;;;;;14656:31:10;;14636:18;;;14629:59;6085:14:6;;-1:-1:-1;6113:35:6;;6151:53;;;;;14499:18:10;;6151:91:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6260:17;;6113:129;;-1:-1:-1;;;;;;6260:22:6;;6256:653;;6347:17;;6305:15;;6324:41;;:14;;:22;:41::i;:::-;6302:63;;;6388:10;6383:512;;6453:329;;;;;;;;6512:9;:17;;;-1:-1:-1;;;;;6453:329:6;;;;;6563:10;-1:-1:-1;;;;;6453:329:6;;;;;6613:9;:32;;;-1:-1:-1;;;;;6453:329:6;;;;;6680:9;:17;;;6453:329;;;;6737:9;:22;;;-1:-1:-1;;;;;6453:329:6;;;;6422:14;6437:12;6422:28;;;;;;;;:::i;:::-;;;;;;:360;;;;6840:14;;;;;6383:512;6284:625;6256:653;-1:-1:-1;;6950:3:6;;6021:957;;;;7025:12;-1:-1:-1;;;;;7001:37:6;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;6988:50;;7053:9;7048:153;7068:12;7064:1;:16;7048:153;;;7114:14;7129:1;7114:17;;;;;;;;:::i;:::-;;;;;;;7098:10;7109:1;7098:13;;;;;;;;:::i;:::-;;;;;;;;;;:33;7173:3;;7048:153;;;;5723:1484;;;;5487:1720;;;;;;:::o;11962:1816::-;12113:27;12142:28;12186:35;12237:14;-1:-1:-1;;;;;12224:50:6;;12275:10;12224:62;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;12224:62:6;;;;;;;;;;;;:::i;:::-;12186:100;;12296:21;12327:20;12358:16;12377:10;:17;12358:36;;12529:9;12524:451;12544:8;12540:1;:12;12524:451;;;12598:27;12574:8;12583:1;12574:11;;;;;;;;:::i;:::-;;;;;;;:20;;;:51;;;;;;;;:::i;:::-;;12570:335;;12643:18;12660:1;12643:18;;:::i;:::-;;;12570:335;;;12844:26;12820:8;12829:1;12820:11;;;;;;;;:::i;:::-;;;;;;;:20;;;:50;;;;;;;;:::i;:::-;;12816:89;;12888:17;12904:1;12888:17;;:::i;:::-;;;12816:89;12947:3;;12524:451;;;;13012:12;-1:-1:-1;;;;;12999:26:6;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12999:26:6;;12985:40;;13063:13;-1:-1:-1;;;;;13050:27:6;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13050:27:6;;13035:42;;13087:22;13119:23;13220:9;13215:557;13235:8;13231:1;:12;13215:557;;;13289:27;13265:8;13274:1;13265:11;;;;;;;;:::i;:::-;;;;;;;:20;;;:51;;;;;;;;:::i;:::-;;13261:442;;13368:10;13379:1;13368:13;;;;;;;;:::i;:::-;;;;;;;13336:12;13349:15;13336:29;;;;;;;;:::i;:::-;;;;;;:45;-1:-1:-1;;;;;13336:45:6;;;-1:-1:-1;;;;;13336:45:6;;;;;13431:17;;;;;13261:442;;;13515:26;13491:8;13500:1;13491:11;;;;;;;;:::i;:::-;;;;;;;:20;;;:50;;;;;;;;:::i;:::-;;13487:216;;13591:10;13602:1;13591:13;;;;;;;;:::i;:::-;;;;;;;13561:11;13573:14;13561:27;;;;;;;;:::i;:::-;;;;;;:43;-1:-1:-1;;;;;13561:43:6;;;-1:-1:-1;;;;;13561:43:6;;;;;13654:16;;;;;13487:216;13744:3;;13215:557;;;;12176:1602;;;;;;11962:1816;;;;;:::o;3069:879::-;3236:14;;3180:27;;3295:7;3236:14;-1:-1:-1;;;;;3321:26:6;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3321:26:6;;;;;;;;;;;;;;;;;3313:34;;3362:9;3357:585;3381:6;3377:1;:10;3357:585;;;3405:13;3421:7;3429:1;3421:10;;;;;;;;:::i;:::-;;;;;;;;;;;3470:37;;-1:-1:-1;;;3470:37:6;;-1:-1:-1;;;;;18800:31:10;;3470:37:6;;;18782:50:10;3421:10:6;;-1:-1:-1;3445:22:6;;-1:-1:-1;;;;;3470:29:6;;;;;18755:18:10;;3470:37:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3553:22;;-1:-1:-1;;;3553:22:6;;-1:-1:-1;;;;;18800:31:10;;3553:22:6;;;18782:50:10;3445:62:6;;-1:-1:-1;3521:29:6;;-1:-1:-1;;;;;3553:14:6;;;;;18755:18:10;;3553:22:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3553:22:6;;;;;;;;;;;;:::i;:::-;3521:54;;3600:272;;;;;;;;3639:6;-1:-1:-1;;;;;3600:272:6;;;;;3673:4;:13;;;3600:272;;;;;;;;:::i;:::-;;;;;3707:4;:6;;;3600:272;;;;;;3743:4;:15;;;3600:272;;;;3793:17;3600:272;;;;;;3841:4;:16;;;3600:272;;;3589:5;3595:1;3589:8;;;;;;;;:::i;:::-;;;;;;:283;;;;3914:3;;;;;3391:551;;;3357:585;;;;3209:739;;3069:879;;;;:::o;10924:595::-;11236:79;;-1:-1:-1;;;11236:79:6;;;;;19654:25:10;;;-1:-1:-1;;;;;19715:31:10;;19695:18;;;19688:59;11086:33:6;;11121:22;;11086:33;;-1:-1:-1;;;;;11236:61:6;;;;;19627:18:10;;11236:79:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;11236:79:6;;;;;;;;;;;;:::i;:::-;11198:117;;-1:-1:-1;11198:117:6;-1:-1:-1;;;;;;;11329:28:6;;;-1:-1:-1;11325:65:6;;11366:24;;-1:-1:-1;;;11366:24:6;;;;;;;;;;;11325:65;11425:87;11461:13;11488:14;11425:22;:87::i;:::-;-1:-1:-1;11401:111:6;10924:595;;-1:-1:-1;10924:595:6;;-1:-1:-1;;;;10924:595:6:o;7604:2790::-;7813:62;;-1:-1:-1;;;7813:62:6;;;;;13056:25:10;;;7731:37:6;;7780:30;;-1:-1:-1;;;;;7813:52:6;;;;;13029:18:10;;7813:62:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7813:62:6;;;;;;;;;;;;:::i;:::-;8087:57;;-1:-1:-1;;;8087:57:6;;;;;13056:25:10;;;7780:95:6;;-1:-1:-1;8063:21:6;;-1:-1:-1;;;;;8087:47:6;;;;;13029:18:10;;8087:57:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;8087:57:6;;;;;;;;;;;;:::i;:::-;:77;8063:101;;8174:41;8255:13;-1:-1:-1;;;;;8218:60:6;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;8347:21:6;;8174:104;;-1:-1:-1;8288:20:6;;;8378:1787;8398:17;8394:1;:21;8378:1787;;;8451:33;8502:22;8541:144;8585:13;8620:8;8650:14;8665:1;8650:17;;;;;;;;:::i;:::-;;;;;;;8541:22;:144::i;:::-;8720:24;;8433:252;;-1:-1:-1;8433:252:6;-1:-1:-1;8699:18:6;8758:1338;8778:10;8774:1;:14;8758:1338;;;8810:35;8857:13;-1:-1:-1;;;;;8848:57:6;;8931:8;8965:14;9005:17;9023:1;9005:20;;;;;;;;:::i;:::-;;;;;;;8848:199;;;;;;;;;;;;;;;;14526:25:10;;;-1:-1:-1;;;;;14587:32:10;;;;14582:2;14567:18;;14560:60;-1:-1:-1;;;;;14656:31:10;14651:2;14636:18;;14629:59;14514:2;14499:18;;14326:368;8848:199:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9069:17;;8810:237;;-1:-1:-1;;;;;;9069:22:6;;9065:946;;9115:29;9181:9;:32;;;-1:-1:-1;;;;;9147:104:6;;9252:9;:17;;;9147:123;;;;;;;;;;;;;13056:25:10;;13044:2;13029:18;;12910:177;9147:123:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;9147:123:6;;;;;;;;;;;;:::i;:::-;9115:155;;9295:15;9314:91;9361:9;:22;;;9314:13;:21;;:91;;;;:::i;:::-;9292:113;;;9432:10;9427:566;;9501:363;;;;;;;;9564:9;:17;;;-1:-1:-1;;;;;9501:363:6;;;;;9619:17;9637:1;9619:20;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;9501:363:6;;;;;9683:9;:32;;;-1:-1:-1;;;;;9501:363:6;;;;;9754:9;:17;;;9501:363;;;;9815:9;:22;;;-1:-1:-1;;;;;9501:363:6;;;;9470:14;9485:12;9470:28;;;;;;;;:::i;:::-;;;;;;:394;;;;9930:14;;;;;9427:566;9093:918;;9065:946;-1:-1:-1;10060:3:6;;8758:1338;;;;10137:3;;;;;8419:1746;;;8378:1787;;;;10212:12;-1:-1:-1;;;;;10188:37:6;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;10175:50;;10240:9;10235:153;10255:12;10251:1;:16;10235:153;;;10301:14;10316:1;10301:17;;;;;;;;:::i;:::-;;;;;;;10285:10;10296:1;10285:13;;;;;;;;:::i;:::-;;;;;;;;;;:33;10360:3;;10235:153;;;;7770:2624;;;;;7604:2790;;;;:::o;1295:361:3:-;1428:8;;1386:7;;;;;1446:177;1466:6;1462:1;:10;1446:177;;;1502:1;-1:-1:-1;;;;;1494:9:3;:1;1496;1494:4;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;1494:9:3;;1490:64;;1531:1;-1:-1:-1;1534:4:3;;-1:-1:-1;1523:16:3;;-1:-1:-1;1523:16:3;1490:64;1595:3;;1446:177;;;;1640:1;1643:5;1632:17;;;;;1295:361;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:10:-;-1:-1:-1;;;;;89:31:10;;79:42;;69:70;;135:1;132;125:12;69:70;14:131;:::o;150:127::-;211:10;206:3;202:20;199:1;192:31;242:4;239:1;232:15;266:4;263:1;256:15;282:252;354:2;348:9;396:3;384:16;;-1:-1:-1;;;;;415:34:10;;451:22;;;412:62;409:88;;;477:18;;:::i;:::-;513:2;506:22;282:252;:::o;539:257::-;611:4;605:11;;;643:17;;-1:-1:-1;;;;;675:34:10;;711:22;;;672:62;669:88;;;737:18;;:::i;801:275::-;872:2;866:9;937:2;918:13;;-1:-1:-1;;914:27:10;902:40;;-1:-1:-1;;;;;957:34:10;;993:22;;;954:62;951:88;;;1019:18;;:::i;:::-;1055:2;1048:22;801:275;;-1:-1:-1;801:275:10:o;1081:182::-;1140:4;-1:-1:-1;;;;;1165:6:10;1162:30;1159:56;;;1195:18;;:::i;:::-;-1:-1:-1;1240:1:10;1236:14;1252:4;1232:25;;1081:182::o;1268:129::-;-1:-1:-1;;;;;1346:5:10;1342:30;1335:5;1332:41;1322:69;;1387:1;1384;1377:12;1402:734;1455:5;1508:3;1501:4;1493:6;1489:17;1485:27;1475:55;;1526:1;1523;1516:12;1475:55;1562:6;1549:20;1588:4;1612:59;1628:42;1667:2;1628:42;:::i;:::-;1612:59;:::i;:::-;1705:15;;;1791:1;1787:10;;;;1775:23;;1771:32;;;1736:12;;;;1815:15;;;1812:35;;;1843:1;1840;1833:12;1812:35;1879:2;1871:6;1867:15;1891:216;1907:6;1902:3;1899:15;1891:216;;;1987:3;1974:17;2004:30;2028:5;2004:30;:::i;:::-;2047:18;;2085:12;;;;1924;;1891:216;;;-1:-1:-1;2125:5:10;1402:734;-1:-1:-1;;;;;;1402:734:10:o;2141:481::-;2233:6;2241;2294:2;2282:9;2273:7;2269:23;2265:32;2262:52;;;2310:1;2307;2300:12;2262:52;2349:9;2336:23;2368:31;2393:5;2368:31;:::i;:::-;2418:5;-1:-1:-1;2474:2:10;2459:18;;2446:32;-1:-1:-1;;;;;2490:30:10;;2487:50;;;2533:1;2530;2523:12;2487:50;2556:60;2608:7;2599:6;2588:9;2584:22;2556:60;:::i;:::-;2546:70;;;2141:481;;;;;:::o;2627:250::-;2712:1;2722:113;2736:6;2733:1;2730:13;2722:113;;;2812:11;;;2806:18;2793:11;;;2786:39;2758:2;2751:10;2722:113;;;-1:-1:-1;;2869:1:10;2851:16;;2844:27;2627:250::o;2882:271::-;2924:3;2962:5;2956:12;2989:6;2984:3;2977:19;3005:76;3074:6;3067:4;3062:3;3058:14;3051:4;3044:5;3040:16;3005:76;:::i;:::-;3135:2;3114:15;-1:-1:-1;;3110:29:10;3101:39;;;;3142:4;3097:50;;2882:271;-1:-1:-1;;2882:271:10:o;3158:127::-;3219:10;3214:3;3210:20;3207:1;3200:31;3250:4;3247:1;3240:15;3274:4;3271:1;3264:15;3370:461;3423:3;3461:5;3455:12;3488:6;3483:3;3476:19;3514:4;3543:2;3538:3;3534:12;3527:19;;3580:2;3573:5;3569:14;3601:1;3611:195;3625:6;3622:1;3619:13;3611:195;;;3690:13;;-1:-1:-1;;;;;3686:39:10;3674:52;;3746:12;;;;3781:15;;;;3722:1;3640:9;3611:195;;;-1:-1:-1;3822:3:10;;3370:461;-1:-1:-1;;;;;3370:461:10:o;3932:1657::-;3997:3;4028;4060:5;4054:12;4087:6;4082:3;4075:19;4113:4;4142:2;4137:3;4133:12;4126:19;;4198:2;4188:6;4185:1;4181:14;4174:5;4170:26;4166:35;4235:2;4228:5;4224:14;4256:1;4277;4287:1276;4303:6;4298:3;4295:15;4287:1276;;;4394:2;4390:7;4382:5;4376:4;4372:16;4368:30;4363:3;4356:43;4428:6;4422:13;4458:4;-1:-1:-1;;;;;4498:2:10;4492:9;4488:34;4482:4;4475:48;4570:2;4566;4562:11;4556:18;4614:1;4600:12;4597:19;4587:170;;-1:-1:-1;;;4648:31:10;;4706:4;4703:1;4696:15;4738:4;4655:1;4728:15;4587:170;4777:13;;;4770:35;4828:4;4873:11;;;4867:18;3357:4;3346:16;4931:13;;;3334:29;4968:4;5013:11;;;5007:18;5045:13;;;5038:25;;;5090:59;5135:13;;;5007:18;5090:59;:::i;:::-;5076:73;;;;5172:4;5225:2;5221;5217:11;5211:18;5242:46;5284:2;5278:4;5274:13;5258:14;3906:13;3899:21;3887:34;;3836:91;5242:46;;;5311:4;5364:2;5360;5356:11;5350:18;5328:40;;5415:4;5407:6;5403:17;5398:2;5392:4;5388:13;5381:40;;5442:41;5476:6;5460:14;5442:41;:::i;:::-;5541:12;;;;5434:49;-1:-1:-1;;;5506:15:10;;;;4329:1;4320:11;4287:1276;;;-1:-1:-1;5579:4:10;;3932:1657;-1:-1:-1;;;;;;;;3932:1657:10:o;5594:756::-;-1:-1:-1;;;;;5955:32:10;;5937:51;;6024:3;6019:2;6004:18;;5997:31;;;-1:-1:-1;;6051:46:10;;6077:19;;6069:6;6051:46;:::i;:::-;6145:9;6137:6;6133:22;6128:2;6117:9;6113:18;6106:50;6179:33;6205:6;6197;6179:33;:::i;:::-;6165:47;;6260:9;6252:6;6248:22;6243:2;6232:9;6228:18;6221:50;6288:56;6337:6;6329;6288:56;:::i;:::-;6280:64;5594:756;-1:-1:-1;;;;;;;5594:756:10:o;6355:247::-;6414:6;6467:2;6455:9;6446:7;6442:23;6438:32;6435:52;;;6483:1;6480;6473:12;6435:52;6522:9;6509:23;6541:31;6566:5;6541:31;:::i;:::-;6591:5;6355:247;-1:-1:-1;;;6355:247:10:o;6607:480::-;-1:-1:-1;;;;;6832:32:10;;6814:51;;6901:2;6896;6881:18;;6874:30;;;-1:-1:-1;;6927:45:10;;6953:18;;6945:6;6927:45;:::i;:::-;7020:9;7012:6;7008:22;7003:2;6992:9;6988:18;6981:50;7048:33;7074:6;7066;7048:33;:::i;:::-;7040:41;6607:480;-1:-1:-1;;;;;;6607:480:10:o;7092:691::-;7202:6;7210;7218;7226;7279:3;7267:9;7258:7;7254:23;7250:33;7247:53;;;7296:1;7293;7286:12;7247:53;7335:9;7322:23;7354:31;7379:5;7354:31;:::i;:::-;7404:5;-1:-1:-1;7456:2:10;7441:18;;7428:32;;-1:-1:-1;7512:2:10;7497:18;;7484:32;7525:33;7484:32;7525:33;:::i;:::-;7577:7;-1:-1:-1;7635:2:10;7620:18;;7607:32;-1:-1:-1;;;;;7651:30:10;;7648:50;;;7694:1;7691;7684:12;7648:50;7717:60;7769:7;7760:6;7749:9;7745:22;7717:60;:::i;:::-;7707:70;;;7092:691;;;;;;;:::o;7788:1115::-;8027:2;8079:21;;;8149:13;;8052:18;;;8171:22;;;7998:4;;8027:2;8212;;8230:18;;;;8271:15;;;7998:4;8314:563;8328:6;8325:1;8322:13;8314:563;;;8387:13;;8470:9;;-1:-1:-1;;;;;8466:18:10;;;8454:31;;8529:11;;;8523:18;8519:27;;8505:12;;;8498:49;8591:11;;;8585:18;-1:-1:-1;;;;;8581:44:10;8567:12;;;8560:66;8649:4;8693:11;;;8687:18;8673:12;;;8666:40;8729:4;8777:11;;;8771:18;8767:27;8753:12;;;8746:49;8613:3;8815:14;;;;8852:15;;;;8622:1;8343:9;8314:563;;;-1:-1:-1;8894:3:10;;7788:1115;-1:-1:-1;;;;;;;7788:1115:10:o;8908:481::-;9000:6;9008;9061:2;9049:9;9040:7;9036:23;9032:32;9029:52;;;9077:1;9074;9067:12;9029:52;9117:9;9104:23;-1:-1:-1;;;;;9142:6:10;9139:30;9136:50;;;9182:1;9179;9172:12;9136:50;9205:60;9257:7;9248:6;9237:9;9233:22;9205:60;:::i;:::-;9195:70;;;9315:2;9304:9;9300:18;9287:32;9328:31;9353:5;9328:31;:::i;:::-;9378:5;9368:15;;;8908:481;;;;;:::o;9394:459::-;9446:3;9484:5;9478:12;9511:6;9506:3;9499:19;9537:4;9566:2;9561:3;9557:12;9550:19;;9603:2;9596:5;9592:14;9624:1;9634:194;9648:6;9645:1;9642:13;9634:194;;;9713:13;;-1:-1:-1;;;;;9709:38:10;9697:51;;9768:12;;;;9803:15;;;;9670:1;9663:9;9634:194;;9858:459;10111:2;10100:9;10093:21;10074:4;10137:55;10188:2;10177:9;10173:18;10165:6;10137:55;:::i;:::-;10240:9;10232:6;10228:22;10223:2;10212:9;10208:18;10201:50;10268:43;10304:6;10296;10268:43;:::i;:::-;10260:51;9858:459;-1:-1:-1;;;;;9858:459:10:o;10322:331::-;10559:2;10548:9;10541:21;10522:4;10579:68;10643:2;10632:9;10628:18;10620:6;10579:68;:::i;10658:454::-;10734:6;10742;10750;10803:2;10791:9;10782:7;10778:23;10774:32;10771:52;;;10819:1;10816;10809:12;10771:52;10858:9;10845:23;10877:31;10902:5;10877:31;:::i;:::-;10927:5;-1:-1:-1;10979:2:10;10964:18;;10951:32;;-1:-1:-1;11035:2:10;11020:18;;11007:32;11048;11007;11048;:::i;:::-;11099:7;11089:17;;;10658:454;;;;;:::o;11117:355::-;11322:2;11311:9;11304:21;11285:4;11342:55;11393:2;11382:9;11378:18;11370:6;11342:55;:::i;:::-;11334:63;;11462:1;11458;11453:3;11449:11;11445:19;11437:6;11433:32;11428:2;11417:9;11413:18;11406:60;11117:355;;;;;:::o;11477:315::-;11545:6;11553;11606:2;11594:9;11585:7;11581:23;11577:32;11574:52;;;11622:1;11619;11612:12;11574:52;11661:9;11648:23;11680:31;11705:5;11680:31;:::i;:::-;11730:5;11782:2;11767:18;;;;11754:32;;-1:-1:-1;;;11477:315:10:o;11797:510::-;11851:5;11904:3;11897:4;11889:6;11885:17;11881:27;11871:55;;11922:1;11919;11912:12;11871:55;11951:6;11945:13;-1:-1:-1;;;;;11973:2:10;11970:26;11967:52;;;11999:18;;:::i;:::-;12043:55;12086:2;12067:13;;-1:-1:-1;;12063:27:10;12092:4;12059:38;12043:55;:::i;:::-;12123:2;12114:7;12107:19;12169:3;12162:4;12157:2;12149:6;12145:15;12141:26;12138:35;12135:55;;;12186:1;12183;12176:12;12135:55;12199:77;12273:2;12266:4;12257:7;12253:18;12246:4;12238:6;12234:17;12199:77;:::i;:::-;12294:7;11797:510;-1:-1:-1;;;;11797:510:10:o;12312:337::-;12392:6;12445:2;12433:9;12424:7;12420:23;12416:32;12413:52;;;12461:1;12458;12451:12;12413:52;12494:9;12488:16;-1:-1:-1;;;;;12519:6:10;12516:30;12513:50;;;12559:1;12556;12549:12;12513:50;12582:61;12635:7;12626:6;12615:9;12611:22;12582:61;:::i;12654:251::-;12724:6;12777:2;12765:9;12756:7;12752:23;12748:32;12745:52;;;12793:1;12790;12783:12;12745:52;12825:9;12819:16;12844:31;12869:5;12844:31;:::i;13092:731::-;13156:5;13209:3;13202:4;13194:6;13190:17;13186:27;13176:55;;13227:1;13224;13217:12;13176:55;13256:6;13250:13;13282:4;13306:59;13322:42;13361:2;13322:42;:::i;13306:59::-;13399:15;;;13485:1;13481:10;;;;13469:23;;13465:32;;;13430:12;;;;13509:15;;;13506:35;;;13537:1;13534;13527:12;13506:35;13573:2;13565:6;13561:15;13585:209;13601:6;13596:3;13593:15;13585:209;;;13674:3;13668:10;13691:30;13715:5;13691:30;:::i;:::-;13734:18;;13772:12;;;;13618;;13585:209;;13828:361;13922:6;13975:2;13963:9;13954:7;13950:23;13946:32;13943:52;;;13991:1;13988;13981:12;13943:52;14024:9;14018:16;-1:-1:-1;;;;;14049:6:10;14046:30;14043:50;;;14089:1;14086;14079:12;14043:50;14112:71;14175:7;14166:6;14155:9;14151:22;14112:71;:::i;14194:127::-;14255:10;14250:3;14246:20;14243:1;14236:31;14286:4;14283:1;14276:15;14310:4;14307:1;14300:15;14699:675;14795:6;14848:3;14836:9;14827:7;14823:23;14819:33;14816:53;;;14865:1;14862;14855:12;14816:53;14891:22;;:::i;:::-;14943:9;14937:16;14962:32;14986:7;14962:32;:::i;:::-;15003:22;;15070:2;15055:18;;15049:25;15083:32;15049:25;15083:32;:::i;:::-;15142:2;15131:14;;15124:31;15208:2;15193:18;;;15187:25;15171:14;;;15164:49;15258:2;15243:18;;15237:25;15271:33;15237:25;15271:33;:::i;:::-;15331:2;15320:14;;15313:31;15324:5;14699:675;-1:-1:-1;;;14699:675:10:o;15379:258::-;15556:2;15545:9;15538:21;15519:4;15576:55;15627:2;15616:9;15612:18;15604:6;15576:55;:::i;15642:733::-;15707:5;15760:3;15753:4;15745:6;15741:17;15737:27;15727:55;;15778:1;15775;15768:12;15727:55;15807:6;15801:13;15833:4;15857:59;15873:42;15912:2;15873:42;:::i;15857:59::-;15950:15;;;16036:1;16032:10;;;;16020:23;;16016:32;;;15981:12;;;;16060:15;;;16057:35;;;16088:1;16085;16078:12;16057:35;16124:2;16116:6;16112:15;16136:210;16152:6;16147:3;16144:15;16136:210;;;16225:3;16219:10;16242:31;16267:5;16242:31;:::i;:::-;16286:18;;16324:12;;;;16169;;16136:210;;16380:873;16442:5;16490:4;16478:9;16473:3;16469:19;16465:30;16462:50;;;16508:1;16505;16498:12;16462:50;16530:22;;:::i;:::-;16521:31;;16582:9;16576:16;16623:1;16614:7;16611:14;16601:42;;16639:1;16636;16629:12;16601:42;16652:22;;16719:2;16704:18;;16698:25;16767:4;16754:18;;16742:31;;16732:59;;16787:1;16784;16777:12;16732:59;16818:2;16807:14;;16800:31;16875:2;16860:18;;16854:25;-1:-1:-1;;;;;16928:14:10;;;16925:34;;;16955:1;16952;16945:12;16925:34;16991:68;17055:3;17046:6;17035:9;17031:22;16991:68;:::i;:::-;16986:2;16979:5;16975:14;16968:92;17106:2;17095:9;17091:18;17085:25;17069:41;;17135:2;17125:8;17122:16;17119:36;;;17151:1;17148;17141:12;17119:36;;17187:59;17242:3;17231:8;17220:9;17216:24;17187:59;:::i;:::-;17182:2;17175:5;17171:14;17164:83;;16380:873;;;;:::o;17258:1148::-;17373:6;17404:2;17447;17435:9;17426:7;17422:23;17418:32;17415:52;;;17463:1;17460;17453:12;17415:52;17496:9;17490:16;-1:-1:-1;;;;;17566:2:10;17558:6;17555:14;17552:34;;;17582:1;17579;17572:12;17552:34;17620:6;17609:9;17605:22;17595:32;;17665:7;17658:4;17654:2;17650:13;17646:27;17636:55;;17687:1;17684;17677:12;17636:55;17716:2;17710:9;17739:59;17755:42;17794:2;17755:42;:::i;17739:59::-;17832:15;;;17914:1;17910:10;;;;17902:19;;17898:28;;;17863:12;;;;17938:19;;;17935:39;;;17970:1;17967;17960:12;17935:39;18002:2;17998;17994:11;18014:362;18030:6;18025:3;18022:15;18014:362;;;18109:3;18103:10;18145:2;18132:11;18129:19;18126:109;;;18189:1;18218:2;18214;18207:14;18126:109;18260:73;18325:7;18320:2;18306:11;18302:2;18298:20;18294:29;18260:73;:::i;:::-;18248:86;;-1:-1:-1;18354:12:10;;;;18047;;18014:362;;;-1:-1:-1;18395:5:10;17258:1148;-1:-1:-1;;;;;;;;17258:1148:10:o;18411:222::-;18476:9;;;18497:10;;;18494:133;;;18549:10;18544:3;18540:20;18537:1;18530:31;18584:4;18581:1;18574:15;18612:4;18609:1;18602:15;18494:133;18411:222;;;;:::o;18843:277::-;18910:6;18963:2;18951:9;18942:7;18938:23;18934:32;18931:52;;;18979:1;18976;18969:12;18931:52;19011:9;19005:16;19064:5;19057:13;19050:21;19043:5;19040:32;19030:60;;19086:1;19083;19076:12;19125:352;19215:6;19268:2;19256:9;19247:7;19243:23;19239:32;19236:52;;;19284:1;19281;19274:12;19236:52;19317:9;19311:16;-1:-1:-1;;;;;19342:6:10;19339:30;19336:50;;;19382:1;19379;19372:12;19336:50;19405:66;19463:7;19454:6;19443:9;19439:22;19405:66;:::i;19758:847::-;19888:6;19896;19904;19912;19965:3;19953:9;19944:7;19940:23;19936:33;19933:53;;;19982:1;19979;19972:12;19933:53;20015:9;20009:16;-1:-1:-1;;;;;20085:2:10;20077:6;20074:14;20071:34;;;20101:1;20098;20091:12;20071:34;20124:61;20177:7;20168:6;20157:9;20153:22;20124:61;:::i;:::-;20114:71;;20228:2;20217:9;20213:18;20207:25;20194:38;;20241:30;20265:5;20241:30;:::i;:::-;20340:2;20325:18;;20319:25;20290:5;;-1:-1:-1;20353:33:10;20319:25;20353:33;:::i;:::-;20458:2;20443:18;;20437:25;20405:7;;-1:-1:-1;20474:16:10;;;20471:36;;;20503:1;20500;20493:12;20471:36;;20526:73;20591:7;20580:8;20569:9;20565:24;20526:73;:::i;20610:1253::-;20727:6;20758:2;20801;20789:9;20780:7;20776:23;20772:32;20769:52;;;20817:1;20814;20807:12;20769:52;20850:9;20844:16;-1:-1:-1;;;;;20875:6:10;20872:30;20869:50;;;20915:1;20912;20905:12;20869:50;20938:22;;20991:4;20983:13;;20979:27;-1:-1:-1;20969:55:10;;21020:1;21017;21010:12;20969:55;21049:2;21043:9;21072:59;21088:42;21127:2;21088:42;:::i;21072:59::-;21165:15;;;21247:1;21243:10;;;;21235:19;;21231:28;;;21196:12;;;;21271:19;;;21268:39;;;21303:1;21300;21293:12;21268:39;21327:11;;;;21347:486;21363:6;21358:3;21355:15;21347:486;;;21445:4;21439:3;21430:7;21426:17;21422:28;21419:118;;;21491:1;21520:2;21516;21509:14;21419:118;21563:22;;:::i;:::-;21618:3;21612:10;21605:5;21598:25;21666:2;21661:3;21657:12;21651:19;21683:33;21708:7;21683:33;:::i;:::-;21736:14;;;21729:31;21773:18;;21389:4;21380:14;;;;;21811:12;;;;21347:486;
Swarm Source
ipfs://62d12355ff8924d59c1555d26558ca2301b98d0f1b9eae53268002f4ee4c2ebe
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.