ETH Price: $3,254.57 (-0.93%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Transfer Ownersh...187976932023-12-16 9:19:59404 days ago1702718399IN
0xDb707aF2...14485D42A
0 ETH0.0010058435.13872834
Withdraw187976932023-12-16 9:19:59404 days ago1702718399IN
0xDb707aF2...14485D42A
0 ETH0.001176734.93872834
Premint182439112023-09-29 20:59:59481 days ago1696021199IN
0xDb707aF2...14485D42A
0 ETH0.044813310.25050785
Deactivate182436742023-09-29 20:12:35481 days ago1696018355IN
0xDb707aF2...14485D42A
0 ETH0.000412219.95024341
Purchase182436122023-09-29 19:59:47481 days ago1696017587IN
0xDb707aF2...14485D42A
0.25069 ETH0.001143367.5556632
Purchase182435372023-09-29 19:44:23481 days ago1696016663IN
0xDb707aF2...14485D42A
0.25069 ETH0.001052656.95481179
Purchase182434582023-09-29 19:28:35481 days ago1696015715IN
0xDb707aF2...14485D42A
0.25069 ETH0.001482399.79478127
Purchase182434402023-09-29 19:24:59481 days ago1696015499IN
0xDb707aF2...14485D42A
0.25069 ETH0.0015619710.32060858
Purchase182433442023-09-29 19:05:47481 days ago1696014347IN
0xDb707aF2...14485D42A
0.25069 ETH0.001298148.57672988
Purchase182432492023-09-29 18:46:47481 days ago1696013207IN
0xDb707aF2...14485D42A
0.25069 ETH0.0015867410.48430117
Purchase182432092023-09-29 18:38:47481 days ago1696012727IN
0xDb707aF2...14485D42A
0.25069 ETH0.001823912.05225399
Purchase182431742023-09-29 18:31:47481 days ago1696012307IN
0xDb707aF2...14485D42A
0.25069 ETH0.0016455910.87314939
Purchase182430192023-09-29 18:00:35481 days ago1696010435IN
0xDb707aF2...14485D42A
0.25069 ETH0.0016326512.16463744
Purchase182429862023-09-29 17:53:47481 days ago1696010027IN
0xDb707aF2...14485D42A
0.25069 ETH0.0015188210.02427592
Purchase182428712023-09-29 17:30:35482 days ago1696008635IN
0xDb707aF2...14485D42A
0.25069 ETH0.0022328214.73551505
Purchase182426782023-09-29 16:51:47482 days ago1696006307IN
0xDb707aF2...14485D42A
0.25069 ETH0.0019264814.33105489
Purchase182426442023-09-29 16:44:59482 days ago1696005899IN
0xDb707aF2...14485D42A
0.25069 ETH0.0019930614.82636767
Purchase182425432023-09-29 16:24:47482 days ago1696004687IN
0xDb707aF2...14485D42A
0.25069 ETH0.0025395516.75975788
Purchase182424242023-09-29 16:00:59482 days ago1696003259IN
0xDb707aF2...14485D42A
0.25069 ETH0.0024085615.89319907
Activate182420542023-09-29 14:46:23482 days ago1695998783IN
0xDb707aF2...14485D42A
0 ETH0.0010534522.52230784
Update Initializ...182420412023-09-29 14:43:47482 days ago1695998627IN
0xDb707aF2...14485D42A
0 ETH0.0010807624.03239087
Premint182420362023-09-29 14:42:47482 days ago1695998567IN
0xDb707aF2...14485D42A
0 ETH0.097628625.80645554
Deactivate182388562023-09-29 4:00:23482 days ago1695960023IN
0xDb707aF2...14485D42A
0 ETH0.000288926.97407217
Purchase182388542023-09-29 3:59:59482 days ago1695959999IN
0xDb707aF2...14485D42A
0.08069 ETH0.000875986.51640438
Purchase182388542023-09-29 3:59:59482 days ago1695959999IN
0xDb707aF2...14485D42A
0.08069 ETH0.000876116.51640438
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block
From
To
187976932023-12-16 9:19:59404 days ago1702718399
0xDb707aF2...14485D42A
5.96436 ETH
182436122023-09-29 19:59:47481 days ago1696017587
0xDb707aF2...14485D42A
0.25 ETH
182435372023-09-29 19:44:23481 days ago1696016663
0xDb707aF2...14485D42A
0.25 ETH
182434582023-09-29 19:28:35481 days ago1696015715
0xDb707aF2...14485D42A
0.25 ETH
182434402023-09-29 19:24:59481 days ago1696015499
0xDb707aF2...14485D42A
0.25 ETH
182433442023-09-29 19:05:47481 days ago1696014347
0xDb707aF2...14485D42A
0.25 ETH
182432492023-09-29 18:46:47481 days ago1696013207
0xDb707aF2...14485D42A
0.25 ETH
182432092023-09-29 18:38:47481 days ago1696012727
0xDb707aF2...14485D42A
0.25 ETH
182431742023-09-29 18:31:47481 days ago1696012307
0xDb707aF2...14485D42A
0.25 ETH
182430192023-09-29 18:00:35481 days ago1696010435
0xDb707aF2...14485D42A
0.25 ETH
182429862023-09-29 17:53:47481 days ago1696010027
0xDb707aF2...14485D42A
0.25 ETH
182428712023-09-29 17:30:35482 days ago1696008635
0xDb707aF2...14485D42A
0.25 ETH
182426782023-09-29 16:51:47482 days ago1696006307
0xDb707aF2...14485D42A
0.25 ETH
182426442023-09-29 16:44:59482 days ago1696005899
0xDb707aF2...14485D42A
0.25 ETH
182425432023-09-29 16:24:47482 days ago1696004687
0xDb707aF2...14485D42A
0.25 ETH
182424242023-09-29 16:00:59482 days ago1696003259
0xDb707aF2...14485D42A
0.25 ETH
182388542023-09-29 3:59:59482 days ago1695959999
0xDb707aF2...14485D42A
0.08 ETH
182388542023-09-29 3:59:59482 days ago1695959999
0xDb707aF2...14485D42A
0.08 ETH
182388542023-09-29 3:59:59482 days ago1695959999
0xDb707aF2...14485D42A
0.08 ETH
182388532023-09-29 3:59:47482 days ago1695959987
0xDb707aF2...14485D42A
0.08 ETH
182388522023-09-29 3:59:35482 days ago1695959975
0xDb707aF2...14485D42A
0.8 ETH
182388472023-09-29 3:58:35482 days ago1695959915
0xDb707aF2...14485D42A
0.08 ETH
182388472023-09-29 3:58:35482 days ago1695959915
0xDb707aF2...14485D42A
0.32 ETH
182388462023-09-29 3:58:23482 days ago1695959903
0xDb707aF2...14485D42A
2.8 ETH
182388432023-09-29 3:57:47482 days ago1695959867
0xDb707aF2...14485D42A
0.08 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ERC721Collectible

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion
File 1 of 20 : ERC721Collectible.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/// @author: manifold.xyz

import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
import "@manifoldxyz/libraries-solidity/contracts/access/AdminControl.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

import "./IERC721Collectible.sol";
import "./CollectibleCore.sol";
import "../../libraries/IERC721CreatorCoreVersion.sol";

contract ERC721Collectible is CollectibleCore, IERC721Collectible {
    struct TokenClaim {
      uint224 instanceId;
      uint32 mintOrder;
    }

    // NOTE: Only used for creatorContract versions < 3
    // { contractAddress => { tokenId => TokenClaim }
    mapping(address => mapping(uint256 => TokenClaim)) internal _tokenIdToTokenClaimMap;

    // { contractAddress => { instanceId => { address => mintCount } }
    mapping(address => mapping(uint256 => mapping(address => uint256))) internal _addressMintCount;

    function supportsInterface(bytes4 interfaceId) public view virtual override(AdminControl, IERC165) returns (bool) {
        return (interfaceId == type(IERC721Collectible).interfaceId ||
            interfaceId == type(ICreatorExtensionTokenURI).interfaceId ||
            interfaceId == type(IERC721CreatorExtensionApproveTransfer).interfaceId ||
            interfaceId == type(IAdminControl).interfaceId ||
            interfaceId == type(IERC165).interfaceId);
    }

    /**
    * See {ICollectibleCore-initializeCollectible}.
    */
    function initializeCollectible(
        address creatorContractAddress,
        uint256 instanceId,
        InitializationParameters calldata initializationParameters
    ) external override creatorAdminRequired(creatorContractAddress) {
        uint8 creatorContractVersion;
        try IERC721CreatorCoreVersion(creatorContractAddress).VERSION() returns(uint256 version) {
            require(version <= 255, "Unsupported contract version");
            creatorContractVersion = uint8(version);
        } catch {}
        _initializeCollectible(creatorContractAddress, creatorContractVersion, instanceId, initializationParameters);
  }

    /**
    * @dev See {IERC721Collectible-premint}.
    */
    function premint(
        address creatorContractAddress,
        uint256 instanceId,
        uint16 amount
    ) external override creatorAdminRequired(creatorContractAddress) {
        CollectibleInstance storage instance = _getInstance(creatorContractAddress, instanceId);
        require(!instance.isActive, "Already active");

        _mint(creatorContractAddress, instanceId, msg.sender, amount);
    }

    /**
    * @dev See {IERC721Collectible-premint}.
    */
    function premint(
        address creatorContractAddress,
        uint256 instanceId,
        address[] calldata addresses
    ) external override creatorAdminRequired(creatorContractAddress) {
        CollectibleInstance storage instance = _getInstance(creatorContractAddress, instanceId);
        require(!instance.isActive, "Already active");

        for (uint256 i = 0; i < addresses.length; ) {
            _mint(creatorContractAddress, instanceId, addresses[i], 1);
            unchecked {
              i++;
            }
        }
    }

    /**
    * @dev See {IERC721Collectible-setTokenURIPrefix}.
    */
    function setTokenURIPrefix(
        address creatorContractAddress,
        uint256 instanceId,
        string calldata prefix
    ) external override creatorAdminRequired(creatorContractAddress) {
        CollectibleInstance storage instance = _getInstance(creatorContractAddress, instanceId);
        instance.baseURI = prefix;
    }

    /**
    * @dev See {IERC721Collectible-setTransferLocked}.
    */
    function setTransferLocked(
        address creatorContractAddress,
        uint256 instanceId,
        bool isLocked
    ) external override creatorAdminRequired(creatorContractAddress) {
        CollectibleInstance storage instance = _getInstance(creatorContractAddress, instanceId);
        instance.isTransferLocked = isLocked;
    }

    /**
    * @dev See {IERC721Collectible-claim}.
    */
    function claim(
        address creatorContractAddress,
        uint256 instanceId,
        uint16 amount,
        bytes32 message,
        bytes calldata signature,
        bytes32 nonce
    ) public payable virtual override {
        _validateClaimRestrictions(creatorContractAddress, instanceId);
        _validateClaimRequest(creatorContractAddress, instanceId, message, signature, nonce, amount);
        _addressMintCount[creatorContractAddress][instanceId][msg.sender] += amount;
        require(msg.value == _getManifoldFee(amount), "Invalid purchase amount");
        _mint(creatorContractAddress, instanceId, msg.sender, amount);
    }

    /**
    * @dev See {IERC721Collection-purchase}.
    */
    function purchase(
      address creatorContractAddress,
      uint256 instanceId,
      uint16 amount,
      bytes32 message,
      bytes calldata signature,
      bytes32 nonce
    ) public payable virtual override {
        CollectibleInstance storage instance = _getInstance(creatorContractAddress, instanceId);
        _validatePurchaseRestrictions(creatorContractAddress, instanceId);

        bool isPresale = _isPresale(creatorContractAddress, instanceId);
        uint256 priceWithoutFee;

        // Check purchase amounts
        require(
            amount <= purchaseRemaining(creatorContractAddress, instanceId) &&
                ((isPresale && instance.useDynamicPresalePurchaseLimit) ||
                  instance.transactionLimit == 0 ||
                  amount <= instance.transactionLimit),
            "Too many requested"
        );

        if (isPresale) {
            if (!instance.useDynamicPresalePurchaseLimit) {
                // Make sure we are not over presalePurchaseLimit
                if (instance.presalePurchaseLimit != 0) {
                    uint256 mintCount = _addressMintCount[creatorContractAddress][instanceId][msg.sender];
                    require(
                        instance.presalePurchaseLimit > mintCount && amount <= (instance.presalePurchaseLimit - mintCount),
                        "Too many requested"
                    );
                }
                // Make sure we are not over purchaseLimit
                if (instance.purchaseLimit != 0) {
                    uint256 mintCount = _addressMintCount[creatorContractAddress][instanceId][msg.sender];
                    require(
                        instance.purchaseLimit > mintCount && amount <= (instance.purchaseLimit - mintCount),
                        "Too many requested"
                    );
                  }
              }
            priceWithoutFee = _validatePresalePrice(amount, instance);
            // Only track mint count if needed
            if (!instance.useDynamicPresalePurchaseLimit && (instance.presalePurchaseLimit != 0 || instance.purchaseLimit != 0)) {
                _addressMintCount[creatorContractAddress][instanceId][msg.sender] += amount;
            }
        } else {
            // Make sure we are not over purchaseLimit
            if (instance.purchaseLimit != 0) {
                uint256 mintCount = _addressMintCount[creatorContractAddress][instanceId][msg.sender];
                require(instance.purchaseLimit > mintCount && amount <= (instance.purchaseLimit - mintCount), "Too many requested");
            }
            priceWithoutFee = _validatePrice(amount, instance);

            if (instance.purchaseLimit != 0) {
                _addressMintCount[creatorContractAddress][instanceId][msg.sender] += amount;
            }
        }

        if (isPresale && instance.useDynamicPresalePurchaseLimit) {
           _validatePurchaseRequestWithAmount(creatorContractAddress, instanceId, message, signature, nonce, amount);
        } else {
            _validatePurchaseRequest(creatorContractAddress, instanceId, message, signature, nonce);
        }

        if (priceWithoutFee > 0) {
            _forwardValue(instance.paymentReceiver, priceWithoutFee);
        }

        _mint(creatorContractAddress, instanceId, msg.sender, amount);
    }

    /**
    * @dev returns the collection state
    */
    function state(address creatorContractAddress, uint256 instanceId) external view returns (CollectibleState memory) {
        CollectibleInstance storage instance = _getInstance(creatorContractAddress, instanceId);

        return CollectibleState(
            instance.isActive,
            instance.useDynamicPresalePurchaseLimit,
            instance.isTransferLocked,
            instance.transactionLimit,
            instance.purchaseMax,
            instance.purchaseLimit,
            instance.presalePurchaseLimit,
            instance.purchaseCount,
            instance.startTime,
            instance.endTime,
            instance.presaleInterval,
            instance.claimStartTime,
            instance.claimEndTime,
            instance.purchasePrice,
            instance.presalePurchasePrice,
            purchaseRemaining(creatorContractAddress, instanceId),
            instance.paymentReceiver
        );
    }

    /**
    * @dev See {IERC721Collectible-purchaseRemaining}.
    */
    function purchaseRemaining(
        address creatorContractAddress,
        uint256 instanceId
    ) public view virtual override returns (uint16) {
        CollectibleInstance storage instance = _getInstance(creatorContractAddress, instanceId);
        return instance.purchaseMax - instance.purchaseCount;
    }

    /**
    * @dev See {ICreatorExtensionTokenURI-tokenURI}
    */
    function tokenURI(address creatorContractAddress, uint256 tokenId) external view override returns (string memory) {
        TokenClaim memory tokenClaim = _tokenIdToTokenClaimMap[creatorContractAddress][tokenId];
        uint256 mintOrder;
        CollectibleInstance memory instance;
        if (tokenClaim.instanceId == 0) {
            // No claim, try to retrieve from tokenData
            uint80 tokenData = IERC721CreatorCore(creatorContractAddress).tokenData(tokenId);
            uint56 instanceId = uint56(tokenData >> 24);
            require(instanceId != 0, "Token not found");
            instance = _getInstance(creatorContractAddress, instanceId);
            mintOrder = uint24(tokenData & MAX_UINT_24);
        } else {
            mintOrder = tokenClaim.mintOrder;
            instance = _getInstance(creatorContractAddress, tokenClaim.instanceId);
        }

        require(bytes(instance.baseURI).length != 0, "No base uri prefix set");

        return string(abi.encodePacked(instance.baseURI, Strings.toString(mintOrder)));
    }

    /**
    * @dev See {IERC721CreatorExtensionApproveTransfer-setApproveTransfer}
    */
    function setApproveTransfer(
      address creatorContractAddress,
      bool enabled
    ) external override creatorAdminRequired(creatorContractAddress) {
        require(
            ERC165Checker.supportsInterface(creatorContractAddress, type(IERC721CreatorCore).interfaceId),
            "creator must implement IERC721CreatorCore"
        );
        IERC721CreatorCore(creatorContractAddress).setApproveTransferExtension(enabled);
    }

    /**
    * @dev See {IERC721CreatorExtensionApproveTransfer-approveTransfer}.
    */
    function approveTransfer(address, address from, address, uint256 tokenId) external view override returns (bool) {
        // always allow mints
        if (from == address(0)) {
            return true;
        }
        TokenClaim memory tokenClaim = _tokenIdToTokenClaimMap[msg.sender][tokenId];
        uint256 instanceId;
        if (tokenClaim.instanceId == 0) {
            // No claim, try to retrieve from tokenData
            uint80 tokenData = IERC721CreatorCore(msg.sender).tokenData(tokenId);
            instanceId = uint56(tokenData >> 24);
            require(instanceId != 0, "Token not found");
        } else {
            instanceId = tokenClaim.instanceId;
        }
        CollectibleInstance storage instance = _getInstance(msg.sender, instanceId);

        return !instance.isTransferLocked;
    }

    /**
    * @dev override if you want to perform different mint functionality
    */
    function _mint(address creatorContractAddress, uint256 instanceId, address to, uint16 amount) internal virtual {
        CollectibleInstance storage instance = _getInstance(creatorContractAddress, instanceId);

        if (amount == 1) {
            uint256 tokenId;
            if (instance.contractVersion >= 3) {
                uint80 tokenData = uint56(instanceId) << 24 | uint24(++instance.purchaseCount);
                tokenId = IERC721CreatorCore(creatorContractAddress).mintExtension(to, tokenData);
            } else {
                ++instance.purchaseCount;
                tokenId = IERC721CreatorCore(creatorContractAddress).mintExtension(to);
                _tokenIdToTokenClaimMap[creatorContractAddress][tokenId] = TokenClaim(uint224(instanceId), instance.purchaseCount);
            }
            emit Unveil(creatorContractAddress, instanceId, instance.purchaseCount, tokenId);
        } else {
            uint32 tokenStart = instance.purchaseCount + 1;
            instance.purchaseCount += amount;
            if (instance.contractVersion >= 3) {
                uint80[] memory tokenDatas = new uint80[](amount);
                for (uint256 i; i < amount;) {
                    tokenDatas[i] = uint56(instanceId) << 24 | uint24(tokenStart + i);
                    unchecked { ++i; }
                }
                uint256[] memory tokenIds = IERC721CreatorCore(creatorContractAddress).mintExtensionBatch(to, tokenDatas);
                for (uint32 i = 0; i < amount; ) {
                    emit Unveil(creatorContractAddress, instanceId, tokenStart + i, tokenIds[i]);
                    unchecked { ++i; }
                }
            } else {
                uint256[] memory tokenIds = IERC721CreatorCore(creatorContractAddress).mintExtensionBatch(to, amount);
                for (uint32 i = 0; i < amount; ) {
                    emit Unveil(creatorContractAddress, instanceId, tokenStart + i, tokenIds[i]);
                    _tokenIdToTokenClaimMap[creatorContractAddress][tokenIds[i]] = TokenClaim(uint224(instanceId), tokenStart + i);
                    unchecked { ++i; }
                }
            }
        }
    }

    /**
    * Validate price (override for custom pricing mechanics)
    */
    function _validatePrice(uint16 numTokens, CollectibleInstance storage instance) internal virtual returns (uint256) {
        uint256 priceWithoutFee = numTokens * instance.purchasePrice;
        uint256 price = priceWithoutFee + _getManifoldFee(numTokens);
        require(msg.value == price, "Invalid purchase amount sent");

        return priceWithoutFee;
    }

    /**
    * Validate price (override for custom pricing mechanics)
    */
    function _validatePresalePrice(uint16 numTokens, CollectibleInstance storage instance) internal virtual returns (uint256) {
        uint256 priceWithoutFee = numTokens * instance.presalePurchasePrice;
        uint256 price = priceWithoutFee + _getManifoldFee(numTokens);
        require(msg.value == price, "Invalid purchase amount sent");

        return priceWithoutFee;
    }
}

File 2 of 20 : IERC721CreatorCoreVersion.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IERC721CreatorCoreVersion {
    function VERSION() external view returns(uint256);
}

File 3 of 20 : CollectibleCore.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/// @author: manifold.xyz
import "@manifoldxyz/libraries-solidity/contracts/access/AdminControl.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "../../libraries/manifold-membership/IManifoldMembership.sol";

import "./ICollectibleCore.sol";

/**
 * Collection Drop Contract (Base)
 */
abstract contract CollectibleCore is ICollectibleCore, AdminControl {
    using ECDSA for bytes32;

    uint256 public constant MINT_FEE = 690000000000000;
    uint256 internal constant MAX_UINT_24 = 0xffffff;
    uint256 internal constant MAX_UINT_56 = 0xffffffffffffff;

    address public manifoldMembershipContract;

    // { creatorContractAddress => { instanceId => nonce => t/f  } }
    mapping(address => mapping(uint256 => mapping(bytes32 => bool))) internal _usedNonces;
    // { creatorContractAddress => { instanceId => address  } }
    mapping(address => mapping(uint256 => address)) private _signingAddresses;
    // { creatorContractAddress => { instanceId => CollectibleInstance } }
    mapping(address => mapping(uint256 => CollectibleInstance)) internal _instances;

    /**
    * @notice This extension is shared, not single-creator. So we must ensure
    * that a claim's initializer is an admin on the creator contract
    * @param creatorContractAddress    the address of the creator contract to check the admin against
    */
    modifier creatorAdminRequired(address creatorContractAddress) {
        AdminControl creatorCoreContract = AdminControl(creatorContractAddress);
        require(creatorCoreContract.isAdmin(msg.sender), "Wallet is not an administrator for contract");
        _;
    }

    /**
    * Initialize collectible
    */
    function _initializeCollectible(
      address creatorContractAddress,
      uint8 creatorContractVersion,
      uint256 instanceId,
      InitializationParameters calldata initializationParameters
    ) internal {
        // Max uint56 for instanceId
        require(instanceId > 0 && instanceId <= MAX_UINT_56, "Invalid instanceId");

        address signingAddress = _signingAddresses[creatorContractAddress][instanceId];
        CollectibleInstance storage instance = _instances[creatorContractAddress][instanceId];

        // Revert if claim at instanceId already exists
        require(signingAddress == address(0), "Collectible already initialized");
        require(initializationParameters.signingAddress != address(0), "Invalid signing address");
        require(initializationParameters.paymentReceiver != address(0), "Invalid payment address");
        require(initializationParameters.purchaseMax != 0, "Invalid purchase max");

        _signingAddresses[creatorContractAddress][instanceId] = initializationParameters.signingAddress;
        instance.contractVersion = creatorContractVersion;
        instance.purchaseMax = initializationParameters.purchaseMax;
        instance.purchasePrice = initializationParameters.purchasePrice;
        instance.purchaseLimit = initializationParameters.purchaseLimit;
        instance.transactionLimit = initializationParameters.transactionLimit;
        instance.presalePurchasePrice = initializationParameters.presalePurchasePrice;
        instance.presalePurchaseLimit = initializationParameters.presalePurchaseLimit;
        instance.useDynamicPresalePurchaseLimit = initializationParameters.useDynamicPresalePurchaseLimit;
        instance.paymentReceiver = initializationParameters.paymentReceiver;

        emit CollectibleInitialized(creatorContractAddress, instanceId, msg.sender);
    }

    /**
    * See {ICollectibleCore-withdraw}.
    */
    function withdraw(address payable receiver, uint256 amount) external override adminRequired {
        (bool sent, ) = receiver.call{ value: amount }("");
        require(sent, "Failed to transfer to receiver");
    }

    /**
    * See {ICollectibleCore-activate}.
    */
    function activate(
      address creatorContractAddress,
      uint256 instanceId,
      ActivationParameters calldata activationParameters
    ) external override creatorAdminRequired(creatorContractAddress) {
        CollectibleInstance storage instance = _getInstance(creatorContractAddress, instanceId);
        require(!instance.isActive, "Already active");
        require(activationParameters.startTime > block.timestamp, "Cannot activate in the past");
        require(
          activationParameters.presaleInterval <= activationParameters.duration,
          "Presale Interval cannot be longer than the sale"
        );
        require(
          activationParameters.claimStartTime <= activationParameters.claimEndTime &&
            activationParameters.claimEndTime <= activationParameters.startTime,
          "Invalid claim times"
        );
        instance.startTime = activationParameters.startTime;
        instance.endTime = activationParameters.startTime + activationParameters.duration;
        instance.presaleInterval = activationParameters.presaleInterval;
        instance.claimStartTime = activationParameters.claimStartTime;
        instance.claimEndTime = activationParameters.claimEndTime;
        instance.isActive = true;

        emit CollectibleActivated(
          creatorContractAddress,
          instanceId,
          instance.startTime,
          instance.endTime,
          instance.presaleInterval,
          instance.claimStartTime,
          instance.claimEndTime
        );
    }

    /**
    * See {ICollectibleCore-deactivate}.
    */
    function deactivate(
      address creatorContractAddress,
      uint256 instanceId
    ) external override creatorAdminRequired(creatorContractAddress) {
        CollectibleInstance storage instance = _getInstance(creatorContractAddress, instanceId);

        instance.startTime = 0;
        instance.endTime = 0;
        instance.isActive = false;
        instance.claimStartTime = 0;
        instance.claimEndTime = 0;

        emit CollectibleDeactivated(creatorContractAddress, instanceId);
    }

    /**
    * @dev See {ICollectibleCore-getCollectible}.
    */
    function getCollectible(
        address creatorContractAddress,
        uint256 index
    ) external view override returns (CollectibleInstance memory) {
        return _getCollectible(creatorContractAddress, index);
    }

    /**
    * @dev See {IERC721Collectible-setMembershipAddress}.
    */
    function setMembershipAddress(address addr) external override adminRequired {
        manifoldMembershipContract = addr;
    }

    /**
    * @dev See {ICollectibleCore-updateInitializationParameters}.
    */
    function updateInitializationParameters(
        address creatorContractAddress,
        uint256 instanceId,
        UpdateInitializationParameters calldata initializationParameters
    ) external override creatorAdminRequired(creatorContractAddress) {
        CollectibleInstance storage instance = _getInstance(creatorContractAddress, instanceId);

        require(!instance.isActive, "Already active");
        instance.purchasePrice = initializationParameters.purchasePrice;
        instance.purchaseLimit = initializationParameters.purchaseLimit;
        instance.transactionLimit = initializationParameters.transactionLimit;
        instance.presalePurchasePrice = initializationParameters.presalePurchasePrice;
        instance.presalePurchaseLimit = initializationParameters.presalePurchaseLimit;
        instance.useDynamicPresalePurchaseLimit = initializationParameters.useDynamicPresalePurchaseLimit;
    }

    /**
    * @dev See {ICollectibleCore-updatePaymentReceiver}.
    */
    function updatePaymentReceiver(
        address creatorContractAddress,
        uint256 instanceId,
        address payable paymentReceiver
    ) external override creatorAdminRequired(creatorContractAddress) {
        CollectibleInstance storage instance = _getInstance(creatorContractAddress, instanceId);
        require(paymentReceiver != address(0), "Invalid payment address");

        instance.paymentReceiver = paymentReceiver;
    }

    /**
    * Validate claim signature
    */
    function _getCollectible(
        address creatorContractAddress,
        uint256 instanceId
    ) internal view returns (CollectibleInstance storage) {
        return _instances[creatorContractAddress][instanceId];
    }

    /**
    * Validate claim signature
    */
    function _validateClaimRequest(
        address creatorContractAddress,
        uint256 instanceId,
        bytes32 message,
        bytes calldata signature,
        bytes32 nonce,
        uint16 amount
    ) internal virtual {
        _validatePurchaseRequestWithAmount(creatorContractAddress, instanceId, message, signature, nonce, amount);
    }

    /**
    * Validate claim restrictions
    */
    function _validateClaimRestrictions(address creatorContractAddress, uint256 instanceId) internal virtual {
        CollectibleInstance storage instance = _getInstance(creatorContractAddress, instanceId);
        require(instance.isActive, "Inactive");
        require(block.timestamp >= instance.claimStartTime && block.timestamp <= instance.claimEndTime, "Outside claim period.");
    }

    /**
    * Validate purchase signature
    */
    function _validatePurchaseRequest(
        address creatorContractAddress,
        uint256 instanceId,
        bytes32 message,
        bytes calldata signature,
        bytes32 nonce
    ) internal virtual {
        // Verify nonce usage/re-use
        require(!_usedNonces[creatorContractAddress][instanceId][nonce], "Cannot replay transaction");
        // Verify valid message based on input variables
        bytes32 expectedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n52", msg.sender, nonce));
        require(message == expectedMessage, "Malformed message");
        // Verify signature was performed by the expected signing address
        address signer = message.recover(signature);
        address signingAddress = _signingAddresses[creatorContractAddress][instanceId];
        require(signer == signingAddress, "Invalid signature");

        _usedNonces[creatorContractAddress][instanceId][nonce] = true;
    }

    /**
    * Validate purchase signature with amount
    */
    function _validatePurchaseRequestWithAmount(
        address creatorContractAddress,
        uint256 instanceId,
        bytes32 message,
        bytes calldata signature,
        bytes32 nonce,
        uint16 amount
    ) internal virtual {
        // Verify nonce usage/re-use
        require(!_usedNonces[creatorContractAddress][instanceId][nonce], "Cannot replay transaction");
        // Verify valid message based on input variables
        bytes32 expectedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n54", msg.sender, nonce, amount));
        require(message == expectedMessage, "Malformed message");
        // Verify signature was performed by the expected signing address
        address signer = message.recover(signature);
        address signingAddress = _signingAddresses[creatorContractAddress][instanceId];
        require(signer == signingAddress, "Invalid signature");

        _usedNonces[creatorContractAddress][instanceId][nonce] = true;
    }

    /**
    * Perform purchase restriction checks. Override if more logic is needed
    */
    function _validatePurchaseRestrictions(address creatorContractAddress, uint256 instanceId) internal virtual {
        CollectibleInstance storage instance = _getInstance(creatorContractAddress, instanceId);

        require(instance.isActive, "Inactive");
        require(block.timestamp >= instance.startTime, "Purchasing not active");
    }

    /**
    * @dev See {ICollectibleCore-nonceUsed}.
    */
    function nonceUsed(
        address creatorContractAddress,
        uint256 instanceId,
        bytes32 nonce
    ) external view override returns (bool) {
        return _usedNonces[creatorContractAddress][instanceId][nonce];
    }

    /**
    * @dev Check if currently in presale
    */
    function _isPresale(address creatorContractAddress, uint256 instanceId) internal view returns (bool) {
        CollectibleInstance storage instance = _getInstance(creatorContractAddress, instanceId);

        return (block.timestamp > instance.startTime && block.timestamp - instance.startTime < instance.presaleInterval);
    }

    function _getInstance(
        address creatorContractAddress,
        uint256 instanceId
    ) internal view returns (CollectibleInstance storage instance) {
        instance = _instances[creatorContractAddress][instanceId];
        require(instance.purchaseMax != 0, "Collectible not initialized");
    }

    /**
    * Send funds to receiver
    */
    function _forwardValue(address payable receiver, uint256 amount) internal {
        (bool sent, ) = receiver.call{ value: amount }("");
        require(sent, "Failed to transfer to recipient");
    }

    /**
    * Helper to check if the sender holds an active Manifold membership
    */
    function _isActiveMember(address sender) internal view returns(bool) {
        return manifoldMembershipContract != address(0) &&
            IManifoldMembership(manifoldMembershipContract).isActiveMember(sender);
    }

    /**
    * Helper to get the Manifold fee for the sender
    */
    function _getManifoldFee(uint256 numTokens) internal view returns(uint256) {
        return _isActiveMember(msg.sender) ? 0 : (MINT_FEE * numTokens);
    }
}

File 4 of 20 : IERC721Collectible.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/// @author: manifold.xyz

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import "@manifoldxyz/creator-core-solidity/contracts/core/IERC721CreatorCore.sol";
import "@manifoldxyz/creator-core-solidity/contracts/extensions/ERC721/IERC721CreatorExtensionApproveTransfer.sol";
import "@manifoldxyz/creator-core-solidity/contracts/extensions/ICreatorExtensionTokenURI.sol";

import "./ICollectibleCore.sol";

/**
 * @dev ERC721 Collection Interface
 */
interface IERC721Collectible is ICollectibleCore, IERC721CreatorExtensionApproveTransfer, ICreatorExtensionTokenURI {
    event Unveil(address creatorContractAddress, uint256 instanceId, uint256 tokenMintIndex, uint256 tokenId);

    /**
    * @dev Pre-mint given amount to caller
    * @param creatorContractAddress    the creator contract the claim will mint tokens for
    * @param instanceId                the id of the claim in the list of creatorContractAddress' _instances
    * @param amount                    the number of tokens to mint
    */
    function premint(address creatorContractAddress, uint256 instanceId, uint16 amount) external;

    /**
    * @dev Pre-mint 1 token to designated addresses
    * @param creatorContractAddress    the creator contract the claim will mint tokens for
    * @param instanceId                the id of the claim in the list of creatorContractAddress' _instances
    * @param addresses                 List of addresses to premint to
    */
    function premint(address creatorContractAddress, uint256 instanceId, address[] calldata addresses) external;

    /**
    *  @dev set the tokenURI prefix
    * @param creatorContractAddress    the creator contract the claim will mint tokens for
    * @param instanceId                the id of the claim in the list of creatorContractAddress' _instances
    * @param prefix                    the uri prefix to set
    */
    function setTokenURIPrefix(address creatorContractAddress, uint256 instanceId, string calldata prefix) external;

    /**
    * @dev Set whether or not token transfers are locked until end of sale.
    * @param creatorContractAddress    the creator contract the claim will mint tokens for
    * @param instanceId                the id of the claim in the list of creatorContractAddress' _instances
    * @param locked Whether or not transfers are locked
    */
    function setTransferLocked(address creatorContractAddress, uint256 instanceId, bool locked) external;

    /**
    * @dev The `claim` function represents minting during a free claim period. A bit of an overloaded use of hte word "claim".
    */
    function claim(
        address creatorContractAddress,
        uint256 instanceId,
        uint16 amount,
        bytes32 message,
        bytes calldata signature,
        bytes32 nonce
    ) external payable;

    /**
    * @dev purchase
    */
    function purchase(
        address creatorContractAddress,
        uint256 instanceId,
        uint16 amount,
        bytes32 message,
        bytes calldata signature,
        bytes32 nonce
    ) external payable;

    /**
    * @dev returns the collection state
    */
    function state(address creatorContractAddress, uint256 instanceId) external view returns (CollectibleState memory);

    /**
    * @dev Get number of tokens left
    */
    function purchaseRemaining(address creatorContractAddress, uint256 instanceId) external view returns (uint16);
}

File 5 of 20 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

File 6 of 20 : AdminControl.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/// @author: manifold.xyz

import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./IAdminControl.sol";

abstract contract AdminControl is Ownable, IAdminControl, ERC165 {
    using EnumerableSet for EnumerableSet.AddressSet;

    // Track registered admins
    EnumerableSet.AddressSet private _admins;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return interfaceId == type(IAdminControl).interfaceId
            || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Only allows approved admins to call the specified function
     */
    modifier adminRequired() {
        require(owner() == msg.sender || _admins.contains(msg.sender), "AdminControl: Must be owner or admin");
        _;
    }   

    /**
     * @dev See {IAdminControl-getAdmins}.
     */
    function getAdmins() external view override returns (address[] memory admins) {
        admins = new address[](_admins.length());
        for (uint i = 0; i < _admins.length(); i++) {
            admins[i] = _admins.at(i);
        }
        return admins;
    }

    /**
     * @dev See {IAdminControl-approveAdmin}.
     */
    function approveAdmin(address admin) external override onlyOwner {
        if (!_admins.contains(admin)) {
            emit AdminApproved(admin, msg.sender);
            _admins.add(admin);
        }
    }

    /**
     * @dev See {IAdminControl-revokeAdmin}.
     */
    function revokeAdmin(address admin) external override onlyOwner {
        if (_admins.contains(admin)) {
            emit AdminRevoked(admin, msg.sender);
            _admins.remove(admin);
        }
    }

    /**
     * @dev See {IAdminControl-isAdmin}.
     */
    function isAdmin(address admin) public override view returns (bool) {
        return (owner() == admin || _admins.contains(admin));
    }

}

File 7 of 20 : ERC165Checker.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.2) (utils/introspection/ERC165Checker.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Library used to query support of an interface declared via {IERC165}.
 *
 * Note that these functions return the actual result of the query: they do not
 * `revert` if an interface is not supported. It is up to the caller to decide
 * what to do in these cases.
 */
library ERC165Checker {
    // As per the EIP-165 spec, no interface should ever match 0xffffffff
    bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;

    /**
     * @dev Returns true if `account` supports the {IERC165} interface,
     */
    function supportsERC165(address account) internal view returns (bool) {
        // Any contract that implements ERC165 must explicitly indicate support of
        // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
        return
            _supportsERC165Interface(account, type(IERC165).interfaceId) &&
            !_supportsERC165Interface(account, _INTERFACE_ID_INVALID);
    }

    /**
     * @dev Returns true if `account` supports the interface defined by
     * `interfaceId`. Support for {IERC165} itself is queried automatically.
     *
     * See {IERC165-supportsInterface}.
     */
    function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {
        // query support of both ERC165 as per the spec and support of _interfaceId
        return supportsERC165(account) && _supportsERC165Interface(account, interfaceId);
    }

    /**
     * @dev Returns a boolean array where each value corresponds to the
     * interfaces passed in and whether they're supported or not. This allows
     * you to batch check interfaces for a contract where your expectation
     * is that some interfaces may not be supported.
     *
     * See {IERC165-supportsInterface}.
     *
     * _Available since v3.4._
     */
    function getSupportedInterfaces(address account, bytes4[] memory interfaceIds)
        internal
        view
        returns (bool[] memory)
    {
        // an array of booleans corresponding to interfaceIds and whether they're supported or not
        bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);

        // query support of ERC165 itself
        if (supportsERC165(account)) {
            // query support of each interface in interfaceIds
            for (uint256 i = 0; i < interfaceIds.length; i++) {
                interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]);
            }
        }

        return interfaceIdsSupported;
    }

    /**
     * @dev Returns true if `account` supports all the interfaces defined in
     * `interfaceIds`. Support for {IERC165} itself is queried automatically.
     *
     * Batch-querying can lead to gas savings by skipping repeated checks for
     * {IERC165} support.
     *
     * See {IERC165-supportsInterface}.
     */
    function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {
        // query support of ERC165 itself
        if (!supportsERC165(account)) {
            return false;
        }

        // query support of each interface in _interfaceIds
        for (uint256 i = 0; i < interfaceIds.length; i++) {
            if (!_supportsERC165Interface(account, interfaceIds[i])) {
                return false;
            }
        }

        // all interfaces supported
        return true;
    }

    /**
     * @notice Query if a contract implements an interface, does not check ERC165 support
     * @param account The address of the contract to query for support of an interface
     * @param interfaceId The interface identifier, as specified in ERC-165
     * @return true if the contract at account indicates support of the interface with
     * identifier interfaceId, false otherwise
     * @dev Assumes that account contains a contract that supports ERC165, otherwise
     * the behavior of this method is undefined. This precondition can be checked
     * with {supportsERC165}.
     * Interface identification is specified in ERC-165.
     */
    function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {
        // prepare call
        bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);

        // perform static call
        bool success;
        uint256 returnSize;
        uint256 returnValue;
        assembly {
            success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)
            returnSize := returndatasize()
            returnValue := mload(0x00)
        }

        return success && returnSize >= 0x20 && returnValue > 0;
    }
}

