Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
105797081 | 580 days ago | 0 ETH | ||||
105796192 | 580 days ago | 0 ETH | ||||
105796191 | 580 days ago | 0 ETH | ||||
105796185 | 580 days ago | 0 ETH | ||||
105796184 | 580 days ago | 0 ETH | ||||
105796166 | 580 days ago | 0 ETH | ||||
105794674 | 580 days ago | 0 ETH | ||||
105794674 | 580 days ago | 0 ETH | ||||
105794674 | 580 days ago | 0 ETH | ||||
105794674 | 580 days ago | 0 ETH | ||||
105794674 | 580 days ago | 0 ETH | ||||
105794674 | 580 days ago | 0 ETH | ||||
105794674 | 580 days ago | 0 ETH | ||||
105794674 | 580 days ago | 0 ETH | ||||
105794674 | 580 days ago | 0 ETH | ||||
105789486 | 580 days ago | 0 ETH | ||||
105789472 | 580 days ago | 0 ETH | ||||
105789466 | 580 days ago | 0 ETH | ||||
105789463 | 580 days ago | 0 ETH | ||||
105788990 | 580 days ago | 0 ETH | ||||
105788218 | 580 days ago | 0 ETH | ||||
105788174 | 580 days ago | 0 ETH | ||||
105788140 | 580 days ago | 0 ETH | ||||
105788105 | 580 days ago | 0 ETH | ||||
105788102 | 580 days ago | 0 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
HolographDropERC721
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 999999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED /* ┌───────────┐ │ HOLOGRAPH │ └───────────┘ ╔═════════════════════════════════════════════════════════════╗ ║ ║ ║ / ^ \ ║ ║ ~~*~~ ¸ ║ ║ [ '<>:<>' ] │░░░ ║ ║ ╔╗ _/"\_ ╔╣ ║ ║ ┌─╬╬─┐ """ ┌─╬╬─┐ ║ ║ ┌─┬┘ ╠╣ └┬─┐ \_/ ┌─┬┘ ╠╣ └┬─┐ ║ ║ ┌─┬┘ │ ╠╣ │ └┬─┐ ┌─┬┘ │ ╠╣ │ └┬─┐ ║ ║ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ║ ║ ┌─┬┘ │ │ │ ╠╣ │ │ │ └┬┐ ┌┬┘ │ │ │ ╠╣ │ │ │ └┬─┐ ║ ╠┬┘ │ │ │ │ ╠╣ │ │ │ │└¤┘│ │ │ │ ╠╣ │ │ │ │ └┬╣ ║│ │ │ │ │ ╠╣ │ │ │ │ │ │ │ │ ╠╣ │ │ │ │ │║ ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣ ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣ ║ ╠╣ ╠╣ ║ ║ ╠╣ ╠╣ ║ ║ , ╠╣ , ,' * ╠╣ ║ ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║ ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝ - one protocol, one bridge = infinite possibilities - *************************************************************** DISCLAIMER: U.S Patent Pending LICENSE: Holograph Limited Public License (H-LPL) https://holograph.xyz/licenses/h-lpl/1.0.0 This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, you are not permitted to use the software. 1. Definitions The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor’s patent claims that read directly on its contribution. 2. Grant of Rights A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in sections 3 and 4, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 3. Conditions and Limitations A) No Trademark License- This license does not grant you rights to use any contributors’ name, logo, or trademarks. B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor is terminated with immediate effect. C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. E) The software is licensed “as-is.” You bear all risks of using it. The contributors give no express warranties, guarantees, or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude all implied warranties, including those of merchantability, fitness for a particular purpose and non-infringement. 4. (F) Platform Limitation- The licenses granted in sections 2.A & 2.B extend only to the software or derivative works that you create that run on a Holograph system product. *************************************************************** */ pragma solidity 0.8.13; import {ERC721H} from "../../abstract/ERC721H.sol"; import {NonReentrant} from "../../abstract/NonReentrant.sol"; import {HolographERC721Interface} from "../../interface/HolographERC721Interface.sol"; import {HolographerInterface} from "../../interface/HolographerInterface.sol"; import {HolographInterface} from "../../interface/HolographInterface.sol"; import {AddressMintDetails} from "../struct/AddressMintDetails.sol"; import {Configuration} from "../struct/Configuration.sol"; import {DropsInitializer} from "../struct/DropsInitializer.sol"; import {SaleDetails} from "../struct/SaleDetails.sol"; import {SalesConfiguration} from "../struct/SalesConfiguration.sol"; import {Address} from "../library/Address.sol"; import {MerkleProof} from "../library/MerkleProof.sol"; import {IMetadataRenderer} from "../interface/IMetadataRenderer.sol"; import {IOperatorFilterRegistry} from "../interface/IOperatorFilterRegistry.sol"; import {IHolographDropERC721} from "../interface/IHolographDropERC721.sol"; import {IDropsPriceOracle} from "../interface/IDropsPriceOracle.sol"; /** * @dev This contract subscribes to the following HolographERC721 events: * - beforeSafeTransfer * - beforeTransfer * - onIsApprovedForAll * - customContractURI * * Do not enable or subscribe to any other events unless you modified your source code for them. */ contract HolographDropERC721 is NonReentrant, ERC721H, IHolographDropERC721 { /** * CONTRACT VARIABLES * all variables, without custom storage slots, are defined here */ /** * @dev bytes32(uint256(keccak256('eip1967.Holograph.osRegistryEnabled')) - 1) */ bytes32 constant _osRegistryEnabledSlot = 0x5c835f3b6bd322d9a084ffdeac746df2b96cce308e7f0612f4ff4f9c490734cc; /** * @dev Address of the operator filter registry */ IOperatorFilterRegistry public constant openseaOperatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); /** * @dev Address of the price oracle proxy */ IDropsPriceOracle public constant dropsPriceOracle = IDropsPriceOracle(0xA3Db09EEC42BAfF7A50fb8F9aF90A0e035Ef3302); /** * @dev Internal reference used for minting incremental token ids. */ uint224 private _currentTokenId; /** * @dev HOLOGRAPH transfer helper address for auto-approval */ address public erc721TransferHelper; /** * @dev Address of the market filter registry */ address public marketFilterAddress; /** * @notice Configuration for NFT minting contract storage */ Configuration public config; /** * @notice Sales configuration */ SalesConfiguration public salesConfig; /** * @dev Mapping for presale mint counts by address to allow public mint limit */ mapping(address => uint256) public presaleMintsByAddress; /** * @dev Mapping for presale mint counts by address to allow public mint limit */ mapping(address => uint256) public totalMintsByAddress; /** * CUSTOM ERRORS */ /** * @notice Thrown when there is no active market filter address supported for the current chain * @dev Used for enabling and disabling filter for the given chain. */ error MarketFilterAddressNotSupportedForChain(); /** * MODIFIERS */ /** * @notice Allows user to mint tokens at a quantity */ modifier canMintTokens(uint256 quantity) { if (config.editionSize != 0 && quantity + _currentTokenId > config.editionSize) { revert Mint_SoldOut(); } _; } /** * @notice Presale active */ modifier onlyPresaleActive() { if (!_presaleActive()) { revert Presale_Inactive(); } _; } /** * @notice Public sale active */ modifier onlyPublicSaleActive() { if (!_publicSaleActive()) { revert Sale_Inactive(); } _; } /** * CONTRACT INITIALIZERS * init function is used instead of constructor */ /** * @dev Constructor is left empty and init is used instead */ constructor() {} /** * @notice Used internally to initialize the contract instead of through a constructor * @dev This function is called by the deployer/factory when creating a contract * @param initPayload abi encoded payload to use for contract initilaization */ function init(bytes memory initPayload) external override returns (bytes4) { require(!_isInitialized(), "HOLOGRAPH: already initialized"); DropsInitializer memory initializer = abi.decode(initPayload, (DropsInitializer)); erc721TransferHelper = initializer.erc721TransferHelper; if (initializer.marketFilterAddress != address(0)) { marketFilterAddress = initializer.marketFilterAddress; } // Setup the owner role _setOwner(initializer.initialOwner); // Setup config variables config = Configuration({ metadataRenderer: IMetadataRenderer(initializer.metadataRenderer), editionSize: initializer.editionSize, royaltyBPS: initializer.royaltyBPS, fundsRecipient: initializer.fundsRecipient }); salesConfig = initializer.salesConfiguration; // TODO: Need to make sure to initialize the metadata renderer if (initializer.metadataRenderer != address(0)) { IMetadataRenderer(initializer.metadataRenderer).initializeWithData(initializer.metadataRendererInit); } if (initializer.enableOpenSeaRoyaltyRegistry && Address.isContract(address(openseaOperatorFilterRegistry))) { if (marketFilterAddress == address(0)) { // this is a default filter that can be used for OS royalty filtering // marketFilterAddress = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6; // we just register to OS royalties and let OS handle it for us with their default filter contract openseaOperatorFilterRegistry.register(address(this)); } else { // allow user to specify custom filtering contract address openseaOperatorFilterRegistry.registerAndSubscribe(address(this), marketFilterAddress); } assembly { sstore(_osRegistryEnabledSlot, true) } } setStatus(1); return _init(initPayload); } /** * PUBLIC NON STATE CHANGING FUNCTIONS * static */ /** * @notice Returns the version of the contract * @dev Used for contract versioning and validation * @return version string representing the version of the contract */ function version() external pure returns (string memory) { return "1.0.0"; } function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { return interfaceId == type(IHolographDropERC721).interfaceId; } /** * PUBLIC NON STATE CHANGING FUNCTIONS * dynamic */ function owner() external view override(ERC721H, IHolographDropERC721) returns (address) { return _getOwner(); } function isAdmin(address user) external view returns (bool) { return (_getOwner() == user); } function beforeSafeTransfer( address _from, address /* _to*/, uint256 /* _tokenId*/, bytes calldata /* _data*/ ) external view returns (bool) { if ( _from != address(0) && // skip on mints _from != msgSender() // skip on transfers from sender ) { bool osRegistryEnabled; assembly { osRegistryEnabled := sload(_osRegistryEnabledSlot) } if (osRegistryEnabled) { try openseaOperatorFilterRegistry.isOperatorAllowed(address(this), msgSender()) returns (bool allowed) { return allowed; } catch { revert OperatorNotAllowed(msgSender()); } } } return true; } function beforeTransfer( address _from, address /* _to*/, uint256 /* _tokenId*/, bytes calldata /* _data*/ ) external view returns (bool) { if ( _from != address(0) && // skip on mints _from != msgSender() // skip on transfers from sender ) { bool osRegistryEnabled; assembly { osRegistryEnabled := sload(_osRegistryEnabledSlot) } if (osRegistryEnabled) { try openseaOperatorFilterRegistry.isOperatorAllowed(address(this), msgSender()) returns (bool allowed) { return allowed; } catch { revert OperatorNotAllowed(msgSender()); } } } return true; } function onIsApprovedForAll(address /* _wallet*/, address _operator) external view returns (bool approved) { approved = (erc721TransferHelper != address(0) && _operator == erc721TransferHelper); } /** * @notice Sale details * @return SaleDetails sale information details */ function saleDetails() external view returns (SaleDetails memory) { return SaleDetails({ publicSaleActive: _publicSaleActive(), presaleActive: _presaleActive(), publicSalePrice: salesConfig.publicSalePrice, publicSaleStart: salesConfig.publicSaleStart, publicSaleEnd: salesConfig.publicSaleEnd, presaleStart: salesConfig.presaleStart, presaleEnd: salesConfig.presaleEnd, presaleMerkleRoot: salesConfig.presaleMerkleRoot, totalMinted: _currentTokenId, maxSupply: config.editionSize, maxSalePurchasePerAddress: salesConfig.maxSalePurchasePerAddress }); } /** * @dev Number of NFTs the user has minted per address * @param minter to get counts for */ function mintedPerAddress(address minter) external view returns (AddressMintDetails memory) { return AddressMintDetails({ presaleMints: presaleMintsByAddress[minter], publicMints: totalMintsByAddress[minter] - presaleMintsByAddress[minter], totalMints: totalMintsByAddress[minter] }); } /** * @notice Contract URI Getter, proxies to metadataRenderer * @return Contract URI */ function contractURI() external view returns (string memory) { return config.metadataRenderer.contractURI(); } /** * @notice Getter for metadataRenderer contract */ function metadataRenderer() external view returns (IMetadataRenderer) { return IMetadataRenderer(config.metadataRenderer); } /** * @notice Convert USD price to current price in native Ether */ function getNativePrice() external view returns (uint256) { return _usdToWei(salesConfig.publicSalePrice); } /** * @notice Returns the name of the token through the holographer entrypoint */ function name() external view returns (string memory) { return HolographERC721Interface(holographer()).name(); } /** * @notice Token URI Getter, proxies to metadataRenderer * @param tokenId id of token to get URI for * @return Token URI */ function tokenURI(uint256 tokenId) external view returns (string memory) { HolographERC721Interface H721 = HolographERC721Interface(holographer()); require(H721.exists(tokenId), "ERC721: token does not exist"); return config.metadataRenderer.tokenURI(tokenId); } /** * PUBLIC STATE CHANGING FUNCTIONS * available to all */ function multicall(bytes[] memory data) public returns (bytes[] memory results) { results = new bytes[](data.length); for (uint256 i = 0; i < data.length; i++) { results[i] = Address.functionDelegateCall(address(this), abi.encodePacked(data[i], msgSender())); } } /** * @dev This allows the user to purchase/mint a edition at the given price in the contract. */ function purchase( uint256 quantity ) external payable nonReentrant canMintTokens(quantity) onlyPublicSaleActive returns (uint256) { uint256 salePrice = _usdToWei(salesConfig.publicSalePrice); if (msg.value < salePrice * quantity) { revert Purchase_WrongPrice(salesConfig.publicSalePrice * quantity); } uint256 remainder = msg.value - (salePrice * quantity); // If max purchase per address == 0 there is no limit. // Any other number, the per address mint limit is that. if ( salesConfig.maxSalePurchasePerAddress != 0 && totalMintsByAddress[msgSender()] + quantity - presaleMintsByAddress[msgSender()] > salesConfig.maxSalePurchasePerAddress ) { revert Purchase_TooManyForAddress(); } _mintNFTs(msgSender(), quantity); HolographERC721Interface H721 = HolographERC721Interface(holographer()); uint256 chainPrepend = H721.sourceGetChainPrepend(); uint256 firstMintedTokenId = (chainPrepend + uint256(_currentTokenId - quantity)) + 1; emit Sale({ to: msgSender(), quantity: quantity, pricePerToken: salePrice, firstPurchasedTokenId: firstMintedTokenId }); if (remainder > 0) { msgSender().call{value: remainder, gas: gasleft() > 210_000 ? 210_000 : gasleft()}(""); } return firstMintedTokenId; } /** * @notice Merkle-tree based presale purchase function * @param quantity quantity to purchase * @param maxQuantity max quantity that can be purchased via merkle proof # * @param pricePerToken price that each token is purchased at * @param merkleProof proof for presale mint */ function purchasePresale( uint256 quantity, uint256 maxQuantity, uint256 pricePerToken, bytes32[] calldata merkleProof ) external payable nonReentrant canMintTokens(quantity) onlyPresaleActive returns (uint256) { if ( !MerkleProof.verify( merkleProof, salesConfig.presaleMerkleRoot, keccak256( // address, uint256, uint256 abi.encode(msgSender(), maxQuantity, pricePerToken) ) ) ) { revert Presale_MerkleNotApproved(); } uint256 weiPricePerToken = _usdToWei(pricePerToken); if (msg.value < weiPricePerToken * quantity) { revert Purchase_WrongPrice(pricePerToken * quantity); } uint256 remainder = msg.value - (weiPricePerToken * quantity); presaleMintsByAddress[msgSender()] += quantity; if (presaleMintsByAddress[msgSender()] > maxQuantity) { revert Presale_TooManyForAddress(); } _mintNFTs(msgSender(), quantity); HolographERC721Interface H721 = HolographERC721Interface(holographer()); uint256 chainPrepend = H721.sourceGetChainPrepend(); uint256 firstMintedTokenId = (chainPrepend + uint256(_currentTokenId - quantity)) + 1; emit Sale({ to: msgSender(), quantity: quantity, pricePerToken: weiPricePerToken, firstPurchasedTokenId: firstMintedTokenId }); if (remainder > 0) { msgSender().call{value: remainder, gas: gasleft() > 210_000 ? 210_000 : gasleft()}(""); } return firstMintedTokenId; } /** * PUBLIC STATE CHANGING FUNCTIONS * admin only */ /** * @notice Proxy to update market filter settings in the main registry contracts * @notice Requires admin permissions * @param args Calldata args to pass to the registry */ function updateMarketFilterSettings(bytes calldata args) external onlyOwner returns (bytes memory) { (bool success, bytes memory ret) = address(openseaOperatorFilterRegistry).call(args); if (!success) { revert RemoteOperatorFilterRegistryCallFailed(); } bool osRegistryEnabled = openseaOperatorFilterRegistry.isRegistered(address(this)); assembly { sstore(_osRegistryEnabledSlot, osRegistryEnabled) } return ret; } /** * @notice Manage subscription for marketplace filtering based off royalty payouts. * @param enable Enable filtering to non-royalty payout marketplaces */ function manageMarketFilterSubscription(bool enable) external onlyOwner { address self = address(this); if (marketFilterAddress == address(0)) { revert MarketFilterAddressNotSupportedForChain(); } if (!openseaOperatorFilterRegistry.isRegistered(self) && enable) { openseaOperatorFilterRegistry.registerAndSubscribe(self, marketFilterAddress); } else if (enable) { openseaOperatorFilterRegistry.subscribe(self, marketFilterAddress); } else { openseaOperatorFilterRegistry.unsubscribe(self, false); openseaOperatorFilterRegistry.unregister(self); } bool osRegistryEnabled = openseaOperatorFilterRegistry.isRegistered(address(this)); assembly { sstore(_osRegistryEnabledSlot, osRegistryEnabled) } } function modifyMarketFilterAddress(address newMarketFilterAddress) external onlyOwner { marketFilterAddress = newMarketFilterAddress; } /** * @notice Admin mint tokens to a recipient for free * @param recipient recipient to mint to * @param quantity quantity to mint */ function adminMint(address recipient, uint256 quantity) external onlyOwner canMintTokens(quantity) returns (uint256) { _mintNFTs(recipient, quantity); return _currentTokenId; } /** * @dev Mints multiple editions to the given list of addresses. * @param recipients list of addresses to send the newly minted editions to */ function adminMintAirdrop( address[] calldata recipients ) external onlyOwner canMintTokens(recipients.length) returns (uint256) { unchecked { for (uint256 i = 0; i < recipients.length; i++) { _mintNFTs(recipients[i], 1); } } return _currentTokenId; } /** * @notice Set a new metadata renderer * @param newRenderer new renderer address to use * @param setupRenderer data to setup new renderer with */ function setMetadataRenderer(IMetadataRenderer newRenderer, bytes memory setupRenderer) external onlyOwner { config.metadataRenderer = newRenderer; if (setupRenderer.length > 0) { newRenderer.initializeWithData(setupRenderer); } emit UpdatedMetadataRenderer({sender: msgSender(), renderer: newRenderer}); } /** * @dev This sets the sales configuration * @param publicSalePrice New public sale price * @param maxSalePurchasePerAddress Max # of purchases (public) per address allowed * @param publicSaleStart unix timestamp when the public sale starts * @param publicSaleEnd unix timestamp when the public sale ends (set to 0 to disable) * @param presaleStart unix timestamp when the presale starts * @param presaleEnd unix timestamp when the presale ends * @param presaleMerkleRoot merkle root for the presale information */ function setSaleConfiguration( uint104 publicSalePrice, uint32 maxSalePurchasePerAddress, uint64 publicSaleStart, uint64 publicSaleEnd, uint64 presaleStart, uint64 presaleEnd, bytes32 presaleMerkleRoot ) external onlyOwner { salesConfig.publicSalePrice = publicSalePrice; salesConfig.maxSalePurchasePerAddress = maxSalePurchasePerAddress; salesConfig.publicSaleStart = publicSaleStart; salesConfig.publicSaleEnd = publicSaleEnd; salesConfig.presaleStart = presaleStart; salesConfig.presaleEnd = presaleEnd; salesConfig.presaleMerkleRoot = presaleMerkleRoot; emit SalesConfigChanged(msgSender()); } /** * @notice Set a different funds recipient * @param newRecipientAddress new funds recipient address */ function setFundsRecipient(address payable newRecipientAddress) external onlyOwner { if (newRecipientAddress == address(0)) { revert("Funds Recipient cannot be 0 address"); } config.fundsRecipient = newRecipientAddress; emit FundsRecipientChanged(newRecipientAddress, msgSender()); } /** * @notice This withdraws ETH from the contract to the contract owner. */ function withdraw() external override nonReentrant { if (config.fundsRecipient == address(0)) { revert("Funds Recipient address not set"); } address sender = msgSender(); // Get fee amount uint256 funds = address(this).balance; address payable feeRecipient = payable( HolographInterface(HolographerInterface(holographer()).getHolograph()).getTreasury() ); // for now set it to 0 since there is no fee uint256 holographFee = 0; // Check if withdraw is allowed for sender if (sender != config.fundsRecipient && sender != _getOwner() && sender != feeRecipient) { revert Access_WithdrawNotAllowed(); } // Payout HOLOGRAPH fee if (holographFee > 0) { (bool successFee, ) = feeRecipient.call{value: holographFee, gas: 210_000}(""); if (!successFee) { revert Withdraw_FundsSendFailure(); } funds -= holographFee; } // Payout recipient (bool successFunds, ) = config.fundsRecipient.call{value: funds, gas: 210_000}(""); if (!successFunds) { revert Withdraw_FundsSendFailure(); } // Emit event for indexing emit FundsWithdrawn(sender, config.fundsRecipient, funds, feeRecipient, holographFee); } /** * @notice Admin function to finalize and open edition sale */ function finalizeOpenEdition() external onlyOwner { if (config.editionSize != type(uint64).max) { revert Admin_UnableToFinalizeNotOpenEdition(); } config.editionSize = uint64(_currentTokenId); emit OpenMintFinalized(msgSender(), config.editionSize); } /** * INTERNAL FUNCTIONS * non state changing */ function _presaleActive() internal view returns (bool) { return salesConfig.presaleStart <= block.timestamp && salesConfig.presaleEnd > block.timestamp; } function _publicSaleActive() internal view returns (bool) { return salesConfig.publicSaleStart <= block.timestamp && salesConfig.publicSaleEnd > block.timestamp; } function _usdToWei(uint256 amount) internal view returns (uint256 weiAmount) { if (amount == 0) { return 0; } weiAmount = dropsPriceOracle.convertUsdToWei(amount); } /** * INTERNAL FUNCTIONS * state changing */ function _mintNFTs(address recipient, uint256 quantity) internal { HolographERC721Interface H721 = HolographERC721Interface(holographer()); uint256 chainPrepend = H721.sourceGetChainPrepend(); uint224 tokenId = 0; for (uint256 i = 0; i < quantity; i++) { _currentTokenId += 1; while ( H721.exists(chainPrepend + uint256(_currentTokenId)) || H721.burned(chainPrepend + uint256(_currentTokenId)) ) { _currentTokenId += 1; } tokenId = _currentTokenId; H721.sourceMint(recipient, tokenId); // uint256 id = chainPrepend + uint256(tokenId); } } fallback() external payable override { assembly { // Allocate memory for the error message let errorMsg := mload(0x40) // Error message: "Function not found", properly padded with zeroes mstore(errorMsg, 0x46756e6374696f6e206e6f7420666f756e640000000000000000000000000000) // Revert with the error message revert(errorMsg, 20) // 20 is the length of the error message in bytes } } }
// SPDX-License-Identifier: UNLICENSED /* ┌───────────┐ │ HOLOGRAPH │ └───────────┘ ╔═════════════════════════════════════════════════════════════╗ ║ ║ ║ / ^ \ ║ ║ ~~*~~ ¸ ║ ║ [ '<>:<>' ] │░░░ ║ ║ ╔╗ _/"\_ ╔╣ ║ ║ ┌─╬╬─┐ """ ┌─╬╬─┐ ║ ║ ┌─┬┘ ╠╣ └┬─┐ \_/ ┌─┬┘ ╠╣ └┬─┐ ║ ║ ┌─┬┘ │ ╠╣ │ └┬─┐ ┌─┬┘ │ ╠╣ │ └┬─┐ ║ ║ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ║ ║ ┌─┬┘ │ │ │ ╠╣ │ │ │ └┬┐ ┌┬┘ │ │ │ ╠╣ │ │ │ └┬─┐ ║ ╠┬┘ │ │ │ │ ╠╣ │ │ │ │└¤┘│ │ │ │ ╠╣ │ │ │ │ └┬╣ ║│ │ │ │ │ ╠╣ │ │ │ │ │ │ │ │ ╠╣ │ │ │ │ │║ ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣ ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣ ║ ╠╣ ╠╣ ║ ║ ╠╣ ╠╣ ║ ║ , ╠╣ , ,' * ╠╣ ║ ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║ ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝ - one protocol, one bridge = infinite possibilities - *************************************************************** DISCLAIMER: U.S Patent Pending LICENSE: Holograph Limited Public License (H-LPL) https://holograph.xyz/licenses/h-lpl/1.0.0 This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, you are not permitted to use the software. 1. Definitions The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor’s patent claims that read directly on its contribution. 2. Grant of Rights A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in sections 3 and 4, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 3. Conditions and Limitations A) No Trademark License- This license does not grant you rights to use any contributors’ name, logo, or trademarks. B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor is terminated with immediate effect. C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. E) The software is licensed “as-is.” You bear all risks of using it. The contributors give no express warranties, guarantees, or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude all implied warranties, including those of merchantability, fitness for a particular purpose and non-infringement. 4. (F) Platform Limitation- The licenses granted in sections 2.A & 2.B extend only to the software or derivative works that you create that run on a Holograph system product. *************************************************************** */ pragma solidity 0.8.13; import "../abstract/Initializable.sol"; abstract contract ERC721H is Initializable { /** * @dev bytes32(uint256(keccak256('eip1967.Holograph.holographer')) - 1) */ bytes32 constant _holographerSlot = 0xe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd; /** * @dev bytes32(uint256(keccak256('eip1967.Holograph.owner')) - 1) */ bytes32 constant _ownerSlot = 0xb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf772777; modifier onlyHolographer() { require(msg.sender == holographer(), "ERC721: holographer only"); _; } modifier onlyOwner() { if (msg.sender == holographer()) { require(msgSender() == _getOwner(), "ERC721: owner only function"); } else { require(msg.sender == _getOwner(), "ERC721: owner only function"); } _; } /** * @dev Constructor is left empty and init is used instead */ constructor() {} /** * @notice Used internally to initialize the contract instead of through a constructor * @dev This function is called by the deployer/factory when creating a contract * @param initPayload abi encoded payload to use for contract initilaization */ function init(bytes memory initPayload) external virtual override returns (bytes4) { return _init(initPayload); } function _init(bytes memory /* initPayload*/) internal returns (bytes4) { require(!_isInitialized(), "ERC721: already initialized"); address _holographer = msg.sender; address currentOwner; assembly { sstore(_holographerSlot, _holographer) currentOwner := sload(_ownerSlot) } require(currentOwner != address(0), "HOLOGRAPH: owner not set"); _setInitialized(); return InitializableInterface.init.selector; } /** * @dev The Holographer passes original msg.sender via calldata. This function extracts it. */ function msgSender() internal pure returns (address sender) { assembly { sender := calldataload(sub(calldatasize(), 0x20)) } } /** * @dev Address of Holograph ERC721 standards enforcer smart contract. */ function holographer() internal view returns (address _holographer) { assembly { _holographer := sload(_holographerSlot) } } function supportsInterface(bytes4) external pure virtual returns (bool) { return false; } /** * @dev Address of initial creator/owner of the collection. */ function owner() external view virtual returns (address) { return _getOwner(); } function isOwner() external view returns (bool) { if (msg.sender == holographer()) { return msgSender() == _getOwner(); } else { return msg.sender == _getOwner(); } } function isOwner(address wallet) external view returns (bool) { return wallet == _getOwner(); } function _getOwner() internal view returns (address ownerAddress) { assembly { ownerAddress := sload(_ownerSlot) } } function _setOwner(address ownerAddress) internal { assembly { sstore(_ownerSlot, ownerAddress) } } function withdraw() external virtual onlyOwner { payable(_getOwner()).transfer(address(this).balance); } event FundsReceived(address indexed source, uint256 amount); /** * @dev This function emits an event to indicate native gas token receipt. Do not rely on this to work. * Please use custom payable functions for accepting native value. */ receive() external payable virtual { emit FundsReceived(msgSender(), msg.value); } /** * @dev Return true for any un-implemented event hooks */ fallback() external payable virtual { assembly { switch eq(sload(_holographerSlot), caller()) case 1 { mstore(0x80, 0x0000000000000000000000000000000000000000000000000000000000000001) return(0x80, 0x20) } default { revert(0x00, 0x00) } } } }
// SPDX-License-Identifier: UNLICENSED /* ┌───────────┐ │ HOLOGRAPH │ └───────────┘ ╔═════════════════════════════════════════════════════════════╗ ║ ║ ║ / ^ \ ║ ║ ~~*~~ ¸ ║ ║ [ '<>:<>' ] │░░░ ║ ║ ╔╗ _/"\_ ╔╣ ║ ║ ┌─╬╬─┐ """ ┌─╬╬─┐ ║ ║ ┌─┬┘ ╠╣ └┬─┐ \_/ ┌─┬┘ ╠╣ └┬─┐ ║ ║ ┌─┬┘ │ ╠╣ │ └┬─┐ ┌─┬┘ │ ╠╣ │ └┬─┐ ║ ║ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ║ ║ ┌─┬┘ │ │ │ ╠╣ │ │ │ └┬┐ ┌┬┘ │ │ │ ╠╣ │ │ │ └┬─┐ ║ ╠┬┘ │ │ │ │ ╠╣ │ │ │ │└¤┘│ │ │ │ ╠╣ │ │ │ │ └┬╣ ║│ │ │ │ │ ╠╣ │ │ │ │ │ │ │ │ ╠╣ │ │ │ │ │║ ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣ ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣ ║ ╠╣ ╠╣ ║ ║ ╠╣ ╠╣ ║ ║ , ╠╣ , ,' * ╠╣ ║ ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║ ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝ - one protocol, one bridge = infinite possibilities - *************************************************************** DISCLAIMER: U.S Patent Pending LICENSE: Holograph Limited Public License (H-LPL) https://holograph.xyz/licenses/h-lpl/1.0.0 This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, you are not permitted to use the software. 1. Definitions The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor’s patent claims that read directly on its contribution. 2. Grant of Rights A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in sections 3 and 4, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 3. Conditions and Limitations A) No Trademark License- This license does not grant you rights to use any contributors’ name, logo, or trademarks. B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor is terminated with immediate effect. C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. E) The software is licensed “as-is.” You bear all risks of using it. The contributors give no express warranties, guarantees, or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude all implied warranties, including those of merchantability, fitness for a particular purpose and non-infringement. 4. (F) Platform Limitation- The licenses granted in sections 2.A & 2.B extend only to the software or derivative works that you create that run on a Holograph system product. *************************************************************** */ pragma solidity 0.8.13; import "../interface/InitializableInterface.sol"; /** * @title Initializable * @author https://github.com/holographxyz * @notice Use init instead of constructor * @dev This allows for use of init function to make one time initializations without the need for a constructor */ abstract contract Initializable is InitializableInterface { /** * @dev bytes32(uint256(keccak256('eip1967.Holograph.initialized')) - 1) */ bytes32 constant _initializedSlot = 0x4e5f991bca30eca2d4643aaefa807e88f96a4a97398933d572a3c0d973004a01; /** * @dev Constructor is left empty and init is used instead */ constructor() {} /** * @notice Used internally to initialize the contract instead of through a constructor * @dev This function is called by the deployer/factory when creating a contract * @param initPayload abi encoded payload to use for contract initilaization */ function init(bytes memory initPayload) external virtual returns (bytes4); function _isInitialized() internal view returns (bool initialized) { assembly { initialized := sload(_initializedSlot) } } function _setInitialized() internal { assembly { sstore(_initializedSlot, 0x0000000000000000000000000000000000000000000000000000000000000001) } } }
// SPDX-License-Identifier: UNLICENSED /* ┌───────────┐ │ HOLOGRAPH │ └───────────┘ ╔═════════════════════════════════════════════════════════════╗ ║ ║ ║ / ^ \ ║ ║ ~~*~~ ¸ ║ ║ [ '<>:<>' ] │░░░ ║ ║ ╔╗ _/"\_ ╔╣ ║ ║ ┌─╬╬─┐ """ ┌─╬╬─┐ ║ ║ ┌─┬┘ ╠╣ └┬─┐ \_/ ┌─┬┘ ╠╣ └┬─┐ ║ ║ ┌─┬┘ │ ╠╣ │ └┬─┐ ┌─┬┘ │ ╠╣ │ └┬─┐ ║ ║ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ║ ║ ┌─┬┘ │ │ │ ╠╣ │ │ │ └┬┐ ┌┬┘ │ │ │ ╠╣ │ │ │ └┬─┐ ║ ╠┬┘ │ │ │ │ ╠╣ │ │ │ │└¤┘│ │ │ │ ╠╣ │ │ │ │ └┬╣ ║│ │ │ │ │ ╠╣ │ │ │ │ │ │ │ │ ╠╣ │ │ │ │ │║ ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣ ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣ ║ ╠╣ ╠╣ ║ ║ ╠╣ ╠╣ ║ ║ , ╠╣ , ,' * ╠╣ ║ ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║ ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝ - one protocol, one bridge = infinite possibilities - *************************************************************** DISCLAIMER: U.S Patent Pending LICENSE: Holograph Limited Public License (H-LPL) https://holograph.xyz/licenses/h-lpl/1.0.0 This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, you are not permitted to use the software. 1. Definitions The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor’s patent claims that read directly on its contribution. 2. Grant of Rights A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in sections 3 and 4, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 3. Conditions and Limitations A) No Trademark License- This license does not grant you rights to use any contributors’ name, logo, or trademarks. B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor is terminated with immediate effect. C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. E) The software is licensed “as-is.” You bear all risks of using it. The contributors give no express warranties, guarantees, or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude all implied warranties, including those of merchantability, fitness for a particular purpose and non-infringement. 4. (F) Platform Limitation- The licenses granted in sections 2.A & 2.B extend only to the software or derivative works that you create that run on a Holograph system product. *************************************************************** */ pragma solidity 0.8.13; abstract contract NonReentrant { /** * @dev bytes32(uint256(keccak256('eip1967.Holograph.reentrant')) - 1) */ bytes32 constant _reentrantSlot = 0x04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a3137279; modifier nonReentrant() { require(getStatus() != 2, "HOLOGRAPH: reentrant call"); setStatus(2); _; setStatus(1); } constructor() {} function getStatus() internal view returns (uint256 status) { assembly { status := sload(_reentrantSlot) } } function setStatus(uint256 status) internal { assembly { sstore(_reentrantSlot, status) } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IDropsPriceOracle { function convertUsdToWei(uint256 usdAmount) external view returns (uint256 weiAmount); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import {IMetadataRenderer} from "./IMetadataRenderer.sol"; import {AddressMintDetails} from "../struct/AddressMintDetails.sol"; import {SaleDetails} from "../struct/SaleDetails.sol"; /// @notice Interface for HOLOGRAPH Drops contract interface IHolographDropERC721 { // Access errors /// @notice Only admin can access this function error Access_OnlyAdmin(); /// @notice Missing the given role or admin access error Access_MissingRoleOrAdmin(bytes32 role); /// @notice Withdraw is not allowed by this user error Access_WithdrawNotAllowed(); /// @notice Cannot withdraw funds due to ETH send failure. error Withdraw_FundsSendFailure(); /// @notice Mint fee send failure error MintFee_FundsSendFailure(); /// @notice Call to external metadata renderer failed. error ExternalMetadataRenderer_CallFailed(); /// @notice Thrown when the operator for the contract is not allowed /// @dev Used when strict enforcement of marketplaces for creator royalties is desired. error OperatorNotAllowed(address operator); /// @notice Thrown when there is no active market filter DAO address supported for the current chain /// @dev Used for enabling and disabling filter for the given chain. error MarketFilterDAOAddressNotSupportedForChain(); /// @notice Used when the operator filter registry external call fails /// @dev Used for bubbling error up to clients. error RemoteOperatorFilterRegistryCallFailed(); // Sale/Purchase errors /// @notice Sale is inactive error Sale_Inactive(); /// @notice Presale is inactive error Presale_Inactive(); /// @notice Presale merkle root is invalid error Presale_MerkleNotApproved(); /// @notice Wrong price for purchase error Purchase_WrongPrice(uint256 correctPrice); /// @notice NFT sold out error Mint_SoldOut(); /// @notice Too many purchase for address error Purchase_TooManyForAddress(); /// @notice Too many presale for address error Presale_TooManyForAddress(); // Admin errors /// @notice Royalty percentage too high error Setup_RoyaltyPercentageTooHigh(uint16 maxRoyaltyBPS); /// @notice Invalid admin upgrade address error Admin_InvalidUpgradeAddress(address proposedAddress); /// @notice Unable to finalize an edition not marked as open (size set to uint64_max_value) error Admin_UnableToFinalizeNotOpenEdition(); /// @notice Event emitted for mint fee payout /// @param mintFeeAmount amount of the mint fee /// @param mintFeeRecipient recipient of the mint fee /// @param success if the payout succeeded event MintFeePayout(uint256 mintFeeAmount, address mintFeeRecipient, bool success); /// @notice Event emitted for each sale /// @param to address sale was made to /// @param quantity quantity of the minted nfts /// @param pricePerToken price for each token /// @param firstPurchasedTokenId first purchased token ID (to get range add to quantity for max) event Sale( address indexed to, uint256 indexed quantity, uint256 indexed pricePerToken, uint256 firstPurchasedTokenId ); /// @notice Sales configuration has been changed /// @dev To access new sales configuration, use getter function. /// @param changedBy Changed by user event SalesConfigChanged(address indexed changedBy); /// @notice Event emitted when the funds recipient is changed /// @param newAddress new address for the funds recipient /// @param changedBy address that the recipient is changed by event FundsRecipientChanged(address indexed newAddress, address indexed changedBy); /// @notice Event emitted when the funds are withdrawn from the minting contract /// @param withdrawnBy address that issued the withdraw /// @param withdrawnTo address that the funds were withdrawn to /// @param amount amount that was withdrawn /// @param feeRecipient user getting withdraw fee (if any) /// @param feeAmount amount of the fee getting sent (if any) event FundsWithdrawn( address indexed withdrawnBy, address indexed withdrawnTo, uint256 amount, address feeRecipient, uint256 feeAmount ); /// @notice Event emitted when an open mint is finalized and further minting is closed forever on the contract. /// @param sender address sending close mint /// @param numberOfMints number of mints the contract is finalized at event OpenMintFinalized(address indexed sender, uint256 numberOfMints); /// @notice Event emitted when metadata renderer is updated. /// @param sender address of the updater /// @param renderer new metadata renderer address event UpdatedMetadataRenderer(address sender, IMetadataRenderer renderer); /// @notice Admin function to update the sales configuration settings /// @param publicSalePrice public sale price in ether /// @param maxSalePurchasePerAddress Max # of purchases (public) per address allowed /// @param publicSaleStart unix timestamp when the public sale starts /// @param publicSaleEnd unix timestamp when the public sale ends (set to 0 to disable) /// @param presaleStart unix timestamp when the presale starts /// @param presaleEnd unix timestamp when the presale ends /// @param presaleMerkleRoot merkle root for the presale information function setSaleConfiguration( uint104 publicSalePrice, uint32 maxSalePurchasePerAddress, uint64 publicSaleStart, uint64 publicSaleEnd, uint64 presaleStart, uint64 presaleEnd, bytes32 presaleMerkleRoot ) external; /// @notice External purchase function (payable in eth) /// @param quantity to purchase /// @return first minted token ID function purchase(uint256 quantity) external payable returns (uint256); /// @notice External purchase presale function (takes a merkle proof and matches to root) (payable in eth) /// @param quantity to purchase /// @param maxQuantity can purchase (verified by merkle root) /// @param pricePerToken price per token allowed (verified by merkle root) /// @param merkleProof input for merkle proof leaf verified by merkle root /// @return first minted token ID function purchasePresale( uint256 quantity, uint256 maxQuantity, uint256 pricePerToken, bytes32[] memory merkleProof ) external payable returns (uint256); /// @notice Function to return the global sales details for the given drop function saleDetails() external view returns (SaleDetails memory); /// @notice Function to return the specific sales details for a given address /// @param minter address for minter to return mint information for function mintedPerAddress(address minter) external view returns (AddressMintDetails memory); /// @notice This is the opensea/public owner setting that can be set by the contract admin function owner() external view returns (address); /// @notice Update the metadata renderer /// @param newRenderer new address for renderer /// @param setupRenderer data to call to bootstrap data for the new renderer (optional) function setMetadataRenderer(IMetadataRenderer newRenderer, bytes memory setupRenderer) external; /// @notice This is an admin mint function to mint a quantity to a specific address /// @param to address to mint to /// @param quantity quantity to mint /// @return the id of the first minted NFT function adminMint(address to, uint256 quantity) external returns (uint256); /// @notice This is an admin mint function to mint a single nft each to a list of addresses /// @param to list of addresses to mint an NFT each to /// @return the id of the first minted NFT function adminMintAirdrop(address[] memory to) external returns (uint256); /// @dev Getter for admin role associated with the contract to handle metadata /// @return boolean if address is admin function isAdmin(address user) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IMetadataRenderer { function tokenURI(uint256) external view returns (string memory); function contractURI() external view returns (string memory); function initializeWithData(bytes memory initData) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IOperatorFilterRegistry { function isOperatorAllowed(address registrant, address operator) external view returns (bool); function register(address registrant) external; function registerAndSubscribe(address registrant, address subscription) external; function registerAndCopyEntries(address registrant, address registrantToCopy) external; function updateOperator(address registrant, address operator, bool filtered) external; function updateOperators(address registrant, address[] calldata operators, bool filtered) external; function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external; function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external; function subscribe(address registrant, address registrantToSubscribe) external; function unsubscribe(address registrant, bool copyExistingEntries) external; function subscriptionOf(address addr) external returns (address registrant); function subscribers(address registrant) external returns (address[] memory); function subscriberAt(address registrant, uint256 index) external returns (address); function copyEntriesOf(address registrant, address registrantToCopy) external; function isOperatorFiltered(address registrant, address operator) external returns (bool); function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool); function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool); function filteredOperators(address addr) external returns (address[] memory); function filteredCodeHashes(address addr) external returns (bytes32[] memory); function filteredOperatorAt(address registrant, uint256 index) external returns (address); function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32); function isRegistered(address addr) external returns (bool); function codeHashOf(address addr) external returns (bytes32); function unregister(address registrant) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; library Address { function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { bytes32 proofElement = proof[i]; if (computedHash <= proofElement) { // Hash(current computed hash + current element of the proof) computedHash = _efficientHash(computedHash, proofElement); } else { // Hash(current element of the proof + current computed hash) computedHash = _efficientHash(proofElement, computedHash); } } return computedHash; } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; /// @notice Return type of specific mint counts and details per address struct AddressMintDetails { /// Number of total mints from the given address uint256 totalMints; /// Number of presale mints from the given address uint256 presaleMints; /// Number of public mints from the given address uint256 publicMints; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import {IMetadataRenderer} from "../interface/IMetadataRenderer.sol"; /// @notice General configuration for NFT Minting and bookkeeping struct Configuration { /// @dev Metadata renderer (uint160) IMetadataRenderer metadataRenderer; /// @dev Total size of edition that can be minted (uint160+64 = 224) uint64 editionSize; /// @dev Royalty amount in bps (uint224+16 = 240) uint16 royaltyBPS; /// @dev Funds recipient for sale (new slot, uint160) address payable fundsRecipient; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import {SalesConfiguration} from "./SalesConfiguration.sol"; /// @param erc721TransferHelper Transfer helper contract /// @param marketFilterAddress Market filter address - Manage subscription to the for marketplace filtering based off royalty payouts. /// @param initialOwner User that owns and can mint the edition, gets royalty and sales payouts and can update the base url if needed. /// @param fundsRecipient Wallet/user that receives funds from sale /// @param editionSize Number of editions that can be minted in total. If type(uint64).max, unlimited editions can be minted as an open edition. /// @param royaltyBPS BPS of the royalty set on the contract. Can be 0 for no royalty. /// @param salesConfiguration The initial SalesConfiguration /// @param metadataRenderer Renderer contract to use /// @param metadataRendererInit Renderer data initial contract struct DropsInitializer { address erc721TransferHelper; address marketFilterAddress; address initialOwner; address payable fundsRecipient; uint64 editionSize; uint16 royaltyBPS; bool enableOpenSeaRoyaltyRegistry; SalesConfiguration salesConfiguration; address metadataRenderer; bytes metadataRendererInit; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; /// @notice Return value for sales details to use with front-ends struct SaleDetails { // Synthesized status variables for sale and presale bool publicSaleActive; bool presaleActive; // Price for public sale uint256 publicSalePrice; // Timed sale actions for public sale uint64 publicSaleStart; uint64 publicSaleEnd; // Timed sale actions for presale uint64 presaleStart; uint64 presaleEnd; // Merkle root (includes address, quantity, and price data for each entry) bytes32 presaleMerkleRoot; // Limit public sale to a specific number of mints per wallet uint256 maxSalePurchasePerAddress; // Information about the rest of the supply // Total that have been minted uint256 totalMinted; // The total supply available uint256 maxSupply; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; /// @notice Sales states and configuration /// @dev Uses 3 storage slots struct SalesConfiguration { /// @dev Public sale price (max ether value > 1000 ether with this value) uint104 publicSalePrice; /// @notice Purchase mint limit per address (if set to 0 === unlimited mints) /// @dev Max purchase number per txn (90+32 = 122) uint32 maxSalePurchasePerAddress; /// @dev uint64 type allows for dates into 292 billion years /// @notice Public sale start timestamp (136+64 = 186) uint64 publicSaleStart; /// @notice Public sale end timestamp (186+64 = 250) uint64 publicSaleEnd; /// @notice Presale start timestamp /// @dev new storage slot uint64 presaleStart; /// @notice Presale end timestamp uint64 presaleEnd; /// @notice Presale merkle root bytes32 presaleMerkleRoot; }
// SPDX-License-Identifier: UNLICENSED /* ┌───────────┐ │ HOLOGRAPH │ └───────────┘ ╔═════════════════════════════════════════════════════════════╗ ║ ║ ║ / ^ \ ║ ║ ~~*~~ ¸ ║ ║ [ '<>:<>' ] │░░░ ║ ║ ╔╗ _/"\_ ╔╣ ║ ║ ┌─╬╬─┐ """ ┌─╬╬─┐ ║ ║ ┌─┬┘ ╠╣ └┬─┐ \_/ ┌─┬┘ ╠╣ └┬─┐ ║ ║ ┌─┬┘ │ ╠╣ │ └┬─┐ ┌─┬┘ │ ╠╣ │ └┬─┐ ║ ║ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ║ ║ ┌─┬┘ │ │ │ ╠╣ │ │ │ └┬┐ ┌┬┘ │ │ │ ╠╣ │ │ │ └┬─┐ ║ ╠┬┘ │ │ │ │ ╠╣ │ │ │ │└¤┘│ │ │ │ ╠╣ │ │ │ │ └┬╣ ║│ │ │ │ │ ╠╣ │ │ │ │ │ │ │ │ ╠╣ │ │ │ │ │║ ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣ ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣ ║ ╠╣ ╠╣ ║ ║ ╠╣ ╠╣ ║ ║ , ╠╣ , ,' * ╠╣ ║ ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║ ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝ - one protocol, one bridge = infinite possibilities - *************************************************************** DISCLAIMER: U.S Patent Pending LICENSE: Holograph Limited Public License (H-LPL) https://holograph.xyz/licenses/h-lpl/1.0.0 This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, you are not permitted to use the software. 1. Definitions The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor’s patent claims that read directly on its contribution. 2. Grant of Rights A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in sections 3 and 4, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 3. Conditions and Limitations A) No Trademark License- This license does not grant you rights to use any contributors’ name, logo, or trademarks. B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor is terminated with immediate effect. C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. E) The software is licensed “as-is.” You bear all risks of using it. The contributors give no express warranties, guarantees, or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude all implied warranties, including those of merchantability, fitness for a particular purpose and non-infringement. 4. (F) Platform Limitation- The licenses granted in sections 2.A & 2.B extend only to the software or derivative works that you create that run on a Holograph system product. *************************************************************** */ pragma solidity 0.8.13; interface CollectionURI { function contractURI() external view returns (string memory); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.13; interface ERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @dev Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface(bytes4 interfaceID) external view returns (bool); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.13; /// @title ERC-721 Non-Fungible Token Standard /// @dev See https://eips.ethereum.org/EIPS/eip-721 /// Note: the ERC-165 identifier for this interface is 0x80ac58cd. /* is ERC165 */ interface ERC721 { /// @dev This emits when ownership of any NFT changes by any mechanism. /// This event emits when NFTs are created (`from` == 0) and destroyed /// (`to` == 0). Exception: during contract creation, any number of NFTs /// may be created and assigned without emitting Transfer. At the time of /// any transfer, the approved address for that NFT (if any) is reset to none. event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); /// @dev This emits when the approved address for an NFT is changed or /// reaffirmed. The zero address indicates there is no approved address. /// When a Transfer event emits, this also indicates that the approved /// address for that NFT (if any) is reset to none. event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); /// @dev This emits when an operator is enabled or disabled for an owner. /// The operator can manage all NFTs of the owner. event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); /// @notice Count all NFTs assigned to an owner /// @dev NFTs assigned to the zero address are considered invalid, and this /// function throws for queries about the zero address. /// @param _owner An address for whom to query the balance /// @return The number of NFTs owned by `_owner`, possibly zero function balanceOf(address _owner) external view returns (uint256); /// @notice Find the owner of an NFT /// @dev NFTs assigned to zero address are considered invalid, and queries /// about them do throw. /// @param _tokenId The identifier for an NFT /// @return The address of the owner of the NFT function ownerOf(uint256 _tokenId) external view returns (address); /// @notice Transfers the ownership of an NFT from one address to another address /// @dev Throws unless `msg.sender` is the current owner, an authorized /// operator, or the approved address for this NFT. Throws if `_from` is /// not the current owner. Throws if `_to` is the zero address. Throws if /// `_tokenId` is not a valid NFT. When transfer is complete, this function /// checks if `_to` is a smart contract (code size > 0). If so, it calls /// `onERC721Received` on `_to` and throws if the return value is not /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer /// @param data Additional data with no specified format, sent in call to `_to` function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable; /// @notice Transfers the ownership of an NFT from one address to another address /// @dev This works identically to the other function with an extra data parameter, /// except this function just sets data to "". /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE /// THEY MAY BE PERMANENTLY LOST /// @dev Throws unless `msg.sender` is the current owner, an authorized /// operator, or the approved address for this NFT. Throws if `_from` is /// not the current owner. Throws if `_to` is the zero address. Throws if /// `_tokenId` is not a valid NFT. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer function transferFrom(address _from, address _to, uint256 _tokenId) external payable; /// @notice Change or reaffirm the approved address for an NFT /// @dev The zero address indicates there is no approved address. /// Throws unless `msg.sender` is the current NFT owner, or an authorized /// operator of the current owner. /// @param _approved The new approved NFT controller /// @param _tokenId The NFT to approve function approve(address _approved, uint256 _tokenId) external payable; /// @notice Enable or disable approval for a third party ("operator") to manage /// all of `msg.sender`'s assets /// @dev Emits the ApprovalForAll event. The contract MUST allow /// multiple operators per owner. /// @param _operator Address to add to the set of authorized operators /// @param _approved True if the operator is approved, false to revoke approval function setApprovalForAll(address _operator, bool _approved) external; /// @notice Get the approved address for a single NFT /// @dev Throws if `_tokenId` is not a valid NFT. /// @param _tokenId The NFT to find the approved address for /// @return The approved address for this NFT, or the zero address if there is none function getApproved(uint256 _tokenId) external view returns (address); /// @notice Query if an address is an authorized operator for another address /// @param _owner The address that owns the NFTs /// @param _operator The address that acts on behalf of the owner /// @return True if `_operator` is an approved operator for `_owner`, false otherwise function isApprovedForAll(address _owner, address _operator) external view returns (bool); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.13; /// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension /// @dev See https://eips.ethereum.org/EIPS/eip-721 /// Note: the ERC-165 identifier for this interface is 0x780e9d63. /* is ERC721 */ interface ERC721Enumerable { /// @notice Count NFTs tracked by this contract /// @return A count of valid NFTs tracked by this contract, where each one of /// them has an assigned and queryable owner not equal to the zero address function totalSupply() external view returns (uint256); /// @notice Enumerate valid NFTs /// @dev Throws if `_index` >= `totalSupply()`. /// @param _index A counter less than `totalSupply()` /// @return The token identifier for the `_index`th NFT, /// (sort order not specified) function tokenByIndex(uint256 _index) external view returns (uint256); /// @notice Enumerate NFTs assigned to an owner /// @dev Throws if `_index` >= `balanceOf(_owner)` or if /// `_owner` is the zero address, representing invalid NFTs. /// @param _owner An address where we are interested in NFTs owned by them /// @param _index A counter less than `balanceOf(_owner)` /// @return The token identifier for the `_index`th NFT assigned to `_owner`, /// (sort order not specified) function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.13; /// @title ERC-721 Non-Fungible Token Standard, optional metadata extension /// @dev See https://eips.ethereum.org/EIPS/eip-721 /// Note: the ERC-165 identifier for this interface is 0x5b5e139f. /* is ERC721 */ interface ERC721Metadata { /// @notice A descriptive name for a collection of NFTs in this contract function name() external view returns (string memory _name); /// @notice An abbreviated name for NFTs in this contract function symbol() external view returns (string memory _symbol); /// @notice A distinct Uniform Resource Identifier (URI) for a given asset. /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC /// 3986. The URI may point to a JSON file that conforms to the "ERC721 /// Metadata JSON Schema". function tokenURI(uint256 _tokenId) external view returns (string memory); }
// SPDX-License-Identifier: UNLICENSED /* ┌───────────┐ │ HOLOGRAPH │ └───────────┘ ╔═════════════════════════════════════════════════════════════╗ ║ ║ ║ / ^ \ ║ ║ ~~*~~ ¸ ║ ║ [ '<>:<>' ] │░░░ ║ ║ ╔╗ _/"\_ ╔╣ ║ ║ ┌─╬╬─┐ """ ┌─╬╬─┐ ║ ║ ┌─┬┘ ╠╣ └┬─┐ \_/ ┌─┬┘ ╠╣ └┬─┐ ║ ║ ┌─┬┘ │ ╠╣ │ └┬─┐ ┌─┬┘ │ ╠╣ │ └┬─┐ ║ ║ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ║ ║ ┌─┬┘ │ │ │ ╠╣ │ │ │ └┬┐ ┌┬┘ │ │ │ ╠╣ │ │ │ └┬─┐ ║ ╠┬┘ │ │ │ │ ╠╣ │ │ │ │└¤┘│ │ │ │ ╠╣ │ │ │ │ └┬╣ ║│ │ │ │ │ ╠╣ │ │ │ │ │ │ │ │ ╠╣ │ │ │ │ │║ ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣ ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣ ║ ╠╣ ╠╣ ║ ║ ╠╣ ╠╣ ║ ║ , ╠╣ , ,' * ╠╣ ║ ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║ ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝ - one protocol, one bridge = infinite possibilities - *************************************************************** DISCLAIMER: U.S Patent Pending LICENSE: Holograph Limited Public License (H-LPL) https://holograph.xyz/licenses/h-lpl/1.0.0 This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, you are not permitted to use the software. 1. Definitions The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor’s patent claims that read directly on its contribution. 2. Grant of Rights A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in sections 3 and 4, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 3. Conditions and Limitations A) No Trademark License- This license does not grant you rights to use any contributors’ name, logo, or trademarks. B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor is terminated with immediate effect. C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. E) The software is licensed “as-is.” You bear all risks of using it. The contributors give no express warranties, guarantees, or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude all implied warranties, including those of merchantability, fitness for a particular purpose and non-infringement. 4. (F) Platform Limitation- The licenses granted in sections 2.A & 2.B extend only to the software or derivative works that you create that run on a Holograph system product. *************************************************************** */ pragma solidity 0.8.13; /// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02. interface ERC721TokenReceiver { /// @notice Handle the receipt of an NFT /// @dev The ERC721 smart contract calls this function on the recipient /// after a `transfer`. This function MAY throw to revert and reject the /// transfer. Return of other than the magic value MUST result in the /// transaction being reverted. /// Note: the contract address is always the message sender. /// @param _operator The address which called `safeTransferFrom` function /// @param _from The address which previously owned the token /// @param _tokenId The NFT identifier which is being transferred /// @param _data Additional data with no specified format /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` /// unless throwing function onERC721Received( address _operator, address _from, uint256 _tokenId, bytes calldata _data ) external returns (bytes4); }
// SPDX-License-Identifier: UNLICENSED /* ┌───────────┐ │ HOLOGRAPH │ └───────────┘ ╔═════════════════════════════════════════════════════════════╗ ║ ║ ║ / ^ \ ║ ║ ~~*~~ ¸ ║ ║ [ '<>:<>' ] │░░░ ║ ║ ╔╗ _/"\_ ╔╣ ║ ║ ┌─╬╬─┐ """ ┌─╬╬─┐ ║ ║ ┌─┬┘ ╠╣ └┬─┐ \_/ ┌─┬┘ ╠╣ └┬─┐ ║ ║ ┌─┬┘ │ ╠╣ │ └┬─┐ ┌─┬┘ │ ╠╣ │ └┬─┐ ║ ║ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ║ ║ ┌─┬┘ │ │ │ ╠╣ │ │ │ └┬┐ ┌┬┘ │ │ │ ╠╣ │ │ │ └┬─┐ ║ ╠┬┘ │ │ │ │ ╠╣ │ │ │ │└¤┘│ │ │ │ ╠╣ │ │ │ │ └┬╣ ║│ │ │ │ │ ╠╣ │ │ │ │ │ │ │ │ ╠╣ │ │ │ │ │║ ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣ ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣ ║ ╠╣ ╠╣ ║ ║ ╠╣ ╠╣ ║ ║ , ╠╣ , ,' * ╠╣ ║ ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║ ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝ - one protocol, one bridge = infinite possibilities - *************************************************************** DISCLAIMER: U.S Patent Pending LICENSE: Holograph Limited Public License (H-LPL) https://holograph.xyz/licenses/h-lpl/1.0.0 This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, you are not permitted to use the software. 1. Definitions The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor’s patent claims that read directly on its contribution. 2. Grant of Rights A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in sections 3 and 4, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 3. Conditions and Limitations A) No Trademark License- This license does not grant you rights to use any contributors’ name, logo, or trademarks. B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor is terminated with immediate effect. C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. E) The software is licensed “as-is.” You bear all risks of using it. The contributors give no express warranties, guarantees, or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude all implied warranties, including those of merchantability, fitness for a particular purpose and non-infringement. 4. (F) Platform Limitation- The licenses granted in sections 2.A & 2.B extend only to the software or derivative works that you create that run on a Holograph system product. *************************************************************** */ pragma solidity 0.8.13; interface Holographable { function bridgeIn(uint32 fromChain, bytes calldata payload) external returns (bytes4); function bridgeOut( uint32 toChain, address sender, bytes calldata payload ) external returns (bytes4 selector, bytes memory data); }
// SPDX-License-Identifier: UNLICENSED /* ┌───────────┐ │ HOLOGRAPH │ └───────────┘ ╔═════════════════════════════════════════════════════════════╗ ║ ║ ║ / ^ \ ║ ║ ~~*~~ ¸ ║ ║ [ '<>:<>' ] │░░░ ║ ║ ╔╗ _/"\_ ╔╣ ║ ║ ┌─╬╬─┐ """ ┌─╬╬─┐ ║ ║ ┌─┬┘ ╠╣ └┬─┐ \_/ ┌─┬┘ ╠╣ └┬─┐ ║ ║ ┌─┬┘ │ ╠╣ │ └┬─┐ ┌─┬┘ │ ╠╣ │ └┬─┐ ║ ║ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ║ ║ ┌─┬┘ │ │ │ ╠╣ │ │ │ └┬┐ ┌┬┘ │ │ │ ╠╣ │ │ │ └┬─┐ ║ ╠┬┘ │ │ │ │ ╠╣ │ │ │ │└¤┘│ │ │ │ ╠╣ │ │ │ │ └┬╣ ║│ │ │ │ │ ╠╣ │ │ │ │ │ │ │ │ ╠╣ │ │ │ │ │║ ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣ ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣ ║ ╠╣ ╠╣ ║ ║ ╠╣ ╠╣ ║ ║ , ╠╣ , ,' * ╠╣ ║ ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║ ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝ - one protocol, one bridge = infinite possibilities - *************************************************************** DISCLAIMER: U.S Patent Pending LICENSE: Holograph Limited Public License (H-LPL) https://holograph.xyz/licenses/h-lpl/1.0.0 This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, you are not permitted to use the software. 1. Definitions The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor’s patent claims that read directly on its contribution. 2. Grant of Rights A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in sections 3 and 4, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 3. Conditions and Limitations A) No Trademark License- This license does not grant you rights to use any contributors’ name, logo, or trademarks. B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor is terminated with immediate effect. C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. E) The software is licensed “as-is.” You bear all risks of using it. The contributors give no express warranties, guarantees, or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude all implied warranties, including those of merchantability, fitness for a particular purpose and non-infringement. 4. (F) Platform Limitation- The licenses granted in sections 2.A & 2.B extend only to the software or derivative works that you create that run on a Holograph system product. *************************************************************** */ pragma solidity 0.8.13; import "./CollectionURI.sol"; import "./ERC165.sol"; import "./ERC721.sol"; import "./ERC721Enumerable.sol"; import "./ERC721Metadata.sol"; import "./ERC721TokenReceiver.sol"; import "./Holographable.sol"; interface HolographERC721Interface is ERC165, ERC721, ERC721Enumerable, ERC721Metadata, ERC721TokenReceiver, CollectionURI, Holographable { function approve(address to, uint256 tokenId) external payable; function burn(uint256 tokenId) external; function safeTransferFrom(address from, address to, uint256 tokenId) external payable; function setApprovalForAll(address to, bool approved) external; function sourceBurn(uint256 tokenId) external; function sourceMint(address to, uint224 tokenId) external; function sourceGetChainPrepend() external view returns (uint256); function sourceTransfer(address to, uint256 tokenId) external; function transfer(address to, uint256 tokenId) external payable; function contractURI() external view returns (string memory); function getApproved(uint256 tokenId) external view returns (address); function isApprovedForAll(address wallet, address operator) external view returns (bool); function name() external view returns (string memory); function burned(uint256 tokenId) external view returns (bool); function decimals() external pure returns (uint256); function exists(uint256 tokenId) external view returns (bool); function ownerOf(uint256 tokenId) external view returns (address); function supportsInterface(bytes4 interfaceId) external view returns (bool); function symbol() external view returns (string memory); function tokenByIndex(uint256 index) external view returns (uint256); function tokenOfOwnerByIndex(address wallet, uint256 index) external view returns (uint256); function tokensOfOwner(address wallet) external view returns (uint256[] memory); function tokenURI(uint256 tokenId) external view returns (string memory); function totalSupply() external view returns (uint256); }
// SPDX-License-Identifier: UNLICENSED /* ┌───────────┐ │ HOLOGRAPH │ └───────────┘ ╔═════════════════════════════════════════════════════════════╗ ║ ║ ║ / ^ \ ║ ║ ~~*~~ ¸ ║ ║ [ '<>:<>' ] │░░░ ║ ║ ╔╗ _/"\_ ╔╣ ║ ║ ┌─╬╬─┐ """ ┌─╬╬─┐ ║ ║ ┌─┬┘ ╠╣ └┬─┐ \_/ ┌─┬┘ ╠╣ └┬─┐ ║ ║ ┌─┬┘ │ ╠╣ │ └┬─┐ ┌─┬┘ │ ╠╣ │ └┬─┐ ║ ║ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ║ ║ ┌─┬┘ │ │ │ ╠╣ │ │ │ └┬┐ ┌┬┘ │ │ │ ╠╣ │ │ │ └┬─┐ ║ ╠┬┘ │ │ │ │ ╠╣ │ │ │ │└¤┘│ │ │ │ ╠╣ │ │ │ │ └┬╣ ║│ │ │ │ │ ╠╣ │ │ │ │ │ │ │ │ ╠╣ │ │ │ │ │║ ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣ ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣ ║ ╠╣ ╠╣ ║ ║ ╠╣ ╠╣ ║ ║ , ╠╣ , ,' * ╠╣ ║ ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║ ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝ - one protocol, one bridge = infinite possibilities - *************************************************************** DISCLAIMER: U.S Patent Pending LICENSE: Holograph Limited Public License (H-LPL) https://holograph.xyz/licenses/h-lpl/1.0.0 This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, you are not permitted to use the software. 1. Definitions The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor’s patent claims that read directly on its contribution. 2. Grant of Rights A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in sections 3 and 4, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 3. Conditions and Limitations A) No Trademark License- This license does not grant you rights to use any contributors’ name, logo, or trademarks. B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor is terminated with immediate effect. C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. E) The software is licensed “as-is.” You bear all risks of using it. The contributors give no express warranties, guarantees, or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude all implied warranties, including those of merchantability, fitness for a particular purpose and non-infringement. 4. (F) Platform Limitation- The licenses granted in sections 2.A & 2.B extend only to the software or derivative works that you create that run on a Holograph system product. *************************************************************** */ pragma solidity 0.8.13; interface HolographerInterface { function getContractType() external view returns (bytes32 contractType); function getDeploymentBlock() external view returns (uint256 deploymentBlock); function getHolograph() external view returns (address holograph); function getHolographEnforcer() external view returns (address); function getOriginChain() external view returns (uint32 originChain); function getSourceContract() external view returns (address sourceContract); }
// SPDX-License-Identifier: UNLICENSED /* ┌───────────┐ │ HOLOGRAPH │ └───────────┘ ╔═════════════════════════════════════════════════════════════╗ ║ ║ ║ / ^ \ ║ ║ ~~*~~ ¸ ║ ║ [ '<>:<>' ] │░░░ ║ ║ ╔╗ _/"\_ ╔╣ ║ ║ ┌─╬╬─┐ """ ┌─╬╬─┐ ║ ║ ┌─┬┘ ╠╣ └┬─┐ \_/ ┌─┬┘ ╠╣ └┬─┐ ║ ║ ┌─┬┘ │ ╠╣ │ └┬─┐ ┌─┬┘ │ ╠╣ │ └┬─┐ ║ ║ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ║ ║ ┌─┬┘ │ │ │ ╠╣ │ │ │ └┬┐ ┌┬┘ │ │ │ ╠╣ │ │ │ └┬─┐ ║ ╠┬┘ │ │ │ │ ╠╣ │ │ │ │└¤┘│ │ │ │ ╠╣ │ │ │ │ └┬╣ ║│ │ │ │ │ ╠╣ │ │ │ │ │ │ │ │ ╠╣ │ │ │ │ │║ ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣ ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣ ║ ╠╣ ╠╣ ║ ║ ╠╣ ╠╣ ║ ║ , ╠╣ , ,' * ╠╣ ║ ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║ ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝ - one protocol, one bridge = infinite possibilities - *************************************************************** DISCLAIMER: U.S Patent Pending LICENSE: Holograph Limited Public License (H-LPL) https://holograph.xyz/licenses/h-lpl/1.0.0 This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, you are not permitted to use the software. 1. Definitions The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor’s patent claims that read directly on its contribution. 2. Grant of Rights A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in sections 3 and 4, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 3. Conditions and Limitations A) No Trademark License- This license does not grant you rights to use any contributors’ name, logo, or trademarks. B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor is terminated with immediate effect. C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. E) The software is licensed “as-is.” You bear all risks of using it. The contributors give no express warranties, guarantees, or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude all implied warranties, including those of merchantability, fitness for a particular purpose and non-infringement. 4. (F) Platform Limitation- The licenses granted in sections 2.A & 2.B extend only to the software or derivative works that you create that run on a Holograph system product. *************************************************************** */ pragma solidity 0.8.13; /** * @title Holograph Protocol * @author https://github.com/holographxyz * @notice This is the primary Holograph Protocol smart contract * @dev This contract stores a reference to all the primary modules and variables of the protocol */ interface HolographInterface { /** * @notice Get the address of the Holograph Bridge module * @dev Used for beaming holographable assets cross-chain */ function getBridge() external view returns (address bridge); /** * @notice Update the Holograph Bridge module address * @param bridge address of the Holograph Bridge smart contract to use */ function setBridge(address bridge) external; /** * @notice Get the chain ID that the Protocol was deployed on * @dev Useful for checking if/when a hard fork occurs */ function getChainId() external view returns (uint256 chainId); /** * @notice Update the chain ID * @dev Useful for updating once a hard fork has been mitigated * @param chainId EVM chain ID to use */ function setChainId(uint256 chainId) external; /** * @notice Get the address of the Holograph Factory module * @dev Used for deploying holographable smart contracts */ function getFactory() external view returns (address factory); /** * @notice Update the Holograph Factory module address * @param factory address of the Holograph Factory smart contract to use */ function setFactory(address factory) external; /** * @notice Get the Holograph chain Id * @dev Holograph uses an internal chain id mapping */ function getHolographChainId() external view returns (uint32 holographChainId); /** * @notice Update the Holograph chain ID * @dev Useful for updating once a hard fork was mitigated * @param holographChainId Holograph chain ID to use */ function setHolographChainId(uint32 holographChainId) external; /** * @notice Get the address of the Holograph Interfaces module * @dev Holograph uses this contract to store data that needs to be accessed by a large portion of the modules */ function getInterfaces() external view returns (address interfaces); /** * @notice Update the Holograph Interfaces module address * @param interfaces address of the Holograph Interfaces smart contract to use */ function setInterfaces(address interfaces) external; /** * @notice Get the address of the Holograph Operator module * @dev All cross-chain Holograph Bridge beams are handled by the Holograph Operator module */ function getOperator() external view returns (address operator); /** * @notice Update the Holograph Operator module address * @param operator address of the Holograph Operator smart contract to use */ function setOperator(address operator) external; /** * @notice Get the Holograph Registry module * @dev This module stores a reference for all deployed holographable smart contracts */ function getRegistry() external view returns (address registry); /** * @notice Update the Holograph Registry module address * @param registry address of the Holograph Registry smart contract to use */ function setRegistry(address registry) external; /** * @notice Get the Holograph Treasury module * @dev All of the Holograph Protocol assets are stored and managed by this module */ function getTreasury() external view returns (address treasury); /** * @notice Update the Holograph Treasury module address * @param treasury address of the Holograph Treasury smart contract to use */ function setTreasury(address treasury) external; /** * @notice Get the Holograph Utility Token address * @dev This is the official utility token of the Holograph Protocol */ function getUtilityToken() external view returns (address utilityToken); /** * @notice Update the Holograph Utility Token address * @param utilityToken address of the Holograph Utility Token smart contract to use */ function setUtilityToken(address utilityToken) external; }
// SPDX-License-Identifier: UNLICENSED /* ┌───────────┐ │ HOLOGRAPH │ └───────────┘ ╔═════════════════════════════════════════════════════════════╗ ║ ║ ║ / ^ \ ║ ║ ~~*~~ ¸ ║ ║ [ '<>:<>' ] │░░░ ║ ║ ╔╗ _/"\_ ╔╣ ║ ║ ┌─╬╬─┐ """ ┌─╬╬─┐ ║ ║ ┌─┬┘ ╠╣ └┬─┐ \_/ ┌─┬┘ ╠╣ └┬─┐ ║ ║ ┌─┬┘ │ ╠╣ │ └┬─┐ ┌─┬┘ │ ╠╣ │ └┬─┐ ║ ║ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ┌─┬┘ │ │ ╠╣ │ │ └┬─┐ ║ ║ ┌─┬┘ │ │ │ ╠╣ │ │ │ └┬┐ ┌┬┘ │ │ │ ╠╣ │ │ │ └┬─┐ ║ ╠┬┘ │ │ │ │ ╠╣ │ │ │ │└¤┘│ │ │ │ ╠╣ │ │ │ │ └┬╣ ║│ │ │ │ │ ╠╣ │ │ │ │ │ │ │ │ ╠╣ │ │ │ │ │║ ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣ ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣ ║ ╠╣ ╠╣ ║ ║ ╠╣ ╠╣ ║ ║ , ╠╣ , ,' * ╠╣ ║ ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║ ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝ - one protocol, one bridge = infinite possibilities - *************************************************************** DISCLAIMER: U.S Patent Pending LICENSE: Holograph Limited Public License (H-LPL) https://holograph.xyz/licenses/h-lpl/1.0.0 This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, you are not permitted to use the software. 1. Definitions The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor’s patent claims that read directly on its contribution. 2. Grant of Rights A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in sections 3 and 4, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 3. Conditions and Limitations A) No Trademark License- This license does not grant you rights to use any contributors’ name, logo, or trademarks. B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor is terminated with immediate effect. C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. E) The software is licensed “as-is.” You bear all risks of using it. The contributors give no express warranties, guarantees, or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude all implied warranties, including those of merchantability, fitness for a particular purpose and non-infringement. 4. (F) Platform Limitation- The licenses granted in sections 2.A & 2.B extend only to the software or derivative works that you create that run on a Holograph system product. *************************************************************** */ pragma solidity 0.8.13; /** * @title Initializable * @author https://github.com/holographxyz * @notice Use init instead of constructor * @dev This allows for use of init function to make one time initializations without the need of a constructor */ interface InitializableInterface { /** * @notice Used internally to initialize the contract instead of through a constructor * @dev This function is called by the deployer/factory when creating a contract * @param initPayload abi encoded payload to use for contract initilaization */ function init(bytes memory initPayload) external returns (bytes4); }
{ "optimizer": { "enabled": true, "runs": 999999 }, "metadata": { "bytecodeHash": "none", "useLiteralContent": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "remappings": [ "ds-test/=lib/forge-std/lib/ds-test/src/", "erc721a-upgradeable/=erc721a-upgradeable/", "forge-std/=lib/forge-std/src/" ], "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"Access_MissingRoleOrAdmin","type":"error"},{"inputs":[],"name":"Access_OnlyAdmin","type":"error"},{"inputs":[],"name":"Access_WithdrawNotAllowed","type":"error"},{"inputs":[{"internalType":"address","name":"proposedAddress","type":"address"}],"name":"Admin_InvalidUpgradeAddress","type":"error"},{"inputs":[],"name":"Admin_UnableToFinalizeNotOpenEdition","type":"error"},{"inputs":[],"name":"ExternalMetadataRenderer_CallFailed","type":"error"},{"inputs":[],"name":"MarketFilterAddressNotSupportedForChain","type":"error"},{"inputs":[],"name":"MarketFilterDAOAddressNotSupportedForChain","type":"error"},{"inputs":[],"name":"MintFee_FundsSendFailure","type":"error"},{"inputs":[],"name":"Mint_SoldOut","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"Presale_Inactive","type":"error"},{"inputs":[],"name":"Presale_MerkleNotApproved","type":"error"},{"inputs":[],"name":"Presale_TooManyForAddress","type":"error"},{"inputs":[],"name":"Purchase_TooManyForAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"correctPrice","type":"uint256"}],"name":"Purchase_WrongPrice","type":"error"},{"inputs":[],"name":"RemoteOperatorFilterRegistryCallFailed","type":"error"},{"inputs":[],"name":"Sale_Inactive","type":"error"},{"inputs":[{"internalType":"uint16","name":"maxRoyaltyBPS","type":"uint16"}],"name":"Setup_RoyaltyPercentageTooHigh","type":"error"},{"inputs":[],"name":"Withdraw_FundsSendFailure","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"source","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FundsReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"},{"indexed":true,"internalType":"address","name":"changedBy","type":"address"}],"name":"FundsRecipientChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"withdrawnBy","type":"address"},{"indexed":true,"internalType":"address","name":"withdrawnTo","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"feeRecipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"feeAmount","type":"uint256"}],"name":"FundsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"mintFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"mintFeeRecipient","type":"address"},{"indexed":false,"internalType":"bool","name":"success","type":"bool"}],"name":"MintFeePayout","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"numberOfMints","type":"uint256"}],"name":"OpenMintFinalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"quantity","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"pricePerToken","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"firstPurchasedTokenId","type":"uint256"}],"name":"Sale","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"changedBy","type":"address"}],"name":"SalesConfigChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"contract IMetadataRenderer","name":"renderer","type":"address"}],"name":"UpdatedMetadataRenderer","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"adminMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"recipients","type":"address[]"}],"name":"adminMintAirdrop","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"beforeSafeTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"beforeTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"config","outputs":[{"internalType":"contract IMetadataRenderer","name":"metadataRenderer","type":"address"},{"internalType":"uint64","name":"editionSize","type":"uint64"},{"internalType":"uint16","name":"royaltyBPS","type":"uint16"},{"internalType":"address payable","name":"fundsRecipient","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dropsPriceOracle","outputs":[{"internalType":"contract IDropsPriceOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"erc721TransferHelper","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finalizeOpenEdition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getNativePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"initPayload","type":"bytes"}],"name":"init","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"enable","type":"bool"}],"name":"manageMarketFilterSubscription","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"marketFilterAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metadataRenderer","outputs":[{"internalType":"contract IMetadataRenderer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"mintedPerAddress","outputs":[{"components":[{"internalType":"uint256","name":"totalMints","type":"uint256"},{"internalType":"uint256","name":"presaleMints","type":"uint256"},{"internalType":"uint256","name":"publicMints","type":"uint256"}],"internalType":"struct AddressMintDetails","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newMarketFilterAddress","type":"address"}],"name":"modifyMarketFilterAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"onIsApprovedForAll","outputs":[{"internalType":"bool","name":"approved","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openseaOperatorFilterRegistry","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"presaleMintsByAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"purchase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"uint256","name":"maxQuantity","type":"uint256"},{"internalType":"uint256","name":"pricePerToken","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"purchasePresale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"saleDetails","outputs":[{"components":[{"internalType":"bool","name":"publicSaleActive","type":"bool"},{"internalType":"bool","name":"presaleActive","type":"bool"},{"internalType":"uint256","name":"publicSalePrice","type":"uint256"},{"internalType":"uint64","name":"publicSaleStart","type":"uint64"},{"internalType":"uint64","name":"publicSaleEnd","type":"uint64"},{"internalType":"uint64","name":"presaleStart","type":"uint64"},{"internalType":"uint64","name":"presaleEnd","type":"uint64"},{"internalType":"bytes32","name":"presaleMerkleRoot","type":"bytes32"},{"internalType":"uint256","name":"maxSalePurchasePerAddress","type":"uint256"},{"internalType":"uint256","name":"totalMinted","type":"uint256"},{"internalType":"uint256","name":"maxSupply","type":"uint256"}],"internalType":"struct SaleDetails","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"salesConfig","outputs":[{"internalType":"uint104","name":"publicSalePrice","type":"uint104"},{"internalType":"uint32","name":"maxSalePurchasePerAddress","type":"uint32"},{"internalType":"uint64","name":"publicSaleStart","type":"uint64"},{"internalType":"uint64","name":"publicSaleEnd","type":"uint64"},{"internalType":"uint64","name":"presaleStart","type":"uint64"},{"internalType":"uint64","name":"presaleEnd","type":"uint64"},{"internalType":"bytes32","name":"presaleMerkleRoot","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"newRecipientAddress","type":"address"}],"name":"setFundsRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IMetadataRenderer","name":"newRenderer","type":"address"},{"internalType":"bytes","name":"setupRenderer","type":"bytes"}],"name":"setMetadataRenderer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint104","name":"publicSalePrice","type":"uint104"},{"internalType":"uint32","name":"maxSalePurchasePerAddress","type":"uint32"},{"internalType":"uint64","name":"publicSaleStart","type":"uint64"},{"internalType":"uint64","name":"publicSaleEnd","type":"uint64"},{"internalType":"uint64","name":"presaleStart","type":"uint64"},{"internalType":"uint64","name":"presaleEnd","type":"uint64"},{"internalType":"bytes32","name":"presaleMerkleRoot","type":"bytes32"}],"name":"setSaleConfiguration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalMintsByAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"args","type":"bytes"}],"name":"updateMarketFilterSettings","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b50615efd80620000216000396000f3fe6080604052600436106102895760003560e01c806361fea76811610153578063ac9650d8116100cb578063e58306f91161007f578063efef39a111610064578063efef39a1146109e6578063f7cd1d9b146109f9578063ffdb716314610a2657610303565b8063e58306f9146109b1578063e8a3d485146109d157610303565b8063bb20d857116100b0578063bb20d8571461092f578063c87b56dd1461094f578063d445b9781461096f57610303565b8063ac9650d8146108e2578063b8ae5a2c1461090f57610303565b80638a1968de116101225780638da5cb5b116101075780638da5cb5b1461088b5780638f32d59b146108a05780639123f01e146108b557610303565b80638a1968de146108435780638cb163f41461086357610303565b806361fea76814610702578063703199701461072f57806379502c551461075a57806384816f2a1461082357610303565b80632ca16676116102015780633bcdcc87116101b557806341e96eb11161019a57806341e96eb1146106565780634ddf47d41461066b57806354fd4d50146106bc57610303565b80633bcdcc87146106215780633ccfd60b1461064157610303565b80632f54bf6e116101e65780632f54bf6e146105df578063343b278f146105925780633474a4a6146105ff57610303565b80632ca16676146105925780632f0ae5fa146105b257610303565b806317430c9e116102585780632078d35f1161023d5780632078d35f1461051857806324d7806c1461055f57806325024a2b1461057f57610303565b806317430c9e146104095780631d2c0b381461042c57610303565b8063015eaa7a1461032e57806301ffc9a71461036357806306fdde03146103c557806310a7eb5d146103e757610303565b3661030357367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff167f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f346040516102f991815260200190565b60405180910390a2005b6040517f46756e6374696f6e206e6f7420666f756e6400000000000000000000000000008152601481fd5b34801561033a57600080fd5b5061034e61034936600461522b565b610a46565b60405190151581526020015b60405180910390f35b34801561036f57600080fd5b5061034e61037e366004615264565b7fffffffff00000000000000000000000000000000000000000000000000000000167f1a95c452000000000000000000000000000000000000000000000000000000001490565b3480156103d157600080fd5b506103da610a91565b60405161035a9190615320565b3480156103f357600080fd5b50610407610402366004615333565b610b50565b005b34801561041557600080fd5b5061041e610e8a565b60405190815260200161035a565b34801561043857600080fd5b506005546006546007546104bf926cffffffffffffffffffffffffff8116926d0100000000000000000000000000820463ffffffff16927101000000000000000000000000000000000090920467ffffffffffffffff9081169281831692680100000000000000008104831692700100000000000000000000000000000000909104169087565b604080516cffffffffffffffffffffffffff909816885263ffffffff909616602088015267ffffffffffffffff948516958701959095529183166060860152821660808501521660a083015260c082015260e00161035a565b34801561052457600080fd5b5061053a6daaeb6d7670e522a718067333cd4e81565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161035a565b34801561056b57600080fd5b5061034e61057a366004615333565b610ea8565b61041e61058d36600461539c565b610f06565b34801561059e57600080fd5b5061034e6105ad36600461543f565b611550565b3480156105be57600080fd5b5060025461053a9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156105eb57600080fd5b5061034e6105fa366004615333565b61175e565b34801561060b57600080fd5b506106146117bd565b60405161035a91906154a1565b34801561062d57600080fd5b5061040761063c3660046156b0565b611928565b34801561064d57600080fd5b50610407611c3e565b34801561066257600080fd5b5061040761216c565b34801561067757600080fd5b5061068b610686366004615700565b61248e565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161035a565b3480156106c857600080fd5b5060408051808201909152600581527f312e302e3000000000000000000000000000000000000000000000000000000060208201526103da565b34801561070e57600080fd5b5061041e61071d366004615333565b60086020526000908152604090205481565b34801561073b57600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff1661053a565b34801561076657600080fd5b506003546004546107d69173ffffffffffffffffffffffffffffffffffffffff8082169274010000000000000000000000000000000000000000830467ffffffffffffffff16927c0100000000000000000000000000000000000000000000000000000000900461ffff16911684565b6040805173ffffffffffffffffffffffffffffffffffffffff958616815267ffffffffffffffff909416602085015261ffff9092169183019190915291909116606082015260800161035a565b34801561082f57600080fd5b5061040761083e366004615333565b612aa3565b34801561084f57600080fd5b5061040761085e366004615743565b612cbc565b34801561086f57600080fd5b5061053a73a3db09eec42baff7a50fb8f9af90a0e035ef330281565b34801561089757600080fd5b5061053a613271565b3480156108ac57600080fd5b5061034e61329b565b3480156108c157600080fd5b5061041e6108d0366004615333565b60096020526000908152604090205481565b3480156108ee57600080fd5b506109026108fd366004615760565b613397565b60405161035a9190615823565b34801561091b57600080fd5b5061041e61092a3660046158a3565b613498565b34801561093b57600080fd5b506103da61094a3660046158e5565b61379b565b34801561095b57600080fd5b506103da61096a36600461591b565b613ae1565b34801561097b57600080fd5b5061098f61098a366004615333565b613cba565b604080518251815260208084015190820152918101519082015260600161035a565b3480156109bd57600080fd5b5061041e6109cc366004615934565b613d3f565b3480156109dd57600080fd5b506103da614007565b61041e6109f436600461591b565b614077565b348015610a0557600080fd5b5060015461053a9073ffffffffffffffffffffffffffffffffffffffff1681565b348015610a3257600080fd5b50610407610a413660046159a3565b6145d0565b60015460009073ffffffffffffffffffffffffffffffffffffffff1615801590610a8a575060015473ffffffffffffffffffffffffffffffffffffffff8381169116145b9392505050565b6060610abb7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b73ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015610b05573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610b4b9190810190615a60565b905090565b7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5473ffffffffffffffffffffffffffffffffffffffff163303610c71577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1614610c6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e000000000060448201526064015b60405180910390fd5b610d27565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d27576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b73ffffffffffffffffffffffffffffffffffffffff8116610dca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f46756e647320526563697069656e742063616e6e6f742062652030206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610c63565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316179055367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f70a7ea5c664ab9c21baf3da59bb2f1e1ca33557b08a0031fab4f17076744995160405160405180910390a350565b600554600090610b4b906cffffffffffffffffffffffffff1661492f565b60008173ffffffffffffffffffffffffffffffffffffffff16610ee97fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775490565b73ffffffffffffffffffffffffffffffffffffffff161492915050565b6000610f307f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a31372795490565b600203610f99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f484f4c4f47524150483a207265656e7472616e742063616c6c000000000000006044820152606401610c63565b610fc260027f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a313727955565b600354869074010000000000000000000000000000000000000000900467ffffffffffffffff161580159061104657506003546000547401000000000000000000000000000000000000000090910467ffffffffffffffff1690611044907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1683615ad8565b115b1561107d576040517f717c513000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110856149d4565b6110bb576040517f95ed3c1a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61116484848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050600754915050367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001356040805173ffffffffffffffffffffffffffffffffffffffff909216602083015281018a90526060810189905260800160405160208183030381529060405280519060200120614a23565b61119a576040517f85b70e5200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006111a58661492f565b90506111b18882615af0565b3410156111f7576111c28887615af0565b6040517f6a1c179e000000000000000000000000000000000000000000000000000000008152600401610c6391815260200190565b60006112038983615af0565b61120d9034615b2d565b73ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe036013516600090815260086020526040812080549293508b9290919061126a908490615ad8565b909155505073ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0360135166000908152600860205260409020548810156112f1576040517fa7b32bb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61131e367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001358a614a39565b60006113487fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b905060008173ffffffffffffffffffffffffffffffffffffffff166377dbd8636040518163ffffffff1660e01b8152600401602060405180830381865afa158015611397573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113bb9190615b44565b60008054919250906113ec908d907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16615b2d565b6113f69083615ad8565b611401906001615ad8565b9050848c367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff167f4e26b0356a15833a75d497ecc40ebbb716b99466ed0dba9454f1fff451e25a908460405161147091815260200190565b60405180910390a4831561151757367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1684620334505a116114c9575a6114ce565b620334505b6040519091906000818181858888f193505050503d806000811461150e576040519150601f19603f3d011682016040523d82523d6000602084013e611513565b606091505b5050505b9550505050505061154760017f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a313727955565b95945050505050565b600073ffffffffffffffffffffffffffffffffffffffff8616158015906115c65750367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614155b15611752577f5c835f3b6bd322d9a084ffdeac746df2b96cce308e7f0612f4ff4f9c490734cc548015611750576daaeb6d7670e522a718067333cd4e63c617113430367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001356040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa9250505080156116d6575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526116d391810190615b68565b60015b611747576040517fede71dcc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0360135166004820152602401610c63565b91506115479050565b505b50600195945050505050565b60006117887fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775490565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050919050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260405180610160016040528061182a614e10565b151581526020016118396149d4565b151581526005546cffffffffffffffffffffffffff8116602083015271010000000000000000000000000000000000810467ffffffffffffffff90811660408401526006548082166060850152680100000000000000008104821660808501527001000000000000000000000000000000009004811660a084015260075460c08401526d010000000000000000000000000090910463ffffffff1660e08301526000547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166101008301526003547401000000000000000000000000000000000000000090041661012090910152919050565b7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5473ffffffffffffffffffffffffffffffffffffffff163303611a44577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1614611a3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b611afa565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611afa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055805115611bc6576040517f856a7ffa00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83169063856a7ffa90611b93908490600401615320565b600060405180830381600087803b158015611bad57600080fd5b505af1158015611bc1573d6000803e3d6000fd5b505050505b7f046c5d913c35948c3e0e44c3599eb14bf33b73f141fa8bb282b300414998b868367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001356040805173ffffffffffffffffffffffffffffffffffffffff928316815291851660208301520160405180910390a15050565b7f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a313727954600203611cc9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f484f4c4f47524150483a207265656e7472616e742063616c6c000000000000006044820152606401610c63565b611cf260027f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a313727955565b60045473ffffffffffffffffffffffffffffffffffffffff16611d71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f46756e647320526563697069656e742061646472657373206e6f7420736574006044820152606401610c63565b7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe036013590479060009073ffffffffffffffffffffffffffffffffffffffff16634827ae0c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e2b9190615b90565b73ffffffffffffffffffffffffffffffffffffffff16633b19e84a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e999190615b90565b60045490915060009073ffffffffffffffffffffffffffffffffffffffff858116911614801590611f1757507fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614155b8015611f4f57508173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614155b15611f86576040517f1dab829b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b801561203a5760008273ffffffffffffffffffffffffffffffffffffffff16826203345090604051600060405180830381858888f193505050503d8060008114611fec576040519150601f19603f3d011682016040523d82523d6000602084013e611ff1565b606091505b505090508061202c576040517f39debd5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120368285615b2d565b9350505b60045460405160009173ffffffffffffffffffffffffffffffffffffffff16906203345090869084818181858888f193505050503d806000811461209a576040519150601f19603f3d011682016040523d82523d6000602084013e61209f565b606091505b50509050806120da576040517f39debd5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004546040805186815273ffffffffffffffffffffffffffffffffffffffff868116602083015291810185905291811691908716907f8a95554e4c9dcaaf33f247387f2ee77390780487d3365e3a804788791a1df5009060600160405180910390a3505050505061216a60017f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a313727955565b565b7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5473ffffffffffffffffffffffffffffffffffffffff163303612288577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1614612283576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b61233e565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461233e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b60035474010000000000000000000000000000000000000000900467ffffffffffffffff9081161461239c576040517fe742c08400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000546003805467ffffffffffffffff90921674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff90921691909117905561241a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe036013590565b6003546040517401000000000000000000000000000000000000000090910467ffffffffffffffff16815273ffffffffffffffffffffffffffffffffffffffff91909116907fb6cc1e876b8d7479c8afe025a58658b0f3c3ec5bd0f28cb4261326b162069bf89060200160405180910390a2565b60006124b87f4e5f991bca30eca2d4643aaefa807e88f96a4a97398933d572a3c0d973004a015490565b1561251f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f484f4c4f47524150483a20616c726561647920696e697469616c697a656400006044820152606401610c63565b6000828060200190518101906125359190615ca0565b8051600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055602082015191925016156125d0576020810151600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790555b6125fc81604001517fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf77277755565b60408051608080820183526101008401805173ffffffffffffffffffffffffffffffffffffffff9081168085528684015167ffffffffffffffff908116602080880182905260a0808b015161ffff16898b018190526060808d015188169a81018b9052600380547c01000000000000000000000000000000000000000000000000000000009093027fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff740100000000000000000000000000000000000000009097027fffffffff00000000000000000000000000000000000000000000000000000000909416909817929092179490941695909517909455600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001690981790975560e0890151805160058054998301519a830151851671010000000000000000000000000000000000027fffffffffffffff0000000000000000ffffffffffffffffffffffffffffffffff63ffffffff909c166d0100000000000000000000000000027fffffffffffffffffffffffffffffff0000000000000000000000000000000000909b166cffffffffffffffffffffffffff90931692909217999099179990991698909817909655948601516006805495880151928801518716700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff93881668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909716929097169190911794909417169390931790915560c090920151600755905116156128f7576101008101516101208201516040517f856a7ffa00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9092169163856a7ffa916128c491600401615320565b600060405180830381600087803b1580156128de57600080fd5b505af11580156128f2573d6000803e3d6000fd5b505050505b8060c00151801561291657506daaeb6d7670e522a718067333cd4e3b15155b15612a715760025473ffffffffffffffffffffffffffffffffffffffff166129b4576040517f4420e4860000000000000000000000000000000000000000000000000000000081523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b15801561299757600080fd5b505af11580156129ab573d6000803e3d6000fd5b50505050612a4c565b6002546040517f7d3e3dbe00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe90604401600060405180830381600087803b158015612a3357600080fd5b505af1158015612a47573d6000803e3d6000fd5b505050505b60017f5c835f3b6bd322d9a084ffdeac746df2b96cce308e7f0612f4ff4f9c490734cc555b612a9a60017f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a313727955565b610a8a83614e55565b7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5473ffffffffffffffffffffffffffffffffffffffff163303612bbf577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1614612bba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b612c75565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612c75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5473ffffffffffffffffffffffffffffffffffffffff163303612dd8577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1614612dd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b612e8e565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612e8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b600254309073ffffffffffffffffffffffffffffffffffffffff16612edf576040517f707ff7e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fc3c5a54700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526daaeb6d7670e522a718067333cd4e9063c3c5a547906024016020604051808303816000875af1158015612f59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f7d9190615b68565b158015612f875750815b1561302b576002546040517f7d3e3dbe00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808416600483015290911660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b15801561300e57600080fd5b505af1158015613022573d6000803e3d6000fd5b505050506131bf565b811561309d576002546040517fb314d41400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808416600483015290911660248201526daaeb6d7670e522a718067333cd4e9063b314d41490604401612ff4565b6040517f34a0dc1000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152600060248201526daaeb6d7670e522a718067333cd4e906334a0dc1090604401600060405180830381600087803b15801561311957600080fd5b505af115801561312d573d6000803e3d6000fd5b50506040517f2ec2c24600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526daaeb6d7670e522a718067333cd4e9250632ec2c2469150602401600060405180830381600087803b1580156131a657600080fd5b505af11580156131ba573d6000803e3d6000fd5b505050505b6040517fc3c5a5470000000000000000000000000000000000000000000000000000000081523060048201526000906daaeb6d7670e522a718067333cd4e9063c3c5a547906024016020604051808303816000875af1158015613226573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061324a9190615b68565b7f5c835f3b6bd322d9a084ffdeac746df2b96cce308e7f0612f4ff4f9c490734cc55505050565b6000610b4b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775490565b60006132c57fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b73ffffffffffffffffffffffffffffffffffffffff163303613359577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1614905090565b507fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16331490565b6060815167ffffffffffffffff8111156133b3576133b361556c565b6040519080825280602002602001820160405280156133e657816020015b60608152602001906001900390816133d15790505b50905060005b8251811015613492576134623084838151811061340b5761340b615dac565b602002602001015161343d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe036013590565b60405160200161344e929190615ddb565b604051602081830303815290604052614ffc565b82828151811061347457613474615dac565b6020026020010181905250808061348a90615e25565b9150506133ec565b50919050565b60006134c27fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b73ffffffffffffffffffffffffffffffffffffffff1633036135bc577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff16146135b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b613672565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b600354829074010000000000000000000000000000000000000000900467ffffffffffffffff16158015906136f657506003546000547401000000000000000000000000000000000000000090910467ffffffffffffffff16906136f4907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1683615ad8565b115b1561372d576040517f717c513000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b838110156137715761376985858381811061374d5761374d615dac565b90506020020160208101906137629190615333565b6001614a39565b600101613730565b50506000547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169392505050565b60606137c57fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b73ffffffffffffffffffffffffffffffffffffffff1633036138bf577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff16146138ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b613975565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613975576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b6000806daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1685856040516139ad929190615e5d565b6000604051808303816000865af19150503d80600081146139ea576040519150601f19603f3d011682016040523d82523d6000602084013e6139ef565b606091505b509150915081613a2b576040517f25f3885400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fc3c5a5470000000000000000000000000000000000000000000000000000000081523060048201526000906daaeb6d7670e522a718067333cd4e9063c3c5a547906024016020604051808303816000875af1158015613a92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ab69190615b68565b7f5c835f3b6bd322d9a084ffdeac746df2b96cce308e7f0612f4ff4f9c490734cc5550949350505050565b60606000613b0d7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b6040517f4f558e790000000000000000000000000000000000000000000000000000000081526004810185905290915073ffffffffffffffffffffffffffffffffffffffff821690634f558e7990602401602060405180830381865afa158015613b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b9f9190615b68565b613c05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433732313a20746f6b656e20646f6573206e6f74206578697374000000006044820152606401610c63565b6003546040517fc87b56dd0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff9091169063c87b56dd90602401600060405180830381865afa158015613c74573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a8a9190810190615a60565b613cde60405180606001604052806000815260200160008152602001600081525090565b6040805160608101825273ffffffffffffffffffffffffffffffffffffffff841660008181526009602081815285832054808652848452600882528684205482870181905294909352529192830191613d379190615b2d565b905292915050565b6000613d697fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b73ffffffffffffffffffffffffffffffffffffffff163303613e63577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1614613e5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b613f19565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613f19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b600354829074010000000000000000000000000000000000000000900467ffffffffffffffff1615801590613f9d57506003546000547401000000000000000000000000000000000000000090910467ffffffffffffffff1690613f9b907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1683615ad8565b115b15613fd4576040517f717c513000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613fde8484614a39565b50506000547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1692915050565b600354604080517fe8a3d485000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff169163e8a3d4859160048083019260009291908290030181865afa158015610b05573d6000803e3d6000fd5b60006140a17f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a31372795490565b60020361410a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f484f4c4f47524150483a207265656e7472616e742063616c6c000000000000006044820152606401610c63565b61413360027f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a313727955565b600354829074010000000000000000000000000000000000000000900467ffffffffffffffff16158015906141b757506003546000547401000000000000000000000000000000000000000090910467ffffffffffffffff16906141b5907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1683615ad8565b115b156141ee576040517f717c513000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6141f6614e10565b61422c576040517ff12dcc7f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055460009061424a906cffffffffffffffffffffffffff1661492f565b90506142568482615af0565b34101561427a576005546111c29085906cffffffffffffffffffffffffff16615af0565b60006142868583615af0565b6142909034615b2d565b6005549091506d0100000000000000000000000000900463ffffffff161580159061433e5750600554367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff166000908152600860209081526040808320546009909252909120546d010000000000000000000000000090920463ffffffff1691614332908890615ad8565b61433c9190615b2d565b115b15614375576040517f220ae94c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6143a2367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013586614a39565b60006143cc7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b905060008173ffffffffffffffffffffffffffffffffffffffff166377dbd8636040518163ffffffff1660e01b8152600401602060405180830381865afa15801561441b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061443f9190615b44565b60008054919250906144709089907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16615b2d565b61447a9083615ad8565b614485906001615ad8565b90508488367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff167f4e26b0356a15833a75d497ecc40ebbb716b99466ed0dba9454f1fff451e25a90846040516144f491815260200190565b60405180910390a4831561459b57367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1684620334505a1161454d575a614552565b620334505b6040519091906000818181858888f193505050503d8060008114614592576040519150601f19603f3d011682016040523d82523d6000602084013e614597565b606091505b5050505b955050505050506145cb60017f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a313727955565b919050565b7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5473ffffffffffffffffffffffffffffffffffffffff1633036146ec577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff16146146e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b6147a2565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146147a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b600580546cffffffffffffffffffffffffff89167fffffffffffffffffffffffffffffff0000000000000000000000000000000000909116176d010000000000000000000000000063ffffffff891602177fffffffffffffff0000000000000000ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000067ffffffffffffffff8881169190910291909117909155600680548683167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116176801000000000000000086841602177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000928516929092029190911790556007819055367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff167fc1ff5e4744ac8dd2b8027a10e3723b165975297501c71c4e7dcb8796d96375db60405160405180910390a250505050505050565b60008160000361494157506000919050565b6040517ff5d781610000000000000000000000000000000000000000000000000000000081526004810183905273a3db09eec42baff7a50fb8f9af90a0e035ef33029063f5d7816190602401602060405180830381865afa1580156149aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149ce9190615b44565b92915050565b600654600090426801000000000000000090910467ffffffffffffffff1611801590610b4b5750506006544270010000000000000000000000000000000090910467ffffffffffffffff161190565b600082614a308584615021565b14949350505050565b6000614a637fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b905060008173ffffffffffffffffffffffffffffffffffffffff166377dbd8636040518163ffffffff1660e01b8152600401602060405180830381865afa158015614ab2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614ad69190615b44565b90506000805b84811015614e085760008054600191908190614b179084907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16615e6d565b92506101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1602179055505b60005473ffffffffffffffffffffffffffffffffffffffff851690634f558e7990614baf907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1686615ad8565b6040518263ffffffff1660e01b8152600401614bcd91815260200190565b602060405180830381865afa158015614bea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614c0e9190615b68565b80614cbc575060005473ffffffffffffffffffffffffffffffffffffffff8516906323250cae90614c5d907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1686615ad8565b6040518263ffffffff1660e01b8152600401614c7b91815260200190565b602060405180830381865afa158015614c98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614cbc9190615b68565b15614d475760008054600191908190614cf49084907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16615e6d565b92506101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550614b66565b6000546040517f3b4f1b2600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88811660048301527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90921660248201819052935090851690633b4f1b2690604401600060405180830381600087803b158015614ddd57600080fd5b505af1158015614df1573d6000803e3d6000fd5b505050508080614e0090615e25565b915050614adc565b505050505050565b600554600090427101000000000000000000000000000000000090910467ffffffffffffffff1611801590610b4b5750506006544267ffffffffffffffff9091161190565b6000614e7f7f4e5f991bca30eca2d4643aaefa807e88f96a4a97398933d572a3c0d973004a015490565b15614ee6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a20616c726561647920696e697469616c697a656400000000006044820152606401610c63565b337fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd8190557fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff8116614faa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f484f4c4f47524150483a206f776e6572206e6f742073657400000000000000006044820152606401610c63565b614fd360017f4e5f991bca30eca2d4643aaefa807e88f96a4a97398933d572a3c0d973004a0155565b507f4ddf47d4000000000000000000000000000000000000000000000000000000009392505050565b6060610a8a8383604051806060016040528060278152602001615eca60279139615095565b600081815b845181101561508d57600085828151811061504357615043615dac565b60200260200101519050808311615069576000838152602082905260409020925061507a565b600081815260208490526040902092505b508061508581615e25565b915050615026565b509392505050565b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516150bf9190615ead565b600060405180830381855af49150503d80600081146150fa576040519150601f19603f3d011682016040523d82523d6000602084013e6150ff565b606091505b50915091506151108683838761511a565b9695505050505050565b606083156151b05782516000036151a95773ffffffffffffffffffffffffffffffffffffffff85163b6151a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c63565b50816151ba565b6151ba83836151c2565b949350505050565b8151156151d25781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c639190615320565b73ffffffffffffffffffffffffffffffffffffffff8116811461522857600080fd5b50565b6000806040838503121561523e57600080fd5b823561524981615206565b9150602083013561525981615206565b809150509250929050565b60006020828403121561527657600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610a8a57600080fd5b60005b838110156152c15781810151838201526020016152a9565b838111156152d0576000848401525b50505050565b600081518084526152ee8160208601602086016152a6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610a8a60208301846152d6565b60006020828403121561534557600080fd5b8135610a8a81615206565b60008083601f84011261536257600080fd5b50813567ffffffffffffffff81111561537a57600080fd5b6020830191508360208260051b850101111561539557600080fd5b9250929050565b6000806000806000608086880312156153b457600080fd5b853594506020860135935060408601359250606086013567ffffffffffffffff8111156153e057600080fd5b6153ec88828901615350565b969995985093965092949392505050565b60008083601f84011261540f57600080fd5b50813567ffffffffffffffff81111561542757600080fd5b60208301915083602082850101111561539557600080fd5b60008060008060006080868803121561545757600080fd5b853561546281615206565b9450602086013561547281615206565b935060408601359250606086013567ffffffffffffffff81111561549557600080fd5b6153ec888289016153fd565b815115158152610160810160208301516154bf602084018215159052565b506040830151604083015260608301516154e5606084018267ffffffffffffffff169052565b506080830151615501608084018267ffffffffffffffff169052565b5060a083015161551d60a084018267ffffffffffffffff169052565b5060c083015161553960c084018267ffffffffffffffff169052565b5060e083810151908301526101008084015190830152610120808401519083015261014092830151929091019190915290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff811182821017156155bf576155bf61556c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561560c5761560c61556c565b604052919050565b600067ffffffffffffffff82111561562e5761562e61556c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261566b57600080fd5b813561567e61567982615614565b6155c5565b81815284602083860101111561569357600080fd5b816020850160208301376000918101602001919091529392505050565b600080604083850312156156c357600080fd5b82356156ce81615206565b9150602083013567ffffffffffffffff8111156156ea57600080fd5b6156f68582860161565a565b9150509250929050565b60006020828403121561571257600080fd5b813567ffffffffffffffff81111561572957600080fd5b6151ba8482850161565a565b801515811461522857600080fd5b60006020828403121561575557600080fd5b8135610a8a81615735565b6000602080838503121561577357600080fd5b823567ffffffffffffffff8082111561578b57600080fd5b818501915085601f83011261579f57600080fd5b8135818111156157b1576157b161556c565b8060051b6157c08582016155c5565b91825283810185019185810190898411156157da57600080fd5b86860192505b83831015615816578235858111156157f85760008081fd5b6158068b89838a010161565a565b83525091860191908601906157e0565b9998505050505050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015615896577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526158848583516152d6565b9450928501929085019060010161584a565b5092979650505050505050565b600080602083850312156158b657600080fd5b823567ffffffffffffffff8111156158cd57600080fd5b6158d985828601615350565b90969095509350505050565b600080602083850312156158f857600080fd5b823567ffffffffffffffff81111561590f57600080fd5b6158d9858286016153fd565b60006020828403121561592d57600080fd5b5035919050565b6000806040838503121561594757600080fd5b823561595281615206565b946020939093013593505050565b6cffffffffffffffffffffffffff8116811461522857600080fd5b63ffffffff8116811461522857600080fd5b67ffffffffffffffff8116811461522857600080fd5b600080600080600080600060e0888a0312156159be57600080fd5b87356159c981615960565b965060208801356159d98161597b565b955060408801356159e98161598d565b945060608801356159f98161598d565b93506080880135615a098161598d565b925060a0880135615a198161598d565b8092505060c0880135905092959891949750929550565b6000615a3e61567984615614565b9050828152838383011115615a5257600080fd5b610a8a8360208301846152a6565b600060208284031215615a7257600080fd5b815167ffffffffffffffff811115615a8957600080fd5b8201601f81018413615a9a57600080fd5b6151ba84825160208401615a30565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115615aeb57615aeb615aa9565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615b2857615b28615aa9565b500290565b600082821015615b3f57615b3f615aa9565b500390565b600060208284031215615b5657600080fd5b5051919050565b80516145cb81615735565b600060208284031215615b7a57600080fd5b8151610a8a81615735565b80516145cb81615206565b600060208284031215615ba257600080fd5b8151610a8a81615206565b80516145cb8161598d565b805161ffff811681146145cb57600080fd5b600060e08284031215615bdc57600080fd5b60405160e0810181811067ffffffffffffffff82111715615bff57615bff61556c565b80604052508091508251615c1281615960565b81526020830151615c228161597b565b60208201526040830151615c358161598d565b60408201526060830151615c488161598d565b6060820152615c5960808401615bad565b6080820152615c6a60a08401615bad565b60a082015260c083015160c08201525092915050565b600082601f830112615c9157600080fd5b610a8a83835160208501615a30565b600060208284031215615cb257600080fd5b815167ffffffffffffffff80821115615cca57600080fd5b908301906102008286031215615cdf57600080fd5b615ce761559b565b615cf083615b85565b8152615cfe60208401615b85565b6020820152615d0f60408401615b85565b6040820152615d2060608401615b85565b6060820152615d3160808401615bad565b6080820152615d4260a08401615bb8565b60a0820152615d5360c08401615b5d565b60c0820152615d658660e08501615bca565b60e0820152615d776101c08401615b85565b6101008201526101e083015182811115615d9057600080fd5b615d9c87828601615c80565b6101208301525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008351615ded8184602088016152a6565b60609390931b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169190920190815260140192915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615e5657615e56615aa9565b5060010190565b8183823760009101908152919050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff808316818516808303821115615ea457615ea4615aa9565b01949350505050565b60008251615ebf8184602087016152a6565b919091019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a164736f6c634300080d000a
Deployed Bytecode
0x6080604052600436106102895760003560e01c806361fea76811610153578063ac9650d8116100cb578063e58306f91161007f578063efef39a111610064578063efef39a1146109e6578063f7cd1d9b146109f9578063ffdb716314610a2657610303565b8063e58306f9146109b1578063e8a3d485146109d157610303565b8063bb20d857116100b0578063bb20d8571461092f578063c87b56dd1461094f578063d445b9781461096f57610303565b8063ac9650d8146108e2578063b8ae5a2c1461090f57610303565b80638a1968de116101225780638da5cb5b116101075780638da5cb5b1461088b5780638f32d59b146108a05780639123f01e146108b557610303565b80638a1968de146108435780638cb163f41461086357610303565b806361fea76814610702578063703199701461072f57806379502c551461075a57806384816f2a1461082357610303565b80632ca16676116102015780633bcdcc87116101b557806341e96eb11161019a57806341e96eb1146106565780634ddf47d41461066b57806354fd4d50146106bc57610303565b80633bcdcc87146106215780633ccfd60b1461064157610303565b80632f54bf6e116101e65780632f54bf6e146105df578063343b278f146105925780633474a4a6146105ff57610303565b80632ca16676146105925780632f0ae5fa146105b257610303565b806317430c9e116102585780632078d35f1161023d5780632078d35f1461051857806324d7806c1461055f57806325024a2b1461057f57610303565b806317430c9e146104095780631d2c0b381461042c57610303565b8063015eaa7a1461032e57806301ffc9a71461036357806306fdde03146103c557806310a7eb5d146103e757610303565b3661030357367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff167f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f346040516102f991815260200190565b60405180910390a2005b6040517f46756e6374696f6e206e6f7420666f756e6400000000000000000000000000008152601481fd5b34801561033a57600080fd5b5061034e61034936600461522b565b610a46565b60405190151581526020015b60405180910390f35b34801561036f57600080fd5b5061034e61037e366004615264565b7fffffffff00000000000000000000000000000000000000000000000000000000167f1a95c452000000000000000000000000000000000000000000000000000000001490565b3480156103d157600080fd5b506103da610a91565b60405161035a9190615320565b3480156103f357600080fd5b50610407610402366004615333565b610b50565b005b34801561041557600080fd5b5061041e610e8a565b60405190815260200161035a565b34801561043857600080fd5b506005546006546007546104bf926cffffffffffffffffffffffffff8116926d0100000000000000000000000000820463ffffffff16927101000000000000000000000000000000000090920467ffffffffffffffff9081169281831692680100000000000000008104831692700100000000000000000000000000000000909104169087565b604080516cffffffffffffffffffffffffff909816885263ffffffff909616602088015267ffffffffffffffff948516958701959095529183166060860152821660808501521660a083015260c082015260e00161035a565b34801561052457600080fd5b5061053a6daaeb6d7670e522a718067333cd4e81565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161035a565b34801561056b57600080fd5b5061034e61057a366004615333565b610ea8565b61041e61058d36600461539c565b610f06565b34801561059e57600080fd5b5061034e6105ad36600461543f565b611550565b3480156105be57600080fd5b5060025461053a9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156105eb57600080fd5b5061034e6105fa366004615333565b61175e565b34801561060b57600080fd5b506106146117bd565b60405161035a91906154a1565b34801561062d57600080fd5b5061040761063c3660046156b0565b611928565b34801561064d57600080fd5b50610407611c3e565b34801561066257600080fd5b5061040761216c565b34801561067757600080fd5b5061068b610686366004615700565b61248e565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161035a565b3480156106c857600080fd5b5060408051808201909152600581527f312e302e3000000000000000000000000000000000000000000000000000000060208201526103da565b34801561070e57600080fd5b5061041e61071d366004615333565b60086020526000908152604090205481565b34801561073b57600080fd5b5060035473ffffffffffffffffffffffffffffffffffffffff1661053a565b34801561076657600080fd5b506003546004546107d69173ffffffffffffffffffffffffffffffffffffffff8082169274010000000000000000000000000000000000000000830467ffffffffffffffff16927c0100000000000000000000000000000000000000000000000000000000900461ffff16911684565b6040805173ffffffffffffffffffffffffffffffffffffffff958616815267ffffffffffffffff909416602085015261ffff9092169183019190915291909116606082015260800161035a565b34801561082f57600080fd5b5061040761083e366004615333565b612aa3565b34801561084f57600080fd5b5061040761085e366004615743565b612cbc565b34801561086f57600080fd5b5061053a73a3db09eec42baff7a50fb8f9af90a0e035ef330281565b34801561089757600080fd5b5061053a613271565b3480156108ac57600080fd5b5061034e61329b565b3480156108c157600080fd5b5061041e6108d0366004615333565b60096020526000908152604090205481565b3480156108ee57600080fd5b506109026108fd366004615760565b613397565b60405161035a9190615823565b34801561091b57600080fd5b5061041e61092a3660046158a3565b613498565b34801561093b57600080fd5b506103da61094a3660046158e5565b61379b565b34801561095b57600080fd5b506103da61096a36600461591b565b613ae1565b34801561097b57600080fd5b5061098f61098a366004615333565b613cba565b604080518251815260208084015190820152918101519082015260600161035a565b3480156109bd57600080fd5b5061041e6109cc366004615934565b613d3f565b3480156109dd57600080fd5b506103da614007565b61041e6109f436600461591b565b614077565b348015610a0557600080fd5b5060015461053a9073ffffffffffffffffffffffffffffffffffffffff1681565b348015610a3257600080fd5b50610407610a413660046159a3565b6145d0565b60015460009073ffffffffffffffffffffffffffffffffffffffff1615801590610a8a575060015473ffffffffffffffffffffffffffffffffffffffff8381169116145b9392505050565b6060610abb7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b73ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015610b05573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610b4b9190810190615a60565b905090565b7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5473ffffffffffffffffffffffffffffffffffffffff163303610c71577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1614610c6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e000000000060448201526064015b60405180910390fd5b610d27565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d27576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b73ffffffffffffffffffffffffffffffffffffffff8116610dca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f46756e647320526563697069656e742063616e6e6f742062652030206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610c63565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316179055367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f70a7ea5c664ab9c21baf3da59bb2f1e1ca33557b08a0031fab4f17076744995160405160405180910390a350565b600554600090610b4b906cffffffffffffffffffffffffff1661492f565b60008173ffffffffffffffffffffffffffffffffffffffff16610ee97fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775490565b73ffffffffffffffffffffffffffffffffffffffff161492915050565b6000610f307f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a31372795490565b600203610f99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f484f4c4f47524150483a207265656e7472616e742063616c6c000000000000006044820152606401610c63565b610fc260027f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a313727955565b600354869074010000000000000000000000000000000000000000900467ffffffffffffffff161580159061104657506003546000547401000000000000000000000000000000000000000090910467ffffffffffffffff1690611044907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1683615ad8565b115b1561107d576040517f717c513000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110856149d4565b6110bb576040517f95ed3c1a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61116484848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050600754915050367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001356040805173ffffffffffffffffffffffffffffffffffffffff909216602083015281018a90526060810189905260800160405160208183030381529060405280519060200120614a23565b61119a576040517f85b70e5200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006111a58661492f565b90506111b18882615af0565b3410156111f7576111c28887615af0565b6040517f6a1c179e000000000000000000000000000000000000000000000000000000008152600401610c6391815260200190565b60006112038983615af0565b61120d9034615b2d565b73ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe036013516600090815260086020526040812080549293508b9290919061126a908490615ad8565b909155505073ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0360135166000908152600860205260409020548810156112f1576040517fa7b32bb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61131e367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001358a614a39565b60006113487fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b905060008173ffffffffffffffffffffffffffffffffffffffff166377dbd8636040518163ffffffff1660e01b8152600401602060405180830381865afa158015611397573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113bb9190615b44565b60008054919250906113ec908d907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16615b2d565b6113f69083615ad8565b611401906001615ad8565b9050848c367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff167f4e26b0356a15833a75d497ecc40ebbb716b99466ed0dba9454f1fff451e25a908460405161147091815260200190565b60405180910390a4831561151757367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1684620334505a116114c9575a6114ce565b620334505b6040519091906000818181858888f193505050503d806000811461150e576040519150601f19603f3d011682016040523d82523d6000602084013e611513565b606091505b5050505b9550505050505061154760017f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a313727955565b95945050505050565b600073ffffffffffffffffffffffffffffffffffffffff8616158015906115c65750367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614155b15611752577f5c835f3b6bd322d9a084ffdeac746df2b96cce308e7f0612f4ff4f9c490734cc548015611750576daaeb6d7670e522a718067333cd4e63c617113430367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001356040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff928316600482015291166024820152604401602060405180830381865afa9250505080156116d6575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526116d391810190615b68565b60015b611747576040517fede71dcc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0360135166004820152602401610c63565b91506115479050565b505b50600195945050505050565b60006117887fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775490565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16149050919050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260405180610160016040528061182a614e10565b151581526020016118396149d4565b151581526005546cffffffffffffffffffffffffff8116602083015271010000000000000000000000000000000000810467ffffffffffffffff90811660408401526006548082166060850152680100000000000000008104821660808501527001000000000000000000000000000000009004811660a084015260075460c08401526d010000000000000000000000000090910463ffffffff1660e08301526000547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166101008301526003547401000000000000000000000000000000000000000090041661012090910152919050565b7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5473ffffffffffffffffffffffffffffffffffffffff163303611a44577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1614611a3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b611afa565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611afa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055805115611bc6576040517f856a7ffa00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83169063856a7ffa90611b93908490600401615320565b600060405180830381600087803b158015611bad57600080fd5b505af1158015611bc1573d6000803e3d6000fd5b505050505b7f046c5d913c35948c3e0e44c3599eb14bf33b73f141fa8bb282b300414998b868367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001356040805173ffffffffffffffffffffffffffffffffffffffff928316815291851660208301520160405180910390a15050565b7f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a313727954600203611cc9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f484f4c4f47524150483a207265656e7472616e742063616c6c000000000000006044820152606401610c63565b611cf260027f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a313727955565b60045473ffffffffffffffffffffffffffffffffffffffff16611d71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f46756e647320526563697069656e742061646472657373206e6f7420736574006044820152606401610c63565b7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe036013590479060009073ffffffffffffffffffffffffffffffffffffffff16634827ae0c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e2b9190615b90565b73ffffffffffffffffffffffffffffffffffffffff16633b19e84a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e999190615b90565b60045490915060009073ffffffffffffffffffffffffffffffffffffffff858116911614801590611f1757507fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614155b8015611f4f57508173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614155b15611f86576040517f1dab829b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b801561203a5760008273ffffffffffffffffffffffffffffffffffffffff16826203345090604051600060405180830381858888f193505050503d8060008114611fec576040519150601f19603f3d011682016040523d82523d6000602084013e611ff1565b606091505b505090508061202c576040517f39debd5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6120368285615b2d565b9350505b60045460405160009173ffffffffffffffffffffffffffffffffffffffff16906203345090869084818181858888f193505050503d806000811461209a576040519150601f19603f3d011682016040523d82523d6000602084013e61209f565b606091505b50509050806120da576040517f39debd5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004546040805186815273ffffffffffffffffffffffffffffffffffffffff868116602083015291810185905291811691908716907f8a95554e4c9dcaaf33f247387f2ee77390780487d3365e3a804788791a1df5009060600160405180910390a3505050505061216a60017f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a313727955565b565b7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5473ffffffffffffffffffffffffffffffffffffffff163303612288577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1614612283576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b61233e565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461233e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b60035474010000000000000000000000000000000000000000900467ffffffffffffffff9081161461239c576040517fe742c08400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000546003805467ffffffffffffffff90921674010000000000000000000000000000000000000000027fffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffff90921691909117905561241a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe036013590565b6003546040517401000000000000000000000000000000000000000090910467ffffffffffffffff16815273ffffffffffffffffffffffffffffffffffffffff91909116907fb6cc1e876b8d7479c8afe025a58658b0f3c3ec5bd0f28cb4261326b162069bf89060200160405180910390a2565b60006124b87f4e5f991bca30eca2d4643aaefa807e88f96a4a97398933d572a3c0d973004a015490565b1561251f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f484f4c4f47524150483a20616c726561647920696e697469616c697a656400006044820152606401610c63565b6000828060200190518101906125359190615ca0565b8051600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055602082015191925016156125d0576020810151600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790555b6125fc81604001517fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf77277755565b60408051608080820183526101008401805173ffffffffffffffffffffffffffffffffffffffff9081168085528684015167ffffffffffffffff908116602080880182905260a0808b015161ffff16898b018190526060808d015188169a81018b9052600380547c01000000000000000000000000000000000000000000000000000000009093027fffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff740100000000000000000000000000000000000000009097027fffffffff00000000000000000000000000000000000000000000000000000000909416909817929092179490941695909517909455600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001690981790975560e0890151805160058054998301519a830151851671010000000000000000000000000000000000027fffffffffffffff0000000000000000ffffffffffffffffffffffffffffffffff63ffffffff909c166d0100000000000000000000000000027fffffffffffffffffffffffffffffff0000000000000000000000000000000000909b166cffffffffffffffffffffffffff90931692909217999099179990991698909817909655948601516006805495880151928801518716700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff93881668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909716929097169190911794909417169390931790915560c090920151600755905116156128f7576101008101516101208201516040517f856a7ffa00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9092169163856a7ffa916128c491600401615320565b600060405180830381600087803b1580156128de57600080fd5b505af11580156128f2573d6000803e3d6000fd5b505050505b8060c00151801561291657506daaeb6d7670e522a718067333cd4e3b15155b15612a715760025473ffffffffffffffffffffffffffffffffffffffff166129b4576040517f4420e4860000000000000000000000000000000000000000000000000000000081523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b15801561299757600080fd5b505af11580156129ab573d6000803e3d6000fd5b50505050612a4c565b6002546040517f7d3e3dbe00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe90604401600060405180830381600087803b158015612a3357600080fd5b505af1158015612a47573d6000803e3d6000fd5b505050505b60017f5c835f3b6bd322d9a084ffdeac746df2b96cce308e7f0612f4ff4f9c490734cc555b612a9a60017f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a313727955565b610a8a83614e55565b7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5473ffffffffffffffffffffffffffffffffffffffff163303612bbf577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1614612bba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b612c75565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612c75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5473ffffffffffffffffffffffffffffffffffffffff163303612dd8577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1614612dd3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b612e8e565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612e8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b600254309073ffffffffffffffffffffffffffffffffffffffff16612edf576040517f707ff7e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fc3c5a54700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526daaeb6d7670e522a718067333cd4e9063c3c5a547906024016020604051808303816000875af1158015612f59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f7d9190615b68565b158015612f875750815b1561302b576002546040517f7d3e3dbe00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808416600483015290911660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b15801561300e57600080fd5b505af1158015613022573d6000803e3d6000fd5b505050506131bf565b811561309d576002546040517fb314d41400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff808416600483015290911660248201526daaeb6d7670e522a718067333cd4e9063b314d41490604401612ff4565b6040517f34a0dc1000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152600060248201526daaeb6d7670e522a718067333cd4e906334a0dc1090604401600060405180830381600087803b15801561311957600080fd5b505af115801561312d573d6000803e3d6000fd5b50506040517f2ec2c24600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526daaeb6d7670e522a718067333cd4e9250632ec2c2469150602401600060405180830381600087803b1580156131a657600080fd5b505af11580156131ba573d6000803e3d6000fd5b505050505b6040517fc3c5a5470000000000000000000000000000000000000000000000000000000081523060048201526000906daaeb6d7670e522a718067333cd4e9063c3c5a547906024016020604051808303816000875af1158015613226573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061324a9190615b68565b7f5c835f3b6bd322d9a084ffdeac746df2b96cce308e7f0612f4ff4f9c490734cc55505050565b6000610b4b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775490565b60006132c57fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b73ffffffffffffffffffffffffffffffffffffffff163303613359577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1614905090565b507fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16331490565b6060815167ffffffffffffffff8111156133b3576133b361556c565b6040519080825280602002602001820160405280156133e657816020015b60608152602001906001900390816133d15790505b50905060005b8251811015613492576134623084838151811061340b5761340b615dac565b602002602001015161343d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe036013590565b60405160200161344e929190615ddb565b604051602081830303815290604052614ffc565b82828151811061347457613474615dac565b6020026020010181905250808061348a90615e25565b9150506133ec565b50919050565b60006134c27fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b73ffffffffffffffffffffffffffffffffffffffff1633036135bc577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff16146135b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b613672565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b600354829074010000000000000000000000000000000000000000900467ffffffffffffffff16158015906136f657506003546000547401000000000000000000000000000000000000000090910467ffffffffffffffff16906136f4907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1683615ad8565b115b1561372d576040517f717c513000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b838110156137715761376985858381811061374d5761374d615dac565b90506020020160208101906137629190615333565b6001614a39565b600101613730565b50506000547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169392505050565b60606137c57fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b73ffffffffffffffffffffffffffffffffffffffff1633036138bf577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff16146138ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b613975565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613975576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b6000806daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1685856040516139ad929190615e5d565b6000604051808303816000865af19150503d80600081146139ea576040519150601f19603f3d011682016040523d82523d6000602084013e6139ef565b606091505b509150915081613a2b576040517f25f3885400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fc3c5a5470000000000000000000000000000000000000000000000000000000081523060048201526000906daaeb6d7670e522a718067333cd4e9063c3c5a547906024016020604051808303816000875af1158015613a92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ab69190615b68565b7f5c835f3b6bd322d9a084ffdeac746df2b96cce308e7f0612f4ff4f9c490734cc5550949350505050565b60606000613b0d7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b6040517f4f558e790000000000000000000000000000000000000000000000000000000081526004810185905290915073ffffffffffffffffffffffffffffffffffffffff821690634f558e7990602401602060405180830381865afa158015613b7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b9f9190615b68565b613c05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433732313a20746f6b656e20646f6573206e6f74206578697374000000006044820152606401610c63565b6003546040517fc87b56dd0000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff9091169063c87b56dd90602401600060405180830381865afa158015613c74573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610a8a9190810190615a60565b613cde60405180606001604052806000815260200160008152602001600081525090565b6040805160608101825273ffffffffffffffffffffffffffffffffffffffff841660008181526009602081815285832054808652848452600882528684205482870181905294909352529192830191613d379190615b2d565b905292915050565b6000613d697fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b73ffffffffffffffffffffffffffffffffffffffff163303613e63577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1614613e5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b613f19565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613f19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b600354829074010000000000000000000000000000000000000000900467ffffffffffffffff1615801590613f9d57506003546000547401000000000000000000000000000000000000000090910467ffffffffffffffff1690613f9b907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1683615ad8565b115b15613fd4576040517f717c513000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613fde8484614a39565b50506000547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1692915050565b600354604080517fe8a3d485000000000000000000000000000000000000000000000000000000008152905160609273ffffffffffffffffffffffffffffffffffffffff169163e8a3d4859160048083019260009291908290030181865afa158015610b05573d6000803e3d6000fd5b60006140a17f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a31372795490565b60020361410a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f484f4c4f47524150483a207265656e7472616e742063616c6c000000000000006044820152606401610c63565b61413360027f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a313727955565b600354829074010000000000000000000000000000000000000000900467ffffffffffffffff16158015906141b757506003546000547401000000000000000000000000000000000000000090910467ffffffffffffffff16906141b5907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1683615ad8565b115b156141ee576040517f717c513000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6141f6614e10565b61422c576040517ff12dcc7f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055460009061424a906cffffffffffffffffffffffffff1661492f565b90506142568482615af0565b34101561427a576005546111c29085906cffffffffffffffffffffffffff16615af0565b60006142868583615af0565b6142909034615b2d565b6005549091506d0100000000000000000000000000900463ffffffff161580159061433e5750600554367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff166000908152600860209081526040808320546009909252909120546d010000000000000000000000000090920463ffffffff1691614332908890615ad8565b61433c9190615b2d565b115b15614375576040517f220ae94c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6143a2367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013586614a39565b60006143cc7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b905060008173ffffffffffffffffffffffffffffffffffffffff166377dbd8636040518163ffffffff1660e01b8152600401602060405180830381865afa15801561441b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061443f9190615b44565b60008054919250906144709089907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16615b2d565b61447a9083615ad8565b614485906001615ad8565b90508488367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff167f4e26b0356a15833a75d497ecc40ebbb716b99466ed0dba9454f1fff451e25a90846040516144f491815260200190565b60405180910390a4831561459b57367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff1684620334505a1161454d575a614552565b620334505b6040519091906000818181858888f193505050503d8060008114614592576040519150601f19603f3d011682016040523d82523d6000602084013e614597565b606091505b5050505b955050505050506145cb60017f04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a313727955565b919050565b7fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5473ffffffffffffffffffffffffffffffffffffffff1633036146ec577fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff16367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff16146146e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b6147a2565b7fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146147a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a206f776e6572206f6e6c792066756e6374696f6e00000000006044820152606401610c63565b600580546cffffffffffffffffffffffffff89167fffffffffffffffffffffffffffffff0000000000000000000000000000000000909116176d010000000000000000000000000063ffffffff891602177fffffffffffffff0000000000000000ffffffffffffffffffffffffffffffffff167101000000000000000000000000000000000067ffffffffffffffff8881169190910291909117909155600680548683167fffffffffffffffffffffffffffffffff00000000000000000000000000000000909116176801000000000000000086841602177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000928516929092029190911790556007819055367fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0013573ffffffffffffffffffffffffffffffffffffffff167fc1ff5e4744ac8dd2b8027a10e3723b165975297501c71c4e7dcb8796d96375db60405160405180910390a250505050505050565b60008160000361494157506000919050565b6040517ff5d781610000000000000000000000000000000000000000000000000000000081526004810183905273a3db09eec42baff7a50fb8f9af90a0e035ef33029063f5d7816190602401602060405180830381865afa1580156149aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149ce9190615b44565b92915050565b600654600090426801000000000000000090910467ffffffffffffffff1611801590610b4b5750506006544270010000000000000000000000000000000090910467ffffffffffffffff161190565b600082614a308584615021565b14949350505050565b6000614a637fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd5490565b905060008173ffffffffffffffffffffffffffffffffffffffff166377dbd8636040518163ffffffff1660e01b8152600401602060405180830381865afa158015614ab2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614ad69190615b44565b90506000805b84811015614e085760008054600191908190614b179084907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16615e6d565b92506101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1602179055505b60005473ffffffffffffffffffffffffffffffffffffffff851690634f558e7990614baf907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1686615ad8565b6040518263ffffffff1660e01b8152600401614bcd91815260200190565b602060405180830381865afa158015614bea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614c0e9190615b68565b80614cbc575060005473ffffffffffffffffffffffffffffffffffffffff8516906323250cae90614c5d907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1686615ad8565b6040518263ffffffff1660e01b8152600401614c7b91815260200190565b602060405180830381865afa158015614c98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614cbc9190615b68565b15614d475760008054600191908190614cf49084907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16615e6d565b92506101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550614b66565b6000546040517f3b4f1b2600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff88811660048301527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90921660248201819052935090851690633b4f1b2690604401600060405180830381600087803b158015614ddd57600080fd5b505af1158015614df1573d6000803e3d6000fd5b505050508080614e0090615e25565b915050614adc565b505050505050565b600554600090427101000000000000000000000000000000000090910467ffffffffffffffff1611801590610b4b5750506006544267ffffffffffffffff9091161190565b6000614e7f7f4e5f991bca30eca2d4643aaefa807e88f96a4a97398933d572a3c0d973004a015490565b15614ee6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4552433732313a20616c726561647920696e697469616c697a656400000000006044820152606401610c63565b337fe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd8190557fb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf7727775473ffffffffffffffffffffffffffffffffffffffff8116614faa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f484f4c4f47524150483a206f776e6572206e6f742073657400000000000000006044820152606401610c63565b614fd360017f4e5f991bca30eca2d4643aaefa807e88f96a4a97398933d572a3c0d973004a0155565b507f4ddf47d4000000000000000000000000000000000000000000000000000000009392505050565b6060610a8a8383604051806060016040528060278152602001615eca60279139615095565b600081815b845181101561508d57600085828151811061504357615043615dac565b60200260200101519050808311615069576000838152602082905260409020925061507a565b600081815260208490526040902092505b508061508581615e25565b915050615026565b509392505050565b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516150bf9190615ead565b600060405180830381855af49150503d80600081146150fa576040519150601f19603f3d011682016040523d82523d6000602084013e6150ff565b606091505b50915091506151108683838761511a565b9695505050505050565b606083156151b05782516000036151a95773ffffffffffffffffffffffffffffffffffffffff85163b6151a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c63565b50816151ba565b6151ba83836151c2565b949350505050565b8151156151d25781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c639190615320565b73ffffffffffffffffffffffffffffffffffffffff8116811461522857600080fd5b50565b6000806040838503121561523e57600080fd5b823561524981615206565b9150602083013561525981615206565b809150509250929050565b60006020828403121561527657600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610a8a57600080fd5b60005b838110156152c15781810151838201526020016152a9565b838111156152d0576000848401525b50505050565b600081518084526152ee8160208601602086016152a6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610a8a60208301846152d6565b60006020828403121561534557600080fd5b8135610a8a81615206565b60008083601f84011261536257600080fd5b50813567ffffffffffffffff81111561537a57600080fd5b6020830191508360208260051b850101111561539557600080fd5b9250929050565b6000806000806000608086880312156153b457600080fd5b853594506020860135935060408601359250606086013567ffffffffffffffff8111156153e057600080fd5b6153ec88828901615350565b969995985093965092949392505050565b60008083601f84011261540f57600080fd5b50813567ffffffffffffffff81111561542757600080fd5b60208301915083602082850101111561539557600080fd5b60008060008060006080868803121561545757600080fd5b853561546281615206565b9450602086013561547281615206565b935060408601359250606086013567ffffffffffffffff81111561549557600080fd5b6153ec888289016153fd565b815115158152610160810160208301516154bf602084018215159052565b506040830151604083015260608301516154e5606084018267ffffffffffffffff169052565b506080830151615501608084018267ffffffffffffffff169052565b5060a083015161551d60a084018267ffffffffffffffff169052565b5060c083015161553960c084018267ffffffffffffffff169052565b5060e083810151908301526101008084015190830152610120808401519083015261014092830151929091019190915290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff811182821017156155bf576155bf61556c565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561560c5761560c61556c565b604052919050565b600067ffffffffffffffff82111561562e5761562e61556c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261566b57600080fd5b813561567e61567982615614565b6155c5565b81815284602083860101111561569357600080fd5b816020850160208301376000918101602001919091529392505050565b600080604083850312156156c357600080fd5b82356156ce81615206565b9150602083013567ffffffffffffffff8111156156ea57600080fd5b6156f68582860161565a565b9150509250929050565b60006020828403121561571257600080fd5b813567ffffffffffffffff81111561572957600080fd5b6151ba8482850161565a565b801515811461522857600080fd5b60006020828403121561575557600080fd5b8135610a8a81615735565b6000602080838503121561577357600080fd5b823567ffffffffffffffff8082111561578b57600080fd5b818501915085601f83011261579f57600080fd5b8135818111156157b1576157b161556c565b8060051b6157c08582016155c5565b91825283810185019185810190898411156157da57600080fd5b86860192505b83831015615816578235858111156157f85760008081fd5b6158068b89838a010161565a565b83525091860191908601906157e0565b9998505050505050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015615896577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08886030184526158848583516152d6565b9450928501929085019060010161584a565b5092979650505050505050565b600080602083850312156158b657600080fd5b823567ffffffffffffffff8111156158cd57600080fd5b6158d985828601615350565b90969095509350505050565b600080602083850312156158f857600080fd5b823567ffffffffffffffff81111561590f57600080fd5b6158d9858286016153fd565b60006020828403121561592d57600080fd5b5035919050565b6000806040838503121561594757600080fd5b823561595281615206565b946020939093013593505050565b6cffffffffffffffffffffffffff8116811461522857600080fd5b63ffffffff8116811461522857600080fd5b67ffffffffffffffff8116811461522857600080fd5b600080600080600080600060e0888a0312156159be57600080fd5b87356159c981615960565b965060208801356159d98161597b565b955060408801356159e98161598d565b945060608801356159f98161598d565b93506080880135615a098161598d565b925060a0880135615a198161598d565b8092505060c0880135905092959891949750929550565b6000615a3e61567984615614565b9050828152838383011115615a5257600080fd5b610a8a8360208301846152a6565b600060208284031215615a7257600080fd5b815167ffffffffffffffff811115615a8957600080fd5b8201601f81018413615a9a57600080fd5b6151ba84825160208401615a30565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115615aeb57615aeb615aa9565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615b2857615b28615aa9565b500290565b600082821015615b3f57615b3f615aa9565b500390565b600060208284031215615b5657600080fd5b5051919050565b80516145cb81615735565b600060208284031215615b7a57600080fd5b8151610a8a81615735565b80516145cb81615206565b600060208284031215615ba257600080fd5b8151610a8a81615206565b80516145cb8161598d565b805161ffff811681146145cb57600080fd5b600060e08284031215615bdc57600080fd5b60405160e0810181811067ffffffffffffffff82111715615bff57615bff61556c565b80604052508091508251615c1281615960565b81526020830151615c228161597b565b60208201526040830151615c358161598d565b60408201526060830151615c488161598d565b6060820152615c5960808401615bad565b6080820152615c6a60a08401615bad565b60a082015260c083015160c08201525092915050565b600082601f830112615c9157600080fd5b610a8a83835160208501615a30565b600060208284031215615cb257600080fd5b815167ffffffffffffffff80821115615cca57600080fd5b908301906102008286031215615cdf57600080fd5b615ce761559b565b615cf083615b85565b8152615cfe60208401615b85565b6020820152615d0f60408401615b85565b6040820152615d2060608401615b85565b6060820152615d3160808401615bad565b6080820152615d4260a08401615bb8565b60a0820152615d5360c08401615b5d565b60c0820152615d658660e08501615bca565b60e0820152615d776101c08401615b85565b6101008201526101e083015182811115615d9057600080fd5b615d9c87828601615c80565b6101208301525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008351615ded8184602088016152a6565b60609390931b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000169190920190815260140192915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615e5657615e56615aa9565b5060010190565b8183823760009101908152919050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff808316818516808303821115615ea457615ea4615aa9565b01949350505050565b60008251615ebf8184602087016152a6565b919091019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a164736f6c634300080d000a
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.