More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 1,920 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer Ownersh... | 18797693 | 404 days ago | IN | 0 ETH | 0.00100584 | ||||
Withdraw | 18797693 | 404 days ago | IN | 0 ETH | 0.0011767 | ||||
Premint | 18243911 | 481 days ago | IN | 0 ETH | 0.0448133 | ||||
Deactivate | 18243674 | 481 days ago | IN | 0 ETH | 0.00041221 | ||||
Purchase | 18243612 | 481 days ago | IN | 0.25069 ETH | 0.00114336 | ||||
Purchase | 18243537 | 481 days ago | IN | 0.25069 ETH | 0.00105265 | ||||
Purchase | 18243458 | 481 days ago | IN | 0.25069 ETH | 0.00148239 | ||||
Purchase | 18243440 | 481 days ago | IN | 0.25069 ETH | 0.00156197 | ||||
Purchase | 18243344 | 481 days ago | IN | 0.25069 ETH | 0.00129814 | ||||
Purchase | 18243249 | 481 days ago | IN | 0.25069 ETH | 0.00158674 | ||||
Purchase | 18243209 | 481 days ago | IN | 0.25069 ETH | 0.0018239 | ||||
Purchase | 18243174 | 481 days ago | IN | 0.25069 ETH | 0.00164559 | ||||
Purchase | 18243019 | 481 days ago | IN | 0.25069 ETH | 0.00163265 | ||||
Purchase | 18242986 | 481 days ago | IN | 0.25069 ETH | 0.00151882 | ||||
Purchase | 18242871 | 482 days ago | IN | 0.25069 ETH | 0.00223282 | ||||
Purchase | 18242678 | 482 days ago | IN | 0.25069 ETH | 0.00192648 | ||||
Purchase | 18242644 | 482 days ago | IN | 0.25069 ETH | 0.00199306 | ||||
Purchase | 18242543 | 482 days ago | IN | 0.25069 ETH | 0.00253955 | ||||
Purchase | 18242424 | 482 days ago | IN | 0.25069 ETH | 0.00240856 | ||||
Activate | 18242054 | 482 days ago | IN | 0 ETH | 0.00105345 | ||||
Update Initializ... | 18242041 | 482 days ago | IN | 0 ETH | 0.00108076 | ||||
Premint | 18242036 | 482 days ago | IN | 0 ETH | 0.0976286 | ||||
Deactivate | 18238856 | 482 days ago | IN | 0 ETH | 0.00028892 | ||||
Purchase | 18238854 | 482 days ago | IN | 0.08069 ETH | 0.00087598 | ||||
Purchase | 18238854 | 482 days ago | IN | 0.08069 ETH | 0.00087611 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
18797693 | 404 days ago | 5.96436 ETH | ||||
18243612 | 481 days ago | 0.25 ETH | ||||
18243537 | 481 days ago | 0.25 ETH | ||||
18243458 | 481 days ago | 0.25 ETH | ||||
18243440 | 481 days ago | 0.25 ETH | ||||
18243344 | 481 days ago | 0.25 ETH | ||||
18243249 | 481 days ago | 0.25 ETH | ||||
18243209 | 481 days ago | 0.25 ETH | ||||
18243174 | 481 days ago | 0.25 ETH | ||||
18243019 | 481 days ago | 0.25 ETH | ||||
18242986 | 481 days ago | 0.25 ETH | ||||
18242871 | 482 days ago | 0.25 ETH | ||||
18242678 | 482 days ago | 0.25 ETH | ||||
18242644 | 482 days ago | 0.25 ETH | ||||
18242543 | 482 days ago | 0.25 ETH | ||||
18242424 | 482 days ago | 0.25 ETH | ||||
18238854 | 482 days ago | 0.08 ETH | ||||
18238854 | 482 days ago | 0.08 ETH | ||||
18238854 | 482 days ago | 0.08 ETH | ||||
18238853 | 482 days ago | 0.08 ETH | ||||
18238852 | 482 days ago | 0.8 ETH | ||||
18238847 | 482 days ago | 0.08 ETH | ||||
18238847 | 482 days ago | 0.32 ETH | ||||
18238846 | 482 days ago | 2.8 ETH | ||||
18238843 | 482 days ago | 0.08 ETH |
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
Contract Source Code (Solidity Standard Json-Input format)
// 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; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IERC721CreatorCoreVersion { function VERSION() external view returns(uint256); }
// 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); } }
// 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: MIT 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)); } }
// 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; } }
// 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; }
// 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); }
// 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); }
// 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); }
// 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); }
// 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); }
// 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)); } }
// 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); }
// 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); } }
// 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; } }
// 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; } }
// 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; } }
// 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); }
{ "optimizer": { "enabled": true, "runs": 1000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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"}]
Contract Creation Code
60806040523480156200001157600080fd5b506200001d3362000023565b62000073565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6155d980620000836000396000f3fe6080604052600436106101cd5760003560e01c80637ab39392116100f7578063d7bf81a311610095578063f1218c1b11610064578063f1218c1b1461059d578063f2fde38b146105bd578063f3fef3a3146105dd578063f97eb3ef146105fd57600080fd5b8063d7bf81a314610507578063dd0a5cf014610530578063e9dc637514610550578063f0b567871461057d57600080fd5b8063a0d742f9116100d1578063a0d742f914610456578063a7e111ac14610476578063c2e5d36e14610496578063cf2ccf97146104b657600080fd5b80637ab39392146104055780638da5cb5b1461042557806391c734f41461044357600080fd5b80632e5f6fd81161016f5780635e6a6f8a1161013e5780635e6a6f8a14610390578063654fb5bd146103b05780636d73e669146103d0578063715018a6146103f057600080fd5b80632e5f6fd8146102e357806331ae450b146103035780633a075a891461032557806350d108391461035857600080fd5b806324d7806c116101ab57806324d7806c1461025657806325e21f671461027657806327686a86146102a35780632d345670146102c357600080fd5b806301ffc9a7146101d257806304853ef7146102075780631b95a22714610234575b600080fd5b3480156101de57600080fd5b506101f26101ed3660046148ce565b610610565b60405190151581526020015b60405180910390f35b34801561021357600080fd5b5061022761022236600461490d565b6106fc565b6040516101fe9190614939565b34801561024057600080fd5b5061025461024f366004614a71565b6108b1565b005b34801561026257600080fd5b506101f2610271366004614aaa565b610a98565b34801561028257600080fd5b5061029661029136600461490d565b610ad1565b6040516101fe9190614b17565b3480156102af57600080fd5b506102546102be366004614c96565b610d2e565b3480156102cf57600080fd5b506102546102de366004614aaa565b610e86565b3480156102ef57600080fd5b506102546102fe366004614cd8565b610ee4565b34801561030f57600080fd5b50610318611048565b6040516101fe9190614d64565b34801561033157600080fd5b5061034561034036600461490d565b6110f7565b60405161ffff90911681526020016101fe565b34801561036457600080fd5b50600354610378906001600160a01b031681565b6040516001600160a01b0390911681526020016101fe565b34801561039c57600080fd5b506101f26103ab366004614db1565b611132565b3480156103bc57600080fd5b506102546103cb366004614e44565b611294565b3480156103dc57600080fd5b506102546103eb366004614aaa565b61137d565b3480156103fc57600080fd5b506102546113d5565b34801561041157600080fd5b50610254610420366004614aaa565b6113e9565b34801561043157600080fd5b506000546001600160a01b0316610378565b610254610451366004614eb7565b611491565b34801561046257600080fd5b50610254610471366004614f3a565b6118fb565b34801561048257600080fd5b50610254610491366004614f85565b611ae6565b3480156104a257600080fd5b506102546104b1366004614fc3565b611c7b565b3480156104c257600080fd5b506101f26104d1366004614ffa565b6001600160a01b0383166000908152600460209081526040808320858452825280832084845290915290205460ff169392505050565b34801561051357600080fd5b506105226602738d24e5200081565b6040519081526020016101fe565b34801561053c57600080fd5b5061025461054b36600461502f565b611d73565b34801561055c57600080fd5b5061057061056b36600461490d565b611e9d565b6040516101fe919061506d565b34801561058957600080fd5b50610254610598366004615080565b612486565b3480156105a957600080fd5b506102546105b836600461490d565b61295b565b3480156105c957600080fd5b506102546105d8366004614aaa565b612abc565b3480156105e957600080fd5b506102546105f836600461490d565b612b49565b61025461060b366004614eb7565b612c77565b60006001600160e01b031982167f02c4b69e00000000000000000000000000000000000000000000000000000000148061067357506001600160e01b031982167fe9dc637500000000000000000000000000000000000000000000000000000000145b806106a757506001600160e01b031982167f45ffcdad00000000000000000000000000000000000000000000000000000000145b806106db57506001600160e01b031982167f553e757e00000000000000000000000000000000000000000000000000000000145b806106f657506001600160e01b031982166301ffc9a760e01b145b92915050565b6040805161022081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e0810182905261020081018290529061078f8484612d45565b6040805161022081018252825460ff8082161515835261010080830482161515602085015262010000830490911615159383019390935261ffff640100000000820481166060840152660100000000000080830482166080850152600160401b8304821660a0850152600160501b8304821660c0850152600160601b830490911660e084015265ffffffffffff600160701b8304811694840194909452600160a01b82048416610120840152600160d01b909104831661014083015260018401548084166101608401520490911661018082015260028201546101a082015260038201546101c08201529091506101e0810161088b86866110f7565b61ffff1681526005909201546001600160a01b0316602090920191909152905092915050565b604051630935e01b60e21b8152336004820152829081906001600160a01b038216906324d7806c90602401602060405180830381865afa1580156108f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091d91906150bc565b6109825760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b60648201526084015b60405180910390fd5b6109ac847fb5d2729f00000000000000000000000000000000000000000000000000000000612dc9565b610a1e5760405162461bcd60e51b815260206004820152602960248201527f63726561746f72206d75737420696d706c656d656e742049455243373231437260448201527f6561746f72436f726500000000000000000000000000000000000000000000006064820152608401610979565b6040517fac0c8cfa00000000000000000000000000000000000000000000000000000000815283151560048201526001600160a01b0385169063ac0c8cfa90602401600060405180830381600087803b158015610a7a57600080fd5b505af1158015610a8e573d6000803e3d6000fd5b5050505050505050565b6000816001600160a01b0316610ab66000546001600160a01b031690565b6001600160a01b031614806106f657506106f6600183612dec565b60408051610240810182526000808252602080830182905282840182905260608084018390526080840183905260a0840183905260c0840183905260e08401839052610100840183905261012084018390526101408401839052610160840183905261018084018390526101a084018390526101c084018390526101e0840183905261020084015261022083018290526001600160a01b0386168252600681528382208583529052919091206040805161024081018252825460ff8082161515835261010080830482161515602085015262010000830482161515948401949094526301000000820416606083015261ffff6401000000008204811660808401526601000000000000808304821660a0850152600160401b8304821660c0850152600160501b8304821660e0850152600160601b83049091169383019390935265ffffffffffff600160701b82048116610120840152600160a01b82048116610140840152600160d01b90910481166101608301526001840154808216610180840152929092049091166101a082015260028201546101c082015260038201546101e082015260048201805491929161020084019190610c90906150d9565b80601f0160208091040260200160405190810160405280929190818152602001828054610cbc906150d9565b8015610d095780601f10610cde57610100808354040283529160200191610d09565b820191906000526020600020905b815481529060010190602001808311610cec57829003601f168201915b5050509183525050600591909101546001600160a01b03166020909101529392505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015610d76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9a91906150bc565b610dfa5760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000610e068686612d45565b90506001600160a01b038416610e5e5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207061796d656e7420616464726573730000000000000000006044820152606401610979565b60050180546001600160a01b0319166001600160a01b03949094169390931790925550505050565b610e8e612e0e565b610e99600182612dec565b15610ee15760405133906001600160a01b038316907f7c0c3c84c67c85fcac635147348bfe374c24a1a93d0366d1cfe9d8853cbf89d590600090a3610edf600182612e68565b505b50565b604051630935e01b60e21b8152336004820152849081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015610f2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5091906150bc565b610fb05760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000610fbc8787612d45565b805490915060ff16156110025760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792061637469766560901b6044820152606401610979565b60005b84811015610a8e57611040888888888581811061102457611024615113565b90506020020160208101906110399190614aaa565b6001612e7d565b600101611005565b60606110546001613582565b67ffffffffffffffff81111561106c5761106c615129565b604051908082528060200260200182016040528015611095578160200160208202803683370190505b50905060005b6110a56001613582565b8110156110f3576110b760018261358c565b8282815181106110c9576110c9615113565b6001600160a01b0390921660209283029190910190910152806110eb81615155565b91505061109b565b5090565b6000806111048484612d45565b805490915061112a9061ffff600160601b8204811691660100000000000090041661516e565b949350505050565b60006001600160a01b03841661114a5750600161112a565b33600090815260076020908152604080832085845282528083208151808301909252546001600160e01b038116808352600160e01b90910463ffffffff1692820192909252919081036112635760405163b4b5b48f60e01b815260048101859052600090339063b4b5b48f90602401602060405180830381865afa1580156111d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fa9190615189565b66ffffffffffffff601882901c1692509050600082900361125d5760405162461bcd60e51b815260206004820152600f60248201527f546f6b656e206e6f7420666f756e6400000000000000000000000000000000006044820152606401610979565b50611270565b5080516001600160e01b03165b600061127c3383612d45565b5462010000900460ff16159350505050949350505050565b604051630935e01b60e21b8152336004820152849081906001600160a01b038216906324d7806c90602401602060405180830381865afa1580156112dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130091906150bc565b6113605760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b600061136c8787612d45565b905060048101610a8e8587836151fb565b611385612e0e565b611390600182612dec565b610ee15760405133906001600160a01b038316907f7e1a1a08d52e4ba0e21554733d66165fd5151f99460116223d9e3a608eec5cb190600090a3610edf600182613598565b6113dd612e0e565b6113e760006135ad565b565b336113fc6000546001600160a01b031690565b6001600160a01b031614806114175750611417600133612dec565b61146f5760405162461bcd60e51b8152602060048201526024808201527f41646d696e436f6e74726f6c3a204d757374206265206f776e6572206f7220616044820152633236b4b760e11b6064820152608401610979565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600061149d8888612d45565b90506114a988886135fd565b60006114b589896136a8565b905060006114c38a8a6110f7565b61ffff168861ffff161115801561151a57508180156114e857508254610100900460ff165b806114fe57508254640100000000900461ffff16155b8061151a5750825461ffff640100000000909104811690891611155b61155b5760405162461bcd60e51b8152602060048201526012602482015271151bdbc81b585b9e481c995c5d595cdd195960721b6044820152606401610979565b8115611770578254610100900460ff166116dd578254600160501b900461ffff1615611626576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091529020548354600160501b900461ffff16811080156115e3575083546115db908290600160501b900461ffff166152bb565b8961ffff1611155b6116245760405162461bcd60e51b8152602060048201526012602482015271151bdbc81b585b9e481c995c5d595cdd195960721b6044820152606401610979565b505b8254600160401b900461ffff16156116dd576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091529020548354600160401b900461ffff168110801561169a57508354611692908290600160401b900461ffff166152bb565b8961ffff1611155b6116db5760405162461bcd60e51b8152602060048201526012602482015271151bdbc81b585b9e481c995c5d595cdd195960721b6044820152606401610979565b505b6116e78884613701565b8354909150610100900460ff1615801561172157508254600160501b900461ffff1615158061172157508254600160401b900461ffff1615155b1561176b576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091528120805461ffff8b1692906117659084906152ce565b90915550505b61188b565b8254600160401b900461ffff1615611827576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091529020548354600160401b900461ffff16811080156117e4575083546117dc908290600160401b900461ffff166152bb565b8961ffff1611155b6118255760405162461bcd60e51b8152602060048201526012602482015271151bdbc81b585b9e481c995c5d595cdd195960721b6044820152606401610979565b505b611831888461378c565b8354909150600160401b900461ffff161561188b576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091528120805461ffff8b1692906118859084906152ce565b90915550505b81801561189e57508254610100900460ff165b156118b7576118b28a8a898989898e6137a3565b6118c5565b6118c58a8a89898989613a04565b80156118e35760058301546118e3906001600160a01b031682613c36565b6118ef8a8a338b612e7d565b50505050505050505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015611943573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061196791906150bc565b6119c75760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b60006119d38686612d45565b805490915060ff1615611a195760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792061637469766560901b6044820152606401610979565b60a08401356002820155611a3360808501606086016152e1565b815461ffff91909116600160401b0269ffff000000000000000019909116178155611a6460408501602086016152e1565b815461ffff919091166401000000000265ffff000000001990911617815560c08401356003820155611a9c60a08501608086016152e1565b815461ffff91909116600160501b026bffff0000000000000000000019909116178155611acc60208501856152fc565b81549015156101000261ff00199091161790555050505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015611b2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b5291906150bc565b611bb25760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000856001600160a01b031663ffa1ad746040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611c0e575060408051601f3d908101601f19168201909252611c0b91810190615319565b60015b15611c675760ff811115611c645760405162461bcd60e51b815260206004820152601c60248201527f556e737570706f7274656420636f6e74726163742076657273696f6e000000006044820152606401610979565b90505b611c7386828787613cd9565b505050505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015611cc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ce791906150bc565b611d475760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000611d538686612d45565b8054941515620100000262ff000019909516949094179093555050505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015611dbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ddf91906150bc565b611e3f5760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000611e4b8686612d45565b805490915060ff1615611e915760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792061637469766560901b6044820152606401610979565b611c7386863387612e7d565b6001600160a01b038216600090815260076020908152604080832084845282528083208151808301835290546001600160e01b0381168252600160e01b900463ffffffff168184015281516102408101835284815292830184905290820183905260608083018490526080830184905260a0830184905260c0830184905260e08301849052610100830184905261012083018490526101408301849052610160830184905261018083018490526101a083018490526101c083018490526101e083018490526102008301819052610220830184905292909182516001600160e01b03166000036122255760405163b4b5b48f60e01b8152600481018690526000906001600160a01b0388169063b4b5b48f90602401602060405180830381865afa158015611fcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ff39190615189565b905066ffffffffffffff601882901c1660008190036120545760405162461bcd60e51b815260206004820152600f60248201527f546f6b656e206e6f7420666f756e6400000000000000000000000000000000006044820152606401610979565b612067888266ffffffffffffff16612d45565b6040805161024081018252825460ff8082161515835261010080830482161515602085015262010000830482161515948401949094526301000000820416606083015261ffff6401000000008204811660808401526601000000000000808304821660a0850152600160401b8304821660c0850152600160501b8304821660e0850152600160601b83049091169383019390935265ffffffffffff600160701b82048116610120840152600160a01b82048116610140840152600160d01b90910481166101608301526001840154808216610180840152929092049091166101a082015260028201546101c082015260038201546101e08201526004820180549192916102008401919061217a906150d9565b80601f01602080910402602001604051908101604052809291908181526020018280546121a6906150d9565b80156121f35780601f106121c8576101008083540402835291602001916121f3565b820191906000526020600020905b8154815290600101906020018083116121d657829003601f168201915b5050509183525050600591909101546001600160a01b031660209091015262ffffff9290921693509091506123f69050565b826020015163ffffffff1691506122498684600001516001600160e01b0316612d45565b6040805161024081018252825460ff8082161515835261010080830482161515602085015262010000830482161515948401949094526301000000820416606083015261ffff6401000000008204811660808401526601000000000000808304821660a0850152600160401b8304821660c0850152600160501b8304821660e0850152600160601b83049091169383019390935265ffffffffffff600160701b82048116610120840152600160a01b82048116610140840152600160d01b90910481166101608301526001840154808216610180840152929092049091166101a082015260028201546101c082015260038201546101e08201526004820180549192916102008401919061235c906150d9565b80601f0160208091040260200160405190810160405280929190818152602001828054612388906150d9565b80156123d55780601f106123aa576101008083540402835291602001916123d5565b820191906000526020600020905b8154815290600101906020018083116123b857829003601f168201915b5050509183525050600591909101546001600160a01b031660209091015290505b8061020001515160000361244c5760405162461bcd60e51b815260206004820152601660248201527f4e6f2062617365207572692070726566697820736574000000000000000000006044820152606401610979565b80610200015161245b836140c2565b60405160200161246c929190615332565b604051602081830303815290604052935050505092915050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa1580156124ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f291906150bc565b6125525760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b600061255e8686612d45565b805490915060ff16156125a45760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792061637469766560901b6044820152606401610979565b426125b26020860186615361565b65ffffffffffff16116126075760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f7420616374697661746520696e20746865207061737400000000006044820152606401610979565b6126176040850160208601615361565b65ffffffffffff1661262f6060860160408701615361565b65ffffffffffff1611156126ab5760405162461bcd60e51b815260206004820152602f60248201527f50726573616c6520496e74657276616c2063616e6e6f74206265206c6f6e676560448201527f72207468616e207468652073616c6500000000000000000000000000000000006064820152608401610979565b6126bb60a0850160808601615361565b65ffffffffffff166126d36080860160608701615361565b65ffffffffffff161115801561271457506126f16020850185615361565b65ffffffffffff1661270960a0860160808701615361565b65ffffffffffff1611155b6127605760405162461bcd60e51b815260206004820152601360248201527f496e76616c696420636c61696d2074696d6573000000000000000000000000006044820152606401610979565b61276d6020850185615361565b815465ffffffffffff91909116600160701b027fffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffff9091161781556127b76040850160208601615361565b6127c46020860186615361565b6127ce9190615389565b815465ffffffffffff91909116600160a01b027fffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffff9091161781556128186060850160408601615361565b815465ffffffffffff91909116600160d01b0279ffffffffffffffffffffffffffffffffffffffffffffffffffff90911617815561285c6080850160608601615361565b60018201805465ffffffffffff191665ffffffffffff9290921691909117905561288c60a0850160808601615361565b600182810180546bffffffffffff000000000000198116660100000000000065ffffffffffff958616810291821793849055865460ff1916909417808755604080516001600160a01b038e168152602081018d9052600160701b8304881691810191909152600160a01b820487166060820152600160d01b909104861660808201529185169085161760a082015291900490911660c08201527fda897ec003b83d996662d95c264c767d3c58171ae697ebb551a313b425551d289060e0015b60405180910390a1505050505050565b604051630935e01b60e21b8152336004820152829081906001600160a01b038216906324d7806c90602401602060405180830381865afa1580156129a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c791906150bc565b612a275760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000612a338585612d45565b80547fffffffffffff000000000000000000000000ffffffffffffffffffffffffff001681556001810180546bffffffffffffffffffffffff19169055604080516001600160a01b0388168152602081018790529192507f54cbaf4a244605e6477ea43f8e1388ace54d61f7f5110cad2268ddc39da2bbac910160405180910390a15050505050565b612ac4612e0e565b6001600160a01b038116612b405760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610979565b610ee1816135ad565b33612b5c6000546001600160a01b031690565b6001600160a01b03161480612b775750612b77600133612dec565b612bcf5760405162461bcd60e51b8152602060048201526024808201527f41646d696e436f6e74726f6c3a204d757374206265206f776e6572206f7220616044820152633236b4b760e11b6064820152608401610979565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612c1c576040519150601f19603f3d011682016040523d82523d6000602084013e612c21565b606091505b5050905080612c725760405162461bcd60e51b815260206004820152601e60248201527f4661696c656420746f207472616e7366657220746f20726563656976657200006044820152606401610979565b505050565b612c8187876141f7565b612c908787868686868b6142c0565b6001600160a01b038716600090815260086020908152604080832089845282528083203384529091528120805461ffff88169290612ccf9084906152ce565b90915550612ce2905061ffff86166142cf565b3414612d305760405162461bcd60e51b815260206004820152601760248201527f496e76616c696420707572636861736520616d6f756e740000000000000000006044820152606401610979565b612d3c87873388612e7d565b50505050505050565b6001600160a01b0382166000908152600660209081526040808320848452909152812080549091660100000000000090910461ffff1690036106f65760405162461bcd60e51b815260206004820152601b60248201527f436f6c6c65637469626c65206e6f7420696e697469616c697a656400000000006044820152606401610979565b6000612dd4836142fc565b8015612de55750612de5838361432f565b9392505050565b6001600160a01b03811660009081526001830160205260408120541515612de5565b6000546001600160a01b031633146113e75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610979565b6000612de5836001600160a01b0384166143b8565b6000612e898585612d45565b90508161ffff166001036131155780546000906003630100000090910460ff1610612f8e5781546000908390600c90612ecc90600160601b900461ffff166153a8565b825461ffff9182166101009390930a83810292021916179091556040517fd39737190000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015266ffffffff00000060188a901b169092176024820181905292509088169063d3973719906044016020604051808303816000875af1158015612f62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f869190615319565b9150506130b2565b81548290600c90612fa990600160601b900461ffff166153a8565b825461ffff9182166101009390930a92830291909202199091161790556040517f2928ca580000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152871690632928ca58906024016020604051808303816000875af1158015613027573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061304b9190615319565b6040805180820182526001600160e01b038089168252855461ffff600160601b9091041660208084019182526001600160a01b038c16600090815260078252858120878252909152939093209151925163ffffffff16600160e01b02921691909117905590505b8154604080516001600160a01b038916815260208101889052600160601b90920461ffff1690820152606081018290527f604f4158d0efdc4ccca2c0fe366be334aab90f8081a92e8a53e4fb849d1a08979060800160405180910390a15061357b565b805460009061313090600160601b900461ffff1660016153c9565b825461ffff918216925084918491600c91613155918591600160601b909104166153c9565b92506101000a81548161ffff021916908361ffff16021790555060038260000160039054906101000a900460ff1660ff161061338c5760008361ffff1667ffffffffffffffff8111156131aa576131aa615129565b6040519080825280602002602001820160405280156131d3578160200160208202803683370190505b50905060005b8461ffff16811015613247576131f58163ffffffff85166152ce565b62ffffff1660188866ffffffffffffff16901b1766ffffffffffffff1682828151811061322457613224615113565b69ffffffffffffffffffff909216602092830291909101909101526001016131d9565b506040517f4278330e0000000000000000000000000000000000000000000000000000000081526000906001600160a01b03891690634278330e9061329290899086906004016153e4565b6000604051808303816000875af11580156132b1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526132d99190810190615447565b905060005b8561ffff168163ffffffff161015613384577f604f4158d0efdc4ccca2c0fe366be334aab90f8081a92e8a53e4fb849d1a0897898961331d8488615505565b858563ffffffff168151811061333557613335615113565b602002602001015160405161337494939291906001600160a01b03949094168452602084019290925263ffffffff166040830152606082015260800190565b60405180910390a16001016132de565b505050611c73565b6040517fe00aab4b0000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015261ffff851660248301526000919088169063e00aab4b906044016000604051808303816000875af11580156133fb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526134239190810190615447565b905060005b8461ffff168163ffffffff161015610a8e577f604f4158d0efdc4ccca2c0fe366be334aab90f8081a92e8a53e4fb849d1a089788886134678487615505565b858563ffffffff168151811061347f5761347f615113565b60200260200101516040516134be94939291906001600160a01b03949094168452602084019290925263ffffffff166040830152606082015260800190565b60405180910390a16040518060400160405280886001600160e01b0316815260200182856134ec9190615505565b63ffffffff16815250600760008a6001600160a01b03166001600160a01b031681526020019081526020016000206000848463ffffffff168151811061353457613534615113565b6020908102919091018101518252818101929092526040016000208251929091015163ffffffff16600160e01b026001600160e01b03909216919091179055600101613428565b5050505050565b60006106f6825490565b6000612de583836144b2565b6000612de5836001600160a01b0384166144dc565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006136098383612d45565b805490915060ff166136485760405162461bcd60e51b8152602060048201526008602482015267496e61637469766560c01b6044820152606401610979565b8054600160701b900465ffffffffffff16421015612c725760405162461bcd60e51b815260206004820152601560248201527f50757263686173696e67206e6f742061637469766500000000000000000000006044820152606401610979565b6000806136b58484612d45565b8054909150600160701b900465ffffffffffff164211801561112a5750805465ffffffffffff600160d01b82048116916136f891600160701b90910416426152bb565b10949350505050565b60008082600301548461ffff166137189190615522565b905060006137298561ffff166142cf565b61373390836152ce565b90508034146137845760405162461bcd60e51b815260206004820152601c60248201527f496e76616c696420707572636861736520616d6f756e742073656e74000000006044820152606401610979565b509392505050565b60008082600201548461ffff166137189190615522565b6001600160a01b0387166000908152600460209081526040808320898452825280832085845290915290205460ff161561381f5760405162461bcd60e51b815260206004820152601960248201527f43616e6e6f74207265706c6179207472616e73616374696f6e000000000000006044820152606401610979565b6040517f19457468657265756d205369676e6564204d6573736167653a0a35340000000060208201526bffffffffffffffffffffffff193360601b16603c820152605081018390527fffff00000000000000000000000000000000000000000000000000000000000060f083901b1660708201526000906072016040516020818303038152906040528051906020012090508086146139005760405162461bcd60e51b815260206004820152601160248201527f4d616c666f726d6564206d6573736167650000000000000000000000000000006044820152606401610979565b600061394486868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b9392505061452b9050565b6001600160a01b03808b1660009081526005602090815260408083208d845290915290205491925090811690821681146139c05760405162461bcd60e51b815260206004820152601160248201527f496e76616c6964207369676e61747572650000000000000000000000000000006044820152606401610979565b5050506001600160a01b0390961660009081526004602090815260408083209783529681528682209282529190915293909320805460ff1916600117905550505050565b6001600160a01b0386166000908152600460209081526040808320888452825280832084845290915290205460ff1615613a805760405162461bcd60e51b815260206004820152601960248201527f43616e6e6f74207265706c6179207472616e73616374696f6e000000000000006044820152606401610979565b6040517f19457468657265756d205369676e6564204d6573736167653a0a35320000000060208201526bffffffffffffffffffffffff193360601b16603c82015260508101829052600090607001604051602081830303815290604052805190602001209050808514613b355760405162461bcd60e51b815260206004820152601160248201527f4d616c666f726d6564206d6573736167650000000000000000000000000000006044820152606401610979565b6000613b7985858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a9392505061452b9050565b6001600160a01b03808a1660009081526005602090815260408083208c84529091529020549192509081169082168114613bf55760405162461bcd60e51b815260206004820152601160248201527f496e76616c6964207369676e61747572650000000000000000000000000000006044820152606401610979565b5050506001600160a01b039095166000908152600460209081526040808320968352958152858220968252959095525050509020805460ff19166001179055565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613c83576040519150601f19603f3d011682016040523d82523d6000602084013e613c88565b606091505b5050905080612c725760405162461bcd60e51b815260206004820152601f60248201527f4661696c656420746f207472616e7366657220746f20726563697069656e74006044820152606401610979565b600082118015613cf0575066ffffffffffffff8211155b613d3c5760405162461bcd60e51b815260206004820152601260248201527f496e76616c696420696e7374616e6365496400000000000000000000000000006044820152606401610979565b6001600160a01b0380851660008181526005602090815260408083208784528252808320549383526006825280832087845290915290209116908115613dc45760405162461bcd60e51b815260206004820152601f60248201527f436f6c6c65637469626c6520616c726561647920696e697469616c697a6564006044820152606401610979565b6000613dd7610100850160e08601614aaa565b6001600160a01b031603613e2d5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207369676e696e6720616464726573730000000000000000006044820152606401610979565b6000613e4161012085016101008601614aaa565b6001600160a01b031603613e975760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207061796d656e7420616464726573730000000000000000006044820152606401610979565b613ea760608401604085016152e1565b61ffff16600003613efa5760405162461bcd60e51b815260206004820152601460248201527f496e76616c6964207075726368617365206d61780000000000000000000000006044820152606401610979565b613f0b610100840160e08501614aaa565b6001600160a01b0387811660009081526005602090815260408083208984529091529081902080546001600160a01b03191693909216929092179055815463ff0000001916630100000060ff881602178255613f6d90606085019085016152e1565b815461ffff9190911666010000000000000267ffff0000000000001990911617815560a08301356002820155613fa960808401606085016152e1565b815461ffff91909116600160401b0269ffff000000000000000019909116178155613fda60408401602085016152e1565b815461ffff919091166401000000000265ffff000000001990911617815560c0830135600382015561401260a08401608085016152e1565b815461ffff91909116600160501b026bffff000000000000000000001990911617815561404260208401846152fc565b815461ff0019166101009115158202178255614065906101208501908501614aaa565b6005820180546001600160a01b0319166001600160a01b039283161790556040805191881682526020820186905233908201527f61da64dacf5829e3b4534db2a9f2ed9214b5c682bc1499c4742ac98f6e4179bd9060600161294b565b60608160000361410557505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561412f578061411981615155565b91506141289050600a8361554f565b9150614109565b60008167ffffffffffffffff81111561414a5761414a615129565b6040519080825280601f01601f191660200182016040528015614174576020820181803683370190505b5090505b841561112a576141896001836152bb565b9150614196600a86615563565b6141a19060306152ce565b60f81b8183815181106141b6576141b6615113565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506141f0600a8661554f565b9450614178565b60006142038383612d45565b805490915060ff166142425760405162461bcd60e51b8152602060048201526008602482015267496e61637469766560c01b6044820152606401610979565b600181015465ffffffffffff164210801590614274575060018101546601000000000000900465ffffffffffff164211155b612c725760405162461bcd60e51b815260206004820152601560248201527f4f75747369646520636c61696d20706572696f642e00000000000000000000006044820152606401610979565b612d3c878787878787876137a3565b60006142da33614547565b6142f4576142ef826602738d24e52000615522565b6106f6565b600092915050565b600061430f826301ffc9a760e01b61432f565b80156106f65750614328826001600160e01b031961432f565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d915060005190508280156143a1575060208210155b80156143ad5750600081115b979650505050505050565b600081815260018301602052604081205480156144a15760006143dc6001836152bb565b85549091506000906143f0906001906152bb565b905081811461445557600086600001828154811061441057614410615113565b906000526020600020015490508087600001848154811061443357614433615113565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061446657614466615577565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106f6565b60009150506106f6565b5092915050565b60008260000182815481106144c9576144c9615113565b9060005260206000200154905092915050565b6000818152600183016020526040812054614523575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106f6565b5060006106f6565b600080600061453a85856145e6565b915091506137848161462b565b6003546000906001600160a01b0316158015906106f657506003546040517f45ecd02f0000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152909116906345ecd02f90602401602060405180830381865afa1580156145c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f691906150bc565b600080825160410361461c5760208301516040840151606085015160001a614610878285856147e1565b94509450505050614624565b506000905060025b9250929050565b600081600481111561463f5761463f61558d565b036146475750565b600181600481111561465b5761465b61558d565b036146a85760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610979565b60028160048111156146bc576146bc61558d565b036147095760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610979565b600381600481111561471d5761471d61558d565b036147755760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610979565b60048160048111156147895761478961558d565b03610ee15760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610979565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561481857506000905060036148c5565b8460ff16601b1415801561483057508460ff16601c14155b1561484157506000905060046148c5565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015614895573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166148be576000600192509250506148c5565b9150600090505b94509492505050565b6000602082840312156148e057600080fd5b81356001600160e01b031981168114612de557600080fd5b6001600160a01b0381168114610ee157600080fd5b6000806040838503121561492057600080fd5b823561492b816148f8565b946020939093013593505050565b81511515815261022081016020830151614957602084018215159052565b50604083015161496b604084018215159052565b506060830151614981606084018261ffff169052565b506080830151614997608084018261ffff169052565b5060a08301516149ad60a084018261ffff169052565b5060c08301516149c360c084018261ffff169052565b5060e08301516149d960e084018261ffff169052565b506101008381015165ffffffffffff9081169184019190915261012080850151821690840152610140808501518216908401526101608085015182169084015261018080850151909116908301526101a080840151908301526101c080840151908301526101e08084015190830152610200928301516001600160a01b0316929091019190915290565b8015158114610ee157600080fd5b60008060408385031215614a8457600080fd5b8235614a8f816148f8565b91506020830135614a9f81614a63565b809150509250929050565b600060208284031215614abc57600080fd5b8135612de5816148f8565b60005b83811015614ae2578181015183820152602001614aca565b50506000910152565b60008151808452614b03816020860160208601614ac7565b601f01601f19169290920160200192915050565b60208152614b2a60208201835115159052565b60006020830151614b3f604084018215159052565b506040830151801515606084015250606083015160ff8116608084015250608083015161ffff811660a08401525060a083015161ffff811660c08401525060c083015161ffff811660e08401525060e0830151610100614ba48185018361ffff169052565b8401519050610120614bbb8482018361ffff169052565b8401519050610140614bd68482018365ffffffffffff169052565b8401519050610160614bf18482018365ffffffffffff169052565b8401519050610180614c0c8482018365ffffffffffff169052565b84015190506101a0614c278482018365ffffffffffff169052565b84015190506101c0614c428482018365ffffffffffff169052565b8401516101e0848101919091528401516102008085019190915284015161024061022080860182905291925090614c7d610260860184614aeb565b9501516001600160a01b03169301929092525090919050565b600080600060608486031215614cab57600080fd5b8335614cb6816148f8565b9250602084013591506040840135614ccd816148f8565b809150509250925092565b60008060008060608587031215614cee57600080fd5b8435614cf9816148f8565b935060208501359250604085013567ffffffffffffffff80821115614d1d57600080fd5b818701915087601f830112614d3157600080fd5b813581811115614d4057600080fd5b8860208260051b8501011115614d5557600080fd5b95989497505060200194505050565b6020808252825182820181905260009190848201906040850190845b81811015614da55783516001600160a01b031683529284019291840191600101614d80565b50909695505050505050565b60008060008060808587031215614dc757600080fd5b8435614dd2816148f8565b93506020850135614de2816148f8565b92506040850135614df2816148f8565b9396929550929360600135925050565b60008083601f840112614e1457600080fd5b50813567ffffffffffffffff811115614e2c57600080fd5b60208301915083602082850101111561462457600080fd5b60008060008060608587031215614e5a57600080fd5b8435614e65816148f8565b935060208501359250604085013567ffffffffffffffff811115614e8857600080fd5b614e9487828801614e02565b95989497509550505050565b803561ffff81168114614eb257600080fd5b919050565b600080600080600080600060c0888a031215614ed257600080fd5b8735614edd816148f8565b965060208801359550614ef260408901614ea0565b945060608801359350608088013567ffffffffffffffff811115614f1557600080fd5b614f218a828b01614e02565b989b979a5095989497959660a090950135949350505050565b6000806000838503610120811215614f5157600080fd5b8435614f5c816148f8565b93506020850135925060e0603f1982011215614f7757600080fd5b506040840190509250925092565b6000806000838503610160811215614f9c57600080fd5b8435614fa7816148f8565b935060208501359250610120603f1982011215614f7757600080fd5b600080600060608486031215614fd857600080fd5b8335614fe3816148f8565b9250602084013591506040840135614ccd81614a63565b60008060006060848603121561500f57600080fd5b833561501a816148f8565b95602085013595506040909401359392505050565b60008060006060848603121561504457600080fd5b833561504f816148f8565b92506020840135915061506460408501614ea0565b90509250925092565b602081526000612de56020830184614aeb565b600080600083850360e081121561509657600080fd5b84356150a1816148f8565b93506020850135925060a0603f1982011215614f7757600080fd5b6000602082840312156150ce57600080fd5b8151612de581614a63565b600181811c908216806150ed57607f821691505b60208210810361510d57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016151675761516761513f565b5060010190565b61ffff8281168282160390808211156144ab576144ab61513f565b60006020828403121561519b57600080fd5b815169ffffffffffffffffffff81168114612de557600080fd5b601f821115612c7257600081815260208120601f850160051c810160208610156151dc5750805b601f850160051c820191505b81811015611c73578281556001016151e8565b67ffffffffffffffff83111561521357615213615129565b6152278361522183546150d9565b836151b5565b6000601f84116001811461525b57600085156152435750838201355b600019600387901b1c1916600186901b17835561357b565b600083815260209020601f19861690835b8281101561528c578685013582556020948501946001909201910161526c565b50868210156152a95760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b818103818111156106f6576106f661513f565b808201808211156106f6576106f661513f565b6000602082840312156152f357600080fd5b612de582614ea0565b60006020828403121561530e57600080fd5b8135612de581614a63565b60006020828403121561532b57600080fd5b5051919050565b60008351615344818460208801614ac7565b835190830190615358818360208801614ac7565b01949350505050565b60006020828403121561537357600080fd5b813565ffffffffffff81168114612de557600080fd5b65ffffffffffff8181168382160190808211156144ab576144ab61513f565b600061ffff8083168181036153bf576153bf61513f565b6001019392505050565b61ffff8181168382160190808211156144ab576144ab61513f565b6000604082016001600160a01b03851683526020604081850152818551808452606086019150828701935060005b8181101561543a57845169ffffffffffffffffffff1683529383019391830191600101615412565b5090979650505050505050565b6000602080838503121561545a57600080fd5b825167ffffffffffffffff8082111561547257600080fd5b818501915085601f83011261548657600080fd5b81518181111561549857615498615129565b8060051b604051601f19603f830116810181811085821117156154bd576154bd615129565b6040529182528482019250838101850191888311156154db57600080fd5b938501935b828510156154f9578451845293850193928501926154e0565b98975050505050505050565b63ffffffff8181168382160190808211156144ab576144ab61513f565b80820281158282048414176106f6576106f661513f565b634e487b7160e01b600052601260045260246000fd5b60008261555e5761555e615539565b500490565b60008261557257615572615539565b500690565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212202e10d92b32ab5c1ebc21eafb3d8416099154aec39e767cbd37c7e6c373655afc64736f6c63430008110033
Deployed Bytecode
0x6080604052600436106101cd5760003560e01c80637ab39392116100f7578063d7bf81a311610095578063f1218c1b11610064578063f1218c1b1461059d578063f2fde38b146105bd578063f3fef3a3146105dd578063f97eb3ef146105fd57600080fd5b8063d7bf81a314610507578063dd0a5cf014610530578063e9dc637514610550578063f0b567871461057d57600080fd5b8063a0d742f9116100d1578063a0d742f914610456578063a7e111ac14610476578063c2e5d36e14610496578063cf2ccf97146104b657600080fd5b80637ab39392146104055780638da5cb5b1461042557806391c734f41461044357600080fd5b80632e5f6fd81161016f5780635e6a6f8a1161013e5780635e6a6f8a14610390578063654fb5bd146103b05780636d73e669146103d0578063715018a6146103f057600080fd5b80632e5f6fd8146102e357806331ae450b146103035780633a075a891461032557806350d108391461035857600080fd5b806324d7806c116101ab57806324d7806c1461025657806325e21f671461027657806327686a86146102a35780632d345670146102c357600080fd5b806301ffc9a7146101d257806304853ef7146102075780631b95a22714610234575b600080fd5b3480156101de57600080fd5b506101f26101ed3660046148ce565b610610565b60405190151581526020015b60405180910390f35b34801561021357600080fd5b5061022761022236600461490d565b6106fc565b6040516101fe9190614939565b34801561024057600080fd5b5061025461024f366004614a71565b6108b1565b005b34801561026257600080fd5b506101f2610271366004614aaa565b610a98565b34801561028257600080fd5b5061029661029136600461490d565b610ad1565b6040516101fe9190614b17565b3480156102af57600080fd5b506102546102be366004614c96565b610d2e565b3480156102cf57600080fd5b506102546102de366004614aaa565b610e86565b3480156102ef57600080fd5b506102546102fe366004614cd8565b610ee4565b34801561030f57600080fd5b50610318611048565b6040516101fe9190614d64565b34801561033157600080fd5b5061034561034036600461490d565b6110f7565b60405161ffff90911681526020016101fe565b34801561036457600080fd5b50600354610378906001600160a01b031681565b6040516001600160a01b0390911681526020016101fe565b34801561039c57600080fd5b506101f26103ab366004614db1565b611132565b3480156103bc57600080fd5b506102546103cb366004614e44565b611294565b3480156103dc57600080fd5b506102546103eb366004614aaa565b61137d565b3480156103fc57600080fd5b506102546113d5565b34801561041157600080fd5b50610254610420366004614aaa565b6113e9565b34801561043157600080fd5b506000546001600160a01b0316610378565b610254610451366004614eb7565b611491565b34801561046257600080fd5b50610254610471366004614f3a565b6118fb565b34801561048257600080fd5b50610254610491366004614f85565b611ae6565b3480156104a257600080fd5b506102546104b1366004614fc3565b611c7b565b3480156104c257600080fd5b506101f26104d1366004614ffa565b6001600160a01b0383166000908152600460209081526040808320858452825280832084845290915290205460ff169392505050565b34801561051357600080fd5b506105226602738d24e5200081565b6040519081526020016101fe565b34801561053c57600080fd5b5061025461054b36600461502f565b611d73565b34801561055c57600080fd5b5061057061056b36600461490d565b611e9d565b6040516101fe919061506d565b34801561058957600080fd5b50610254610598366004615080565b612486565b3480156105a957600080fd5b506102546105b836600461490d565b61295b565b3480156105c957600080fd5b506102546105d8366004614aaa565b612abc565b3480156105e957600080fd5b506102546105f836600461490d565b612b49565b61025461060b366004614eb7565b612c77565b60006001600160e01b031982167f02c4b69e00000000000000000000000000000000000000000000000000000000148061067357506001600160e01b031982167fe9dc637500000000000000000000000000000000000000000000000000000000145b806106a757506001600160e01b031982167f45ffcdad00000000000000000000000000000000000000000000000000000000145b806106db57506001600160e01b031982167f553e757e00000000000000000000000000000000000000000000000000000000145b806106f657506001600160e01b031982166301ffc9a760e01b145b92915050565b6040805161022081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e0810182905261020081018290529061078f8484612d45565b6040805161022081018252825460ff8082161515835261010080830482161515602085015262010000830490911615159383019390935261ffff640100000000820481166060840152660100000000000080830482166080850152600160401b8304821660a0850152600160501b8304821660c0850152600160601b830490911660e084015265ffffffffffff600160701b8304811694840194909452600160a01b82048416610120840152600160d01b909104831661014083015260018401548084166101608401520490911661018082015260028201546101a082015260038201546101c08201529091506101e0810161088b86866110f7565b61ffff1681526005909201546001600160a01b0316602090920191909152905092915050565b604051630935e01b60e21b8152336004820152829081906001600160a01b038216906324d7806c90602401602060405180830381865afa1580156108f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091d91906150bc565b6109825760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b60648201526084015b60405180910390fd5b6109ac847fb5d2729f00000000000000000000000000000000000000000000000000000000612dc9565b610a1e5760405162461bcd60e51b815260206004820152602960248201527f63726561746f72206d75737420696d706c656d656e742049455243373231437260448201527f6561746f72436f726500000000000000000000000000000000000000000000006064820152608401610979565b6040517fac0c8cfa00000000000000000000000000000000000000000000000000000000815283151560048201526001600160a01b0385169063ac0c8cfa90602401600060405180830381600087803b158015610a7a57600080fd5b505af1158015610a8e573d6000803e3d6000fd5b5050505050505050565b6000816001600160a01b0316610ab66000546001600160a01b031690565b6001600160a01b031614806106f657506106f6600183612dec565b60408051610240810182526000808252602080830182905282840182905260608084018390526080840183905260a0840183905260c0840183905260e08401839052610100840183905261012084018390526101408401839052610160840183905261018084018390526101a084018390526101c084018390526101e0840183905261020084015261022083018290526001600160a01b0386168252600681528382208583529052919091206040805161024081018252825460ff8082161515835261010080830482161515602085015262010000830482161515948401949094526301000000820416606083015261ffff6401000000008204811660808401526601000000000000808304821660a0850152600160401b8304821660c0850152600160501b8304821660e0850152600160601b83049091169383019390935265ffffffffffff600160701b82048116610120840152600160a01b82048116610140840152600160d01b90910481166101608301526001840154808216610180840152929092049091166101a082015260028201546101c082015260038201546101e082015260048201805491929161020084019190610c90906150d9565b80601f0160208091040260200160405190810160405280929190818152602001828054610cbc906150d9565b8015610d095780601f10610cde57610100808354040283529160200191610d09565b820191906000526020600020905b815481529060010190602001808311610cec57829003601f168201915b5050509183525050600591909101546001600160a01b03166020909101529392505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015610d76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9a91906150bc565b610dfa5760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000610e068686612d45565b90506001600160a01b038416610e5e5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207061796d656e7420616464726573730000000000000000006044820152606401610979565b60050180546001600160a01b0319166001600160a01b03949094169390931790925550505050565b610e8e612e0e565b610e99600182612dec565b15610ee15760405133906001600160a01b038316907f7c0c3c84c67c85fcac635147348bfe374c24a1a93d0366d1cfe9d8853cbf89d590600090a3610edf600182612e68565b505b50565b604051630935e01b60e21b8152336004820152849081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015610f2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5091906150bc565b610fb05760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000610fbc8787612d45565b805490915060ff16156110025760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792061637469766560901b6044820152606401610979565b60005b84811015610a8e57611040888888888581811061102457611024615113565b90506020020160208101906110399190614aaa565b6001612e7d565b600101611005565b60606110546001613582565b67ffffffffffffffff81111561106c5761106c615129565b604051908082528060200260200182016040528015611095578160200160208202803683370190505b50905060005b6110a56001613582565b8110156110f3576110b760018261358c565b8282815181106110c9576110c9615113565b6001600160a01b0390921660209283029190910190910152806110eb81615155565b91505061109b565b5090565b6000806111048484612d45565b805490915061112a9061ffff600160601b8204811691660100000000000090041661516e565b949350505050565b60006001600160a01b03841661114a5750600161112a565b33600090815260076020908152604080832085845282528083208151808301909252546001600160e01b038116808352600160e01b90910463ffffffff1692820192909252919081036112635760405163b4b5b48f60e01b815260048101859052600090339063b4b5b48f90602401602060405180830381865afa1580156111d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fa9190615189565b66ffffffffffffff601882901c1692509050600082900361125d5760405162461bcd60e51b815260206004820152600f60248201527f546f6b656e206e6f7420666f756e6400000000000000000000000000000000006044820152606401610979565b50611270565b5080516001600160e01b03165b600061127c3383612d45565b5462010000900460ff16159350505050949350505050565b604051630935e01b60e21b8152336004820152849081906001600160a01b038216906324d7806c90602401602060405180830381865afa1580156112dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130091906150bc565b6113605760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b600061136c8787612d45565b905060048101610a8e8587836151fb565b611385612e0e565b611390600182612dec565b610ee15760405133906001600160a01b038316907f7e1a1a08d52e4ba0e21554733d66165fd5151f99460116223d9e3a608eec5cb190600090a3610edf600182613598565b6113dd612e0e565b6113e760006135ad565b565b336113fc6000546001600160a01b031690565b6001600160a01b031614806114175750611417600133612dec565b61146f5760405162461bcd60e51b8152602060048201526024808201527f41646d696e436f6e74726f6c3a204d757374206265206f776e6572206f7220616044820152633236b4b760e11b6064820152608401610979565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600061149d8888612d45565b90506114a988886135fd565b60006114b589896136a8565b905060006114c38a8a6110f7565b61ffff168861ffff161115801561151a57508180156114e857508254610100900460ff165b806114fe57508254640100000000900461ffff16155b8061151a5750825461ffff640100000000909104811690891611155b61155b5760405162461bcd60e51b8152602060048201526012602482015271151bdbc81b585b9e481c995c5d595cdd195960721b6044820152606401610979565b8115611770578254610100900460ff166116dd578254600160501b900461ffff1615611626576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091529020548354600160501b900461ffff16811080156115e3575083546115db908290600160501b900461ffff166152bb565b8961ffff1611155b6116245760405162461bcd60e51b8152602060048201526012602482015271151bdbc81b585b9e481c995c5d595cdd195960721b6044820152606401610979565b505b8254600160401b900461ffff16156116dd576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091529020548354600160401b900461ffff168110801561169a57508354611692908290600160401b900461ffff166152bb565b8961ffff1611155b6116db5760405162461bcd60e51b8152602060048201526012602482015271151bdbc81b585b9e481c995c5d595cdd195960721b6044820152606401610979565b505b6116e78884613701565b8354909150610100900460ff1615801561172157508254600160501b900461ffff1615158061172157508254600160401b900461ffff1615155b1561176b576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091528120805461ffff8b1692906117659084906152ce565b90915550505b61188b565b8254600160401b900461ffff1615611827576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091529020548354600160401b900461ffff16811080156117e4575083546117dc908290600160401b900461ffff166152bb565b8961ffff1611155b6118255760405162461bcd60e51b8152602060048201526012602482015271151bdbc81b585b9e481c995c5d595cdd195960721b6044820152606401610979565b505b611831888461378c565b8354909150600160401b900461ffff161561188b576001600160a01b038a1660009081526008602090815260408083208c845282528083203384529091528120805461ffff8b1692906118859084906152ce565b90915550505b81801561189e57508254610100900460ff165b156118b7576118b28a8a898989898e6137a3565b6118c5565b6118c58a8a89898989613a04565b80156118e35760058301546118e3906001600160a01b031682613c36565b6118ef8a8a338b612e7d565b50505050505050505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015611943573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061196791906150bc565b6119c75760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b60006119d38686612d45565b805490915060ff1615611a195760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792061637469766560901b6044820152606401610979565b60a08401356002820155611a3360808501606086016152e1565b815461ffff91909116600160401b0269ffff000000000000000019909116178155611a6460408501602086016152e1565b815461ffff919091166401000000000265ffff000000001990911617815560c08401356003820155611a9c60a08501608086016152e1565b815461ffff91909116600160501b026bffff0000000000000000000019909116178155611acc60208501856152fc565b81549015156101000261ff00199091161790555050505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015611b2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b5291906150bc565b611bb25760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000856001600160a01b031663ffa1ad746040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611c0e575060408051601f3d908101601f19168201909252611c0b91810190615319565b60015b15611c675760ff811115611c645760405162461bcd60e51b815260206004820152601c60248201527f556e737570706f7274656420636f6e74726163742076657273696f6e000000006044820152606401610979565b90505b611c7386828787613cd9565b505050505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015611cc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ce791906150bc565b611d475760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000611d538686612d45565b8054941515620100000262ff000019909516949094179093555050505050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa158015611dbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ddf91906150bc565b611e3f5760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000611e4b8686612d45565b805490915060ff1615611e915760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792061637469766560901b6044820152606401610979565b611c7386863387612e7d565b6001600160a01b038216600090815260076020908152604080832084845282528083208151808301835290546001600160e01b0381168252600160e01b900463ffffffff168184015281516102408101835284815292830184905290820183905260608083018490526080830184905260a0830184905260c0830184905260e08301849052610100830184905261012083018490526101408301849052610160830184905261018083018490526101a083018490526101c083018490526101e083018490526102008301819052610220830184905292909182516001600160e01b03166000036122255760405163b4b5b48f60e01b8152600481018690526000906001600160a01b0388169063b4b5b48f90602401602060405180830381865afa158015611fcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ff39190615189565b905066ffffffffffffff601882901c1660008190036120545760405162461bcd60e51b815260206004820152600f60248201527f546f6b656e206e6f7420666f756e6400000000000000000000000000000000006044820152606401610979565b612067888266ffffffffffffff16612d45565b6040805161024081018252825460ff8082161515835261010080830482161515602085015262010000830482161515948401949094526301000000820416606083015261ffff6401000000008204811660808401526601000000000000808304821660a0850152600160401b8304821660c0850152600160501b8304821660e0850152600160601b83049091169383019390935265ffffffffffff600160701b82048116610120840152600160a01b82048116610140840152600160d01b90910481166101608301526001840154808216610180840152929092049091166101a082015260028201546101c082015260038201546101e08201526004820180549192916102008401919061217a906150d9565b80601f01602080910402602001604051908101604052809291908181526020018280546121a6906150d9565b80156121f35780601f106121c8576101008083540402835291602001916121f3565b820191906000526020600020905b8154815290600101906020018083116121d657829003601f168201915b5050509183525050600591909101546001600160a01b031660209091015262ffffff9290921693509091506123f69050565b826020015163ffffffff1691506122498684600001516001600160e01b0316612d45565b6040805161024081018252825460ff8082161515835261010080830482161515602085015262010000830482161515948401949094526301000000820416606083015261ffff6401000000008204811660808401526601000000000000808304821660a0850152600160401b8304821660c0850152600160501b8304821660e0850152600160601b83049091169383019390935265ffffffffffff600160701b82048116610120840152600160a01b82048116610140840152600160d01b90910481166101608301526001840154808216610180840152929092049091166101a082015260028201546101c082015260038201546101e08201526004820180549192916102008401919061235c906150d9565b80601f0160208091040260200160405190810160405280929190818152602001828054612388906150d9565b80156123d55780601f106123aa576101008083540402835291602001916123d5565b820191906000526020600020905b8154815290600101906020018083116123b857829003601f168201915b5050509183525050600591909101546001600160a01b031660209091015290505b8061020001515160000361244c5760405162461bcd60e51b815260206004820152601660248201527f4e6f2062617365207572692070726566697820736574000000000000000000006044820152606401610979565b80610200015161245b836140c2565b60405160200161246c929190615332565b604051602081830303815290604052935050505092915050565b604051630935e01b60e21b8152336004820152839081906001600160a01b038216906324d7806c90602401602060405180830381865afa1580156124ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f291906150bc565b6125525760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b600061255e8686612d45565b805490915060ff16156125a45760405162461bcd60e51b815260206004820152600e60248201526d416c72656164792061637469766560901b6044820152606401610979565b426125b26020860186615361565b65ffffffffffff16116126075760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f7420616374697661746520696e20746865207061737400000000006044820152606401610979565b6126176040850160208601615361565b65ffffffffffff1661262f6060860160408701615361565b65ffffffffffff1611156126ab5760405162461bcd60e51b815260206004820152602f60248201527f50726573616c6520496e74657276616c2063616e6e6f74206265206c6f6e676560448201527f72207468616e207468652073616c6500000000000000000000000000000000006064820152608401610979565b6126bb60a0850160808601615361565b65ffffffffffff166126d36080860160608701615361565b65ffffffffffff161115801561271457506126f16020850185615361565b65ffffffffffff1661270960a0860160808701615361565b65ffffffffffff1611155b6127605760405162461bcd60e51b815260206004820152601360248201527f496e76616c696420636c61696d2074696d6573000000000000000000000000006044820152606401610979565b61276d6020850185615361565b815465ffffffffffff91909116600160701b027fffffffffffffffffffffffff000000000000ffffffffffffffffffffffffffff9091161781556127b76040850160208601615361565b6127c46020860186615361565b6127ce9190615389565b815465ffffffffffff91909116600160a01b027fffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffff9091161781556128186060850160408601615361565b815465ffffffffffff91909116600160d01b0279ffffffffffffffffffffffffffffffffffffffffffffffffffff90911617815561285c6080850160608601615361565b60018201805465ffffffffffff191665ffffffffffff9290921691909117905561288c60a0850160808601615361565b600182810180546bffffffffffff000000000000198116660100000000000065ffffffffffff958616810291821793849055865460ff1916909417808755604080516001600160a01b038e168152602081018d9052600160701b8304881691810191909152600160a01b820487166060820152600160d01b909104861660808201529185169085161760a082015291900490911660c08201527fda897ec003b83d996662d95c264c767d3c58171ae697ebb551a313b425551d289060e0015b60405180910390a1505050505050565b604051630935e01b60e21b8152336004820152829081906001600160a01b038216906324d7806c90602401602060405180830381865afa1580156129a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c791906150bc565b612a275760405162461bcd60e51b815260206004820152602b60248201527f57616c6c6574206973206e6f7420616e2061646d696e6973747261746f72206660448201526a1bdc8818dbdb9d1c9858dd60aa1b6064820152608401610979565b6000612a338585612d45565b80547fffffffffffff000000000000000000000000ffffffffffffffffffffffffff001681556001810180546bffffffffffffffffffffffff19169055604080516001600160a01b0388168152602081018790529192507f54cbaf4a244605e6477ea43f8e1388ace54d61f7f5110cad2268ddc39da2bbac910160405180910390a15050505050565b612ac4612e0e565b6001600160a01b038116612b405760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610979565b610ee1816135ad565b33612b5c6000546001600160a01b031690565b6001600160a01b03161480612b775750612b77600133612dec565b612bcf5760405162461bcd60e51b8152602060048201526024808201527f41646d696e436f6e74726f6c3a204d757374206265206f776e6572206f7220616044820152633236b4b760e11b6064820152608401610979565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612c1c576040519150601f19603f3d011682016040523d82523d6000602084013e612c21565b606091505b5050905080612c725760405162461bcd60e51b815260206004820152601e60248201527f4661696c656420746f207472616e7366657220746f20726563656976657200006044820152606401610979565b505050565b612c8187876141f7565b612c908787868686868b6142c0565b6001600160a01b038716600090815260086020908152604080832089845282528083203384529091528120805461ffff88169290612ccf9084906152ce565b90915550612ce2905061ffff86166142cf565b3414612d305760405162461bcd60e51b815260206004820152601760248201527f496e76616c696420707572636861736520616d6f756e740000000000000000006044820152606401610979565b612d3c87873388612e7d565b50505050505050565b6001600160a01b0382166000908152600660209081526040808320848452909152812080549091660100000000000090910461ffff1690036106f65760405162461bcd60e51b815260206004820152601b60248201527f436f6c6c65637469626c65206e6f7420696e697469616c697a656400000000006044820152606401610979565b6000612dd4836142fc565b8015612de55750612de5838361432f565b9392505050565b6001600160a01b03811660009081526001830160205260408120541515612de5565b6000546001600160a01b031633146113e75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610979565b6000612de5836001600160a01b0384166143b8565b6000612e898585612d45565b90508161ffff166001036131155780546000906003630100000090910460ff1610612f8e5781546000908390600c90612ecc90600160601b900461ffff166153a8565b825461ffff9182166101009390930a83810292021916179091556040517fd39737190000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015266ffffffff00000060188a901b169092176024820181905292509088169063d3973719906044016020604051808303816000875af1158015612f62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f869190615319565b9150506130b2565b81548290600c90612fa990600160601b900461ffff166153a8565b825461ffff9182166101009390930a92830291909202199091161790556040517f2928ca580000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152871690632928ca58906024016020604051808303816000875af1158015613027573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061304b9190615319565b6040805180820182526001600160e01b038089168252855461ffff600160601b9091041660208084019182526001600160a01b038c16600090815260078252858120878252909152939093209151925163ffffffff16600160e01b02921691909117905590505b8154604080516001600160a01b038916815260208101889052600160601b90920461ffff1690820152606081018290527f604f4158d0efdc4ccca2c0fe366be334aab90f8081a92e8a53e4fb849d1a08979060800160405180910390a15061357b565b805460009061313090600160601b900461ffff1660016153c9565b825461ffff918216925084918491600c91613155918591600160601b909104166153c9565b92506101000a81548161ffff021916908361ffff16021790555060038260000160039054906101000a900460ff1660ff161061338c5760008361ffff1667ffffffffffffffff8111156131aa576131aa615129565b6040519080825280602002602001820160405280156131d3578160200160208202803683370190505b50905060005b8461ffff16811015613247576131f58163ffffffff85166152ce565b62ffffff1660188866ffffffffffffff16901b1766ffffffffffffff1682828151811061322457613224615113565b69ffffffffffffffffffff909216602092830291909101909101526001016131d9565b506040517f4278330e0000000000000000000000000000000000000000000000000000000081526000906001600160a01b03891690634278330e9061329290899086906004016153e4565b6000604051808303816000875af11580156132b1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526132d99190810190615447565b905060005b8561ffff168163ffffffff161015613384577f604f4158d0efdc4ccca2c0fe366be334aab90f8081a92e8a53e4fb849d1a0897898961331d8488615505565b858563ffffffff168151811061333557613335615113565b602002602001015160405161337494939291906001600160a01b03949094168452602084019290925263ffffffff166040830152606082015260800190565b60405180910390a16001016132de565b505050611c73565b6040517fe00aab4b0000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015261ffff851660248301526000919088169063e00aab4b906044016000604051808303816000875af11580156133fb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526134239190810190615447565b905060005b8461ffff168163ffffffff161015610a8e577f604f4158d0efdc4ccca2c0fe366be334aab90f8081a92e8a53e4fb849d1a089788886134678487615505565b858563ffffffff168151811061347f5761347f615113565b60200260200101516040516134be94939291906001600160a01b03949094168452602084019290925263ffffffff166040830152606082015260800190565b60405180910390a16040518060400160405280886001600160e01b0316815260200182856134ec9190615505565b63ffffffff16815250600760008a6001600160a01b03166001600160a01b031681526020019081526020016000206000848463ffffffff168151811061353457613534615113565b6020908102919091018101518252818101929092526040016000208251929091015163ffffffff16600160e01b026001600160e01b03909216919091179055600101613428565b5050505050565b60006106f6825490565b6000612de583836144b2565b6000612de5836001600160a01b0384166144dc565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006136098383612d45565b805490915060ff166136485760405162461bcd60e51b8152602060048201526008602482015267496e61637469766560c01b6044820152606401610979565b8054600160701b900465ffffffffffff16421015612c725760405162461bcd60e51b815260206004820152601560248201527f50757263686173696e67206e6f742061637469766500000000000000000000006044820152606401610979565b6000806136b58484612d45565b8054909150600160701b900465ffffffffffff164211801561112a5750805465ffffffffffff600160d01b82048116916136f891600160701b90910416426152bb565b10949350505050565b60008082600301548461ffff166137189190615522565b905060006137298561ffff166142cf565b61373390836152ce565b90508034146137845760405162461bcd60e51b815260206004820152601c60248201527f496e76616c696420707572636861736520616d6f756e742073656e74000000006044820152606401610979565b509392505050565b60008082600201548461ffff166137189190615522565b6001600160a01b0387166000908152600460209081526040808320898452825280832085845290915290205460ff161561381f5760405162461bcd60e51b815260206004820152601960248201527f43616e6e6f74207265706c6179207472616e73616374696f6e000000000000006044820152606401610979565b6040517f19457468657265756d205369676e6564204d6573736167653a0a35340000000060208201526bffffffffffffffffffffffff193360601b16603c820152605081018390527fffff00000000000000000000000000000000000000000000000000000000000060f083901b1660708201526000906072016040516020818303038152906040528051906020012090508086146139005760405162461bcd60e51b815260206004820152601160248201527f4d616c666f726d6564206d6573736167650000000000000000000000000000006044820152606401610979565b600061394486868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b9392505061452b9050565b6001600160a01b03808b1660009081526005602090815260408083208d845290915290205491925090811690821681146139c05760405162461bcd60e51b815260206004820152601160248201527f496e76616c6964207369676e61747572650000000000000000000000000000006044820152606401610979565b5050506001600160a01b0390961660009081526004602090815260408083209783529681528682209282529190915293909320805460ff1916600117905550505050565b6001600160a01b0386166000908152600460209081526040808320888452825280832084845290915290205460ff1615613a805760405162461bcd60e51b815260206004820152601960248201527f43616e6e6f74207265706c6179207472616e73616374696f6e000000000000006044820152606401610979565b6040517f19457468657265756d205369676e6564204d6573736167653a0a35320000000060208201526bffffffffffffffffffffffff193360601b16603c82015260508101829052600090607001604051602081830303815290604052805190602001209050808514613b355760405162461bcd60e51b815260206004820152601160248201527f4d616c666f726d6564206d6573736167650000000000000000000000000000006044820152606401610979565b6000613b7985858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a9392505061452b9050565b6001600160a01b03808a1660009081526005602090815260408083208c84529091529020549192509081169082168114613bf55760405162461bcd60e51b815260206004820152601160248201527f496e76616c6964207369676e61747572650000000000000000000000000000006044820152606401610979565b5050506001600160a01b039095166000908152600460209081526040808320968352958152858220968252959095525050509020805460ff19166001179055565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613c83576040519150601f19603f3d011682016040523d82523d6000602084013e613c88565b606091505b5050905080612c725760405162461bcd60e51b815260206004820152601f60248201527f4661696c656420746f207472616e7366657220746f20726563697069656e74006044820152606401610979565b600082118015613cf0575066ffffffffffffff8211155b613d3c5760405162461bcd60e51b815260206004820152601260248201527f496e76616c696420696e7374616e6365496400000000000000000000000000006044820152606401610979565b6001600160a01b0380851660008181526005602090815260408083208784528252808320549383526006825280832087845290915290209116908115613dc45760405162461bcd60e51b815260206004820152601f60248201527f436f6c6c65637469626c6520616c726561647920696e697469616c697a6564006044820152606401610979565b6000613dd7610100850160e08601614aaa565b6001600160a01b031603613e2d5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207369676e696e6720616464726573730000000000000000006044820152606401610979565b6000613e4161012085016101008601614aaa565b6001600160a01b031603613e975760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207061796d656e7420616464726573730000000000000000006044820152606401610979565b613ea760608401604085016152e1565b61ffff16600003613efa5760405162461bcd60e51b815260206004820152601460248201527f496e76616c6964207075726368617365206d61780000000000000000000000006044820152606401610979565b613f0b610100840160e08501614aaa565b6001600160a01b0387811660009081526005602090815260408083208984529091529081902080546001600160a01b03191693909216929092179055815463ff0000001916630100000060ff881602178255613f6d90606085019085016152e1565b815461ffff9190911666010000000000000267ffff0000000000001990911617815560a08301356002820155613fa960808401606085016152e1565b815461ffff91909116600160401b0269ffff000000000000000019909116178155613fda60408401602085016152e1565b815461ffff919091166401000000000265ffff000000001990911617815560c0830135600382015561401260a08401608085016152e1565b815461ffff91909116600160501b026bffff000000000000000000001990911617815561404260208401846152fc565b815461ff0019166101009115158202178255614065906101208501908501614aaa565b6005820180546001600160a01b0319166001600160a01b039283161790556040805191881682526020820186905233908201527f61da64dacf5829e3b4534db2a9f2ed9214b5c682bc1499c4742ac98f6e4179bd9060600161294b565b60608160000361410557505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561412f578061411981615155565b91506141289050600a8361554f565b9150614109565b60008167ffffffffffffffff81111561414a5761414a615129565b6040519080825280601f01601f191660200182016040528015614174576020820181803683370190505b5090505b841561112a576141896001836152bb565b9150614196600a86615563565b6141a19060306152ce565b60f81b8183815181106141b6576141b6615113565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506141f0600a8661554f565b9450614178565b60006142038383612d45565b805490915060ff166142425760405162461bcd60e51b8152602060048201526008602482015267496e61637469766560c01b6044820152606401610979565b600181015465ffffffffffff164210801590614274575060018101546601000000000000900465ffffffffffff164211155b612c725760405162461bcd60e51b815260206004820152601560248201527f4f75747369646520636c61696d20706572696f642e00000000000000000000006044820152606401610979565b612d3c878787878787876137a3565b60006142da33614547565b6142f4576142ef826602738d24e52000615522565b6106f6565b600092915050565b600061430f826301ffc9a760e01b61432f565b80156106f65750614328826001600160e01b031961432f565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d915060005190508280156143a1575060208210155b80156143ad5750600081115b979650505050505050565b600081815260018301602052604081205480156144a15760006143dc6001836152bb565b85549091506000906143f0906001906152bb565b905081811461445557600086600001828154811061441057614410615113565b906000526020600020015490508087600001848154811061443357614433615113565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061446657614466615577565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506106f6565b60009150506106f6565b5092915050565b60008260000182815481106144c9576144c9615113565b9060005260206000200154905092915050565b6000818152600183016020526040812054614523575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556106f6565b5060006106f6565b600080600061453a85856145e6565b915091506137848161462b565b6003546000906001600160a01b0316158015906106f657506003546040517f45ecd02f0000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152909116906345ecd02f90602401602060405180830381865afa1580156145c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f691906150bc565b600080825160410361461c5760208301516040840151606085015160001a614610878285856147e1565b94509450505050614624565b506000905060025b9250929050565b600081600481111561463f5761463f61558d565b036146475750565b600181600481111561465b5761465b61558d565b036146a85760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610979565b60028160048111156146bc576146bc61558d565b036147095760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610979565b600381600481111561471d5761471d61558d565b036147755760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610979565b60048160048111156147895761478961558d565b03610ee15760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610979565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561481857506000905060036148c5565b8460ff16601b1415801561483057508460ff16601c14155b1561484157506000905060046148c5565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015614895573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166148be576000600192509250506148c5565b9150600090505b94509492505050565b6000602082840312156148e057600080fd5b81356001600160e01b031981168114612de557600080fd5b6001600160a01b0381168114610ee157600080fd5b6000806040838503121561492057600080fd5b823561492b816148f8565b946020939093013593505050565b81511515815261022081016020830151614957602084018215159052565b50604083015161496b604084018215159052565b506060830151614981606084018261ffff169052565b506080830151614997608084018261ffff169052565b5060a08301516149ad60a084018261ffff169052565b5060c08301516149c360c084018261ffff169052565b5060e08301516149d960e084018261ffff169052565b506101008381015165ffffffffffff9081169184019190915261012080850151821690840152610140808501518216908401526101608085015182169084015261018080850151909116908301526101a080840151908301526101c080840151908301526101e08084015190830152610200928301516001600160a01b0316929091019190915290565b8015158114610ee157600080fd5b60008060408385031215614a8457600080fd5b8235614a8f816148f8565b91506020830135614a9f81614a63565b809150509250929050565b600060208284031215614abc57600080fd5b8135612de5816148f8565b60005b83811015614ae2578181015183820152602001614aca565b50506000910152565b60008151808452614b03816020860160208601614ac7565b601f01601f19169290920160200192915050565b60208152614b2a60208201835115159052565b60006020830151614b3f604084018215159052565b506040830151801515606084015250606083015160ff8116608084015250608083015161ffff811660a08401525060a083015161ffff811660c08401525060c083015161ffff811660e08401525060e0830151610100614ba48185018361ffff169052565b8401519050610120614bbb8482018361ffff169052565b8401519050610140614bd68482018365ffffffffffff169052565b8401519050610160614bf18482018365ffffffffffff169052565b8401519050610180614c0c8482018365ffffffffffff169052565b84015190506101a0614c278482018365ffffffffffff169052565b84015190506101c0614c428482018365ffffffffffff169052565b8401516101e0848101919091528401516102008085019190915284015161024061022080860182905291925090614c7d610260860184614aeb565b9501516001600160a01b03169301929092525090919050565b600080600060608486031215614cab57600080fd5b8335614cb6816148f8565b9250602084013591506040840135614ccd816148f8565b809150509250925092565b60008060008060608587031215614cee57600080fd5b8435614cf9816148f8565b935060208501359250604085013567ffffffffffffffff80821115614d1d57600080fd5b818701915087601f830112614d3157600080fd5b813581811115614d4057600080fd5b8860208260051b8501011115614d5557600080fd5b95989497505060200194505050565b6020808252825182820181905260009190848201906040850190845b81811015614da55783516001600160a01b031683529284019291840191600101614d80565b50909695505050505050565b60008060008060808587031215614dc757600080fd5b8435614dd2816148f8565b93506020850135614de2816148f8565b92506040850135614df2816148f8565b9396929550929360600135925050565b60008083601f840112614e1457600080fd5b50813567ffffffffffffffff811115614e2c57600080fd5b60208301915083602082850101111561462457600080fd5b60008060008060608587031215614e5a57600080fd5b8435614e65816148f8565b935060208501359250604085013567ffffffffffffffff811115614e8857600080fd5b614e9487828801614e02565b95989497509550505050565b803561ffff81168114614eb257600080fd5b919050565b600080600080600080600060c0888a031215614ed257600080fd5b8735614edd816148f8565b965060208801359550614ef260408901614ea0565b945060608801359350608088013567ffffffffffffffff811115614f1557600080fd5b614f218a828b01614e02565b989b979a5095989497959660a090950135949350505050565b6000806000838503610120811215614f5157600080fd5b8435614f5c816148f8565b93506020850135925060e0603f1982011215614f7757600080fd5b506040840190509250925092565b6000806000838503610160811215614f9c57600080fd5b8435614fa7816148f8565b935060208501359250610120603f1982011215614f7757600080fd5b600080600060608486031215614fd857600080fd5b8335614fe3816148f8565b9250602084013591506040840135614ccd81614a63565b60008060006060848603121561500f57600080fd5b833561501a816148f8565b95602085013595506040909401359392505050565b60008060006060848603121561504457600080fd5b833561504f816148f8565b92506020840135915061506460408501614ea0565b90509250925092565b602081526000612de56020830184614aeb565b600080600083850360e081121561509657600080fd5b84356150a1816148f8565b93506020850135925060a0603f1982011215614f7757600080fd5b6000602082840312156150ce57600080fd5b8151612de581614a63565b600181811c908216806150ed57607f821691505b60208210810361510d57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016151675761516761513f565b5060010190565b61ffff8281168282160390808211156144ab576144ab61513f565b60006020828403121561519b57600080fd5b815169ffffffffffffffffffff81168114612de557600080fd5b601f821115612c7257600081815260208120601f850160051c810160208610156151dc5750805b601f850160051c820191505b81811015611c73578281556001016151e8565b67ffffffffffffffff83111561521357615213615129565b6152278361522183546150d9565b836151b5565b6000601f84116001811461525b57600085156152435750838201355b600019600387901b1c1916600186901b17835561357b565b600083815260209020601f19861690835b8281101561528c578685013582556020948501946001909201910161526c565b50868210156152a95760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b818103818111156106f6576106f661513f565b808201808211156106f6576106f661513f565b6000602082840312156152f357600080fd5b612de582614ea0565b60006020828403121561530e57600080fd5b8135612de581614a63565b60006020828403121561532b57600080fd5b5051919050565b60008351615344818460208801614ac7565b835190830190615358818360208801614ac7565b01949350505050565b60006020828403121561537357600080fd5b813565ffffffffffff81168114612de557600080fd5b65ffffffffffff8181168382160190808211156144ab576144ab61513f565b600061ffff8083168181036153bf576153bf61513f565b6001019392505050565b61ffff8181168382160190808211156144ab576144ab61513f565b6000604082016001600160a01b03851683526020604081850152818551808452606086019150828701935060005b8181101561543a57845169ffffffffffffffffffff1683529383019391830191600101615412565b5090979650505050505050565b6000602080838503121561545a57600080fd5b825167ffffffffffffffff8082111561547257600080fd5b818501915085601f83011261548657600080fd5b81518181111561549857615498615129565b8060051b604051601f19603f830116810181811085821117156154bd576154bd615129565b6040529182528482019250838101850191888311156154db57600080fd5b938501935b828510156154f9578451845293850193928501926154e0565b98975050505050505050565b63ffffffff8181168382160190808211156144ab576144ab61513f565b80820281158282048414176106f6576106f661513f565b634e487b7160e01b600052601260045260246000fd5b60008261555e5761555e615539565b500490565b60008261557257615572615539565b500690565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212202e10d92b32ab5c1ebc21eafb3d8416099154aec39e767cbd37c7e6c373655afc64736f6c63430008110033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.