File 8 of 20 : ICollectibleCore.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

/// @author: manifold.xyz

/**
 * @dev CollectibleBase Interface
 */
interface ICollectibleCore is IERC165 {
    struct ActivationParameters {
        uint48 startTime;
        uint48 duration;
        uint48 presaleInterval;
        uint48 claimStartTime;
        uint48 claimEndTime;
    }

    struct InitializationParameters {
        bool useDynamicPresalePurchaseLimit;
        uint16 transactionLimit;
        uint16 purchaseMax;
        uint16 purchaseLimit;
        uint16 presalePurchaseLimit;
        uint256 purchasePrice;
        uint256 presalePurchasePrice;
        address signingAddress;
        address payable paymentReceiver;
    }


    struct UpdateInitializationParameters {
        bool useDynamicPresalePurchaseLimit;
        uint16 transactionLimit;
        uint16 purchaseMax;
        uint16 purchaseLimit;
        uint16 presalePurchaseLimit;
        uint256 purchasePrice;
        uint256 presalePurchasePrice;
    }

    struct CollectibleInstance {
        bool isActive;
        bool useDynamicPresalePurchaseLimit;
        bool isTransferLocked;
        uint8 contractVersion;
        uint16 transactionLimit;
        uint16 purchaseMax;
        uint16 purchaseLimit;
        uint16 presalePurchaseLimit;
        uint16 purchaseCount;
        uint48 startTime;
        uint48 endTime;
        uint48 presaleInterval;
        uint48 claimStartTime;
        uint48 claimEndTime;
        uint256 purchasePrice;
        uint256 presalePurchasePrice;
        string baseURI;
        address payable paymentReceiver;
    }

    struct CollectibleState {
        bool isActive;
        bool useDynamicPresalePurchaseLimit;
        bool isTransferLocked;
        uint16 transactionLimit;
        uint16 purchaseMax;
        uint16 purchaseLimit;
        uint16 presalePurchaseLimit;
        uint16 purchaseCount;
        uint48 startTime;
        uint48 endTime;
        uint48 presaleInterval;
        uint48 claimStartTime;
        uint48 claimEndTime;
        uint256 purchasePrice;
        uint256 presalePurchasePrice;
        uint256 purchaseRemaining;
        address payable paymentReceiver;
    }

    event CollectibleInitialized(address creatorContractAddress, uint256 instanceId, address initializer);

    event CollectibleActivated(
        address creatorContractAddress,
        uint256 instanceId,
        uint48 startTime,
        uint48 endTime,
        uint48 presaleInterval,
        uint48 claimStartTime,
        uint48 claimEndTime
    );

    event CollectibleDeactivated(address creatorContractAddress, uint256 instanceId);

    /**
    * @notice get a burn redeem corresponding to a creator contract and index
    * @param creatorContractAddress    the address of the creator contract
    * @param index                     the index of the burn redeem
    * @return CollectibleInstsance               the burn redeem object
    */
    function getCollectible(
        address creatorContractAddress,
        uint256 index
    ) external view returns (CollectibleInstance memory);

    /**
    * @dev Check if nonce has been used
    * @param creatorContractAddress    the creator contract address
    * @param instanceId                the index of the claim for which we will mint
    */
    function nonceUsed(address creatorContractAddress, uint256 instanceId, bytes32 nonce) external view returns (bool);

    /**
    * @dev Activate the contract
    * @param creatorContractAddress    the creator contract the claim will mint tokens for
    * @param instanceId                the index of the claim in the list of creatorContractAddress' _claims
    * @param activationParameters      the sale start time
    */
    function activate(
        address creatorContractAddress,
        uint256 instanceId,
        ActivationParameters calldata activationParameters
    ) external;

    /**
    * @dev Deactivate the contract
    * @param creatorContractAddress    the creator contract the claim will mint tokens for
    * @param instanceId                the index of the claim in the list of creatorContractAddress' _claims
    */
    function deactivate(address creatorContractAddress, uint256 instanceId) external;

    /**
    * @notice Set the Manifold Membership address
    */
    function setMembershipAddress(address membershipAddress) external;

    /**
    * @notice withdraw Manifold fee proceeds from the contract
    * @param recipient                 recepient of the funds
    * @param amount                    amount to withdraw in Wei
    */
    function withdraw(address payable recipient, uint256 amount) external;

    /**
    * @notice initialize a new burn redeem, emit initialize event, and return the newly created index
    * @param creatorContractAddress    the creator contract the burn will mint redeem tokens for
    * @param instanceId                the id of the multi-asssetclaim in the mapping of creatorContractAddress <-> instance id
    * @param initializationParameters  initial claim parameters
    */
    function initializeCollectible(
        address creatorContractAddress,
        uint256 instanceId,
        InitializationParameters calldata initializationParameters
    ) external;

    /**
    * Updates a handful of sale parameters
    * @param creatorContractAddress    the creator contract the burn will mint redeem tokens for
    * @param instanceId                the id of the multi-asssetclaim in the mapping of creatorContractAddress <-> instance id
    * @param initializationParameters  initial claim parameters
    */
    function updateInitializationParameters(
        address creatorContractAddress,
        uint256 instanceId,
        UpdateInitializationParameters calldata initializationParameters
    ) external;

    /**
    * Updates payment receiver
    * @param creatorContractAddress    the creator contract the burn will mint redeem tokens for
    * @param instanceId                the id of the multi-asssetclaim in the mapping of creatorContractAddress <-> instance id
    * @param paymentReceiver           the new address that will receive payments
    */
    function updatePaymentReceiver(
        address creatorContractAddress,
        uint256 instanceId,
        address payable paymentReceiver
    ) external;
}

File 9 of 20 : ICreatorExtensionTokenURI.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/// @author: manifold.xyz

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

/**
 * @dev Implement this if you want your extension to have overloadable URI's
 */
interface ICreatorExtensionTokenURI is IERC165 {

    /**
     * Get the uri for a given creator/tokenId
     */
    function tokenURI(address creator, uint256 tokenId) external view returns (string memory);
}

File 10 of 20 : IERC721CreatorExtensionApproveTransfer.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/// @author: manifold.xyz

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

/**
 * Implement this if you want your extension to approve a transfer
 */
interface IERC721CreatorExtensionApproveTransfer is IERC165 {

    /**
     * @dev Set whether or not the creator will check the extension for approval of token transfer
     */
    function setApproveTransfer(address creator, bool enabled) external;

    /**
     * @dev Called by creator contract to approve a transfer
     */
    function approveTransfer(address operator, address from, address to, uint256 tokenId) external returns (bool);
}

File 11 of 20 : IERC721CreatorCore.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/// @author: manifold.xyz

import "./ICreatorCore.sol";

/**
 * @dev Core ERC721 creator interface
 */
interface IERC721CreatorCore is ICreatorCore {

    /**
     * @dev mint a token with no extension. Can only be called by an admin.
     * Returns tokenId minted
     */
    function mintBase(address to) external returns (uint256);

    /**
     * @dev mint a token with no extension. Can only be called by an admin.
     * Returns tokenId minted
     */
    function mintBase(address to, string calldata uri) external returns (uint256);

    /**
     * @dev batch mint a token with no extension. Can only be called by an admin.
     * Returns tokenId minted
     */
    function mintBaseBatch(address to, uint16 count) external returns (uint256[] memory);

    /**
     * @dev batch mint a token with no extension. Can only be called by an admin.
     * Returns tokenId minted
     */
    function mintBaseBatch(address to, string[] calldata uris) external returns (uint256[] memory);

    /**
     * @dev mint a token. Can only be called by a registered extension.
     * Returns tokenId minted
     */
    function mintExtension(address to) external returns (uint256);

    /**
     * @dev mint a token. Can only be called by a registered extension.
     * Returns tokenId minted
     */
    function mintExtension(address to, string calldata uri) external returns (uint256);

    /**
     * @dev mint a token. Can only be called by a registered extension.
     * Returns tokenId minted
     */
    function mintExtension(address to, uint80 data) external returns (uint256);

    /**
     * @dev batch mint a token. Can only be called by a registered extension.
     * Returns tokenIds minted
     */
    function mintExtensionBatch(address to, uint16 count) external returns (uint256[] memory);

    /**
     * @dev batch mint a token. Can only be called by a registered extension.
     * Returns tokenId minted
     */
    function mintExtensionBatch(address to, string[] calldata uris) external returns (uint256[] memory);

    /**
     * @dev batch mint a token. Can only be called by a registered extension.
     * Returns tokenId minted
     */
    function mintExtensionBatch(address to, uint80[] calldata data) external returns (uint256[] memory);

    /**
     * @dev burn a token. Can only be called by token owner or approved address.
     * On burn, calls back to the registered extension's onBurn method
     */
    function burn(uint256 tokenId) external;

    /**
     * @dev get token data
     */
    function tokenData(uint256 tokenId) external view returns (uint80);

}

File 12 of 20 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface 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);
}

File 13 of 20 : IManifoldMembership.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/// @author: manifold.xyz

/**
 * Manifold Membership interface
 */
interface IManifoldMembership {
   function isActiveMember(address sender) external view returns (bool);
}

File 14 of 20 : ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

import "../Strings.sol";

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

File 15 of 20 : IAdminControl.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/// @author: manifold.xyz

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

/**
 * @dev Interface for admin control
 */
interface IAdminControl is IERC165 {

    event AdminApproved(address indexed account, address indexed sender);
    event AdminRevoked(address indexed account, address indexed sender);

    /**
     * @dev gets address of all admins
     */
    function getAdmins() external view returns (address[] memory);

    /**
     * @dev add an admin.  Can only be called by contract owner.
     */
    function approveAdmin(address admin) external;

    /**
     * @dev remove an admin.  Can only be called by contract owner.
     */
    function revokeAdmin(address admin) external;

    /**
     * @dev checks whether or not given address is an admin
     * Returns True if they are
     */
    function isAdmin(address admin) external view returns (bool);

}

File 16 of 20 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../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.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 17 of 20 : EnumerableSet.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 *  Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.
 *  See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 *  In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.
 * ====
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastValue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastValue;
                // Update the index for the moved value
                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        return _values(set._inner);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}

File 18 of 20 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 19 of 20 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 20 of 20 : ICreatorCore.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/// @author: manifold.xyz

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

/**
 * @dev Core creator interface
 */
interface ICreatorCore is IERC165 {

    event ExtensionRegistered(address indexed extension, address indexed sender);
    event ExtensionUnregistered(address indexed extension, address indexed sender);
    event ExtensionBlacklisted(address indexed extension, address indexed sender);
    event MintPermissionsUpdated(address indexed extension, address indexed permissions, address indexed sender);
    event RoyaltiesUpdated(uint256 indexed tokenId, address payable[] receivers, uint256[] basisPoints);
    event DefaultRoyaltiesUpdated(address payable[] receivers, uint256[] basisPoints);
    event ApproveTransferUpdated(address extension);
    event ExtensionRoyaltiesUpdated(address indexed extension, address payable[] receivers, uint256[] basisPoints);
    event ExtensionApproveTransferUpdated(address indexed extension, bool enabled);

    /**
     * @dev gets address of all extensions
     */
    function getExtensions() external view returns (address[] memory);

    /**
     * @dev add an extension.  Can only be called by contract owner or admin.
     * extension address must point to a contract implementing ICreatorExtension.
     * Returns True if newly added, False if already added.
     */
    function registerExtension(address extension, string calldata baseURI) external;

    /**
     * @dev add an extension.  Can only be called by contract owner or admin.
     * extension address must point to a contract implementing ICreatorExtension.
     * Returns True if newly added, False if already added.
     */
    function registerExtension(address extension, string calldata baseURI, bool baseURIIdentical) external;

    /**
     * @dev add an extension.  Can only be called by contract owner or admin.
     * Returns True if removed, False if already removed.
     */
    function unregisterExtension(address extension) external;

    /**
     * @dev blacklist an extension.  Can only be called by contract owner or admin.
     * This function will destroy all ability to reference the metadata of any tokens created
     * by the specified extension. It will also unregister the extension if needed.
     * Returns True if removed, False if already removed.
     */
    function blacklistExtension(address extension) external;

    /**
     * @dev set the baseTokenURI of an extension.  Can only be called by extension.
     */
    function setBaseTokenURIExtension(string calldata uri) external;

    /**
     * @dev set the baseTokenURI of an extension.  Can only be called by extension.
     * For tokens with no uri configured, tokenURI will return "uri+tokenId"
     */
    function setBaseTokenURIExtension(string calldata uri, bool identical) external;

    /**
     * @dev set the common prefix of an extension.  Can only be called by extension.
     * If configured, and a token has a uri set, tokenURI will return "prefixURI+tokenURI"
     * Useful if you want to use ipfs/arweave
     */
    function setTokenURIPrefixExtension(string calldata prefix) external;

    /**
     * @dev set the tokenURI of a token extension.  Can only be called by extension that minted token.
     */
    function setTokenURIExtension(uint256 tokenId, string calldata uri) external;

    /**
     * @dev set the tokenURI of a token extension for multiple tokens.  Can only be called by extension that minted token.
     */
    function setTokenURIExtension(uint256[] memory tokenId, string[] calldata uri) external;

    /**
     * @dev set the baseTokenURI for tokens with no extension.  Can only be called by owner/admin.
     * For tokens with no uri configured, tokenURI will return "uri+tokenId"
     */
    function setBaseTokenURI(string calldata uri) external;

    /**
     * @dev set the common prefix for tokens with no extension.  Can only be called by owner/admin.
     * If configured, and a token has a uri set, tokenURI will return "prefixURI+tokenURI"
     * Useful if you want to use ipfs/arweave
     */
    function setTokenURIPrefix(string calldata prefix) external;

    /**
     * @dev set the tokenURI of a token with no extension.  Can only be called by owner/admin.
     */
    function setTokenURI(uint256 tokenId, string calldata uri) external;

    /**
     * @dev set the tokenURI of multiple tokens with no extension.  Can only be called by owner/admin.
     */
    function setTokenURI(uint256[] memory tokenIds, string[] calldata uris) external;

    /**
     * @dev set a permissions contract for an extension.  Used to control minting.
     */
    function setMintPermissions(address extension, address permissions) external;

    /**
     * @dev Configure so transfers of tokens created by the caller (must be extension) gets approval
     * from the extension before transferring
     */
    function setApproveTransferExtension(bool enabled) external;

    /**
     * @dev get the extension of a given token
     */
    function tokenExtension(uint256 tokenId) external view returns (address);

    /**
     * @dev Set default royalties
     */
    function setRoyalties(address payable[] calldata receivers, uint256[] calldata basisPoints) external;

    /**
     * @dev Set royalties of a token
     */
    function setRoyalties(uint256 tokenId, address payable[] calldata receivers, uint256[] calldata basisPoints) external;

    /**
     * @dev Set royalties of an extension
     */
    function setRoyaltiesExtension(address extension, address payable[] calldata receivers, uint256[] calldata basisPoints) external;

    /**
     * @dev Get royalites of a token.  Returns list of receivers and basisPoints
     */
    function getRoyalties(uint256 tokenId) external view returns (address payable[] memory, uint256[] memory);
    
    // Royalty support for various other standards
    function getFeeRecipients(uint256 tokenId) external view returns (address payable[] memory);
    function getFeeBps(uint256 tokenId) external view returns (uint[] memory);
    function getFees(uint256 tokenId) external view returns (address payable[] memory, uint256[] memory);
    function royaltyInfo(uint256 tokenId, uint256 value) external view returns (address, uint256);

    /**
     * @dev Set the default approve transfer contract location.
     */
    function setApproveTransfer(address extension) external; 

    /**
     * @dev Get the default approve transfer contract location.
     */
    function getApproveTransfer() external view returns (address);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 1000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"AdminApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"AdminRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"creatorContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"instanceId","type":"uint256"},{"indexed":false,"internalType":"uint48","name":"startTime","type":"uint48"},{"indexed":false,"internalType":"uint48","name":"endTime","type":"uint48"},{"indexed":false,"internalType":"uint48","name":"presaleInterval","type":"uint48"},{"indexed":false,"internalType":"uint48","name":"claimStartTime","type":"uint48"},{"indexed":false,"internalType":"uint48","name":"claimEndTime","type":"uint48"}],"name":"CollectibleActivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"creatorContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"instanceId","type":"uint256"}],"name":"CollectibleDeactivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"creatorContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"instanceId","type":"uint256"},{"indexed":false,"internalType":"address","name":"initializer","type":"address"}],"name":"CollectibleInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"creatorContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"instanceId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenMintIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Unveil","type":"event"},{"inputs":[],"name":"MINT_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"creatorContractAddress","type":"address"},{"internalType":"uint256","name":"instanceId","type":"uint256"},{"components":[{"internalType":"uint48","name":"startTime","type":"uint48"},{"internalType":"uint48","name":"duration","type":"uint48"},{"internalType":"uint48","name":"presaleInterval","type":"uint48"},{"internalType":"uint48","name":"claimStartTime","type":"uint48"},{"internalType":"uint48","name":"claimEndTime","type":"uint48"}],"internalType":"struct ICollectibleCore.ActivationParameters","name":"activationParameters","type":"tuple"}],"name":"activate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"approveAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approveTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"creatorContractAddress","type":"address"},{"internalType":"uint256","name":"instanceId","type":"uint256"},{"internalType":"uint16","name":"amount","type":"uint16"},{"internalType":"bytes32","name":"message","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"claim","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"creatorContractAddress","type":"address"},{"internalType":"uint256","name":"instanceId","type":"uint256"}],"name":"deactivate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAdmins","outputs":[{"internalType":"address[]","name":"admins","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"creatorContractAddress","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getCollectible","outputs":[{"components":[{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"bool","name":"useDynamicPresalePurchaseLimit","type":"bool"},{"internalType":"bool","name":"isTransferLocked","type":"bool"},{"internalType":"uint8","name":"contractVersion","type":"uint8"},{"internalType":"uint16","name":"transactionLimit","type":"uint16"},{"internalType":"uint16","name":"purchaseMax","type":"uint16"},{"internalType":"uint16","name":"purchaseLimit","type":"uint16"},{"internalType":"uint16","name":"presalePurchaseLimit","type":"uint16"},{"internalType":"uint16","name":"purchaseCount","type":"uint16"},{"internalType":"uint48","name":"startTime","type":"uint48"},{"internalType":"uint48","name":"endTime","type":"uint48"},{"internalType":"uint48","name":"presaleInterval","type":"uint48"},{"internalType":"uint48","name":"claimStartTime","type":"uint48"},{"internalType":"uint48","name":"claimEndTime","type":"uint48"},{"internalType":"uint256","name":"purchasePrice","type":"uint256"},{"internalType":"uint256","name":"presalePurchasePrice","type":"uint256"},{"internalType":"string","name":"baseURI","type":"string"},{"internalType":"address payable","name":"paymentReceiver","type":"address"}],"internalType":"struct ICollectibleCore.CollectibleInstance","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"creatorContractAddress","type":"address"},{"internalType":"uint256","name":"instanceId","type":"uint256"},{"components":[{"internalType":"bool","name":"useDynamicPresalePurchaseLimit","type":"bool"},{"internalType":"uint16","name":"transactionLimit","type":"uint16"},{"internalType":"uint16","name":"purchaseMax","type":"uint16"},{"internalType":"uint16","name":"purchaseLimit","type":"uint16"},{"internalType":"uint16","name":"presalePurchaseLimit","type":"uint16"},{"internalType":"uint256","name":"purchasePrice","type":"uint256"},{"internalType":"uint256","name":"presalePurchasePrice","type":"uint256"},{"internalType":"address","name":"signingAddress","type":"address"},{"internalType":"address payable","name":"paymentReceiver","type":"address"}],"internalType":"struct ICollectibleCore.InitializationParameters","name":"initializationParameters","type":"tuple"}],"name":"initializeCollectible","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manifoldMembershipContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"creatorContractAddress","type":"address"},{"internalType":"uint256","name":"instanceId","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"nonceUsed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"creatorContractAddress","type":"address"},{"internalType":"uint256","name":"instanceId","type":"uint256"},{"internalType":"address[]","name":"addresses","type":"address[]"}],"name":"premint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"creatorContractAddress","type":"address"},{"internalType":"uint256","name":"instanceId","type":"uint256"},{"internalType":"uint16","name":"amount","type":"uint16"}],"name":"premint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"creatorContractAddress","type":"address"},{"internalType":"uint256","name":"instanceId","type":"uint256"},{"internalType":"uint16","name":"amount","type":"uint16"},{"internalType":"bytes32","name":"message","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"purchase","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"creatorContractAddress","type":"address"},{"internalType":"uint256","name":"instanceId","type":"uint256"}],"name":"purchaseRemaining","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"revokeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"creatorContractAddress","type":"address"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setApproveTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setMembershipAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"creatorContractAddress","type":"address"},{"internalType":"uint256","name":"instanceId","type":"uint256"},{"internalType":"string","name":"prefix","type":"string"}],"name":"setTokenURIPrefix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"creatorContractAddress","type":"address"},{"internalType":"uint256","name":"instanceId","type":"uint256"},{"internalType":"bool","name":"isLocked","type":"bool"}],"name":"setTransferLocked","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"creatorContractAddress","type":"address"},{"internalType":"uint256","name":"instanceId","type":"uint256"}],"name":"state","outputs":[{"components":[{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"bool","name":"useDynamicPresalePurchaseLimit","type":"bool"},{"internalType":"bool","name":"isTransferLocked","type":"bool"},{"internalType":"uint16","name":"transactionLimit","type":"uint16"},{"internalType":"uint16","name":"purchaseMax","type":"uint16"},{"internalType":"uint16","name":"purchaseLimit","type":"uint16"},{"internalType":"uint16","name":"presalePurchaseLimit","type":"uint16"},{"internalType":"uint16","name":"purchaseCount","type":"uint16"},{"internalType":"uint48","name":"startTime","type":"uint48"},{"internalType":"uint48","name":"endTime","type":"uint48"},{"internalType":"uint48","name":"presaleInterval","type":"uint48"},{"internalType":"uint48","name":"claimStartTime","type":"uint48"},{"internalType":"uint48","name":"claimEndTime","type":"uint48"},{"internalType":"uint256","name":"purchasePrice","type":"uint256"},{"internalType":"uint256","name":"presalePurchasePrice","type":"uint256"},{"internalType":"uint256","name":"purchaseRemaining","type":"uint256"},{"internalType":"address payable","name":"paymentReceiver","type":"address"}],"internalType":"struct ICollectibleCore.CollectibleState","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"creatorContractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"creatorContractAddress","type":"address"},{"internalType":"uint256","name":"instanceId","type":"uint256"},{"components":[{"internalType":"bool","name":"useDynamicPresalePurchaseLimit","type":"bool"},{"internalType":"uint16","name":"transactionLimit","type":"uint16"},{"internalType":"uint16","name":"purchaseMax","type":"uint16"},{"internalType":"uint16","name":"purchaseLimit","type":"uint16"},{"internalType":"uint16","name":"presalePurchaseLimit","type":"uint16"},{"internalType":"uint256","name":"purchasePrice","type":"uint256"},{"internalType":"uint256","name":"presalePurchasePrice","type":"uint256"}],"internalType":"struct ICollectibleCore.UpdateInitializationParameters","name":"initializationParameters","type":"tuple"}],"name":"updateInitializationParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"creatorContractAddress","type":"address"},{"internalType":"uint256","name":"instanceId","type":"uint256"},{"internalType":"address payable","name":"paymentReceiver","type":"address"}],"name":"updatePaymentReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b506200001d3362000023565b62000073565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6155d980620000836000396000f3fe6080604052600436106101cd5760003560e01c80637ab39392116100f7578063d7bf81a311610095578063f1218c1b11610064578063f1218c1b1461059d578063f2fde38b146105bd578063f3fef3a3146105dd578063f97eb3ef146105fd57600080fd5b8063d7bf81a314610507578063dd0a5cf014610530578063e9dc637514610550578063f0b567871461057d57600080fd5b8063a0d742f9116100d1578063a0d742f914610456578063a7e111ac14610476578063c2e5d36e14610496578063cf2ccf97146104b657600080fd5b80637ab39392146104055780638da5cb5b1461042557806391c734f41461044357600080fd5b80632e5f6fd81161016f5780635e6a6f8a1161013e5780635e6a6f8a14610390578063654fb5bd146103b05780636d73e669146103d0578063715018a6146103f057600080fd5b80632e5f6fd8146102e357806331ae450b146103035780633a075a891461032557806350d108391461035857600080fd5b806324d7806c116101ab57806324d7806c1461025657806325e21f671461027657806327686a86146102a35780632d345670146102c357600080fd5b806301ffc9a7146101d257806304853ef7146102075780631b95a22714610234575b600080fd5b3480156101de57600080fd5b506101f26101ed3660046148ce565b610610565b60405190151581526020015b60405180910390f35b34801561021357600080fd5b5061022761022236600461490d565b6106fc565b6040516101fe9190614939565b34801561024057600080fd5b5061025461024f366004614a71565b6108b1565b005b34801561026257600080fd5b506101f2610271366004614aaa565b610a98565b34801561028257600080fd5b5061029661029136600461490d565b610ad1565b6040516101fe9190614b17565b3480156102af57600080fd5b506102546102be366004614c96565b610d2e565b3480156102cf57600080fd5b506102546102de366004614aaa565b610e86565b3480156102ef57600080fd5b506102546102fe366004614cd8565b610ee4565b34801561030f57600080fd5b50610318611048565b6040516101fe9190614d64565b34801561033157600080fd5b5061034561034036600461490d565b6110f7565b60405161ffff90911681526020016101fe565b34801561036457600080fd5b50600354610378906001600160a01b031681565b6040516001600160a01b0390911681526020016101fe565b34801561039c57600080fd5b506101f26103ab366004614db1565b611132565b3480156103bc57600080fd5b506102546103cb366004614e44565b611294565b3480156103dc57600080fd5b506102546103eb366004614aaa565b61137d565b3480156103fc57600080fd5b506102546113d5565b34801561041157600080fd5b50610254610420366004614aaa565b6113e9565b34801561043157600080fd5b506000546001600160a01b0316610378565b610254610451366004614eb7565b611491565b34801561046257600080fd5b50610254610471366004614f3a565b6118fb565b34801561048257600080fd5b50610254610491366004614f85565b611ae6565b3480156104a257600080fd5b506102546104b1366004614fc3565b611c7b565b3480156104c257600080fd5b506101f26104d1366004614ffa565b6001600160a01b0383166000908152600460209081526040808320858452825280832084845290915290205460ff169392505050565b34801561051357600080fd5b506105226602738d24e5200081565b6040519081526020016101fe565b34801561053c57600080fd5b5061025461054b36600461502f565b611d73565b34801561055c57600080fd5b5061057061056b36600461490d565b611e9d565b6040516101fe919061506d565b34801561058957600080fd5b50610254610598366004615080565b612486565b3480156105a957600080fd5b506102546105b836600461490d565b61295b565b3480156105c957600080fd5b506102546105d8366004614aaa565b612abc565b3480156105e957600080fd5b506102546105f836600461490d565b612b49565b61025461060b366004614eb7565b612c77565b60006001600160e01b031982167f02c4b69e00000000000000000000000000000000000000000000000000000000148061067357506001600160e01b031982167fe9dc637500000000000000000000000000000000000000000000000000000000145b806106a757506001600160e01b031982167f45ffcdad00000000000000000000000000000000000000000000000000000000145b806106db57506001600160e01b031982167f553e757e00000000000000000000000000000000000000000000000000000000145b806106f657506001600160e01b031982166301ffc9a760e01b145b92915050565b6040805161022081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e0810182905261020081018290529061078f8484612d45565b6040805161022081018252825460ff8082161515835261010080830482161515602085015262010000830490911615159383019390935261ffff640100000000820481166060840152660100000000000080830482166080850152600160401b8304821660a0850152600160501b8304821660c0850152600160601b830490911660e084015265ffffffffffff600160701b8304811694840194909452600160a01b82048416610120840152600160d01b909104831661014083015260018401548084166101608401520490911661018082015260028201546101a082015260038201546101c08201529091506101e0810161088b86866110f7565b61ffff1681526005909201546001600160a01b0316602090920191909152905092915050565b604051630935e01b60e21b8152336004820152829081906001600160a01b038216906324d7806c90602401602060405180830381865afa1580156108f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091d91906150bc565b6109825760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b60648201526084015b60405180910390fd5b6109ac847fb5d2729f00000000000000000000000000000000000000000000000000000000612dc9565b610a1e5760405162461bcd60e51b815260206004820152602960248201527f63726561746f72206d75737420696d706c656d656e742049455243373231437260448201527f6561746f72436f726500000000000000000000000000000000000000000000006064820152608401610979565b6040517fac0c8cfa00000000000000000000000000000000000000000000000000000000815283151560048201526001600160a01b0385169063ac0c8cfa90602401600060405180830381600087803b158015610a7a57600080fd5b505af1158015610a8e573d6000803e3d6000fd5b5050505050505050565b6000816001600160a01b0316610ab66000546001600160a01b031690565b6001600160a01b031614806106f657506106f6600183612dec565b60408051610240810182526000808252602080830182905282840182905260608084018390526080840183905260a0840183905260c0840183905260e08401839052610100840183905261012084018390526101408401839052610160840183905261018084018390526101a084018390526101c084018390526101e0840183905261020084015261022083018290526001600160a01b0386168252600681528382208583529052919091206040805161024081018252825460ff8082161515835261010080830482161515602085015262010000830482161515948401949094526301000000820416606083015261ffff6401000000008204811660808401526601000000000000808304821660a0850152600160401b8304821660c0850152600160501b8304821660e0850152600160601b83049091169383019390935265ffffffffffff600160701b82048116610120840152600160a01b82048116610140840152600160d01b90910481166101608301526001840154808216610180840152929092049091166101a082015260028201546101c082015260038201546101e082015260048201805491929161020084019190610c90906150d9565b80601f0160208091040260200160405190810160405280929190818152602001828054610cbc906150d9565b8015610d095780601f10610cde57610100808354040283529160200191610d09565b820191906000526020600020905b815481529060010190602001808311610cec57829003601f168201915b5050509183525050600591909101546001600160a01b03166020909101529392505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015610d76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9a91906150bc565b610dfa5760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000610e068686612d45565b90506001600160a01b038416610e5e5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207061796d656e7420616464726573730000000000000000006044820152606401610979565b60050180546001600160a01b0319166001600160a01b03949094169390931790925550505050565b610e8e612e0e565b610e99600182612dec565b15610ee15760405133906001600160a01b038316907f7c0c3c84c67c85fcac635147348bfe374c24a1a93d0366d1cfe9d8853cbf89d590600090a3610edf600182612e68565b505b50565b604051630935e01b60e21b8152336004820152849081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015610f2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5091906150bc565b610fb05760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000610fbc8787612d45565b805490915060ff16156110025760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792061637469766560901b6044820152606401610979565b60005b84811015610a8e57611040888888888581811061102457611024615113565b90506020020160208101906110399190614aaa565b6001612e7d565b600101611005565b60606110546001613582565b67ffffffffffffffff81111561106c5761106c615129565b604051908082528060200260200182016040528015611095578160200160208202803683370190505b50905060005b6110a56001613582565b8110156110f3576110b760018261358c565b8282815181106110c9576110c9615113565b6001600160a01b0390921660209283029190910190910152806110eb81615155565b91505061109b565b5090565b6000806111048484612d45565b805490915061112a9061ffff600160601b8204811691660100000000000090041661516e565b949350505050565b60006001600160a01b03841661114a5750600161112a565b33600090815260076020908152604080832085845282528083208151808301909252546001600160e01b038116808352600160e01b90910463ffffffff1692820192909252919081036112635760405163b4b5b48f60e01b815260048101859052600090339063b4b5b48f90602401602060405180830381865afa1580156111d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fa9190615189565b66ffffffffffffff601882901c1692509050600082900361125d5760405162461bcd60e51b815260206004820152600f60248201527f546f6b656e206e6f7420666f756e6400000000000000000000000000000000006044820152606401610979565b50611270565b5080516001600160e01b03165b600061127c3383612d45565b5462010000900460ff16159350505050949350505050565b604051630935e01b60e21b8152336004820152849081906001600160a01b038216906324d7806c90602401602060405180830381865afa1580156112dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130091906150bc565b6113605760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b600061136c8787612d45565b905060048101610a8e8587836151fb565b611385612e0e565b611390600182612dec565b610ee15760405133906001600160a01b038316907f7e1a1a08d52e4ba0e21554733d66165fd5151f99460116223d9e3a608eec5cb190600090a3610edf600182613598565b6113dd612e0e565b6113e760006135ad565b565b336113fc6000546001600160a01b031690565b6001600160a01b031614806114175750611417600133612dec565b61146f5760405162461bcd60e51b8152602060048201526024808201527f41646d696e436f6e74726f6c3a204d757374206265206f776e6572206f7220616044820152633236b4b760e11b6064820152608401610979565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600061149d8888612d45565b90506114a988886135fd565b60006114b589896136a8565b905060006114c38a8a6110f7565b61ffff168861ffff161115801561151a57508180156114e857508254610100900460ff165b806114fe57508254640100000000900461ffff16155b8061151a5750825461ffff640100000000909104811690891611155b61155b5760405162461bcd60e51b8152602060048201526012602482015271151bdbc81b585b9e481c995c5d595cdd195960721b6044820152606401610979565b8115611770578254610100900460ff166116dd578254600160501b900461ffff1615611626576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091529020548354600160501b900461ffff16811080156115e3575083546115db908290600160501b900461ffff166152bb565b8961ffff1611155b6116245760405162461bcd60e51b8152602060048201526012602482015271151bdbc81b585b9e481c995c5d595cdd195960721b6044820152606401610979565b505b8254600160401b900461ffff16156116dd576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091529020548354600160401b900461ffff168110801561169a57508354611692908290600160401b900461ffff166152bb565b8961ffff1611155b6116db5760405162461bcd60e51b8152602060048201526012602482015271151bdbc81b585b9e481c995c5d595cdd195960721b6044820152606401610979565b505b6116e78884613701565b8354909150610100900460ff1615801561172157508254600160501b900461ffff1615158061172157508254600160401b900461ffff1615155b1561176b576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091528120805461ffff8b1692906117659084906152ce565b90915550505b61188b565b8254600160401b900461ffff1615611827576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091529020548354600160401b900461ffff16811080156117e4575083546117dc908290600160401b900461ffff166152bb565b8961ffff1611155b6118255760405162461bcd60e51b8152602060048201526012602482015271151bdbc81b585b9e481c995c5d595cdd195960721b6044820152606401610979565b505b611831888461378c565b8354909150600160401b900461ffff161561188b576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091528120805461ffff8b1692906118859084906152ce565b90915550505b81801561189e57508254610100900460ff165b156118b7576118b28a8a898989898e6137a3565b6118c5565b6118c58a8a89898989613a04565b80156118e35760058301546118e3906001600160a01b031682613c36565b6118ef8a8a338b612e7d565b50505050505050505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015611943573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061196791906150bc565b6119c75760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b60006119d38686612d45565b805490915060ff1615611a195760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792061637469766560901b6044820152606401610979565b60a08401356002820155611a3360808501606086016152e1565b815461ffff91909116600160401b0269ffff000000000000000019909116178155611a6460408501602086016152e1565b815461ffff919091166401000000000265ffff000000001990911617815560c08401356003820155611a9c60a08501608086016152e1565b815461ffff91909116600160501b026bffff0000000000000000000019909116178155611acc60208501856152fc565b81549015156101000261ff00199091161790555050505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015611b2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b5291906150bc565b611bb25760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000856001600160a01b031663ffa1ad746040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611c0e575060408051601f3d908101601f19168201909252611c0b91810190615319565b60015b15611c675760ff811115611c645760405162461bcd60e51b815260206004820152601c60248201527f556e737570706f7274656420636f6e74726163742076657273696f6e000000006044820152606401610979565b90505b611c7386828787613cd9565b505050505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015611cc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ce791906150bc565b611d475760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000611d538686612d45565b8054941515620100000262ff000019909516949094179093555050505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015611dbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ddf91906150bc565b611e3f5760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000611e4b8686612d45565b805490915060ff1615611e915760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792061637469766560901b6044820152606401610979565b611c7386863387612e7d565b6001600160a01b038216600090815260076020908152604080832084845282528083208151808301835290546001600160e01b0381168252600160e01b900463ffffffff168184015281516102408101835284815292830184905290820183905260608083018490526080830184905260a0830184905260c0830184905260e08301849052610100830184905261012083018490526101408301849052610160830184905261018083018490526101a083018490526101c083018490526101e083018490526102008301819052610220830184905292909182516001600160e01b03166000036122255760405163b4b5b48f60e01b8152600481018690526000906001600160a01b0388169063b4b5b48f90602401602060405180830381865afa158015611fcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ff39190615189565b905066ffffffffffffff601882901c1660008190036120545760405162461bcd60e51b815260206004820152600f60248201527f546f6b656e206e6f7420666f756e6400000000000000000000000000000000006044820152606401610979565b612067888266ffffffffffffff16612d45565b6040805161024081018252825460ff8082161515835261010080830482161515602085015262010000830482161515948401949094526301000000820416606083015261ffff6401000000008204811660808401526601000000000000808304821660a0850152600160401b8304821660c0850152600160501b8304821660e0850152600160601b83049091169383019390935265ffffffffffff600160701b82048116610120840152600160a01b82048116610140840152600160d01b90910481166101608301526001840154808216610180840152929092049091166101a082015260028201546101c082015260038201546101e08201526004820180549192916102008401919061217a906150d9565b80601f01602080910402602001604051908101604052809291908181526020018280546121a6906150d9565b80156121f35780601f106121c8576101008083540402835291602001916121f3565b820191906000526020600020905b8154815290600101906020018083116121d657829003601f168201915b5050509183525050600591909101546001600160a01b031660209091015262ffffff9290921693509091506123f69050565b826020015163ffffffff1691506122498684600001516001600160e01b0316612d45565b6040805161024081018252825460ff8082161515835261010080830482161515602085015262010000830482161515948401949094526301000000820416606083015261ffff6401000000008204811660808401526601000000000000808304821660a0850152600160401b8304821660c0850152600160501b8304821660e0850152600160601b83049091169383019390935265ffffffffffff600160701b82048116610120840152600160a01b82048116610140840152600160d01b90910481166101608301526001840154808216610180840152929092049091166101a082015260028201546101c082015260038201546101e08201526004820180549192916102008401919061235c906150d9565b80601f0160208091040260200160405190810160405280929190818152602001828054612388906150d9565b80156123d55780601f106123aa576101008083540402835291602001916123d5565b820191906000526020600020905b8154815290600101906020018083116123b857829003601f168201915b5050509183525050600591909101546001600160a01b031660209091015290505b8061020001515160000361244c5760405162461bcd60e51b815260206004820152601660248201527f4e6f2062617365207572692070726566697820736574000000000000000000006044820152606401610979565b80610200015161245b836140c2565b60405160200161246c929190615332565b604051602081830303815290604052935050505092915050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa1580156124ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f291906150bc565b6125525760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b600061255e8686612d45565b805490915060ff16156125a45760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792061637469766560901b6044820152606401610979565b426125b26020860186615361565b65ffffffffffff16116126075760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f7420616374697661746520696e20746865207061737400000000006044820152606401610979565b6126176040850160208601615361565b65ffffffffffff1661262f6060860160408701615361565b65ffffffffffff1611156126ab5760405162461bcd60e51b815260206004820152602f60248201527f50726573616c6520496e74657276616c2063616e6e6f74206265206c6f6e676560448201527f72207468616e207468652073616c6500000000000000000000000000000000006064820152608401610979565b6126bb60a0850160808601615361565b65ffffffffffff166126d36080860160608701615361565b65ffffffffffff161115801561271457506126f16020850185615361565b65ffffffffffff1661270960a0860160808701615361565b65ffffffffffff1611155b6127605760405162461bcd60e51b815260206004820152601360248201527f496e76616c696420636c61696d2074696d6573000000000000000000000000006044820152606401610979565b61276d6020850185615361565b815465ffffffffffff91909116600160701b027fffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffff9091161781556127b76040850160208601615361565b6127c46020860186615361565b6127ce9190615389565b815465ffffffffffff91909116600160a01b027fffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffff9091161781556128186060850160408601615361565b815465ffffffffffff91909116600160d01b0279ffffffffffffffffffffffffffffffffffffffffffffffffffff90911617815561285c6080850160608601615361565b60018201805465ffffffffffff191665ffffffffffff9290921691909117905561288c60a0850160808601615361565b600182810180546bffffffffffff000000000000198116660100000000000065ffffffffffff958616810291821793849055865460ff1916909417808755604080516001600160a01b038e168152602081018d9052600160701b8304881691810191909152600160a01b820487166060820152600160d01b909104861660808201529185169085161760a082015291900490911660c08201527fda897ec003b83d996662d95c264c767d3c58171ae697ebb551a313b425551d289060e0015b60405180910390a1505050505050565b604051630935e01b60e21b8152336004820152829081906001600160a01b038216906324d7806c90602401602060405180830381865afa1580156129a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c791906150bc565b612a275760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000612a338585612d45565b80547fffffffffffff000000000000000000000000ffffffffffffffffffffffffff001681556001810180546bffffffffffffffffffffffff19169055604080516001600160a01b0388168152602081018790529192507f54cbaf4a244605e6477ea43f8e1388ace54d61f7f5110cad2268ddc39da2bbac910160405180910390a15050505050565b612ac4612e0e565b6001600160a01b038116612b405760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610979565b610ee1816135ad565b33612b5c6000546001600160a01b031690565b6001600160a01b03161480612b775750612b77600133612dec565b612bcf5760405162461bcd60e51b8152602060048201526024808201527f41646d696e436f6e74726f6c3a204d757374206265206f776e6572206f7220616044820152633236b4b760e11b6064820152608401610979565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612c1c576040519150601f19603f3d011682016040523d82523d6000602084013e612c21565b606091505b5050905080612c725760405162461bcd60e51b815260206004820152601e60248201527f4661696c656420746f207472616e7366657220746f20726563656976657200006044820152606401610979565b505050565b612c8187876141f7565b612c908787868686868b6142c0565b6001600160a01b038716600090815260086020908152604080832089845282528083203384529091528120805461ffff88169290612ccf9084906152ce565b90915550612ce2905061ffff86166142cf565b3414612d305760405162461bcd60e51b815260206004820152601760248201527f496e76616c696420707572636861736520616d6f756e740000000000000000006044820152606401610979565b612d3c87873388612e7d565b50505050505050565b6001600160a01b0382166000908152600660209081526040808320848452909152812080549091660100000000000090910461ffff1690036106f65760405162461bcd60e51b815260206004820152601b60248201527f436f6c6c65637469626c65206e6f7420696e697469616c697a656400000000006044820152606401610979565b6000612dd4836142fc565b8015612de55750612de5838361432f565b9392505050565b6001600160a01b03811660009081526001830160205260408120541515612de5565b6000546001600160a01b031633146113e75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610979565b6000612de5836001600160a01b0384166143b8565b6000612e898585612d45565b90508161ffff166001036131155780546000906003630100000090910460ff1610612f8e5781546000908390600c90612ecc90600160601b900461ffff166153a8565b825461ffff9182166101009390930a83810292021916179091556040517fd39737190000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015266ffffffff00000060188a901b169092176024820181905292509088169063d3973719906044016020604051808303816000875af1158015612f62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f869190615319565b9150506130b2565b81548290600c90612fa990600160601b900461ffff166153a8565b825461ffff9182166101009390930a92830291909202199091161790556040517f2928ca580000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152871690632928ca58906024016020604051808303816000875af1158015613027573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061304b9190615319565b6040805180820182526001600160e01b038089168252855461ffff600160601b9091041660208084019182526001600160a01b038c16600090815260078252858120878252909152939093209151925163ffffffff16600160e01b02921691909117905590505b8154604080516001600160a01b038916815260208101889052600160601b90920461ffff1690820152606081018290527f604f4158d0efdc4ccca2c0fe366be334aab90f8081a92e8a53e4fb849d1a08979060800160405180910390a15061357b565b805460009061313090600160601b900461ffff1660016153c9565b825461ffff918216925084918491600c91613155918591600160601b909104166153c9565b92506101000a81548161ffff021916908361ffff16021790555060038260000160039054906101000a900460ff1660ff161061338c5760008361ffff1667ffffffffffffffff8111156131aa576131aa615129565b6040519080825280602002602001820160405280156131d3578160200160208202803683370190505b50905060005b8461ffff16811015613247576131f58163ffffffff85166152ce565b62ffffff1660188866ffffffffffffff16901b1766ffffffffffffff1682828151811061322457613224615113565b69ffffffffffffffffffff909216602092830291909101909101526001016131d9565b506040517f4278330e0000000000000000000000000000000000000000000000000000000081526000906001600160a01b03891690634278330e9061329290899086906004016153e4565b6000604051808303816000875af11580156132b1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526132d99190810190615447565b905060005b8561ffff168163ffffffff161015613384577f604f4158d0efdc4ccca2c0fe366be334aab90f8081a92e8a53e4fb849d1a0897898961331d8488615505565b858563ffffffff168151811061333557613335615113565b602002602001015160405161337494939291906001600160a01b03949094168452602084019290925263ffffffff166040830152606082015260800190565b60405180910390a16001016132de565b505050611c73565b6040517fe00aab4b0000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015261ffff851660248301526000919088169063e00aab4b906044016000604051808303816000875af11580156133fb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526134239190810190615447565b905060005b8461ffff168163ffffffff161015610a8e577f604f4158d0efdc4ccca2c0fe366be334aab90f8081a92e8a53e4fb849d1a089788886134678487615505565b858563ffffffff168151811061347f5761347f615113565b60200260200101516040516134be94939291906001600160a01b03949094168452602084019290925263ffffffff166040830152606082015260800190565b60405180910390a16040518060400160405280886001600160e01b0316815260200182856134ec9190615505565b63ffffffff16815250600760008a6001600160a01b03166001600160a01b031681526020019081526020016000206000848463ffffffff168151811061353457613534615113565b6020908102919091018101518252818101929092526040016000208251929091015163ffffffff16600160e01b026001600160e01b03909216919091179055600101613428565b5050505050565b60006106f6825490565b6000612de583836144b2565b6000612de5836001600160a01b0384166144dc565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006136098383612d45565b805490915060ff166136485760405162461bcd60e51b8152602060048201526008602482015267496e61637469766560c01b6044820152606401610979565b8054600160701b900465ffffffffffff16421015612c725760405162461bcd60e51b815260206004820152601560248201527f50757263686173696e67206e6f742061637469766500000000000000000000006044820152606401610979565b6000806136b58484612d45565b8054909150600160701b900465ffffffffffff164211801561112a5750805465ffffffffffff600160d01b82048116916136f891600160701b90910416426152bb565b10949350505050565b60008082600301548461ffff166137189190615522565b905060006137298561ffff166142cf565b61373390836152ce565b90508034146137845760405162461bcd60e51b815260206004820152601c60248201527f496e76616c696420707572636861736520616d6f756e742073656e74000000006044820152606401610979565b509392505050565b60008082600201548461ffff166137189190615522565b6001600160a01b0387166000908152600460209081526040808320898452825280832085845290915290205460ff161561381f5760405162461bcd60e51b815260206004820152601960248201527f43616e6e6f74207265706c6179207472616e73616374696f6e000000000000006044820152606401610979565b6040517f19457468657265756d205369676e6564204d6573736167653a0a35340000000060208201526bffffffffffffffffffffffff193360601b16603c820152605081018390527fffff00000000000000000000000000000000000000000000000000000000000060f083901b1660708201526000906072016040516020818303038152906040528051906020012090508086146139005760405162461bcd60e51b815260206004820152601160248201527f4d616c666f726d6564206d6573736167650000000000000000000000000000006044820152606401610979565b600061394486868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b9392505061452b9050565b6001600160a01b03808b1660009081526005602090815260408083208d845290915290205491925090811690821681146139c05760405162461bcd60e51b815260206004820152601160248201527f496e76616c6964207369676e61747572650000000000000000000000000000006044820152606401610979565b5050506001600160a01b0390961660009081526004602090815260408083209783529681528682209282529190915293909320805460ff1916600117905550505050565b6001600160a01b0386166000908152600460209081526040808320888452825280832084845290915290205460ff1615613a805760405162461bcd60e51b815260206004820152601960248201527f43616e6e6f74207265706c6179207472616e73616374696f6e000000000000006044820152606401610979565b6040517f19457468657265756d205369676e6564204d6573736167653a0a35320000000060208201526bffffffffffffffffffffffff193360601b16603c82015260508101829052600090607001604051602081830303815290604052805190602001209050808514613b355760405162461bcd60e51b815260206004820152601160248201527f4d616c666f726d6564206d6573736167650000000000000000000000000000006044820152606401610979565b6000613b7985858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a9392505061452b9050565b6001600160a01b03808a1660009081526005602090815260408083208c84529091529020549192509081169082168114613bf55760405162461bcd60e51b815260206004820152601160248201527f496e76616c6964207369676e61747572650000000000000000000000000000006044820152606401610979565b5050506001600160a01b039095166000908152600460209081526040808320968352958152858220968252959095525050509020805460ff19166001179055565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613c83576040519150601f19603f3d011682016040523d82523d6000602084013e613c88565b606091505b5050905080612c725760405162461bcd60e51b815260206004820152601f60248201527f4661696c656420746f207472616e7366657220746f20726563697069656e74006044820152606401610979565b600082118015613cf0575066ffffffffffffff8211155b613d3c5760405162461bcd60e51b815260206004820152601260248201527f496e76616c696420696e7374616e6365496400000000000000000000000000006044820152606401610979565b6001600160a01b0380851660008181526005602090815260408083208784528252808320549383526006825280832087845290915290209116908115613dc45760405162461bcd60e51b815260206004820152601f60248201527f436f6c6c65637469626c6520616c726561647920696e697469616c697a6564006044820152606401610979565b6000613dd7610100850160e08601614aaa565b6001600160a01b031603613e2d5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207369676e696e6720616464726573730000000000000000006044820152606401610979565b6000613e4161012085016101008601614aaa565b6001600160a01b031603613e975760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207061796d656e7420616464726573730000000000000000006044820152606401610979565b613ea760608401604085016152e1565b61ffff16600003613efa5760405162461bcd60e51b815260206004820152601460248201527f496e76616c6964207075726368617365206d61780000000000000000000000006044820152606401610979565b613f0b610100840160e08501614aaa565b6001600160a01b0387811660009081526005602090815260408083208984529091529081902080546001600160a01b03191693909216929092179055815463ff0000001916630100000060ff881602178255613f6d90606085019085016152e1565b815461ffff9190911666010000000000000267ffff0000000000001990911617815560a08301356002820155613fa960808401606085016152e1565b815461ffff91909116600160401b0269ffff000000000000000019909116178155613fda60408401602085016152e1565b815461ffff919091166401000000000265ffff000000001990911617815560c0830135600382015561401260a08401608085016152e1565b815461ffff91909116600160501b026bffff000000000000000000001990911617815561404260208401846152fc565b815461ff0019166101009115158202178255614065906101208501908501614aaa565b6005820180546001600160a01b0319166001600160a01b039283161790556040805191881682526020820186905233908201527f61da64dacf5829e3b4534db2a9f2ed9214b5c682bc1499c4742ac98f6e4179bd9060600161294b565b60608160000361410557505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561412f578061411981615155565b91506141289050600a8361554f565b9150614109565b60008167ffffffffffffffff81111561414a5761414a615129565b6040519080825280601f01601f191660200182016040528015614174576020820181803683370190505b5090505b841561112a576141896001836152bb565b9150614196600a86615563565b6141a19060306152ce565b60f81b8183815181106141b6576141b6615113565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506141f0600a8661554f565b9450614178565b60006142038383612d45565b805490915060ff166142425760405162461bcd60e51b8152602060048201526008602482015267496e61637469766560c01b6044820152606401610979565b600181015465ffffffffffff164210801590614274575060018101546601000000000000900465ffffffffffff164211155b612c725760405162461bcd60e51b815260206004820152601560248201527f4f75747369646520636c61696d20706572696f642e00000000000000000000006044820152606401610979565b612d3c878787878787876137a3565b60006142da33614547565b6142f4576142ef826602738d24e52000615522565b6106f6565b600092915050565b600061430f826301ffc9a760e01b61432f565b80156106f65750614328826001600160e01b031961432f565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d915060005190508280156143a1575060208210155b80156143ad5750600081115b979650505050505050565b600081815260018301602052604081205480156144a15760006143dc6001836152bb565b85549091506000906143f0906001906152bb565b905081811461445557600086600001828154811061441057614410615113565b906000526020600020015490508087600001848154811061443357614433615113565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061446657614466615577565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106f6565b60009150506106f6565b5092915050565b60008260000182815481106144c9576144c9615113565b9060005260206000200154905092915050565b6000818152600183016020526040812054614523575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106f6565b5060006106f6565b600080600061453a85856145e6565b915091506137848161462b565b6003546000906001600160a01b0316158015906106f657506003546040517f45ecd02f0000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152909116906345ecd02f90602401602060405180830381865afa1580156145c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f691906150bc565b600080825160410361461c5760208301516040840151606085015160001a614610878285856147e1565b94509450505050614624565b506000905060025b9250929050565b600081600481111561463f5761463f61558d565b036146475750565b600181600481111561465b5761465b61558d565b036146a85760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610979565b60028160048111156146bc576146bc61558d565b036147095760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610979565b600381600481111561471d5761471d61558d565b036147755760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610979565b60048160048111156147895761478961558d565b03610ee15760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610979565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561481857506000905060036148c5565b8460ff16601b1415801561483057508460ff16601c14155b1561484157506000905060046148c5565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015614895573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166148be576000600192509250506148c5565b9150600090505b94509492505050565b6000602082840312156148e057600080fd5b81356001600160e01b031981168114612de557600080fd5b6001600160a01b0381168114610ee157600080fd5b6000806040838503121561492057600080fd5b823561492b816148f8565b946020939093013593505050565b81511515815261022081016020830151614957602084018215159052565b50604083015161496b604084018215159052565b506060830151614981606084018261ffff169052565b506080830151614997608084018261ffff169052565b5060a08301516149ad60a084018261ffff169052565b5060c08301516149c360c084018261ffff169052565b5060e08301516149d960e084018261ffff169052565b506101008381015165ffffffffffff9081169184019190915261012080850151821690840152610140808501518216908401526101608085015182169084015261018080850151909116908301526101a080840151908301526101c080840151908301526101e08084015190830152610200928301516001600160a01b0316929091019190915290565b8015158114610ee157600080fd5b60008060408385031215614a8457600080fd5b8235614a8f816148f8565b91506020830135614a9f81614a63565b809150509250929050565b600060208284031215614abc57600080fd5b8135612de5816148f8565b60005b83811015614ae2578181015183820152602001614aca565b50506000910152565b60008151808452614b03816020860160208601614ac7565b601f01601f19169290920160200192915050565b60208152614b2a60208201835115159052565b60006020830151614b3f604084018215159052565b506040830151801515606084015250606083015160ff8116608084015250608083015161ffff811660a08401525060a083015161ffff811660c08401525060c083015161ffff811660e08401525060e0830151610100614ba48185018361ffff169052565b8401519050610120614bbb8482018361ffff169052565b8401519050610140614bd68482018365ffffffffffff169052565b8401519050610160614bf18482018365ffffffffffff169052565b8401519050610180614c0c8482018365ffffffffffff169052565b84015190506101a0614c278482018365ffffffffffff169052565b84015190506101c0614c428482018365ffffffffffff169052565b8401516101e0848101919091528401516102008085019190915284015161024061022080860182905291925090614c7d610260860184614aeb565b9501516001600160a01b03169301929092525090919050565b600080600060608486031215614cab57600080fd5b8335614cb6816148f8565b9250602084013591506040840135614ccd816148f8565b809150509250925092565b60008060008060608587031215614cee57600080fd5b8435614cf9816148f8565b935060208501359250604085013567ffffffffffffffff80821115614d1d57600080fd5b818701915087601f830112614d3157600080fd5b813581811115614d4057600080fd5b8860208260051b8501011115614d5557600080fd5b95989497505060200194505050565b6020808252825182820181905260009190848201906040850190845b81811015614da55783516001600160a01b031683529284019291840191600101614d80565b50909695505050505050565b60008060008060808587031215614dc757600080fd5b8435614dd2816148f8565b93506020850135614de2816148f8565b92506040850135614df2816148f8565b9396929550929360600135925050565b60008083601f840112614e1457600080fd5b50813567ffffffffffffffff811115614e2c57600080fd5b60208301915083602082850101111561462457600080fd5b60008060008060608587031215614e5a57600080fd5b8435614e65816148f8565b935060208501359250604085013567ffffffffffffffff811115614e8857600080fd5b614e9487828801614e02565b95989497509550505050565b803561ffff81168114614eb257600080fd5b919050565b600080600080600080600060c0888a031215614ed257600080fd5b8735614edd816148f8565b965060208801359550614ef260408901614ea0565b945060608801359350608088013567ffffffffffffffff811115614f1557600080fd5b614f218a828b01614e02565b989b979a5095989497959660a090950135949350505050565b6000806000838503610120811215614f5157600080fd5b8435614f5c816148f8565b93506020850135925060e0603f1982011215614f7757600080fd5b506040840190509250925092565b6000806000838503610160811215614f9c57600080fd5b8435614fa7816148f8565b935060208501359250610120603f1982011215614f7757600080fd5b600080600060608486031215614fd857600080fd5b8335614fe3816148f8565b9250602084013591506040840135614ccd81614a63565b60008060006060848603121561500f57600080fd5b833561501a816148f8565b95602085013595506040909401359392505050565b60008060006060848603121561504457600080fd5b833561504f816148f8565b92506020840135915061506460408501614ea0565b90509250925092565b602081526000612de56020830184614aeb565b600080600083850360e081121561509657600080fd5b84356150a1816148f8565b93506020850135925060a0603f1982011215614f7757600080fd5b6000602082840312156150ce57600080fd5b8151612de581614a63565b600181811c908216806150ed57607f821691505b60208210810361510d57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016151675761516761513f565b5060010190565b61ffff8281168282160390808211156144ab576144ab61513f565b60006020828403121561519b57600080fd5b815169ffffffffffffffffffff81168114612de557600080fd5b601f821115612c7257600081815260208120601f850160051c810160208610156151dc5750805b601f850160051c820191505b81811015611c73578281556001016151e8565b67ffffffffffffffff83111561521357615213615129565b6152278361522183546150d9565b836151b5565b6000601f84116001811461525b57600085156152435750838201355b600019600387901b1c1916600186901b17835561357b565b600083815260209020601f19861690835b8281101561528c578685013582556020948501946001909201910161526c565b50868210156152a95760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b818103818111156106f6576106f661513f565b808201808211156106f6576106f661513f565b6000602082840312156152f357600080fd5b612de582614ea0565b60006020828403121561530e57600080fd5b8135612de581614a63565b60006020828403121561532b57600080fd5b5051919050565b60008351615344818460208801614ac7565b835190830190615358818360208801614ac7565b01949350505050565b60006020828403121561537357600080fd5b813565ffffffffffff81168114612de557600080fd5b65ffffffffffff8181168382160190808211156144ab576144ab61513f565b600061ffff8083168181036153bf576153bf61513f565b6001019392505050565b61ffff8181168382160190808211156144ab576144ab61513f565b6000604082016001600160a01b03851683526020604081850152818551808452606086019150828701935060005b8181101561543a57845169ffffffffffffffffffff1683529383019391830191600101615412565b5090979650505050505050565b6000602080838503121561545a57600080fd5b825167ffffffffffffffff8082111561547257600080fd5b818501915085601f83011261548657600080fd5b81518181111561549857615498615129565b8060051b604051601f19603f830116810181811085821117156154bd576154bd615129565b6040529182528482019250838101850191888311156154db57600080fd5b938501935b828510156154f9578451845293850193928501926154e0565b98975050505050505050565b63ffffffff8181168382160190808211156144ab576144ab61513f565b80820281158282048414176106f6576106f661513f565b634e487b7160e01b600052601260045260246000fd5b60008261555e5761555e615539565b500490565b60008261557257615572615539565b500690565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212202e10d92b32ab5c1ebc21eafb3d8416099154aec39e767cbd37c7e6c373655afc64736f6c63430008110033

Deployed Bytecode

0x6080604052600436106101cd5760003560e01c80637ab39392116100f7578063d7bf81a311610095578063f1218c1b11610064578063f1218c1b1461059d578063f2fde38b146105bd578063f3fef3a3146105dd578063f97eb3ef146105fd57600080fd5b8063d7bf81a314610507578063dd0a5cf014610530578063e9dc637514610550578063f0b567871461057d57600080fd5b8063a0d742f9116100d1578063a0d742f914610456578063a7e111ac14610476578063c2e5d36e14610496578063cf2ccf97146104b657600080fd5b80637ab39392146104055780638da5cb5b1461042557806391c734f41461044357600080fd5b80632e5f6fd81161016f5780635e6a6f8a1161013e5780635e6a6f8a14610390578063654fb5bd146103b05780636d73e669146103d0578063715018a6146103f057600080fd5b80632e5f6fd8146102e357806331ae450b146103035780633a075a891461032557806350d108391461035857600080fd5b806324d7806c116101ab57806324d7806c1461025657806325e21f671461027657806327686a86146102a35780632d345670146102c357600080fd5b806301ffc9a7146101d257806304853ef7146102075780631b95a22714610234575b600080fd5b3480156101de57600080fd5b506101f26101ed3660046148ce565b610610565b60405190151581526020015b60405180910390f35b34801561021357600080fd5b5061022761022236600461490d565b6106fc565b6040516101fe9190614939565b34801561024057600080fd5b5061025461024f366004614a71565b6108b1565b005b34801561026257600080fd5b506101f2610271366004614aaa565b610a98565b34801561028257600080fd5b5061029661029136600461490d565b610ad1565b6040516101fe9190614b17565b3480156102af57600080fd5b506102546102be366004614c96565b610d2e565b3480156102cf57600080fd5b506102546102de366004614aaa565b610e86565b3480156102ef57600080fd5b506102546102fe366004614cd8565b610ee4565b34801561030f57600080fd5b50610318611048565b6040516101fe9190614d64565b34801561033157600080fd5b5061034561034036600461490d565b6110f7565b60405161ffff90911681526020016101fe565b34801561036457600080fd5b50600354610378906001600160a01b031681565b6040516001600160a01b0390911681526020016101fe565b34801561039c57600080fd5b506101f26103ab366004614db1565b611132565b3480156103bc57600080fd5b506102546103cb366004614e44565b611294565b3480156103dc57600080fd5b506102546103eb366004614aaa565b61137d565b3480156103fc57600080fd5b506102546113d5565b34801561041157600080fd5b50610254610420366004614aaa565b6113e9565b34801561043157600080fd5b506000546001600160a01b0316610378565b610254610451366004614eb7565b611491565b34801561046257600080fd5b50610254610471366004614f3a565b6118fb565b34801561048257600080fd5b50610254610491366004614f85565b611ae6565b3480156104a257600080fd5b506102546104b1366004614fc3565b611c7b565b3480156104c257600080fd5b506101f26104d1366004614ffa565b6001600160a01b0383166000908152600460209081526040808320858452825280832084845290915290205460ff169392505050565b34801561051357600080fd5b506105226602738d24e5200081565b6040519081526020016101fe565b34801561053c57600080fd5b5061025461054b36600461502f565b611d73565b34801561055c57600080fd5b5061057061056b36600461490d565b611e9d565b6040516101fe919061506d565b34801561058957600080fd5b50610254610598366004615080565b612486565b3480156105a957600080fd5b506102546105b836600461490d565b61295b565b3480156105c957600080fd5b506102546105d8366004614aaa565b612abc565b3480156105e957600080fd5b506102546105f836600461490d565b612b49565b61025461060b366004614eb7565b612c77565b60006001600160e01b031982167f02c4b69e00000000000000000000000000000000000000000000000000000000148061067357506001600160e01b031982167fe9dc637500000000000000000000000000000000000000000000000000000000145b806106a757506001600160e01b031982167f45ffcdad00000000000000000000000000000000000000000000000000000000145b806106db57506001600160e01b031982167f553e757e00000000000000000000000000000000000000000000000000000000145b806106f657506001600160e01b031982166301ffc9a760e01b145b92915050565b6040805161022081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e0810182905261020081018290529061078f8484612d45565b6040805161022081018252825460ff8082161515835261010080830482161515602085015262010000830490911615159383019390935261ffff640100000000820481166060840152660100000000000080830482166080850152600160401b8304821660a0850152600160501b8304821660c0850152600160601b830490911660e084015265ffffffffffff600160701b8304811694840194909452600160a01b82048416610120840152600160d01b909104831661014083015260018401548084166101608401520490911661018082015260028201546101a082015260038201546101c08201529091506101e0810161088b86866110f7565b61ffff1681526005909201546001600160a01b0316602090920191909152905092915050565b604051630935e01b60e21b8152336004820152829081906001600160a01b038216906324d7806c90602401602060405180830381865afa1580156108f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091d91906150bc565b6109825760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b60648201526084015b60405180910390fd5b6109ac847fb5d2729f00000000000000000000000000000000000000000000000000000000612dc9565b610a1e5760405162461bcd60e51b815260206004820152602960248201527f63726561746f72206d75737420696d706c656d656e742049455243373231437260448201527f6561746f72436f726500000000000000000000000000000000000000000000006064820152608401610979565b6040517fac0c8cfa00000000000000000000000000000000000000000000000000000000815283151560048201526001600160a01b0385169063ac0c8cfa90602401600060405180830381600087803b158015610a7a57600080fd5b505af1158015610a8e573d6000803e3d6000fd5b5050505050505050565b6000816001600160a01b0316610ab66000546001600160a01b031690565b6001600160a01b031614806106f657506106f6600183612dec565b60408051610240810182526000808252602080830182905282840182905260608084018390526080840183905260a0840183905260c0840183905260e08401839052610100840183905261012084018390526101408401839052610160840183905261018084018390526101a084018390526101c084018390526101e0840183905261020084015261022083018290526001600160a01b0386168252600681528382208583529052919091206040805161024081018252825460ff8082161515835261010080830482161515602085015262010000830482161515948401949094526301000000820416606083015261ffff6401000000008204811660808401526601000000000000808304821660a0850152600160401b8304821660c0850152600160501b8304821660e0850152600160601b83049091169383019390935265ffffffffffff600160701b82048116610120840152600160a01b82048116610140840152600160d01b90910481166101608301526001840154808216610180840152929092049091166101a082015260028201546101c082015260038201546101e082015260048201805491929161020084019190610c90906150d9565b80601f0160208091040260200160405190810160405280929190818152602001828054610cbc906150d9565b8015610d095780601f10610cde57610100808354040283529160200191610d09565b820191906000526020600020905b815481529060010190602001808311610cec57829003601f168201915b5050509183525050600591909101546001600160a01b03166020909101529392505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015610d76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9a91906150bc565b610dfa5760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000610e068686612d45565b90506001600160a01b038416610e5e5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207061796d656e7420616464726573730000000000000000006044820152606401610979565b60050180546001600160a01b0319166001600160a01b03949094169390931790925550505050565b610e8e612e0e565b610e99600182612dec565b15610ee15760405133906001600160a01b038316907f7c0c3c84c67c85fcac635147348bfe374c24a1a93d0366d1cfe9d8853cbf89d590600090a3610edf600182612e68565b505b50565b604051630935e01b60e21b8152336004820152849081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015610f2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5091906150bc565b610fb05760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000610fbc8787612d45565b805490915060ff16156110025760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792061637469766560901b6044820152606401610979565b60005b84811015610a8e57611040888888888581811061102457611024615113565b90506020020160208101906110399190614aaa565b6001612e7d565b600101611005565b60606110546001613582565b67ffffffffffffffff81111561106c5761106c615129565b604051908082528060200260200182016040528015611095578160200160208202803683370190505b50905060005b6110a56001613582565b8110156110f3576110b760018261358c565b8282815181106110c9576110c9615113565b6001600160a01b0390921660209283029190910190910152806110eb81615155565b91505061109b565b5090565b6000806111048484612d45565b805490915061112a9061ffff600160601b8204811691660100000000000090041661516e565b949350505050565b60006001600160a01b03841661114a5750600161112a565b33600090815260076020908152604080832085845282528083208151808301909252546001600160e01b038116808352600160e01b90910463ffffffff1692820192909252919081036112635760405163b4b5b48f60e01b815260048101859052600090339063b4b5b48f90602401602060405180830381865afa1580156111d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fa9190615189565b66ffffffffffffff601882901c1692509050600082900361125d5760405162461bcd60e51b815260206004820152600f60248201527f546f6b656e206e6f7420666f756e6400000000000000000000000000000000006044820152606401610979565b50611270565b5080516001600160e01b03165b600061127c3383612d45565b5462010000900460ff16159350505050949350505050565b604051630935e01b60e21b8152336004820152849081906001600160a01b038216906324d7806c90602401602060405180830381865afa1580156112dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130091906150bc565b6113605760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b600061136c8787612d45565b905060048101610a8e8587836151fb565b611385612e0e565b611390600182612dec565b610ee15760405133906001600160a01b038316907f7e1a1a08d52e4ba0e21554733d66165fd5151f99460116223d9e3a608eec5cb190600090a3610edf600182613598565b6113dd612e0e565b6113e760006135ad565b565b336113fc6000546001600160a01b031690565b6001600160a01b031614806114175750611417600133612dec565b61146f5760405162461bcd60e51b8152602060048201526024808201527f41646d696e436f6e74726f6c3a204d757374206265206f776e6572206f7220616044820152633236b4b760e11b6064820152608401610979565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600061149d8888612d45565b90506114a988886135fd565b60006114b589896136a8565b905060006114c38a8a6110f7565b61ffff168861ffff161115801561151a57508180156114e857508254610100900460ff165b806114fe57508254640100000000900461ffff16155b8061151a5750825461ffff640100000000909104811690891611155b61155b5760405162461bcd60e51b8152602060048201526012602482015271151bdbc81b585b9e481c995c5d595cdd195960721b6044820152606401610979565b8115611770578254610100900460ff166116dd578254600160501b900461ffff1615611626576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091529020548354600160501b900461ffff16811080156115e3575083546115db908290600160501b900461ffff166152bb565b8961ffff1611155b6116245760405162461bcd60e51b8152602060048201526012602482015271151bdbc81b585b9e481c995c5d595cdd195960721b6044820152606401610979565b505b8254600160401b900461ffff16156116dd576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091529020548354600160401b900461ffff168110801561169a57508354611692908290600160401b900461ffff166152bb565b8961ffff1611155b6116db5760405162461bcd60e51b8152602060048201526012602482015271151bdbc81b585b9e481c995c5d595cdd195960721b6044820152606401610979565b505b6116e78884613701565b8354909150610100900460ff1615801561172157508254600160501b900461ffff1615158061172157508254600160401b900461ffff1615155b1561176b576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091528120805461ffff8b1692906117659084906152ce565b90915550505b61188b565b8254600160401b900461ffff1615611827576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091529020548354600160401b900461ffff16811080156117e4575083546117dc908290600160401b900461ffff166152bb565b8961ffff1611155b6118255760405162461bcd60e51b8152602060048201526012602482015271151bdbc81b585b9e481c995c5d595cdd195960721b6044820152606401610979565b505b611831888461378c565b8354909150600160401b900461ffff161561188b576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091528120805461ffff8b1692906118859084906152ce565b90915550505b81801561189e57508254610100900460ff165b156118b7576118b28a8a898989898e6137a3565b6118c5565b6118c58a8a89898989613a04565b80156118e35760058301546118e3906001600160a01b031682613c36565b6118ef8a8a338b612e7d565b50505050505050505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015611943573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061196791906150bc565b6119c75760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b60006119d38686612d45565b805490915060ff1615611a195760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792061637469766560901b6044820152606401610979565b60a08401356002820155611a3360808501606086016152e1565b815461ffff91909116600160401b0269ffff000000000000000019909116178155611a6460408501602086016152e1565b815461ffff919091166401000000000265ffff000000001990911617815560c08401356003820155611a9c60a08501608086016152e1565b815461ffff91909116600160501b026bffff0000000000000000000019909116178155611acc60208501856152fc565b81549015156101000261ff00199091161790555050505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015611b2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b5291906150bc565b611bb25760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000856001600160a01b031663ffa1ad746040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611c0e575060408051601f3d908101601f19168201909252611c0b91810190615319565b60015b15611c675760ff811115611c645760405162461bcd60e51b815260206004820152601c60248201527f556e737570706f7274656420636f6e74726163742076657273696f6e000000006044820152606401610979565b90505b611c7386828787613cd9565b505050505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015611cc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ce791906150bc565b611d475760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000611d538686612d45565b8054941515620100000262ff000019909516949094179093555050505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015611dbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ddf91906150bc565b611e3f5760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000611e4b8686612d45565b805490915060ff1615611e915760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792061637469766560901b6044820152606401610979565b611c7386863387612e7d565b6001600160a01b038216600090815260076020908152604080832084845282528083208151808301835290546001600160e01b0381168252600160e01b900463ffffffff168184015281516102408101835284815292830184905290820183905260608083018490526080830184905260a0830184905260c0830184905260e08301849052610100830184905261012083018490526101408301849052610160830184905261018083018490526101a083018490526101c083018490526101e083018490526102008301819052610220830184905292909182516001600160e01b03166000036122255760405163b4b5b48f60e01b8152600481018690526000906001600160a01b0388169063b4b5b48f90602401602060405180830381865afa158015611fcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ff39190615189565b905066ffffffffffffff601882901c1660008190036120545760405162461bcd60e51b815260206004820152600f60248201527f546f6b656e206e6f7420666f756e6400000000000000000000000000000000006044820152606401610979565b612067888266ffffffffffffff16612d45565b6040805161024081018252825460ff8082161515835261010080830482161515602085015262010000830482161515948401949094526301000000820416606083015261ffff6401000000008204811660808401526601000000000000808304821660a0850152600160401b8304821660c0850152600160501b8304821660e0850152600160601b83049091169383019390935265ffffffffffff600160701b82048116610120840152600160a01b82048116610140840152600160d01b90910481166101608301526001840154808216610180840152929092049091166101a082015260028201546101c082015260038201546101e08201526004820180549192916102008401919061217a906150d9565b80601f01602080910402602001604051908101604052809291908181526020018280546121a6906150d9565b80156121f35780601f106121c8576101008083540402835291602001916121f3565b820191906000526020600020905b8154815290600101906020018083116121d657829003601f168201915b5050509183525050600591909101546001600160a01b031660209091015262ffffff9290921693509091506123f69050565b826020015163ffffffff1691506122498684600001516001600160e01b0316612d45565b6040805161024081018252825460ff8082161515835261010080830482161515602085015262010000830482161515948401949094526301000000820416606083015261ffff6401000000008204811660808401526601000000000000808304821660a0850152600160401b8304821660c0850152600160501b8304821660e0850152600160601b83049091169383019390935265ffffffffffff600160701b82048116610120840152600160a01b82048116610140840152600160d01b90910481166101608301526001840154808216610180840152929092049091166101a082015260028201546101c082015260038201546101e08201526004820180549192916102008401919061235c906150d9565b80601f0160208091040260200160405190810160405280929190818152602001828054612388906150d9565b80156123d55780601f106123aa576101008083540402835291602001916123d5565b820191906000526020600020905b8154815290600101906020018083116123b857829003601f168201915b5050509183525050600591909101546001600160a01b031660209091015290505b8061020001515160000361244c5760405162461bcd60e51b815260206004820152601660248201527f4e6f2062617365207572692070726566697820736574000000000000000000006044820152606401610979565b80610200015161245b836140c2565b60405160200161246c929190615332565b604051602081830303815290604052935050505092915050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa1580156124ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f291906150bc565b6125525760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b600061255e8686612d45565b805490915060ff16156125a45760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792061637469766560901b6044820152606401610979565b426125b26020860186615361565b65ffffffffffff16116126075760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f7420616374697661746520696e20746865207061737400000000006044820152606401610979565b6126176040850160208601615361565b65ffffffffffff1661262f6060860160408701615361565b65ffffffffffff1611156126ab5760405162461bcd60e51b815260206004820152602f60248201527f50726573616c6520496e74657276616c2063616e6e6f74206265206c6f6e676560448201527f72207468616e207468652073616c6500000000000000000000000000000000006064820152608401610979565b6126bb60a0850160808601615361565b65ffffffffffff166126d36080860160608701615361565b65ffffffffffff161115801561271457506126f16020850185615361565b65ffffffffffff1661270960a0860160808701615361565b65ffffffffffff1611155b6127605760405162461bcd60e51b815260206004820152601360248201527f496e76616c696420636c61696d2074696d6573000000000000000000000000006044820152606401610979565b61276d6020850185615361565b815465ffffffffffff91909116600160701b027fffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffff9091161781556127b76040850160208601615361565b6127c46020860186615361565b6127ce9190615389565b815465ffffffffffff91909116600160a01b027fffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffff9091161781556128186060850160408601615361565b815465ffffffffffff91909116600160d01b0279ffffffffffffffffffffffffffffffffffffffffffffffffffff90911617815561285c6080850160608601615361565b60018201805465ffffffffffff191665ffffffffffff9290921691909117905561288c60a0850160808601615361565b600182810180546bffffffffffff000000000000198116660100000000000065ffffffffffff958616810291821793849055865460ff1916909417808755604080516001600160a01b038e168152602081018d9052600160701b8304881691810191909152600160a01b820487166060820152600160d01b909104861660808201529185169085161760a082015291900490911660c08201527fda897ec003b83d996662d95c264c767d3c58171ae697ebb551a313b425551d289060e0015b60405180910390a1505050505050565b604051630935e01b60e21b8152336004820152829081906001600160a01b038216906324d7806c90602401602060405180830381865afa1580156129a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c791906150bc565b612a275760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000612a338585612d45565b80547fffffffffffff000000000000000000000000ffffffffffffffffffffffffff001681556001810180546bffffffffffffffffffffffff19169055604080516001600160a01b0388168152602081018790529192507f54cbaf4a244605e6477ea43f8e1388ace54d61f7f5110cad2268ddc39da2bbac910160405180910390a15050505050565b612ac4612e0e565b6001600160a01b038116612b405760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610979565b610ee1816135ad565b33612b5c6000546001600160a01b031690565b6001600160a01b03161480612b775750612b77600133612dec565b612bcf5760405162461bcd60e51b8152602060048201526024808201527f41646d696e436f6e74726f6c3a204d757374206265206f776e6572206f7220616044820152633236b4b760e11b6064820152608401610979565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612c1c576040519150601f19603f3d011682016040523d82523d6000602084013e612c21565b606091505b5050905080612c725760405162461bcd60e51b815260206004820152601e60248201527f4661696c656420746f207472616e7366657220746f20726563656976657200006044820152606401610979565b505050565b612c8187876141f7565b612c908787868686868b6142c0565b6001600160a01b038716600090815260086020908152604080832089845282528083203384529091528120805461ffff88169290612ccf9084906152ce565b90915550612ce2905061ffff86166142cf565b3414612d305760405162461bcd60e51b815260206004820152601760248201527f496e76616c696420707572636861736520616d6f756e740000000000000000006044820152606401610979565b612d3c87873388612e7d565b50505050505050565b6001600160a01b0382166000908152600660209081526040808320848452909152812080549091660100000000000090910461ffff1690036106f65760405162461bcd60e51b815260206004820152601b60248201527f436f6c6c65637469626c65206e6f7420696e697469616c697a656400000000006044820152606401610979565b6000612dd4836142fc565b8015612de55750612de5838361432f565b9392505050565b6001600160a01b03811660009081526001830160205260408120541515612de5565b6000546001600160a01b031633146113e75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610979565b6000612de5836001600160a01b0384166143b8565b6000612e898585612d45565b90508161ffff166001036131155780546000906003630100000090910460ff1610612f8e5781546000908390600c90612ecc90600160601b900461ffff166153a8565b825461ffff9182166101009390930a83810292021916179091556040517fd39737190000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015266ffffffff00000060188a901b169092176024820181905292509088169063d3973719906044016020604051808303816000875af1158015612f62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f869190615319565b9150506130b2565b81548290600c90612fa990600160601b900461ffff166153a8565b825461ffff9182166101009390930a92830291909202199091161790556040517f2928ca580000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152871690632928ca58906024016020604051808303816000875af1158015613027573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061304b9190615319565b6040805180820182526001600160e01b038089168252855461ffff600160601b9091041660208084019182526001600160a01b038c16600090815260078252858120878252909152939093209151925163ffffffff16600160e01b02921691909117905590505b8154604080516001600160a01b038916815260208101889052600160601b90920461ffff1690820152606081018290527f604f4158d0efdc4ccca2c0fe366be334aab90f8081a92e8a53e4fb849d1a08979060800160405180910390a15061357b565b805460009061313090600160601b900461ffff1660016153c9565b825461ffff918216925084918491600c91613155918591600160601b909104166153c9565b92506101000a81548161ffff021916908361ffff16021790555060038260000160039054906101000a900460ff1660ff161061338c5760008361ffff1667ffffffffffffffff8111156131aa576131aa615129565b6040519080825280602002602001820160405280156131d3578160200160208202803683370190505b50905060005b8461ffff16811015613247576131f58163ffffffff85166152ce565b62ffffff1660188866ffffffffffffff16901b1766ffffffffffffff1682828151811061322457613224615113565b69ffffffffffffffffffff909216602092830291909101909101526001016131d9565b506040517f4278330e0000000000000000000000000000000000000000000000000000000081526000906001600160a01b03891690634278330e9061329290899086906004016153e4565b6000604051808303816000875af11580156132b1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526132d99190810190615447565b905060005b8561ffff168163ffffffff161015613384577f604f4158d0efdc4ccca2c0fe366be334aab90f8081a92e8a53e4fb849d1a0897898961331d8488615505565b858563ffffffff168151811061333557613335615113565b602002602001015160405161337494939291906001600160a01b03949094168452602084019290925263ffffffff166040830152606082015260800190565b60405180910390a16001016132de565b505050611c73565b6040517fe00aab4b0000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015261ffff851660248301526000919088169063e00aab4b906044016000604051808303816000875af11580156133fb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526134239190810190615447565b905060005b8461ffff168163ffffffff161015610a8e577f604f4158d0efdc4ccca2c0fe366be334aab90f8081a92e8a53e4fb849d1a089788886134678487615505565b858563ffffffff168151811061347f5761347f615113565b60200260200101516040516134be94939291906001600160a01b03949094168452602084019290925263ffffffff166040830152606082015260800190565b60405180910390a16040518060400160405280886001600160e01b0316815260200182856134ec9190615505565b63ffffffff16815250600760008a6001600160a01b03166001600160a01b031681526020019081526020016000206000848463ffffffff168151811061353457613534615113565b6020908102919091018101518252818101929092526040016000208251929091015163ffffffff16600160e01b026001600160e01b03909216919091179055600101613428565b5050505050565b60006106f6825490565b6000612de583836144b2565b6000612de5836001600160a01b0384166144dc565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006136098383612d45565b805490915060ff166136485760405162461bcd60e51b8152602060048201526008602482015267496e61637469766560c01b6044820152606401610979565b8054600160701b900465ffffffffffff16421015612c725760405162461bcd60e51b815260206004820152601560248201527f50757263686173696e67206e6f742061637469766500000000000000000000006044820152606401610979565b6000806136b58484612d45565b8054909150600160701b900465ffffffffffff164211801561112a5750805465ffffffffffff600160d01b82048116916136f891600160701b90910416426152bb565b10949350505050565b60008082600301548461ffff166137189190615522565b905060006137298561ffff166142cf565b61373390836152ce565b90508034146137845760405162461bcd60e51b815260206004820152601c60248201527f496e76616c696420707572636861736520616d6f756e742073656e74000000006044820152606401610979565b509392505050565b60008082600201548461ffff166137189190615522565b6001600160a01b0387166000908152600460209081526040808320898452825280832085845290915290205460ff161561381f5760405162461bcd60e51b815260206004820152601960248201527f43616e6e6f74207265706c6179207472616e73616374696f6e000000000000006044820152606401610979565b6040517f19457468657265756d205369676e6564204d6573736167653a0a35340000000060208201526bffffffffffffffffffffffff193360601b16603c820152605081018390527fffff00000000000000000000000000000000000000000000000000000000000060f083901b1660708201526000906072016040516020818303038152906040528051906020012090508086146139005760405162461bcd60e51b815260206004820152601160248201527f4d616c666f726d6564206d6573736167650000000000000000000000000000006044820152606401610979565b600061394486868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b9392505061452b9050565b6001600160a01b03808b1660009081526005602090815260408083208d845290915290205491925090811690821681146139c05760405162461bcd60e51b815260206004820152601160248201527f496e76616c6964207369676e61747572650000000000000000000000000000006044820152606401610979565b5050506001600160a01b0390961660009081526004602090815260408083209783529681528682209282529190915293909320805460ff1916600117905550505050565b6001600160a01b0386166000908152600460209081526040808320888452825280832084845290915290205460ff1615613a805760405162461bcd60e51b815260206004820152601960248201527f43616e6e6f74207265706c6179207472616e73616374696f6e000000000000006044820152606401610979565b6040517f19457468657265756d205369676e6564204d6573736167653a0a35320000000060208201526bffffffffffffffffffffffff193360601b16603c82015260508101829052600090607001604051602081830303815290604052805190602001209050808514613b355760405162461bcd60e51b815260206004820152601160248201527f4d616c666f726d6564206d6573736167650000000000000000000000000000006044820152606401610979565b6000613b7985858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a9392505061452b9050565b6001600160a01b03808a1660009081526005602090815260408083208c84529091529020549192509081169082168114613bf55760405162461bcd60e51b815260206004820152601160248201527f496e76616c6964207369676e61747572650000000000000000000000000000006044820152606401610979565b5050506001600160a01b039095166000908152600460209081526040808320968352958152858220968252959095525050509020805460ff19166001179055565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613c83576040519150601f19603f3d011682016040523d82523d6000602084013e613c88565b606091505b5050905080612c725760405162461bcd60e51b815260206004820152601f60248201527f4661696c656420746f207472616e7366657220746f20726563697069656e74006044820152606401610979565b600082118015613cf0575066ffffffffffffff8211155b613d3c5760405162461bcd60e51b815260206004820152601260248201527f496e76616c696420696e7374616e6365496400000000000000000000000000006044820152606401610979565b6001600160a01b0380851660008181526005602090815260408083208784528252808320549383526006825280832087845290915290209116908115613dc45760405162461bcd60e51b815260206004820152601f60248201527f436f6c6c65637469626c6520616c726561647920696e697469616c697a6564006044820152606401610979565b6000613dd7610100850160e08601614aaa565b6001600160a01b031603613e2d5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207369676e696e6720616464726573730000000000000000006044820152606401610979565b6000613e4161012085016101008601614aaa565b6001600160a01b031603613e975760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207061796d656e7420616464726573730000000000000000006044820152606401610979565b613ea760608401604085016152e1565b61ffff16600003613efa5760405162461bcd60e51b815260206004820152601460248201527f496e76616c6964207075726368617365206d61780000000000000000000000006044820152606401610979565b613f0b610100840160e08501614aaa565b6001600160a01b0387811660009081526005602090815260408083208984529091529081902080546001600160a01b03191693909216929092179055815463ff0000001916630100000060ff881602178255613f6d90606085019085016152e1565b815461ffff9190911666010000000000000267ffff0000000000001990911617815560a08301356002820155613fa960808401606085016152e1565b815461ffff91909116600160401b0269ffff000000000000000019909116178155613fda60408401602085016152e1565b815461ffff919091166401000000000265ffff000000001990911617815560c0830135600382015561401260a08401608085016152e1565b815461ffff91909116600160501b026bffff000000000000000000001990911617815561404260208401846152fc565b815461ff0019166101009115158202178255614065906101208501908501614aaa565b6005820180546001600160a01b0319166001600160a01b039283161790556040805191881682526020820186905233908201527f61da64dacf5829e3b4534db2a9f2ed9214b5c682bc1499c4742ac98f6e4179bd9060600161294b565b60608160000361410557505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561412f578061411981615155565b91506141289050600a8361554f565b9150614109565b60008167ffffffffffffffff81111561414a5761414a615129565b6040519080825280601f01601f191660200182016040528015614174576020820181803683370190505b5090505b841561112a576141896001836152bb565b9150614196600a86615563565b6141a19060306152ce565b60f81b8183815181106141b6576141b6615113565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506141f0600a8661554f565b9450614178565b60006142038383612d45565b805490915060ff166142425760405162461bcd60e51b8152602060048201526008602482015267496e61637469766560c01b6044820152606401610979565b600181015465ffffffffffff164210801590614274575060018101546601000000000000900465ffffffffffff164211155b612c725760405162461bcd60e51b815260206004820152601560248201527f4f75747369646520636c61696d20706572696f642e00000000000000000000006044820152606401610979565b612d3c878787878787876137a3565b60006142da33614547565b6142f4576142ef826602738d24e52000615522565b6106f6565b600092915050565b600061430f826301ffc9a760e01b61432f565b80156106f65750614328826001600160e01b031961432f565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d915060005190508280156143a1575060208210155b80156143ad5750600081115b979650505050505050565b600081815260018301602052604081205480156144a15760006143dc6001836152bb565b85549091506000906143f0906001906152bb565b905081811461445557600086600001828154811061441057614410615113565b906000526020600020015490508087600001848154811061443357614433615113565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061446657614466615577565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106f6565b60009150506106f6565b5092915050565b60008260000182815481106144c9576144c9615113565b9060005260206000200154905092915050565b6000818152600183016020526040812054614523575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106f6565b5060006106f6565b600080600061453a85856145e6565b915091506137848161462b565b6003546000906001600160a01b0316158015906106f657506003546040517f45ecd02f0000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152909116906345ecd02f90602401602060405180830381865afa1580156145c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f691906150bc565b600080825160410361461c5760208301516040840151606085015160001a614610878285856147e1565b94509450505050614624565b506000905060025b9250929050565b600081600481111561463f5761463f61558d565b036146475750565b600181600481111561465b5761465b61558d565b036146a85760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610979565b60028160048111156146bc576146bc61558d565b036147095760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610979565b600381600481111561471d5761471d61558d565b036147755760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610979565b60048160048111156147895761478961558d565b03610ee15760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610979565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561481857506000905060036148c5565b8460ff16601b1415801561483057508460ff16601c14155b1561484157506000905060046148c5565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015614895573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166148be576000600192509250506148c5565b9150600090505b94509492505050565b6000602082840312156148e057600080fd5b81356001600160e01b031981168114612de557600080fd5b6001600160a01b0381168114610ee157600080fd5b6000806040838503121561492057600080fd5b823561492b816148f8565b946020939093013593505050565b81511515815261022081016020830151614957602084018215159052565b50604083015161496b604084018215159052565b506060830151614981606084018261ffff169052565b506080830151614997608084018261ffff169052565b5060a08301516149ad60a084018261ffff169052565b5060c08301516149c360c084018261ffff169052565b5060e08301516149d960e084018261ffff169052565b506101008381015165ffffffffffff9081169184019190915261012080850151821690840152610140808501518216908401526101608085015182169084015261018080850151909116908301526101a080840151908301526101c080840151908301526101e08084015190830152610200928301516001600160a01b0316929091019190915290565b8015158114610ee157600080fd5b60008060408385031215614a8457600080fd5b8235614a8f816148f8565b91506020830135614a9f81614a63565b809150509250929050565b600060208284031215614abc57600080fd5b8135612de5816148f8565b60005b83811015614ae2578181015183820152602001614aca565b50506000910152565b60008151808452614b03816020860160208601614ac7565b601f01601f19169290920160200192915050565b60208152614b2a60208201835115159052565b60006020830151614b3f604084018215159052565b506040830151801515606084015250606083015160ff8116608084015250608083015161ffff811660a08401525060a083015161ffff811660c08401525060c083015161ffff811660e08401525060e0830151610100614ba48185018361ffff169052565b8401519050610120614bbb8482018361ffff169052565b8401519050610140614bd68482018365ffffffffffff169052565b8401519050610160614bf18482018365ffffffffffff169052565b8401519050610180614c0c8482018365ffffffffffff169052565b84015190506101a0614c278482018365ffffffffffff169052565b84015190506101c0614c428482018365ffffffffffff169052565b8401516101e0848101919091528401516102008085019190915284015161024061022080860182905291925090614c7d610260860184614aeb565b9501516001600160a01b03169301929092525090919050565b600080600060608486031215614cab57600080fd5b8335614cb6816148f8565b9250602084013591506040840135614ccd816148f8565b809150509250925092565b60008060008060608587031215614cee57600080fd5b8435614cf9816148f8565b935060208501359250604085013567ffffffffffffffff80821115614d1d57600080fd5b818701915087601f830112614d3157600080fd5b813581811115614d4057600080fd5b8860208260051b8501011115614d5557600080fd5b95989497505060200194505050565b6020808252825182820181905260009190848201906040850190845b81811015614da55783516001600160a01b031683529284019291840191600101614d80565b50909695505050505050565b60008060008060808587031215614dc757600080fd5b8435614dd2816148f8565b93506020850135614de2816148f8565b92506040850135614df2816148f8565b9396929550929360600135925050565b60008083601f840112614e1457600080fd5b50813567ffffffffffffffff811115614e2c57600080fd5b60208301915083602082850101111561462457600080fd5b60008060008060608587031215614e5a57600080fd5b8435614e65816148f8565b935060208501359250604085013567ffffffffffffffff811115614e8857600080fd5b614e9487828801614e02565b95989497509550505050565b803561ffff81168114614eb257600080fd5b919050565b600080600080600080600060c0888a031215614ed257600080fd5b8735614edd816148f8565b965060208801359550614ef260408901614ea0565b945060608801359350608088013567ffffffffffffffff811115614f1557600080fd5b614f218a828b01614e02565b989b979a5095989497959660a090950135949350505050565b6000806000838503610120811215614f5157600080fd5b8435614f5c816148f8565b93506020850135925060e0603f1982011215614f7757600080fd5b506040840190509250925092565b6000806000838503610160811215614f9c57600080fd5b8435614fa7816148f8565b935060208501359250610120603f1982011215614f7757600080fd5b600080600060608486031215614fd857600080fd5b8335614fe3816148f8565b9250602084013591506040840135614ccd81614a63565b60008060006060848603121561500f57600080fd5b833561501a816148f8565b95602085013595506040909401359392505050565b60008060006060848603121561504457600080fd5b833561504f816148f8565b92506020840135915061506460408501614ea0565b90509250925092565b602081526000612de56020830184614aeb565b600080600083850360e081121561509657600080fd5b84356150a1816148f8565b93506020850135925060a0603f1982011215614f7757600080fd5b6000602082840312156150ce57600080fd5b8151612de581614a63565b600181811c908216806150ed57607f821691505b60208210810361510d57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016151675761516761513f565b5060010190565b61ffff8281168282160390808211156144ab576144ab61513f565b60006020828403121561519b57600080fd5b815169ffffffffffffffffffff81168114612de557600080fd5b601f821115612c7257600081815260208120601f850160051c810160208610156151dc5750805b601f850160051c820191505b81811015611c73578281556001016151e8565b67ffffffffffffffff83111561521357615213615129565b6152278361522183546150d9565b836151b5565b6000601f84116001811461525b57600085156152435750838201355b600019600387901b1c1916600186901b17835561357b565b600083815260209020601f19861690835b8281101561528c578685013582556020948501946001909201910161526c565b50868210156152a95760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b818103818111156106f6576106f661513f565b808201808211156106f6576106f661513f565b6000602082840312156152f357600080fd5b612de582614ea0565b60006020828403121561530e57600080fd5b8135612de581614a63565b60006020828403121561532b57600080fd5b5051919050565b60008351615344818460208801614ac7565b835190830190615358818360208801614ac7565b01949350505050565b60006020828403121561537357600080fd5b813565ffffffffffff81168114612de557600080fd5b65ffffffffffff8181168382160190808211156144ab576144ab61513f565b600061ffff8083168181036153bf576153bf61513f565b6001019392505050565b61ffff8181168382160190808211156144ab576144ab61513f565b6000604082016001600160a01b03851683526020604081850152818551808452606086019150828701935060005b8181101561543a57845169ffffffffffffffffffff1683529383019391830191600101615412565b5090979650505050505050565b6000602080838503121561545a57600080fd5b825167ffffffffffffffff8082111561547257600080fd5b818501915085601f83011261548657600080fd5b81518181111561549857615498615129565b8060051b604051601f19603f830116810181811085821117156154bd576154bd615129565b6040529182528482019250838101850191888311156154db57600080fd5b938501935b828510156154f9578451845293850193928501926154e0565b98975050505050505050565b63ffffffff8181168382160190808211156144ab576144ab61513f565b80820281158282048414176106f6576106f661513f565b634e487b7160e01b600052601260045260246000fd5b60008261555e5761555e615539565b500490565b60008261557257615572615539565b500690565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212202e10d92b32ab5c1ebc21eafb3d8416099154aec39e767cbd37c7e6c373655afc64736f6c63430008110033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.