Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
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:
ZoraCreator1155Impl
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 3000 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {ERC1155Upgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/ERC1155Upgradeable.sol"; import {ReentrancyGuardUpgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/security/ReentrancyGuardUpgradeable.sol"; import {UUPSUpgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol"; import {IERC1155MetadataURIUpgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1155MetadataURIUpgradeable.sol"; import {IERC165Upgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC165Upgradeable.sol"; import {IProtocolRewards} from "@zoralabs/protocol-rewards/dist/contracts/interfaces/IProtocolRewards.sol"; import {ERC1155Rewards} from "@zoralabs/protocol-rewards/dist/contracts/abstract/ERC1155/ERC1155Rewards.sol"; import {ERC1155RewardsStorageV1} from "@zoralabs/protocol-rewards/dist/contracts/abstract/ERC1155/ERC1155RewardsStorageV1.sol"; import {IZoraCreator1155} from "../interfaces/IZoraCreator1155.sol"; import {IZoraCreator1155Initializer} from "../interfaces/IZoraCreator1155Initializer.sol"; import {ReentrancyGuardUpgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/security/ReentrancyGuardUpgradeable.sol"; import {UUPSUpgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol"; import {MathUpgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/utils/math/MathUpgradeable.sol"; import {ContractVersionBase} from "../version/ContractVersionBase.sol"; import {CreatorPermissionControl} from "../permissions/CreatorPermissionControl.sol"; import {CreatorRendererControl} from "../renderer/CreatorRendererControl.sol"; import {CreatorRoyaltiesControl} from "../royalties/CreatorRoyaltiesControl.sol"; import {ICreatorCommands} from "../interfaces/ICreatorCommands.sol"; import {IMinter1155} from "../interfaces/IMinter1155.sol"; import {IRenderer1155} from "../interfaces/IRenderer1155.sol"; import {ITransferHookReceiver} from "../interfaces/ITransferHookReceiver.sol"; import {IFactoryManagedUpgradeGate} from "../interfaces/IFactoryManagedUpgradeGate.sol"; import {IZoraCreator1155} from "../interfaces/IZoraCreator1155.sol"; import {LegacyNamingControl} from "../legacy-naming/LegacyNamingControl.sol"; import {MintFeeManager} from "../fee/MintFeeManager.sol"; import {PublicMulticall} from "../utils/PublicMulticall.sol"; import {SharedBaseConstants} from "../shared/SharedBaseConstants.sol"; import {TransferHelperUtils} from "../utils/TransferHelperUtils.sol"; import {ZoraCreator1155StorageV1} from "./ZoraCreator1155StorageV1.sol"; /// Imagine. Mint. Enjoy. /// @title ZoraCreator1155Impl /// @notice The core implementation contract for a creator's 1155 token /// @author @iainnash / @tbtstl contract ZoraCreator1155Impl is IZoraCreator1155, IZoraCreator1155Initializer, ContractVersionBase, ReentrancyGuardUpgradeable, PublicMulticall, ERC1155Upgradeable, MintFeeManager, UUPSUpgradeable, CreatorRendererControl, LegacyNamingControl, ZoraCreator1155StorageV1, CreatorPermissionControl, CreatorRoyaltiesControl, ERC1155Rewards, ERC1155RewardsStorageV1 { /// @notice This user role allows for any action to be performed uint256 public constant PERMISSION_BIT_ADMIN = 2 ** 1; /// @notice This user role allows for only mint actions to be performed uint256 public constant PERMISSION_BIT_MINTER = 2 ** 2; /// @notice This user role allows for only managing sales configurations uint256 public constant PERMISSION_BIT_SALES = 2 ** 3; /// @notice This user role allows for only managing metadata configuration uint256 public constant PERMISSION_BIT_METADATA = 2 ** 4; /// @notice This user role allows for only withdrawing funds and setting funds withdraw address uint256 public constant PERMISSION_BIT_FUNDS_MANAGER = 2 ** 5; /// @notice Factory contract IFactoryManagedUpgradeGate internal immutable factory; constructor( uint256 _mintFeeAmount, address _mintFeeRecipient, address _factory, address _protocolRewards ) MintFeeManager(_mintFeeAmount, _mintFeeRecipient) ERC1155Rewards(_protocolRewards, _mintFeeRecipient) initializer { factory = IFactoryManagedUpgradeGate(_factory); } /// @notice Initializes the contract /// @param contractName the legacy on-chain contract name /// @param newContractURI The contract URI /// @param defaultRoyaltyConfiguration The default royalty configuration /// @param defaultAdmin The default admin to manage the token /// @param setupActions The setup actions to run, if any function initialize( string memory contractName, string memory newContractURI, RoyaltyConfiguration memory defaultRoyaltyConfiguration, address payable defaultAdmin, bytes[] calldata setupActions ) external nonReentrant initializer { // We are not initalizing the OZ 1155 implementation // to save contract storage space and runtime // since the only thing affected here is the uri. // __ERC1155_init(""); // Setup uups __UUPSUpgradeable_init(); // Setup re-entracy guard __ReentrancyGuard_init(); // Setup contract-default token ID _setupDefaultToken(defaultAdmin, newContractURI, defaultRoyaltyConfiguration); // Set owner to default admin _setOwner(defaultAdmin); _setFundsRecipient(defaultAdmin); _setName(contractName); // Run Setup actions if (setupActions.length > 0) { // Temporarily make sender admin _addPermission(CONTRACT_BASE_ID, msg.sender, PERMISSION_BIT_ADMIN); // Make calls multicall(setupActions); // Remove admin _removePermission(CONTRACT_BASE_ID, msg.sender, PERMISSION_BIT_ADMIN); } } /// @notice sets up the global configuration for the 1155 contract /// @param newContractURI The contract URI /// @param defaultRoyaltyConfiguration The default royalty configuration function _setupDefaultToken(address defaultAdmin, string memory newContractURI, RoyaltyConfiguration memory defaultRoyaltyConfiguration) internal { // Add admin permission to default admin to manage contract _addPermission(CONTRACT_BASE_ID, defaultAdmin, PERMISSION_BIT_ADMIN); // Mint token ID 0 / don't allow any user mints _setupNewToken(newContractURI, 0); // Update default royalties _updateRoyalties(CONTRACT_BASE_ID, defaultRoyaltyConfiguration); } /// @notice Updates the royalty configuration for a token /// @param tokenId The token ID to update /// @param newConfiguration The new royalty configuration function updateRoyaltiesForToken( uint256 tokenId, RoyaltyConfiguration memory newConfiguration ) external onlyAdminOrRole(tokenId, PERMISSION_BIT_FUNDS_MANAGER) { _updateRoyalties(tokenId, newConfiguration); } /// @notice remove this function from openzeppelin impl /// @dev This makes this internal function a no-op function _setURI(string memory newuri) internal virtual override {} /// @notice This gets the next token in line to be minted when minting linearly (default behavior) and updates the counter function _getAndUpdateNextTokenId() internal returns (uint256) { unchecked { return nextTokenId++; } } /// @notice Ensure that the next token ID is correct /// @dev This reverts if the invariant doesn't match. This is used for multicall token id assumptions /// @param lastTokenId The last token ID function assumeLastTokenIdMatches(uint256 lastTokenId) external view { unchecked { if (nextTokenId - 1 != lastTokenId) { revert TokenIdMismatch(lastTokenId, nextTokenId - 1); } } } /// @notice Checks if a user either has a role for a token or if they are the admin /// @dev This is an internal function that is called by the external getter and internal functions /// @param user The user to check /// @param tokenId The token ID to check /// @param role The role to check /// @return true or false if the permission exists for the user given the token id function _isAdminOrRole(address user, uint256 tokenId, uint256 role) internal view returns (bool) { return _hasAnyPermission(tokenId, user, PERMISSION_BIT_ADMIN | role); } /// @notice Checks if a user either has a role for a token or if they are the admin /// @param user The user to check /// @param tokenId The token ID to check /// @param role The role to check /// @return true or false if the permission exists for the user given the token id function isAdminOrRole(address user, uint256 tokenId, uint256 role) external view returns (bool) { return _isAdminOrRole(user, tokenId, role); } /// @notice Checks if the user is an admin for the given tokenId /// @dev This function reverts if the permission does not exist for the given user and tokenId /// @param user user to check /// @param tokenId tokenId to check /// @param role role to check for admin function _requireAdminOrRole(address user, uint256 tokenId, uint256 role) internal view { if (!(_hasAnyPermission(tokenId, user, PERMISSION_BIT_ADMIN | role) || _hasAnyPermission(CONTRACT_BASE_ID, user, PERMISSION_BIT_ADMIN | role))) { revert UserMissingRoleForToken(user, tokenId, role); } } /// @notice Checks if the user is an admin /// @dev This reverts if the user is not an admin for the given token id or contract /// @param user user to check /// @param tokenId tokenId to check function _requireAdmin(address user, uint256 tokenId) internal view { if (!(_hasAnyPermission(tokenId, user, PERMISSION_BIT_ADMIN) || _hasAnyPermission(CONTRACT_BASE_ID, user, PERMISSION_BIT_ADMIN))) { revert UserMissingRoleForToken(user, tokenId, PERMISSION_BIT_ADMIN); } } /// @notice Modifier checking if the user is an admin or has a role /// @dev This reverts if the msg.sender is not an admin for the given token id or contract /// @param tokenId tokenId to check /// @param role role to check modifier onlyAdminOrRole(uint256 tokenId, uint256 role) { _requireAdminOrRole(msg.sender, tokenId, role); _; } /// @notice Modifier checking if the user is an admin /// @dev This reverts if the msg.sender is not an admin for the given token id or contract /// @param tokenId tokenId to check modifier onlyAdmin(uint256 tokenId) { _requireAdmin(msg.sender, tokenId); _; } /// @notice Modifier checking if the requested quantity of tokens can be minted for the tokenId /// @dev This reverts if the number that can be minted is exceeded /// @param tokenId token id to check available allowed quantity /// @param quantity requested to be minted modifier canMintQuantity(uint256 tokenId, uint256 quantity) { _requireCanMintQuantity(tokenId, quantity); _; } /// @notice Only from approved address for burn /// @param from address that the tokens will be burned from, validate that this is msg.sender or that msg.sender is approved modifier onlyFromApprovedForBurn(address from) { if (from != msg.sender && !isApprovedForAll(from, msg.sender)) { revert Burn_NotOwnerOrApproved(msg.sender, from); } _; } /// @notice Checks if a user can mint a quantity of a token /// @dev Reverts if the mint exceeds the allowed quantity (or if the token does not exist) /// @param tokenId The token ID to check /// @param quantity The quantity of tokens to mint to check function _requireCanMintQuantity(uint256 tokenId, uint256 quantity) internal view { TokenData storage tokenInformation = tokens[tokenId]; if (tokenInformation.totalMinted + quantity > tokenInformation.maxSupply) { revert CannotMintMoreTokens(tokenId, quantity, tokenInformation.totalMinted, tokenInformation.maxSupply); } } /// @notice Set up a new token /// @param newURI The URI for the token /// @param maxSupply The maximum supply of the token function setupNewToken( string calldata newURI, uint256 maxSupply ) public onlyAdminOrRole(CONTRACT_BASE_ID, PERMISSION_BIT_MINTER) nonReentrant returns (uint256) { uint256 tokenId = _setupNewTokenAndPermission(newURI, maxSupply, msg.sender, PERMISSION_BIT_ADMIN); return tokenId; } /// @notice Set up a new token with a create referral /// @param newURI The URI for the token /// @param maxSupply The maximum supply of the token /// @param createReferral The address of the create referral function setupNewTokenWithCreateReferral( string calldata newURI, uint256 maxSupply, address createReferral ) public onlyAdminOrRole(CONTRACT_BASE_ID, PERMISSION_BIT_MINTER) nonReentrant returns (uint256) { uint256 tokenId = _setupNewTokenAndPermission(newURI, maxSupply, msg.sender, PERMISSION_BIT_ADMIN); _setCreateReferral(tokenId, createReferral); return tokenId; } function _setupNewTokenAndPermission(string calldata newURI, uint256 maxSupply, address user, uint256 permission) internal returns (uint256) { uint256 tokenId = _setupNewToken(newURI, maxSupply); _addPermission(tokenId, user, permission); if (bytes(newURI).length > 0) { emit URI(newURI, tokenId); } emit SetupNewToken(tokenId, user, newURI, maxSupply); return tokenId; } /// @notice Update the token URI for a token /// @param tokenId The token ID to update the URI for /// @param _newURI The new URI function updateTokenURI(uint256 tokenId, string memory _newURI) external onlyAdminOrRole(tokenId, PERMISSION_BIT_METADATA) { if (tokenId == CONTRACT_BASE_ID) { revert(); } emit URI(_newURI, tokenId); tokens[tokenId].uri = _newURI; } /// @notice Update the global contract metadata /// @param _newURI The new contract URI /// @param _newName The new contract name function updateContractMetadata(string memory _newURI, string memory _newName) external onlyAdminOrRole(0, PERMISSION_BIT_METADATA) { tokens[CONTRACT_BASE_ID].uri = _newURI; _setName(_newName); emit ContractMetadataUpdated(msg.sender, _newURI, _newName); } function _setupNewToken(string memory newURI, uint256 maxSupply) internal returns (uint256 tokenId) { tokenId = _getAndUpdateNextTokenId(); TokenData memory tokenData = TokenData({uri: newURI, maxSupply: maxSupply, totalMinted: 0}); tokens[tokenId] = tokenData; emit UpdatedToken(msg.sender, tokenId, tokenData); } /// @notice Add a role to a user for a token /// @param tokenId The token ID to add the role to /// @param user The user to add the role to /// @param permissionBits The permission bit to add function addPermission(uint256 tokenId, address user, uint256 permissionBits) external onlyAdmin(tokenId) { _addPermission(tokenId, user, permissionBits); } /// @notice Remove a role from a user for a token /// @param tokenId The token ID to remove the role from /// @param user The user to remove the role from /// @param permissionBits The permission bit to remove function removePermission(uint256 tokenId, address user, uint256 permissionBits) external onlyAdmin(tokenId) { _removePermission(tokenId, user, permissionBits); // Clear owner field if (tokenId == CONTRACT_BASE_ID && user == config.owner && !_hasAnyPermission(CONTRACT_BASE_ID, user, PERMISSION_BIT_ADMIN)) { _setOwner(address(0)); } } /// @notice Set the owner of the contract /// @param newOwner The new owner of the contract function setOwner(address newOwner) external onlyAdmin(CONTRACT_BASE_ID) { if (!_hasAnyPermission(CONTRACT_BASE_ID, newOwner, PERMISSION_BIT_ADMIN)) { revert NewOwnerNeedsToBeAdmin(); } // Update owner field _setOwner(newOwner); } /// @notice Getter for the owner singleton of the contract for outside interfaces /// @return the owner of the contract singleton for compat. function owner() external view returns (address) { return config.owner; } /// @notice AdminMint that only checks if the requested quantity can be minted and has a re-entrant guard /// @param recipient recipient for admin minted tokens /// @param tokenId token id to mint /// @param quantity quantity to mint /// @param data callback data as specified by the 1155 spec function _adminMint(address recipient, uint256 tokenId, uint256 quantity, bytes memory data) internal { _mint(recipient, tokenId, quantity, data); } /// @notice Mint a token to a user as the admin or minter /// @param recipient The recipient of the token /// @param tokenId The token ID to mint /// @param quantity The quantity of tokens to mint /// @param data The data to pass to the onERC1155Received function function adminMint( address recipient, uint256 tokenId, uint256 quantity, bytes memory data ) external nonReentrant onlyAdminOrRole(tokenId, PERMISSION_BIT_MINTER) { // Call internal admin mint _adminMint(recipient, tokenId, quantity, data); } /// @notice Batch mint tokens to a user as the admin or minter /// @param recipient The recipient of the tokens /// @param tokenIds The token IDs to mint /// @param quantities The quantities of tokens to mint /// @param data The data to pass to the onERC1155BatchReceived function function adminMintBatch(address recipient, uint256[] memory tokenIds, uint256[] memory quantities, bytes memory data) external nonReentrant { bool isGlobalAdminOrMinter = _isAdminOrRole(msg.sender, CONTRACT_BASE_ID, PERMISSION_BIT_MINTER); for (uint256 i = 0; i < tokenIds.length; ++i) { if (!isGlobalAdminOrMinter) { _requireAdminOrRole(msg.sender, tokenIds[i], PERMISSION_BIT_MINTER); } } _mintBatch(recipient, tokenIds, quantities, data); } /// @notice Mint tokens given a minter contract and minter arguments /// @param minter The minter contract to use /// @param tokenId The token ID to mint /// @param quantity The quantity of tokens to mint /// @param minterArguments The arguments to pass to the minter function mint(IMinter1155 minter, uint256 tokenId, uint256 quantity, bytes calldata minterArguments) external payable nonReentrant { // Require admin from the minter to mint _requireAdminOrRole(address(minter), tokenId, PERMISSION_BIT_MINTER); // Get value sent and handle mint fee uint256 ethValueSent = _handleFeeAndGetValueSent(quantity); // Execute commands returned from minter _executeCommands(minter.requestMint(msg.sender, tokenId, quantity, ethValueSent, minterArguments).commands, ethValueSent, tokenId); emit Purchased(msg.sender, address(minter), tokenId, quantity, msg.value); } /// @notice Get the creator reward recipient address /// @dev The creator is not enforced to set a funds recipient address, so in that case the reward would be claimable by creator's contract function getCreatorRewardRecipient() public view returns (address payable) { return config.fundsRecipient != address(0) ? config.fundsRecipient : payable(address(this)); } /// @notice Mint tokens and payout rewards given a minter contract, minter arguments, a finder, and a origin /// @param minter The minter contract to use /// @param tokenId The token ID to mint /// @param quantity The quantity of tokens to mint /// @param minterArguments The arguments to pass to the minter /// @param mintReferral The referrer of the mint function mintWithRewards( IMinter1155 minter, uint256 tokenId, uint256 quantity, bytes calldata minterArguments, address mintReferral ) external payable nonReentrant { // Require admin from the minter to mint _requireAdminOrRole(address(minter), tokenId, PERMISSION_BIT_MINTER); // Get value sent and handle mint rewards uint256 ethValueSent = _handleRewardsAndGetValueSent(msg.value, quantity, getCreatorRewardRecipient(), createReferrals[tokenId], mintReferral); // Execute commands returned from minter _executeCommands(minter.requestMint(msg.sender, tokenId, quantity, ethValueSent, minterArguments).commands, ethValueSent, tokenId); emit Purchased(msg.sender, address(minter), tokenId, quantity, msg.value); } /// @notice Set a metadata renderer for a token /// @param tokenId The token ID to set the renderer for /// @param renderer The renderer to set function setTokenMetadataRenderer(uint256 tokenId, IRenderer1155 renderer) external nonReentrant onlyAdminOrRole(tokenId, PERMISSION_BIT_METADATA) { _setRenderer(tokenId, renderer); if (tokenId == 0) { emit ContractRendererUpdated(renderer); } else { // We don't know the uri from the renderer but can emit a notification to the indexer here emit URI("", tokenId); } } /// Execute Minter Commands /// /// @notice Internal functions to execute commands returned by the minter /// @param commands list of command structs /// @param ethValueSent the ethereum value sent in the mint transaction into the contract /// @param tokenId the token id the user requested to mint (0 if the token id is set by the minter itself across the whole contract) function _executeCommands(ICreatorCommands.Command[] memory commands, uint256 ethValueSent, uint256 tokenId) internal { for (uint256 i = 0; i < commands.length; ++i) { ICreatorCommands.CreatorActions method = commands[i].method; if (method == ICreatorCommands.CreatorActions.SEND_ETH) { (address recipient, uint256 amount) = abi.decode(commands[i].args, (address, uint256)); if (ethValueSent > amount) { revert Mint_InsolventSaleTransfer(); } if (!TransferHelperUtils.safeSendETH(recipient, amount, TransferHelperUtils.FUNDS_SEND_NORMAL_GAS_LIMIT)) { revert Mint_ValueTransferFail(); } } else if (method == ICreatorCommands.CreatorActions.MINT) { (address recipient, uint256 mintTokenId, uint256 quantity) = abi.decode(commands[i].args, (address, uint256, uint256)); if (tokenId != 0 && mintTokenId != tokenId) { revert Mint_TokenIDMintNotAllowed(); } _mint(recipient, tokenId, quantity, ""); } else { // no-op } } } /// @notice Token info getter /// @param tokenId token id to get info for /// @return TokenData struct returned function getTokenInfo(uint256 tokenId) external view returns (TokenData memory) { return tokens[tokenId]; } /// @notice Proxy setter for sale contracts (only callable by SALES permission or admin) /// @param tokenId The token ID to call the sale contract with /// @param salesConfig The sales config contract to call /// @param data The data to pass to the sales config contract function callSale(uint256 tokenId, IMinter1155 salesConfig, bytes memory data) external onlyAdminOrRole(tokenId, PERMISSION_BIT_SALES) { _requireAdminOrRole(address(salesConfig), tokenId, PERMISSION_BIT_MINTER); if (!salesConfig.supportsInterface(type(IMinter1155).interfaceId)) { revert Sale_CannotCallNonSalesContract(address(salesConfig)); } (bool success, bytes memory why) = address(salesConfig).call(data); if (!success) { revert CallFailed(why); } } /// @notice Proxy setter for renderer contracts (only callable by METADATA permission or admin) /// @param tokenId The token ID to call the renderer contract with /// @param data The data to pass to the renderer contract function callRenderer(uint256 tokenId, bytes memory data) external onlyAdminOrRole(tokenId, PERMISSION_BIT_METADATA) { // We assume any renderers set are checked for EIP165 signature during write stage. (bool success, bytes memory why) = address(getCustomRenderer(tokenId)).call(data); if (!success) { revert CallFailed(why); } } /// @notice Returns true if the contract implements the interface defined by interfaceId /// @param interfaceId The interface to check for /// @return if the interfaceId is marked as supported function supportsInterface( bytes4 interfaceId ) public view virtual override(CreatorRoyaltiesControl, ERC1155Upgradeable, IERC165Upgradeable) returns (bool) { return super.supportsInterface(interfaceId) || interfaceId == type(IZoraCreator1155).interfaceId || ERC1155Upgradeable.supportsInterface(interfaceId); } function _handleSupplyRoyalty(uint256 tokenId, uint256 mintAmount, bytes memory data) internal returns (uint256 totalRoyaltyMints) { uint256 royaltyMintSchedule = royalties[tokenId].royaltyMintSchedule; if (royaltyMintSchedule == 0) { royaltyMintSchedule = royalties[CONTRACT_BASE_ID].royaltyMintSchedule; } if (royaltyMintSchedule == 0) { // If we still have no schedule, return 0 supply royalty. return 0; } uint256 maxSupply = tokens[tokenId].maxSupply; uint256 totalMinted = tokens[tokenId].totalMinted; totalRoyaltyMints = (mintAmount + (totalMinted % royaltyMintSchedule)) / (royaltyMintSchedule - 1); totalRoyaltyMints = MathUpgradeable.min(totalRoyaltyMints, maxSupply - (mintAmount + totalMinted)); if (totalRoyaltyMints > 0) { address royaltyRecipient = royalties[tokenId].royaltyRecipient; if (royaltyRecipient == address(0)) { royaltyRecipient = royalties[CONTRACT_BASE_ID].royaltyRecipient; } // If we have no recipient set, return 0 supply royalty. if (royaltyRecipient == address(0)) { return 0; } super._mint(royaltyRecipient, tokenId, totalRoyaltyMints, data); } } /// Generic 1155 function overrides /// /// @notice Mint function that 1) checks quantity and 2) handles supply royalty 3) keeps track of allowed tokens /// @param to to mint to /// @param id token id to mint /// @param amount of tokens to mint /// @param data as specified by 1155 standard function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual override { uint256 supplyRoyaltyMints = _handleSupplyRoyalty(id, amount, data); _requireCanMintQuantity(id, amount + supplyRoyaltyMints); super._mint(to, id, amount, data); tokens[id].totalMinted += amount + supplyRoyaltyMints; } /// @notice Mint batch function that 1) checks quantity and 2) handles supply royalty 3) keeps track of allowed tokens /// @param to to mint to /// @param ids token ids to mint /// @param amounts of tokens to mint /// @param data as specified by 1155 standard function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual override { super._mintBatch(to, ids, amounts, data); for (uint256 i = 0; i < ids.length; ++i) { uint256 supplyRoyaltyMints = _handleSupplyRoyalty(ids[i], amounts[i], data); _requireCanMintQuantity(ids[i], amounts[i] + supplyRoyaltyMints); tokens[ids[i]].totalMinted += amounts[i] + supplyRoyaltyMints; } } /// @notice Burns a batch of tokens /// @dev Only the current owner is allowed to burn /// @param from the user to burn from /// @param tokenIds The token ID to burn /// @param amounts The amount of tokens to burn function burnBatch(address from, uint256[] calldata tokenIds, uint256[] calldata amounts) external { if (from != msg.sender && !isApprovedForAll(from, msg.sender)) { revert Burn_NotOwnerOrApproved(msg.sender, from); } _burnBatch(from, tokenIds, amounts); } function setTransferHook(ITransferHookReceiver transferHook) external onlyAdmin(CONTRACT_BASE_ID) { if (address(transferHook) != address(0)) { if (!transferHook.supportsInterface(type(ITransferHookReceiver).interfaceId)) { revert Config_TransferHookNotSupported(address(transferHook)); } } config.transferHook = transferHook; emit ConfigUpdated(msg.sender, ConfigUpdate.TRANSFER_HOOK, config); } /// @notice Hook before token transfer that checks for a transfer hook integration /// @param operator operator moving the tokens /// @param from from address /// @param to to address /// @param ids token ids to move /// @param amounts amounts of tokens /// @param data data of tokens function _beforeBatchTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal override { super._beforeBatchTokenTransfer(operator, from, to, ids, amounts, data); if (address(config.transferHook) != address(0)) { config.transferHook.onTokenTransferBatch({target: address(this), operator: operator, from: from, to: to, ids: ids, amounts: amounts, data: data}); } } /// @notice Returns the URI for the contract function contractURI() external view returns (string memory) { IRenderer1155 customRenderer = getCustomRenderer(CONTRACT_BASE_ID); if (address(customRenderer) != address(0)) { return customRenderer.contractURI(); } return uri(0); } /// @notice Returns the URI for a token /// @param tokenId The token ID to return the URI for function uri(uint256 tokenId) public view override(ERC1155Upgradeable, IERC1155MetadataURIUpgradeable) returns (string memory) { if (bytes(tokens[tokenId].uri).length > 0) { return tokens[tokenId].uri; } return _render(tokenId); } /// @notice Internal setter for contract admin with no access checks /// @param newOwner new owner address function _setOwner(address newOwner) internal { address lastOwner = config.owner; config.owner = newOwner; emit OwnershipTransferred(lastOwner, newOwner); emit ConfigUpdated(msg.sender, ConfigUpdate.OWNER, config); } /// @notice Set funds recipient address /// @param fundsRecipient new funds recipient address function setFundsRecipient(address payable fundsRecipient) external onlyAdminOrRole(CONTRACT_BASE_ID, PERMISSION_BIT_FUNDS_MANAGER) { _setFundsRecipient(fundsRecipient); } /// @notice Internal no-checks set funds recipient address /// @param fundsRecipient new funds recipient address function _setFundsRecipient(address payable fundsRecipient) internal { config.fundsRecipient = fundsRecipient; emit ConfigUpdated(msg.sender, ConfigUpdate.FUNDS_RECIPIENT, config); } /// @notice Allows the create referral to update the address that can claim their rewards function updateCreateReferral(uint256 tokenId, address recipient) external { if (msg.sender != createReferrals[tokenId]) revert ONLY_CREATE_REFERRAL(); _setCreateReferral(tokenId, recipient); } function _setCreateReferral(uint256 tokenId, address recipient) internal { createReferrals[tokenId] = recipient; } /// @notice Withdraws all ETH from the contract to the funds recipient address function withdraw() public onlyAdminOrRole(CONTRACT_BASE_ID, PERMISSION_BIT_FUNDS_MANAGER) { uint256 contractValue = address(this).balance; if (!TransferHelperUtils.safeSendETH(config.fundsRecipient, contractValue, TransferHelperUtils.FUNDS_SEND_NORMAL_GAS_LIMIT)) { revert ETHWithdrawFailed(config.fundsRecipient, contractValue); } } /// @notice Withdraws ETH from the Zora Rewards contract function withdrawRewards(address to, uint256 amount) public onlyAdminOrRole(CONTRACT_BASE_ID, PERMISSION_BIT_FUNDS_MANAGER) { bytes memory data = abi.encodeWithSelector(IProtocolRewards.withdraw.selector, to, amount); (bool success, ) = address(protocolRewards).call(data); if (!success) { revert ProtocolRewardsWithdrawFailed(msg.sender, to, amount); } } /// /// /// MANAGER UPGRADE /// /// /// /// @notice Ensures the caller is authorized to upgrade the contract /// @dev This function is called in `upgradeTo` & `upgradeToAndCall` /// @param _newImpl The new implementation address function _authorizeUpgrade(address _newImpl) internal view override onlyAdmin(CONTRACT_BASE_ID) { if (!factory.isRegisteredUpgradePath(_getImplementation(), _newImpl)) { revert(); } } }
// SPDX-License-Identifier: MIT // Modifications from OpenZeppelin Contracts (last updated v4.8.0) (token/ERC1155/ERC1155.sol): // - Revert strings replaced with custom errors // - Decoupled hooks // - `_beforeTokenTransfer` --> `_beforeTokenTransfer` & `_beforeBatchTokenTransfer` // - `_afterTokenTransfer` --> `_afterTokenTransfer` & `_afterBatchTokenTransfer` // - Minor gas optimizations (eg. array length caching, unchecked loop iteration) pragma solidity ^0.8.0; import "./IERC1155Upgradeable.sol"; import "./IERC1155ReceiverUpgradeable.sol"; import "./extensions/IERC1155MetadataURIUpgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/ContextUpgradeable.sol"; import "../../utils/introspection/ERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.sol"; error ERC1155_ADDRESS_ZERO_IS_NOT_A_VALID_OWNER(); error ERC1155_ACCOUNTS_AND_IDS_LENGTH_MISMATCH(); error ERC1155_IDS_AND_AMOUNTS_LENGTH_MISMATCH(); error ERC1155_CALLER_IS_NOT_TOKEN_OWNER_OR_APPROVED(); error ERC1155_TRANSFER_TO_ZERO_ADDRESS(); error ERC1155_INSUFFICIENT_BALANCE_FOR_TRANSFER(); error ERC1155_MINT_TO_ZERO_ADDRESS(); error ERC1155_BURN_FROM_ZERO_ADDRESS(); error ERC1155_BURN_AMOUNT_EXCEEDS_BALANCE(); error ERC1155_SETTING_APPROVAL_FOR_SELF(); error ERC1155_ERC1155RECEIVER_REJECTED_TOKENS(); error ERC1155_TRANSFER_TO_NON_ERC1155RECEIVER_IMPLEMENTER(); /** * @dev Implementation of the basic standard multi-token. * See https://eips.ethereum.org/EIPS/eip-1155 * Originally based on code by Enjin: https://github.com/enjin/erc-1155 * * _Available since v3.1._ */ contract ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable { using AddressUpgradeable for address; // Mapping from token ID to account balances mapping(uint256 => mapping(address => uint256)) private _balances; // Mapping from account to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json string private _uri; /** * @dev See {_setURI}. */ function __ERC1155_init(string memory uri_) internal onlyInitializing { __ERC1155_init_unchained(uri_); } function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing { _setURI(uri_); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { return interfaceId == type(IERC1155Upgradeable).interfaceId || interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC1155MetadataURI-uri}. * * This implementation returns the same URI for *all* token types. It relies * on the token type ID substitution mechanism * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. * * Clients calling this function must replace the `\{id\}` substring with the * actual token type ID. */ function uri(uint256) public view virtual override returns (string memory) { return _uri; } /** * @dev See {IERC1155-balanceOf}. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) public view virtual override returns (uint256) { if (account == address(0)) { revert ERC1155_ADDRESS_ZERO_IS_NOT_A_VALID_OWNER(); } return _balances[id][account]; } /** * @dev See {IERC1155-balanceOfBatch}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch( address[] memory accounts, uint256[] memory ids ) public view virtual override returns (uint256[] memory batchBalances) { uint256 numAccounts = accounts.length; if (numAccounts != ids.length) { revert ERC1155_ACCOUNTS_AND_IDS_LENGTH_MISMATCH(); } batchBalances = new uint256[](numAccounts); unchecked { for (uint256 i; i < numAccounts; ++i) { batchBalances[i] = balanceOf(accounts[i], ids[i]); } } } /** * @dev See {IERC1155-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC1155-isApprovedForAll}. */ function isApprovedForAll(address account, address operator) public view virtual override returns (bool) { return _operatorApprovals[account][operator]; } /** * @dev See {IERC1155-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data ) public virtual override { if (from != _msgSender() && !isApprovedForAll(from, _msgSender())) { revert ERC1155_CALLER_IS_NOT_TOKEN_OWNER_OR_APPROVED(); } _safeTransferFrom(from, to, id, amount, data); } /** * @dev See {IERC1155-safeBatchTransferFrom}. */ function safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) public virtual override { if (from != _msgSender() && !isApprovedForAll(from, _msgSender())) { revert ERC1155_CALLER_IS_NOT_TOKEN_OWNER_OR_APPROVED(); } _safeBatchTransferFrom(from, to, ids, amounts, data); } /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function _safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data ) internal virtual { if (to == address(0)) { revert ERC1155_TRANSFER_TO_ZERO_ADDRESS(); } address operator = _msgSender(); _beforeTokenTransfer(operator, from, to, id, amount, data); uint256 fromBalance = _balances[id][from]; if (fromBalance < amount) { revert ERC1155_INSUFFICIENT_BALANCE_FOR_TRANSFER(); } unchecked { _balances[id][from] = fromBalance - amount; } _balances[id][to] += amount; emit TransferSingle(operator, from, to, id, amount); _afterTokenTransfer(operator, from, to, id, amount, data); _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function _safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { uint256 numIds = ids.length; if (numIds != amounts.length) { revert ERC1155_ACCOUNTS_AND_IDS_LENGTH_MISMATCH(); } if (to == address(0)) { revert ERC1155_TRANSFER_TO_ZERO_ADDRESS(); } address operator = _msgSender(); _beforeBatchTokenTransfer(operator, from, to, ids, amounts, data); uint256 id; uint256 amount; uint256 fromBalance; for (uint256 i; i < numIds; ) { id = ids[i]; amount = amounts[i]; fromBalance = _balances[id][from]; if (fromBalance < amount) { revert ERC1155_INSUFFICIENT_BALANCE_FOR_TRANSFER(); } _balances[id][to] += amount; unchecked { _balances[id][from] = fromBalance - amount; ++i; } } emit TransferBatch(operator, from, to, ids, amounts); _afterBatchTokenTransfer(operator, from, to, ids, amounts, data); _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data); } /** * @dev Sets a new URI for all token types, by relying on the token type ID * substitution mechanism * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. * * By this mechanism, any occurrence of the `\{id\}` substring in either the * URI or any of the amounts in the JSON file at said URI will be replaced by * clients with the token type ID. * * For example, the `https://token-cdn-domain/\{id\}.json` URI would be * interpreted by clients as * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json` * for token type ID 0x4cce0. * * See {uri}. * * Because these URIs cannot be meaningfully represented by the {URI} event, * this function emits no events. */ function _setURI(string memory newuri) internal virtual { _uri = newuri; } /** * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual { if (to == address(0)) { revert ERC1155_MINT_TO_ZERO_ADDRESS(); } address operator = _msgSender(); _beforeTokenTransfer(operator, address(0), to, id, amount, data); _balances[id][to] += amount; emit TransferSingle(operator, address(0), to, id, amount); _afterTokenTransfer(operator, address(0), to, id, amount, data); _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function _mintBatch( address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { if (to == address(0)) { revert ERC1155_MINT_TO_ZERO_ADDRESS(); } uint256 numIds = ids.length; if (numIds != amounts.length) { revert ERC1155_IDS_AND_AMOUNTS_LENGTH_MISMATCH(); } address operator = _msgSender(); _beforeBatchTokenTransfer(operator, address(0), to, ids, amounts, data); for (uint256 i; i < numIds; ) { _balances[ids[i]][to] += amounts[i]; unchecked { ++i; } } emit TransferBatch(operator, address(0), to, ids, amounts); _afterBatchTokenTransfer(operator, address(0), to, ids, amounts, data); _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data); } /** * @dev Destroys `amount` tokens of token type `id` from `from` * * Emits a {TransferSingle} event. * * Requirements: * * - `from` cannot be the zero address. * - `from` must have at least `amount` tokens of token type `id`. */ function _burn(address from, uint256 id, uint256 amount) internal virtual { if (from == address(0)) { revert ERC1155_BURN_FROM_ZERO_ADDRESS(); } address operator = _msgSender(); _beforeTokenTransfer(operator, from, address(0), id, amount, ""); uint256 fromBalance = _balances[id][from]; if (fromBalance < amount) { revert ERC1155_BURN_AMOUNT_EXCEEDS_BALANCE(); } unchecked { _balances[id][from] = fromBalance - amount; } emit TransferSingle(operator, from, address(0), id, amount); _afterTokenTransfer(operator, from, address(0), id, amount, ""); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. */ function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual { if (from == address(0)) { revert ERC1155_BURN_FROM_ZERO_ADDRESS(); } uint256 numIds = ids.length; if (numIds != amounts.length) { revert ERC1155_IDS_AND_AMOUNTS_LENGTH_MISMATCH(); } address operator = _msgSender(); _beforeBatchTokenTransfer(operator, from, address(0), ids, amounts, ""); uint256 id; uint256 amount; uint256 fromBalance; for (uint256 i; i < numIds; ) { id = ids[i]; amount = amounts[i]; fromBalance = _balances[id][from]; if (fromBalance < amount) { revert ERC1155_BURN_AMOUNT_EXCEEDS_BALANCE(); } unchecked { _balances[id][from] = fromBalance - amount; ++i; } } emit TransferBatch(operator, from, address(0), ids, amounts); _afterBatchTokenTransfer(operator, from, address(0), ids, amounts, ""); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { if (owner == operator) { revert ERC1155_SETTING_APPROVAL_FOR_SELF(); } _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Hook that is called before a single token transfer. */ function _beforeTokenTransfer( address operator, address from, address to, uint256 id, uint256 amount, bytes memory data ) internal virtual { } /** * @dev Hook that is called before a batch token transfer. */ function _beforeBatchTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual {} /** * @dev Hook that is called after a single token transfer. */ function _afterTokenTransfer( address operator, address from, address to, uint256 id, uint256 amount, bytes memory data ) internal virtual {} /** * @dev Hook that is called after a batch token transfer. */ function _afterBatchTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual {} function _doSafeTransferAcceptanceCheck( address operator, address from, address to, uint256 id, uint256 amount, bytes memory data ) private { if (to.isContract()) { try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) { if (response != IERC1155ReceiverUpgradeable.onERC1155Received.selector) { revert ERC1155_ERC1155RECEIVER_REJECTED_TOKENS(); } } catch Error(string memory reason) { revert(reason); } catch { revert ERC1155_TRANSFER_TO_NON_ERC1155RECEIVER_IMPLEMENTER(); } } } function _doSafeBatchTransferAcceptanceCheck( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) private { if (to.isContract()) { try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns ( bytes4 response ) { if (response != IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector) { revert ERC1155_ERC1155RECEIVER_REJECTED_TOKENS(); } } catch Error(string memory reason) { revert(reason); } catch { revert ERC1155_TRANSFER_TO_NON_ERC1155RECEIVER_IMPLEMENTER(); } } } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[47] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; error FUNCTION_MUST_BE_CALLED_THROUGH_DELEGATECALL(); error FUNCTION_MUST_BE_CALLED_THROUGH_ACTIVE_PROXY(); error UUPS_UPGRADEABLE_MUST_NOT_BE_CALLED_THROUGH_DELEGATECALL(); /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { if (address(this) == __self) { revert FUNCTION_MUST_BE_CALLED_THROUGH_DELEGATECALL(); } if (_getImplementation() != __self) { revert FUNCTION_MUST_BE_CALLED_THROUGH_ACTIVE_PROXY(); } _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { if (address(this) != __self) { revert UUPS_UPGRADEABLE_MUST_NOT_BE_CALLED_THROUGH_DELEGATECALL(); } _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate the implementation's compatibility when performing an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeTo(address newImplementation) public virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155MetadataURI.sol) pragma solidity ^0.8.0; import "../token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165Upgradeable.sol";
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /// @title IProtocolRewards /// @notice The interface for deposits & withdrawals of protocol rewards interface IProtocolRewards { event RewardsDeposit( address indexed creator, address indexed createReferral, address indexed mintReferral, address firstMinter, address zora, address from, uint256 creatorReward, uint256 createReferralReward, uint256 mintReferralReward, uint256 firstMinterReward, uint256 zoraReward ); event Deposit(address indexed from, address indexed to, uint256 amount, string comment); event Withdraw(address indexed from, address indexed to, uint256 amount); error ADDRESS_ZERO(); error ARRAY_LENGTH_MISMATCH(); error INVALID_DEPOSIT(); error INVALID_SIGNATURE(); error INVALID_WITHDRAW(); error SIGNATURE_DEADLINE_EXPIRED(); error TRANSFER_FAILED(); function deposit(address to, string calldata comment) external payable; function depositBatch(address[] calldata recipients, uint256[] calldata amounts, string calldata comment) external payable; function depositRewards( address creator, uint256 creatorReward, address createReferral, uint256 createReferralReward, address mintReferral, uint256 mintReferralReward, address firstMinter, uint256 firstMinterReward, address zora, uint256 zoraReward ) external payable; function withdraw(address to, uint256 amount) external; function withdrawWithSig(address from, address to, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {RewardSplits} from "../RewardSplits.sol"; /// @notice The base logic for handling Zora ERC-1155 protocol rewards /// @dev Used in https://github.com/ourzora/zora-1155-contracts/blob/main/src/nft/ZoraCreator1155Impl.sol abstract contract ERC1155Rewards is RewardSplits { constructor(address _protocolRewards, address _zoraRewardRecipient) payable RewardSplits(_protocolRewards, _zoraRewardRecipient) {} function _handleRewardsAndGetValueSent( uint256 msgValue, uint256 numTokens, address creator, address createReferral, address mintReferral ) internal returns (uint256) { uint256 totalReward = computeTotalReward(numTokens); if (msgValue < totalReward) { revert INVALID_ETH_AMOUNT(); } else if (msgValue == totalReward) { _depositFreeMintRewards(totalReward, numTokens, creator, createReferral, mintReferral); return 0; } else { _depositPaidMintRewards(totalReward, numTokens, creator, createReferral, mintReferral); unchecked { return msgValue - totalReward; } } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; contract ERC1155RewardsStorageV1 { mapping(uint256 => address) public createReferrals; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IERC165Upgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC165Upgradeable.sol"; import {IERC1155MetadataURIUpgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC1155MetadataURIUpgradeable.sol"; import {IZoraCreator1155TypesV1} from "../nft/IZoraCreator1155TypesV1.sol"; import {IRenderer1155} from "../interfaces/IRenderer1155.sol"; import {IMinter1155} from "../interfaces/IMinter1155.sol"; import {IOwnable} from "../interfaces/IOwnable.sol"; import {IVersionedContract} from "./IVersionedContract.sol"; import {ICreatorRoyaltiesControl} from "../interfaces/ICreatorRoyaltiesControl.sol"; /* ░░░░░░░░░░░░░░ ░░▒▒░░░░░░░░░░░░░░░░░░░░ ░░▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░ ░░▒▒▒▒░░░░░░░░░░░░░░ ░░░░░░░░ ░▓▓▒▒▒▒░░░░░░░░░░░░ ░░░░░░░ ░▓▓▓▒▒▒▒░░░░░░░░░░░░ ░░░░░░░░ ░▓▓▓▒▒▒▒░░░░░░░░░░░░░░ ░░░░░░░░░░ ░▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░▓▓▓▓▓▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░ ░▓▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░ ░░▓▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░ ░░▓▓▓▓▓▓▒▒▒▒▒▒▒▒░░░░░░░░░▒▒▒▒▒░░ ░░▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░ ░░▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░░ OURS TRULY, */ /// @notice Main interface for the ZoraCreator1155 contract /// @author @iainnash / @tbtstl interface IZoraCreator1155 is IZoraCreator1155TypesV1, IVersionedContract, IOwnable, IERC1155MetadataURIUpgradeable { function PERMISSION_BIT_ADMIN() external returns (uint256); function PERMISSION_BIT_MINTER() external returns (uint256); function PERMISSION_BIT_SALES() external returns (uint256); function PERMISSION_BIT_METADATA() external returns (uint256); /// @notice Used to label the configuration update type enum ConfigUpdate { OWNER, FUNDS_RECIPIENT, TRANSFER_HOOK } event ConfigUpdated(address indexed updater, ConfigUpdate indexed updateType, ContractConfig newConfig); event UpdatedToken(address indexed from, uint256 indexed tokenId, TokenData tokenData); event SetupNewToken(uint256 indexed tokenId, address indexed sender, string newURI, uint256 maxSupply); function setOwner(address newOwner) external; event ContractRendererUpdated(IRenderer1155 renderer); event ContractMetadataUpdated(address indexed updater, string uri, string name); event Purchased(address indexed sender, address indexed minter, uint256 indexed tokenId, uint256 quantity, uint256 value); error TokenIdMismatch(uint256 expected, uint256 actual); error UserMissingRoleForToken(address user, uint256 tokenId, uint256 role); error Config_TransferHookNotSupported(address proposedAddress); error Mint_InsolventSaleTransfer(); error Mint_ValueTransferFail(); error Mint_TokenIDMintNotAllowed(); error Mint_UnknownCommand(); error Burn_NotOwnerOrApproved(address operator, address user); error NewOwnerNeedsToBeAdmin(); error Sale_CannotCallNonSalesContract(address targetContract); error CallFailed(bytes reason); error Renderer_NotValidRendererContract(); error ETHWithdrawFailed(address recipient, uint256 amount); error FundsWithdrawInsolvent(uint256 amount, uint256 contractValue); error ProtocolRewardsWithdrawFailed(address caller, address recipient, uint256 amount); error CannotMintMoreTokens(uint256 tokenId, uint256 quantity, uint256 totalMinted, uint256 maxSupply); /// @notice Only allow minting one token id at time /// @dev Mint contract function that calls the underlying sales function for commands /// @param minter Address for the minter /// @param tokenId tokenId to mint, set to 0 for new tokenId /// @param quantity to mint /// @param minterArguments calldata for the minter contracts function mint(IMinter1155 minter, uint256 tokenId, uint256 quantity, bytes calldata minterArguments) external payable; function adminMint(address recipient, uint256 tokenId, uint256 quantity, bytes memory data) external; function adminMintBatch(address recipient, uint256[] memory tokenIds, uint256[] memory quantities, bytes memory data) external; function burnBatch(address user, uint256[] calldata tokenIds, uint256[] calldata amounts) external; /// @notice Contract call to setupNewToken /// @param tokenURI URI for the token /// @param maxSupply maxSupply for the token, set to 0 for open edition function setupNewToken(string memory tokenURI, uint256 maxSupply) external returns (uint256 tokenId); function updateTokenURI(uint256 tokenId, string memory _newURI) external; function updateContractMetadata(string memory _newURI, string memory _newName) external; // Public interface for `setTokenMetadataRenderer(uint256, address) has been deprecated. function contractURI() external view returns (string memory); function assumeLastTokenIdMatches(uint256 tokenId) external; function updateRoyaltiesForToken(uint256 tokenId, ICreatorRoyaltiesControl.RoyaltyConfiguration memory royaltyConfiguration) external; function addPermission(uint256 tokenId, address user, uint256 permissionBits) external; function removePermission(uint256 tokenId, address user, uint256 permissionBits) external; function isAdminOrRole(address user, uint256 tokenId, uint256 role) external view returns (bool); function getTokenInfo(uint256 tokenId) external view returns (TokenData memory); function callRenderer(uint256 tokenId, bytes memory data) external; function callSale(uint256 tokenId, IMinter1155 salesConfig, bytes memory data) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {ICreatorRoyaltiesControl} from "../interfaces/ICreatorRoyaltiesControl.sol"; interface IZoraCreator1155Initializer { function initialize( string memory contractName, string memory newContractURI, ICreatorRoyaltiesControl.RoyaltyConfiguration memory defaultRoyaltyConfiguration, address payable defaultAdmin, bytes[] calldata setupActions ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IVersionedContract} from "../interfaces/IVersionedContract.sol"; /// @title ContractVersionBase /// @notice Base contract for versioning contracts contract ContractVersionBase is IVersionedContract { /// @notice The version of the contract function contractVersion() external pure override returns (string memory) { return "1.4.0"; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {CreatorPermissionStorageV1} from "./CreatorPermissionStorageV1.sol"; import {ICreatorPermissionControl} from "../interfaces/ICreatorPermissionControl.sol"; /// Imagine. Mint. Enjoy. /// @author @iainnash / @tbtstl contract CreatorPermissionControl is CreatorPermissionStorageV1, ICreatorPermissionControl { /// @notice Check if the user has the given permissions /// @dev if multiple permissions are passed in this checks for all the permissions requested /// @return true or false if all of the passed in permissions apply function _hasPermissions(uint256 tokenId, address user, uint256 permissionBits) internal view returns (bool) { // Does a bitwise and and checks if any of those permissions match return permissions[tokenId][user] & permissionBits == permissionBits; } /// @notice Check if the user has any of the given permissions /// @dev if multiple permissions are passed in this checks for any one of those permissions /// @return true or false if any of the passed in permissions apply function _hasAnyPermission(uint256 tokenId, address user, uint256 permissionBits) internal view returns (bool) { // Does a bitwise and and checks if any of those permissions match return permissions[tokenId][user] & permissionBits > 0; } /// @return raw permission bits for the given user function getPermissions(uint256 tokenId, address user) external view returns (uint256) { return permissions[tokenId][user]; } /// @notice addPermission – internal function to add a set of permission bits to a user /// @param tokenId token id to add the permission to (0 indicates contract-wide add) /// @param user user to update permissions for /// @param permissionBits bits to add permissions to function _addPermission(uint256 tokenId, address user, uint256 permissionBits) internal { uint256 tokenPermissions = permissions[tokenId][user]; tokenPermissions |= permissionBits; permissions[tokenId][user] = tokenPermissions; emit UpdatedPermissions(tokenId, user, tokenPermissions); } /// @notice _clearPermission clear permissions for user /// @param tokenId token id to clear permission from (0 indicates contract-wide action) function _clearPermissions(uint256 tokenId, address user) internal { permissions[tokenId][user] = 0; emit UpdatedPermissions(tokenId, user, 0); } /// @notice _removePermission removes permissions for user /// @param tokenId token id to clear permission from (0 indicates contract-wide action) /// @param user user to manage permissions for /// @param permissionBits set of permission bits to remove function _removePermission(uint256 tokenId, address user, uint256 permissionBits) internal { uint256 tokenPermissions = permissions[tokenId][user]; tokenPermissions &= ~permissionBits; permissions[tokenId][user] = tokenPermissions; emit UpdatedPermissions(tokenId, user, tokenPermissions); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {CreatorRendererStorageV1} from "./CreatorRendererStorageV1.sol"; import {IRenderer1155} from "../interfaces/IRenderer1155.sol"; import {ITransferHookReceiver} from "../interfaces/ITransferHookReceiver.sol"; import {SharedBaseConstants} from "../shared/SharedBaseConstants.sol"; /// @title CreatorRendererControl /// @notice Contract for managing the renderer of an 1155 contract abstract contract CreatorRendererControl is CreatorRendererStorageV1, SharedBaseConstants { function _setRenderer(uint256 tokenId, IRenderer1155 renderer) internal { customRenderers[tokenId] = renderer; if (address(renderer) != address(0)) { if (!renderer.supportsInterface(type(IRenderer1155).interfaceId)) { revert RendererNotValid(address(renderer)); } } emit RendererUpdated({tokenId: tokenId, renderer: address(renderer), user: msg.sender}); } /// @notice Return the renderer for a given token /// @dev Returns address 0 for no results /// @param tokenId The token to get the renderer for function getCustomRenderer(uint256 tokenId) public view returns (IRenderer1155 customRenderer) { customRenderer = customRenderers[tokenId]; if (address(customRenderer) == address(0)) { customRenderer = customRenderers[CONTRACT_BASE_ID]; } } /// @notice Function called to render when an empty tokenURI exists on the contract function _render(uint256 tokenId) internal view returns (string memory) { return getCustomRenderer(tokenId).uri(tokenId); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {CreatorRoyaltiesStorageV1} from "./CreatorRoyaltiesStorageV1.sol"; import {ICreatorRoyaltiesControl} from "../interfaces/ICreatorRoyaltiesControl.sol"; import {SharedBaseConstants} from "../shared/SharedBaseConstants.sol"; import {IERC2981} from "@openzeppelin/contracts/interfaces/IERC2981.sol"; /// Imagine. Mint. Enjoy. /// @title CreatorRoyaltiesControl /// @author ZORA @iainnash / @tbtstl /// @notice Contract for managing the royalties of an 1155 contract abstract contract CreatorRoyaltiesControl is CreatorRoyaltiesStorageV1, SharedBaseConstants { uint256 immutable ROYALTY_BPS_TO_PERCENT = 10_000; /// @notice The royalty information for a given token. /// @param tokenId The token ID to get the royalty information for. function getRoyalties(uint256 tokenId) public view returns (RoyaltyConfiguration memory) { if (royalties[tokenId].royaltyRecipient != address(0)) { return royalties[tokenId]; } // Otherwise, return default. return royalties[CONTRACT_BASE_ID]; } /// @notice Returns the royalty information for a given token. /// @param tokenId The token ID to get the royalty information for. /// @param salePrice The sale price of the NFT asset specified by tokenId function royaltyInfo(uint256 tokenId, uint256 salePrice) public view returns (address receiver, uint256 royaltyAmount) { RoyaltyConfiguration memory config = getRoyalties(tokenId); royaltyAmount = (config.royaltyBPS * salePrice) / ROYALTY_BPS_TO_PERCENT; receiver = config.royaltyRecipient; } /// @notice Returns the supply royalty information for a given token. /// @param tokenId The token ID to get the royalty information for. /// @param mintAmount The amount of tokens being minted. /// @param totalSupply The total supply of the token, function supplyRoyaltyInfo(uint256 tokenId, uint256 totalSupply, uint256 mintAmount) public view returns (address receiver, uint256 royaltyAmount) { RoyaltyConfiguration memory config = getRoyalties(tokenId); if (config.royaltyMintSchedule == 0) { return (config.royaltyRecipient, 0); } uint256 totalRoyaltyMints = (mintAmount + (totalSupply % config.royaltyMintSchedule)) / (config.royaltyMintSchedule - 1); return (config.royaltyRecipient, totalRoyaltyMints); } function _updateRoyalties(uint256 tokenId, RoyaltyConfiguration memory configuration) internal { // Don't allow 100% supply royalties if (configuration.royaltyMintSchedule == 1) { revert InvalidMintSchedule(); } // Don't allow setting royalties to burn address if (configuration.royaltyRecipient == address(0) && (configuration.royaltyMintSchedule > 0 || configuration.royaltyBPS > 0)) { revert InvalidMintSchedule(); } royalties[tokenId] = configuration; emit UpdatedRoyalties(tokenId, msg.sender, configuration); } function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC2981).interfaceId; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /// @notice Creator Commands used by minter modules passed back to the main modules interface ICreatorCommands { /// @notice This enum is used to define supported creator action types. /// This can change in the future enum CreatorActions { // No operation - also the default for mintings that may not return a command NO_OP, // Send ether SEND_ETH, // Mint operation MINT } /// @notice This command is for struct Command { // Method for operation CreatorActions method; // Arguments used for this operation bytes args; } /// @notice This command set is returned from the minter back to the user struct CommandSet { Command[] commands; uint256 at; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IERC165Upgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC165Upgradeable.sol"; import {ICreatorCommands} from "./ICreatorCommands.sol"; /// @notice Minter standard interface /// @dev Minters need to confirm to the ERC165 selector of type(IMinter1155).interfaceId interface IMinter1155 is IERC165Upgradeable { function requestMint( address sender, uint256 tokenId, uint256 quantity, uint256 ethValueSent, bytes calldata minterArguments ) external returns (ICreatorCommands.CommandSet memory commands); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IERC165Upgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC165Upgradeable.sol"; /// @dev IERC165 type required interface IRenderer1155 is IERC165Upgradeable { /// @notice Called for assigned tokenId, or when token id is globally set to a renderer /// @dev contract target is assumed to be msg.sender /// @param tokenId token id to get uri for function uri(uint256 tokenId) external view returns (string memory); /// @notice Only called for tokenId == 0 /// @dev contract target is assumed to be msg.sender function contractURI() external view returns (string memory); /// @notice Sets up renderer from contract /// @param initData data to setup renderer with /// @dev contract target is assumed to be msg.sender function setup(bytes memory initData) external; // IERC165 type required – set in base helper }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IERC165Upgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/interfaces/IERC165Upgradeable.sol"; interface ITransferHookReceiver is IERC165Upgradeable { /// @notice Token transfer batch callback /// @param target target contract for transfer /// @param operator operator address for transfer /// @param from user address for amount transferred /// @param to user address for amount transferred /// @param ids list of token ids transferred /// @param amounts list of values transferred /// @param data data as perscribed by 1155 standard function onTokenTransferBatch( address target, address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) external; // IERC165 type required }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /// @notice Factory Upgrade Gate Admin Factory Implementation – Allows specific contract upgrades as a safety measure interface IFactoryManagedUpgradeGate { /// @notice If an implementation is registered by the Builder DAO as an optional upgrade /// @param baseImpl The base implementation address /// @param upgradeImpl The upgrade implementation address function isRegisteredUpgradePath(address baseImpl, address upgradeImpl) external view returns (bool); /// @notice Called by the Builder DAO to offer implementation upgrades for created DAOs /// @param baseImpls The base implementation addresses /// @param upgradeImpl The upgrade implementation address function registerUpgradePath(address[] memory baseImpls, address upgradeImpl) external; /// @notice Called by the Builder DAO to remove an upgrade /// @param baseImpl The base implementation address /// @param upgradeImpl The upgrade implementation address function removeUpgradePath(address baseImpl, address upgradeImpl) external; event UpgradeRegistered(address indexed baseImpl, address indexed upgradeImpl); event UpgradeRemoved(address indexed baseImpl, address indexed upgradeImpl); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {ILegacyNaming} from "../interfaces/ILegacyNaming.sol"; import {LegacyNamingStorageV1} from "./LegacyNamingStorageV1.sol"; /// @title LegacyNamingControl /// @notice Contract for managing the name and symbol of an 1155 contract in the legacy naming scheme contract LegacyNamingControl is LegacyNamingStorageV1, ILegacyNaming { /// @notice The name of the contract function name() external view returns (string memory) { return _name; } /// @notice The token symbol of the contract function symbol() external pure returns (string memory) {} function _setName(string memory _newName) internal { _name = _newName; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {TransferHelperUtils} from "../utils/TransferHelperUtils.sol"; import {IMintFeeManager} from "../interfaces/IMintFeeManager.sol"; /// @title MintFeeManager /// @notice Manages mint fees for an 1155 contract contract MintFeeManager is IMintFeeManager { uint256 public immutable mintFee; address public immutable mintFeeRecipient; constructor(uint256 _mintFee, address _mintFeeRecipient) { // Set fixed finders fee if (_mintFee >= 0.1 ether) { revert MintFeeCannotBeMoreThanZeroPointOneETH(_mintFee); } if (_mintFeeRecipient == address(0) && _mintFee > 0) { revert CannotSetMintFeeToZeroAddress(); } mintFeeRecipient = _mintFeeRecipient; mintFee = _mintFee; } /// @notice Sends the mint fee to the mint fee recipient and returns the amount of ETH remaining that can be used in this transaction /// @param _quantity The amount of toknens being minted function _handleFeeAndGetValueSent(uint256 _quantity) internal returns (uint256 ethValueSent) { ethValueSent = msg.value; // Handle mint fee if (mintFeeRecipient != address(0)) { uint256 totalFee = mintFee * _quantity; ethValueSent -= totalFee; if (!TransferHelperUtils.safeSendETH(mintFeeRecipient, totalFee, TransferHelperUtils.FUNDS_SEND_LOW_GAS_LIMIT)) { revert CannotSendMintFee(mintFeeRecipient, totalFee); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import "@openzeppelin/contracts/utils/Address.sol"; /// @title PublicMulticall /// @notice Contract for executing a batch of function calls on this contract abstract contract PublicMulticall { /** * @notice Receives and executes a batch of function calls on this contract. */ function multicall(bytes[] calldata data) public virtual returns (bytes[] memory results) { results = new bytes[](data.length); for (uint256 i = 0; i < data.length; i++) { results[i] = Address.functionDelegateCall(address(this), data[i]); } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; contract SharedBaseConstants { uint256 public constant CONTRACT_BASE_ID = 0; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /// @title TransferHelperUtils /// @notice Helper functions for sending ETH library TransferHelperUtils { /// @dev Gas limit to send funds uint256 internal constant FUNDS_SEND_LOW_GAS_LIMIT = 110_000; // @dev Gas limit to send funds – usable for splits, can use with withdraws uint256 internal constant FUNDS_SEND_NORMAL_GAS_LIMIT = 310_000; /// @notice Sends ETH to a recipient, making conservative estimates to not run out of gas /// @param recipient The address to send ETH to /// @param value The amount of ETH to send function safeSendETH(address recipient, uint256 value, uint256 gasLimit) internal returns (bool success) { (success, ) = recipient.call{value: value, gas: gasLimit}(""); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IZoraCreator1155TypesV1} from "./IZoraCreator1155TypesV1.sol"; /* ░░░░░░░░░░░░░░ ░░▒▒░░░░░░░░░░░░░░░░░░░░ ░░▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░ ░░▒▒▒▒░░░░░░░░░░░░░░ ░░░░░░░░ ░▓▓▒▒▒▒░░░░░░░░░░░░ ░░░░░░░ ░▓▓▓▒▒▒▒░░░░░░░░░░░░ ░░░░░░░░ ░▓▓▓▒▒▒▒░░░░░░░░░░░░░░ ░░░░░░░░░░ ░▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░▓▓▓▓▓▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░ ░▓▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░ ░░▓▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░ ░░▓▓▓▓▓▓▒▒▒▒▒▒▒▒░░░░░░░░░▒▒▒▒▒░░ ░░▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░ ░░▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░░ OURS TRULY, github.com/ourzora/zora-1155-contracts */ /// Imagine. Mint. Enjoy. /// @notice Storage for 1155 contract /// @author @iainnash / @tbtstl contract ZoraCreator1155StorageV1 is IZoraCreator1155TypesV1 { /// @notice token data stored for each token mapping(uint256 => TokenData) internal tokens; /// @notice metadata renderer contract for each token mapping(uint256 => address) public metadataRendererContract; /// @notice next token id available when using a linear mint style (default for launch) uint256 public nextTokenId; /// @notice Global contract configuration ContractConfig public config; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch( address[] calldata accounts, uint256[] calldata ids ) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155ReceiverUpgradeable is IERC165Upgradeable { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol) pragma solidity ^0.8.0; import "../IERC1155Upgradeable.sol"; /** * @dev Interface of the optional ERC1155MetadataExtension interface, as defined * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. * * _Available since v3.1._ */ interface IERC1155MetadataURIUpgradeable is IERC1155Upgradeable { /** * @dev Returns the URI for token type `id`. * * If the `\{id\}` substring is present in the URI, it must be replaced by * clients with the actual token type ID. */ function uri(uint256 id) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; error ADDRESS_INSUFFICIENT_BALANCE(); error ADDRESS_UNABLE_TO_SEND_VALUE(); error ADDRESS_LOW_LEVEL_CALL_FAILED(); error ADDRESS_LOW_LEVEL_CALL_WITH_VALUE_FAILED(); error ADDRESS_INSUFFICIENT_BALANCE_FOR_CALL(); error ADDRESS_LOW_LEVEL_STATIC_CALL_FAILED(); error ADDRESS_CALL_TO_NON_CONTRACT(); /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance > amount) { revert ADDRESS_INSUFFICIENT_BALANCE(); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert ADDRESS_UNABLE_TO_SEND_VALUE(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { if (address(this).balance < value) { revert ADDRESS_INSUFFICIENT_BALANCE(); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @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 ) 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 if (!isContract(target)) { revert ADDRESS_CALL_TO_NON_CONTRACT(); } } return returndata; } else { _revert(returndata); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata); } } function _revert(bytes memory returndata) 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 ADDRESS_LOW_LEVEL_CALL_FAILED(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; error INITIALIZABLE_CONTRACT_ALREADY_INITIALIZED(); error INITIALIZABLE_CONTRACT_IS_NOT_INITIALIZING(); error INITIALIZABLE_CONTRACT_IS_INITIALIZING(); /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; if ((!isTopLevelCall || _initialized != 0) && (AddressUpgradeable.isContract(address(this)) || _initialized != 1)) { revert INITIALIZABLE_CONTRACT_ALREADY_INITIALIZED(); } _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { if (_initializing || _initialized >= version) { revert INITIALIZABLE_CONTRACT_ALREADY_INITIALIZED(); } _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { if (!_initializing) { revert INITIALIZABLE_CONTRACT_IS_NOT_INITIALIZING(); } _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { if (_initializing) { revert INITIALIZABLE_CONTRACT_IS_INITIALIZING(); } if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.sol"; error ERC1967_NEW_IMPL_NOT_CONTRACT(); error ERC1967_UNSUPPORTED_PROXIABLEUUID(); error ERC1967_NEW_IMPL_NOT_UUPS(); error ERC1967_NEW_ADMIN_IS_ZERO_ADDRESS(); error ERC1967_NEW_BEACON_IS_NOT_CONTRACT(); error ERC1967_BEACON_IMPL_IS_NOT_CONTRACT(); error ADDRESS_DELEGATECALL_TO_NON_CONTRACT(); /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ */ abstract contract ERC1967UpgradeUpgradeable is Initializable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { if (!AddressUpgradeable.isContract(newImplementation)) { revert ERC1967_NEW_IMPL_NOT_CONTRACT(); } StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { if (slot != _IMPLEMENTATION_SLOT) { revert ERC1967_UNSUPPORTED_PROXIABLEUUID(); } } catch { revert ERC1967_NEW_IMPL_NOT_UUPS(); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { if (newAdmin == address(0)) { revert ERC1967_NEW_ADMIN_IS_ZERO_ADDRESS(); } StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { if (!AddressUpgradeable.isContract(newBeacon)) { revert ERC1967_NEW_BEACON_IS_NOT_CONTRACT(); } if (!AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation())) { revert ERC1967_BEACON_IMPL_IS_NOT_CONTRACT(); } StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @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) private returns (bytes memory) { if (!AddressUpgradeable.isContract(target)) { revert ADDRESS_DELEGATECALL_TO_NON_CONTRACT(); } // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IProtocolRewards} from "../interfaces/IProtocolRewards.sol"; struct RewardsSettings { uint256 creatorReward; uint256 createReferralReward; uint256 mintReferralReward; uint256 firstMinterReward; uint256 zoraReward; } /// @notice Common logic for between Zora ERC-721 & ERC-1155 contracts for protocol reward splits & deposits abstract contract RewardSplits { error CREATOR_FUNDS_RECIPIENT_NOT_SET(); error INVALID_ADDRESS_ZERO(); error INVALID_ETH_AMOUNT(); error ONLY_CREATE_REFERRAL(); uint256 internal constant TOTAL_REWARD_PER_MINT = 0.000777 ether; uint256 internal constant CREATOR_REWARD = 0.000333 ether; uint256 internal constant FIRST_MINTER_REWARD = 0.000111 ether; uint256 internal constant CREATE_REFERRAL_FREE_MINT_REWARD = 0.000111 ether; uint256 internal constant MINT_REFERRAL_FREE_MINT_REWARD = 0.000111 ether; uint256 internal constant ZORA_FREE_MINT_REWARD = 0.000111 ether; uint256 internal constant MINT_REFERRAL_PAID_MINT_REWARD = 0.000222 ether; uint256 internal constant CREATE_REFERRAL_PAID_MINT_REWARD = 0.000222 ether; uint256 internal constant ZORA_PAID_MINT_REWARD = 0.000222 ether; address internal immutable zoraRewardRecipient; IProtocolRewards internal immutable protocolRewards; constructor(address _protocolRewards, address _zoraRewardRecipient) payable { if (_protocolRewards == address(0) || _zoraRewardRecipient == address(0)) { revert INVALID_ADDRESS_ZERO(); } protocolRewards = IProtocolRewards(_protocolRewards); zoraRewardRecipient = _zoraRewardRecipient; } function computeTotalReward(uint256 numTokens) public pure returns (uint256) { return numTokens * TOTAL_REWARD_PER_MINT; } function computeFreeMintRewards(uint256 numTokens) public pure returns (RewardsSettings memory) { return RewardsSettings({ creatorReward: numTokens * CREATOR_REWARD, createReferralReward: numTokens * CREATE_REFERRAL_FREE_MINT_REWARD, mintReferralReward: numTokens * MINT_REFERRAL_FREE_MINT_REWARD, firstMinterReward: numTokens * FIRST_MINTER_REWARD, zoraReward: numTokens * ZORA_FREE_MINT_REWARD }); } function computePaidMintRewards(uint256 numTokens) public pure returns (RewardsSettings memory) { return RewardsSettings({ creatorReward: 0, createReferralReward: numTokens * CREATE_REFERRAL_PAID_MINT_REWARD, mintReferralReward: numTokens * MINT_REFERRAL_PAID_MINT_REWARD, firstMinterReward: numTokens * FIRST_MINTER_REWARD, zoraReward: numTokens * ZORA_PAID_MINT_REWARD }); } function _depositFreeMintRewards(uint256 totalReward, uint256 numTokens, address creator, address createReferral, address mintReferral) internal { RewardsSettings memory settings = computeFreeMintRewards(numTokens); if (createReferral == address(0)) { createReferral = zoraRewardRecipient; } if (mintReferral == address(0)) { mintReferral = zoraRewardRecipient; } protocolRewards.depositRewards{value: totalReward}( creator, settings.creatorReward, createReferral, settings.createReferralReward, mintReferral, settings.mintReferralReward, creator, settings.firstMinterReward, zoraRewardRecipient, settings.zoraReward ); } function _depositPaidMintRewards(uint256 totalReward, uint256 numTokens, address creator, address createReferral, address mintReferral) internal { RewardsSettings memory settings = computePaidMintRewards(numTokens); if (createReferral == address(0)) { createReferral = zoraRewardRecipient; } if (mintReferral == address(0)) { mintReferral = zoraRewardRecipient; } protocolRewards.depositRewards{value: totalReward}( address(0), 0, createReferral, settings.createReferralReward, mintReferral, settings.mintReferralReward, creator, settings.firstMinterReward, zoraRewardRecipient, settings.zoraReward ); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {ITransferHookReceiver} from "../interfaces/ITransferHookReceiver.sol"; /* ░░░░░░░░░░░░░░ ░░▒▒░░░░░░░░░░░░░░░░░░░░ ░░▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░ ░░▒▒▒▒░░░░░░░░░░░░░░ ░░░░░░░░ ░▓▓▒▒▒▒░░░░░░░░░░░░ ░░░░░░░ ░▓▓▓▒▒▒▒░░░░░░░░░░░░ ░░░░░░░░ ░▓▓▓▒▒▒▒░░░░░░░░░░░░░░ ░░░░░░░░░░ ░▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░▓▓▓▓▓▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░ ░▓▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░ ░░▓▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░ ░░▓▓▓▓▓▓▒▒▒▒▒▒▒▒░░░░░░░░░▒▒▒▒▒░░ ░░▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░ ░░▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░░ OURS TRULY, */ /// Imagine. Mint. Enjoy. /// @notice Interface for types used across the ZoraCreator1155 contract /// @author @iainnash / @tbtstl interface IZoraCreator1155TypesV1 { /// @notice Used to store individual token data struct TokenData { string uri; uint256 maxSupply; uint256 totalMinted; } /// @notice Used to store contract-level configuration struct ContractConfig { address owner; uint96 __gap1; address payable fundsRecipient; uint96 __gap2; ITransferHookReceiver transferHook; uint96 __gap3; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface IOwnable { function owner() external returns (address); event OwnershipTransferred(address lastOwner, address newOwner); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface IVersionedContract { function contractVersion() external returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IERC2981} from "@openzeppelin/contracts/interfaces/IERC2981.sol"; interface ICreatorRoyaltiesControl is IERC2981 { /// @notice The RoyaltyConfiguration struct is used to store the royalty configuration for a given token. /// @param royaltyMintSchedule Every nth token will go to the royalty recipient. /// @param royaltyBPS The royalty amount in basis points for secondary sales. /// @param royaltyRecipient The address that will receive the royalty payments. struct RoyaltyConfiguration { uint32 royaltyMintSchedule; uint32 royaltyBPS; address royaltyRecipient; } /// @notice Thrown when a user tries to have 100% supply royalties error InvalidMintSchedule(); /// @notice Event emitted when royalties are updated event UpdatedRoyalties(uint256 indexed tokenId, address indexed user, RoyaltyConfiguration configuration); /// @notice External data getter to get royalties for a token /// @param tokenId tokenId to get royalties configuration for function getRoyalties(uint256 tokenId) external view returns (RoyaltyConfiguration memory); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /// Imagine. Mint. Enjoy. /// @author @iainnash / @tbtstl contract CreatorPermissionStorageV1 { mapping(uint256 => mapping(address => uint256)) public permissions; uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /// @notice Generic control interface for bit-based permissions-control interface ICreatorPermissionControl { /// @notice Emitted when permissions are updated event UpdatedPermissions(uint256 indexed tokenId, address indexed user, uint256 indexed permissions); /// @notice Public interface to get permissions given a token id and a user address /// @return Returns raw permission bits function getPermissions(uint256 tokenId, address user) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {ICreatorRendererControl} from "../interfaces/ICreatorRendererControl.sol"; import {IRenderer1155} from "../interfaces/IRenderer1155.sol"; /// @notice Creator Renderer Storage Configuration Contract V1 abstract contract CreatorRendererStorageV1 is ICreatorRendererControl { /// @notice Mapping for custom renderers mapping(uint256 => IRenderer1155) public customRenderers; uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {ICreatorRoyaltiesControl} from "../interfaces/ICreatorRoyaltiesControl.sol"; /// Imagine. Mint. Enjoy. /// @title CreatorRoyaltiesControl /// @author ZORA @iainnash / @tbtstl /// @notice Royalty storage contract pattern abstract contract CreatorRoyaltiesStorageV1 is ICreatorRoyaltiesControl { mapping(uint256 => RoyaltyConfiguration) public royalties; uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165.sol"; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. * * _Available since v4.5._ */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo( uint256 tokenId, uint256 salePrice ) external view returns (address receiver, uint256 royaltyAmount); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface ILegacyNaming { function name() external returns (string memory); function symbol() external returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; contract LegacyNamingStorageV1 { string internal _name; uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface IMintFeeManager { error MintFeeCannotBeMoreThanZeroPointOneETH(uint256 mintFeeBPS); error CannotSendMintFee(address mintFeeRecipient, uint256 mintFee); error CannotSetMintFeeToZeroAddress(); function mintFee() external view returns (uint256); function mintFeeRecipient() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; import {IRenderer1155} from "./IRenderer1155.sol"; /// @notice Interface for creator renderer controls interface ICreatorRendererControl { /// @notice Get the custom renderer contract (if any) for the given token id /// @dev Reverts if not custom renderer is set for this token function getCustomRenderer(uint256 tokenId) external view returns (IRenderer1155 renderer); error NoRendererForToken(uint256 tokenId); error RendererNotValid(address renderer); event RendererUpdated(uint256 indexed tokenId, address indexed renderer, address indexed user); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
{ "remappings": [ "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/", "@zoralabs/openzeppelin-contracts-upgradeable/=node_modules/@zoralabs/openzeppelin-contracts-upgradeable/", "@zoralabs/protocol-rewards/=node_modules/@zoralabs/protocol-rewards/", "_imagine/=_imagine/", "ds-test/=node_modules/ds-test/src/", "forge-std/=node_modules/forge-std/src/", "mint/=_imagine/mint/" ], "optimizer": { "enabled": true, "runs": 3000 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "viaIR": true, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"uint256","name":"_mintFeeAmount","type":"uint256"},{"internalType":"address","name":"_mintFeeRecipient","type":"address"},{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_protocolRewards","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ADDRESS_DELEGATECALL_TO_NON_CONTRACT","type":"error"},{"inputs":[],"name":"ADDRESS_LOW_LEVEL_CALL_FAILED","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"Burn_NotOwnerOrApproved","type":"error"},{"inputs":[],"name":"CREATOR_FUNDS_RECIPIENT_NOT_SET","type":"error"},{"inputs":[{"internalType":"bytes","name":"reason","type":"bytes"}],"name":"CallFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"uint256","name":"totalMinted","type":"uint256"},{"internalType":"uint256","name":"maxSupply","type":"uint256"}],"name":"CannotMintMoreTokens","type":"error"},{"inputs":[{"internalType":"address","name":"mintFeeRecipient","type":"address"},{"internalType":"uint256","name":"mintFee","type":"uint256"}],"name":"CannotSendMintFee","type":"error"},{"inputs":[],"name":"CannotSetMintFeeToZeroAddress","type":"error"},{"inputs":[{"internalType":"address","name":"proposedAddress","type":"address"}],"name":"Config_TransferHookNotSupported","type":"error"},{"inputs":[],"name":"ERC1155_ACCOUNTS_AND_IDS_LENGTH_MISMATCH","type":"error"},{"inputs":[],"name":"ERC1155_ADDRESS_ZERO_IS_NOT_A_VALID_OWNER","type":"error"},{"inputs":[],"name":"ERC1155_BURN_AMOUNT_EXCEEDS_BALANCE","type":"error"},{"inputs":[],"name":"ERC1155_BURN_FROM_ZERO_ADDRESS","type":"error"},{"inputs":[],"name":"ERC1155_CALLER_IS_NOT_TOKEN_OWNER_OR_APPROVED","type":"error"},{"inputs":[],"name":"ERC1155_ERC1155RECEIVER_REJECTED_TOKENS","type":"error"},{"inputs":[],"name":"ERC1155_IDS_AND_AMOUNTS_LENGTH_MISMATCH","type":"error"},{"inputs":[],"name":"ERC1155_INSUFFICIENT_BALANCE_FOR_TRANSFER","type":"error"},{"inputs":[],"name":"ERC1155_MINT_TO_ZERO_ADDRESS","type":"error"},{"inputs":[],"name":"ERC1155_SETTING_APPROVAL_FOR_SELF","type":"error"},{"inputs":[],"name":"ERC1155_TRANSFER_TO_NON_ERC1155RECEIVER_IMPLEMENTER","type":"error"},{"inputs":[],"name":"ERC1155_TRANSFER_TO_ZERO_ADDRESS","type":"error"},{"inputs":[],"name":"ERC1967_NEW_IMPL_NOT_CONTRACT","type":"error"},{"inputs":[],"name":"ERC1967_NEW_IMPL_NOT_UUPS","type":"error"},{"inputs":[],"name":"ERC1967_UNSUPPORTED_PROXIABLEUUID","type":"error"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ETHWithdrawFailed","type":"error"},{"inputs":[],"name":"FUNCTION_MUST_BE_CALLED_THROUGH_ACTIVE_PROXY","type":"error"},{"inputs":[],"name":"FUNCTION_MUST_BE_CALLED_THROUGH_DELEGATECALL","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"contractValue","type":"uint256"}],"name":"FundsWithdrawInsolvent","type":"error"},{"inputs":[],"name":"INITIALIZABLE_CONTRACT_ALREADY_INITIALIZED","type":"error"},{"inputs":[],"name":"INITIALIZABLE_CONTRACT_IS_NOT_INITIALIZING","type":"error"},{"inputs":[],"name":"INVALID_ADDRESS_ZERO","type":"error"},{"inputs":[],"name":"INVALID_ETH_AMOUNT","type":"error"},{"inputs":[],"name":"InvalidMintSchedule","type":"error"},{"inputs":[{"internalType":"uint256","name":"mintFeeBPS","type":"uint256"}],"name":"MintFeeCannotBeMoreThanZeroPointOneETH","type":"error"},{"inputs":[],"name":"Mint_InsolventSaleTransfer","type":"error"},{"inputs":[],"name":"Mint_TokenIDMintNotAllowed","type":"error"},{"inputs":[],"name":"Mint_UnknownCommand","type":"error"},{"inputs":[],"name":"Mint_ValueTransferFail","type":"error"},{"inputs":[],"name":"NewOwnerNeedsToBeAdmin","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"NoRendererForToken","type":"error"},{"inputs":[],"name":"ONLY_CREATE_REFERRAL","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ProtocolRewardsWithdrawFailed","type":"error"},{"inputs":[{"internalType":"address","name":"renderer","type":"address"}],"name":"RendererNotValid","type":"error"},{"inputs":[],"name":"Renderer_NotValidRendererContract","type":"error"},{"inputs":[{"internalType":"address","name":"targetContract","type":"address"}],"name":"Sale_CannotCallNonSalesContract","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"actual","type":"uint256"}],"name":"TokenIdMismatch","type":"error"},{"inputs":[],"name":"UUPS_UPGRADEABLE_MUST_NOT_BE_CALLED_THROUGH_DELEGATECALL","type":"error"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"role","type":"uint256"}],"name":"UserMissingRoleForToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updater","type":"address"},{"indexed":true,"internalType":"enum IZoraCreator1155.ConfigUpdate","name":"updateType","type":"uint8"},{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint96","name":"__gap1","type":"uint96"},{"internalType":"address payable","name":"fundsRecipient","type":"address"},{"internalType":"uint96","name":"__gap2","type":"uint96"},{"internalType":"contract ITransferHookReceiver","name":"transferHook","type":"address"},{"internalType":"uint96","name":"__gap3","type":"uint96"}],"indexed":false,"internalType":"struct IZoraCreator1155TypesV1.ContractConfig","name":"newConfig","type":"tuple"}],"name":"ConfigUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"string","name":"uri","type":"string"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"ContractMetadataUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IRenderer1155","name":"renderer","type":"address"}],"name":"ContractRendererUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"lastOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Purchased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"renderer","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"RendererUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"string","name":"newURI","type":"string"},{"indexed":false,"internalType":"uint256","name":"maxSupply","type":"uint256"}],"name":"SetupNewToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"permissions","type":"uint256"}],"name":"UpdatedPermissions","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"components":[{"internalType":"uint32","name":"royaltyMintSchedule","type":"uint32"},{"internalType":"uint32","name":"royaltyBPS","type":"uint32"},{"internalType":"address","name":"royaltyRecipient","type":"address"}],"indexed":false,"internalType":"struct ICreatorRoyaltiesControl.RoyaltyConfiguration","name":"configuration","type":"tuple"}],"name":"UpdatedRoyalties","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"string","name":"uri","type":"string"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"uint256","name":"totalMinted","type":"uint256"}],"indexed":false,"internalType":"struct IZoraCreator1155TypesV1.TokenData","name":"tokenData","type":"tuple"}],"name":"UpdatedToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"CONTRACT_BASE_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMISSION_BIT_ADMIN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMISSION_BIT_FUNDS_MANAGER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMISSION_BIT_METADATA","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMISSION_BIT_MINTER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMISSION_BIT_SALES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"permissionBits","type":"uint256"}],"name":"addPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"adminMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"quantities","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"adminMintBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"lastTokenId","type":"uint256"}],"name":"assumeLastTokenIdMatches","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"batchBalances","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"burnBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"callRenderer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"contract IMinter1155","name":"salesConfig","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"callSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numTokens","type":"uint256"}],"name":"computeFreeMintRewards","outputs":[{"components":[{"internalType":"uint256","name":"creatorReward","type":"uint256"},{"internalType":"uint256","name":"createReferralReward","type":"uint256"},{"internalType":"uint256","name":"mintReferralReward","type":"uint256"},{"internalType":"uint256","name":"firstMinterReward","type":"uint256"},{"internalType":"uint256","name":"zoraReward","type":"uint256"}],"internalType":"struct RewardsSettings","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"numTokens","type":"uint256"}],"name":"computePaidMintRewards","outputs":[{"components":[{"internalType":"uint256","name":"creatorReward","type":"uint256"},{"internalType":"uint256","name":"createReferralReward","type":"uint256"},{"internalType":"uint256","name":"mintReferralReward","type":"uint256"},{"internalType":"uint256","name":"firstMinterReward","type":"uint256"},{"internalType":"uint256","name":"zoraReward","type":"uint256"}],"internalType":"struct RewardsSettings","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"numTokens","type":"uint256"}],"name":"computeTotalReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"config","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint96","name":"__gap1","type":"uint96"},{"internalType":"address payable","name":"fundsRecipient","type":"address"},{"internalType":"uint96","name":"__gap2","type":"uint96"},{"internalType":"contract ITransferHookReceiver","name":"transferHook","type":"address"},{"internalType":"uint96","name":"__gap3","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"createReferrals","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"customRenderers","outputs":[{"internalType":"contract IRenderer1155","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCreatorRewardRecipient","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getCustomRenderer","outputs":[{"internalType":"contract IRenderer1155","name":"customRenderer","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"getPermissions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getRoyalties","outputs":[{"components":[{"internalType":"uint32","name":"royaltyMintSchedule","type":"uint32"},{"internalType":"uint32","name":"royaltyBPS","type":"uint32"},{"internalType":"address","name":"royaltyRecipient","type":"address"}],"internalType":"struct ICreatorRoyaltiesControl.RoyaltyConfiguration","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTokenInfo","outputs":[{"components":[{"internalType":"string","name":"uri","type":"string"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"uint256","name":"totalMinted","type":"uint256"}],"internalType":"struct IZoraCreator1155TypesV1.TokenData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"contractName","type":"string"},{"internalType":"string","name":"newContractURI","type":"string"},{"components":[{"internalType":"uint32","name":"royaltyMintSchedule","type":"uint32"},{"internalType":"uint32","name":"royaltyBPS","type":"uint32"},{"internalType":"address","name":"royaltyRecipient","type":"address"}],"internalType":"struct ICreatorRoyaltiesControl.RoyaltyConfiguration","name":"defaultRoyaltyConfiguration","type":"tuple"},{"internalType":"address payable","name":"defaultAdmin","type":"address"},{"internalType":"bytes[]","name":"setupActions","type":"bytes[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"role","type":"uint256"}],"name":"isAdminOrRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"metadataRendererContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IMinter1155","name":"minter","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"bytes","name":"minterArguments","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintFeeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IMinter1155","name":"minter","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"bytes","name":"minterArguments","type":"bytes"},{"internalType":"address","name":"mintReferral","type":"address"}],"name":"mintWithRewards","outputs":[],"stateMutability":"payable","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":[],"name":"nextTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"permissions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"permissionBits","type":"uint256"}],"name":"removePermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"royalties","outputs":[{"internalType":"uint32","name":"royaltyMintSchedule","type":"uint32"},{"internalType":"uint32","name":"royaltyBPS","type":"uint32"},{"internalType":"address","name":"royaltyRecipient","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"fundsRecipient","type":"address"}],"name":"setFundsRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"contract IRenderer1155","name":"renderer","type":"address"}],"name":"setTokenMetadataRenderer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ITransferHookReceiver","name":"transferHook","type":"address"}],"name":"setTransferHook","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newURI","type":"string"},{"internalType":"uint256","name":"maxSupply","type":"uint256"}],"name":"setupNewToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newURI","type":"string"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"address","name":"createReferral","type":"address"}],"name":"setupNewTokenWithCreateReferral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"mintAmount","type":"uint256"}],"name":"supplyRoyaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"_newURI","type":"string"},{"internalType":"string","name":"_newName","type":"string"}],"name":"updateContractMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"updateCreateReferral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint32","name":"royaltyMintSchedule","type":"uint32"},{"internalType":"uint32","name":"royaltyBPS","type":"uint32"},{"internalType":"address","name":"royaltyRecipient","type":"address"}],"internalType":"struct ICreatorRoyaltiesControl.RoyaltyConfiguration","name":"newConfiguration","type":"tuple"}],"name":"updateRoyaltiesForToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"_newURI","type":"string"}],"name":"updateTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawRewards","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
610160346200028657601f620062b038819003918201601f191683019291906001600160401b038411838510176200028b57816080928492604096875283398101031262000286578051906200005860208201620002a1565b926200007460606200006c838501620002a1565b9301620002a1565b67016345785d8a00008410156200026e576001600160a01b038581161594909190858062000264575b620002535760a08790526080523060c05261271060e05281169384159081156200024a575b5062000239576101209384526101009485526000549060ff8260081c161591828015906200022c575b8062000212575b620002015760ff19811660011760005582620001ee575b5061014093168352620001b3575b5191615ff99384620002b785396080518481816123aa0152613be0015260a0518481816122960152612339015260c051848181612b9401528181612c4e015261326e015260e0518461384e01525183818161508a015281816150e8015281816151100152818161520d01528181615272015261529a015251828181610c5401528181614fdf0152615169015251818181612cf5015261331f0152f35b61ff0019600054166000557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986020825160018152a162000117565b61ffff1916610101176000553862000109565b8351633d5c224160e11b8152600490fd5b50303b151580620000f25750600160ff82161415620000f2565b5060ff81161515620000eb565b8151632d87658960e01b8152600490fd5b905038620000c2565b835163c64a448960e01b8152600490fd5b508015156200009d565b8151637f19df9f60e11b815260048101859052602490fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b0382168203620002865756fe6080604052600436101561001257600080fd5b60003560e01c8062fdd58e14613e595780630114420114613e3d57806301ffc9a714613d2057806306fdde0314613c4c5780630e89341c14613c2d57806310a7eb5d14613c0357806313966db514613bc857806313af403514613b3357806317bd48bb14613a9c57806318711c7d14613a8057806318e97fd1146138ef57806323bd03861461389c5780632a55205a1461380d5780632eb2c2d6146134a2578063300ecdb91461309b5780633659cfe6146132485780633ccfd60b146131325780634132239b146130e55780634913162d1461309b5780634e1273f414612f355780634f1ef28614612c0e57806352d1902d14612b795780635c04608414612b5a5780635d0f6cba146129d157806364ea3835146129b65780636661a9ba14612815578063674cbae61461278557806369a5b3021461274f5780636b20c45414612494578063722933f71461243a578063731133e9146122d957806375794a3c146122ba578063765b0c361461227657806379502c551461221a5780637dafae4d146121e45780637f2dc61c146120965780637f77f574146120465780638621ea4b146120075780638a08eb4c14611a0b5780638c7a63ae146119945780638da5cb5b1461196c5780638ec998a0146118e7578063929a7128146118cc57806395d89b411461186e5780639c5c63c9146117c25780639dbb844d1461167a578063a0a8e46014611609578063a22cb46514611552578063a453eaf014611536578063ac9650d81461147e578063afed7e9e14611250578063bb3bafd6146111f9578063c0464356146111dd578063c238d1ee14611181578063d1ad846b14610d23578063d258609a14610cc3578063d6ef7af014610bca578063d904b94a146109e8578063dd15e05f146109b2578063e72878b414610956578063e74d86c214610927578063e8a3d485146108f3578063e985e9c51461089c578063ef71c82e14610618578063f1b0d6bb146105fc5763f242432a146102f157600080fd5b346105f75760a06003193601126105f75761030a613e88565b610312613e9e565b9060643560443560843567ffffffffffffffff81116105f757610339903690600401613ff6565b6001600160a01b038094169333851415806105d2575b6105a8578516801561057e578260005260209560978752604060002086600052875260406000205485811061055457859085600052609789526040600020886000528952036040600020558360005260978752604060002082600052875260406000206103bd8682546142ac565b90558186604051868152878a8201527fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260403392a43b6103f957005b6104569360008794604051968795869485937ff23a6e61000000000000000000000000000000000000000000000000000000009b8c865233600487015260248601526044850152606484015260a0608484015260a4830190613ed7565b03925af160009181610525575b506104eb575050600190610475614316565b6308c379a0146104b2575b50610488575b005b60046040517fefab6922000000000000000000000000000000000000000000000000000000008152fd5b6104ba614334565b90816104c65750610480565b6104e760405192839262461bcd60e51b845260048401526024830190613ed7565b0390fd5b7fffffffff0000000000000000000000000000000000000000000000000000000016149050610486576004604051633fbfe7f560e21b8152fd5b610546919250843d861161054d575b61053e8183613f80565b8101906142de565b9038610463565b503d610534565b60046040517fdd543d52000000000000000000000000000000000000000000000000000000008152fd5b60046040517f714fd844000000000000000000000000000000000000000000000000000000008152fd5b60046040517ff8ba8054000000000000000000000000000000000000000000000000000000008152fd5b5084600052609860205260406000203360005260205260ff604060002054161561034f565b600080fd5b346105f75760006003193601126105f757602060405160048152f35b346105f75760406003193601126105f75767ffffffffffffffff6004358181116105f75761064a903690600401613ff6565b6024358281116105f757610662903690600401613ff6565b3360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf6508602090815260409091205491939091601216158015906101fe90610878575b501561085357600080526101c68252604060002090835190811161083d576106d082546144e3565b601f81116107f7575b5082601f821160011461076a57927f74b7c2afa3f89c562b59674a101e2c48bceeb27cdb620afefa14446f1ffa487b94928261075a9361074b9660009161075f575b506000198260011b9260031b1c19161790555b61073786614619565b604051938493604085526040850190613ed7565b90838203908401523395613ed7565b0390a2005b90508501518961071b565b601f1982169083600052846000209160005b8181106107e057508361074b96937f74b7c2afa3f89c562b59674a101e2c48bceeb27cdb620afefa14446f1ffa487b98969361075a96600194106107c7575b5050811b01905561072e565b87015160001960f88460031b161c1916905589806107bb565b91928660018192868b01518155019401920161077c565b8260005283600020601f830160051c810191858410610833575b601f0160051c01905b81811061082757506106d9565b6000815560010161081a565b9091508190610811565b634e487b7160e01b600052604160045260246000fd5b6064604051634baa2a4d60e01b81523360048201526000602482015260106044820152fd5b905060008052825260406000203360005282526012604060002054161515856106a8565b346105f75760406003193601126105f7576108b5613e88565b6108bd613e9e565b906001600160a01b03809116600052609860205260406000209116600052602052602060ff604060002054166040519015158152f35b346105f75760006003193601126105f75761092361090f6158e7565b604051918291602083526020830190613ed7565b0390f35b346105f75760206003193601126105f7576020610945600435615ccc565b6001600160a01b0360405191168152f35b346105f75760206003193601126105f7576004356000196101c854019080820361097c57005b604491604051917f4fa09b3f00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b346105f75760206003193601126105f75760043560005261012d60205260206001600160a01b0360406000205416604051908152f35b346105f75760606003193601126105f757600435610a04613e9e565b9060443567ffffffffffffffff81116105f757610a25903690600401613ff6565b90806000526101fe926020938085526040600020336000528552600a604060002054161590811591610ba6575b5015610b81576001600160a01b03610a6c91169182614942565b6040516301ffc9a760e01b81527f6890e5b30000000000000000000000000000000000000000000000000000000060048201528381602481855afa908115610b7557600091610b48575b5015610b1757816000929183858194519301915af190610ad46141fb565b9115610adc57005b6104e76040519283927fa5fa8d2b00000000000000000000000000000000000000000000000000000000845260048401526024830190613ed7565b602490604051907fe15b8e060000000000000000000000000000000000000000000000000000000082526004820152fd5b610b689150843d8611610b6e575b610b608183613f80565b8101906154bb565b84610ab6565b503d610b56565b6040513d6000823e3d90fd5b60648260405190634baa2a4d60e01b8252336004830152602482015260086044820152fd5b90506000805284526040600020336000528452600a60406000205416151585610a52565b346105f75760406003193601126105f757610be3613e88565b60243590610bf033614764565b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000602082019081526001600160a01b03831660248301526044808301859052825292906000908190610c46606482613f80565b516001600160a01b039582877f0000000000000000000000000000000000000000000000000000000000000000165af1610c7e6141fb565b5015610c8657005b606492604051927f424cf2e30000000000000000000000000000000000000000000000000000000084523360048501521660248301526044820152fd5b346105f75760406003193601126105f75760043567ffffffffffffffff81116105f757610d16610cf960209236906004016140f3565b90610d03336148aa565b610d0b6145c4565b3391602435916149c6565b6001606555604051908152f35b346105f7576003196080813601126105f757610d3d613e88565b67ffffffffffffffff6024358181116105f757610d5e90369060040161407a565b906044358181116105f757610d7790369060040161407a565b906064359081116105f757610d90903690600401613ff6565b90610d996145c4565b3360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020908152604082205460061615969092915b8551811015610e0857610dea9088610def57614d93565b610dd3565b610e03610dfc8289614282565b5133614942565b614d93565b50908491866001600160a01b0390818116918215611157578551908551820361112d576101cb54168061109b575b5060005b8181106110585750508160006040517f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb339180610e788a8c836142b9565b0390a43b610f21575b505060005b8251811015610f1a5780610ee8610eb687610ea4610f159588614282565b51610eaf8588614282565b5190615799565b610ede610ec38488614282565b51610ed883610ed2878a614282565b516142ac565b906156fb565b610ed28386614282565b610ef28286614282565b516000526101c68652610f0e60026040600020019182546142ac565b9055614d93565b610e86565b6001606555005b84604051809281600081610f977fbc197c81000000000000000000000000000000000000000000000000000000009889835233600484015283602484015260a06044840152610f87610f778d60a4860190614095565b828582030160648601528c614095565b908382030160848401528d613ed7565b03925af160009181611039575b506110015750506001610fb5614316565b6308c379a014610fcc575b610488575b8480610e81565b610fd4614334565b80610fdf5750610fc0565b846104e760405192839262461bcd60e51b845260048401526024830190613ed7565b7fffffffff000000000000000000000000000000000000000000000000000000001614610fc5576004604051633fbfe7f560e21b8152fd5b611051919250863d881161054d5761053e8183613f80565b9087610fa4565b8061106560019288614282565b51611070828a614282565b5160005260978a526040600020866000528a5261109360406000209182546142ac565b905501610e3a565b803b156105f75760006110f0879289838861110f8f6110ff8d6040519a8b998a988997634058856760e11b89523060048a01523360248a01528960448a0152606489015260e0608489015260e4880190614095565b918683030160a4870152614095565b908d8483030160c4850152613ed7565b03925af18015610b755715610e365761112790613f50565b88610e36565b60046040517ff9532c39000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8113ddc8000000000000000000000000000000000000000000000000000000008152fd5b346105f75760806003193601126105f75761119a613e88565b6024356064359167ffffffffffffffff83116105f7576111c1610f1a933690600401613ff6565b916111ca6145c4565b6111d48133614942565b604435916154d3565b346105f75760006003193601126105f757602060405160028152f35b346105f75760206003193601126105f757610923611218600435615cff565b6040519182918291909160406001600160a01b0381606084019563ffffffff8082511686526020820151166020860152015116910152565b346105f75760806003193601126105f75760043560607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc3601126105f7576040519061129b82613efc565b63ffffffff60243581811681036105f757835260443581811681036105f7576020808501918252606435906001600160a01b0380831683036105f75760408701928352856000526101fe8083526040600020336000528352602260406000205416159081159161145a575b501561143657600185885116146113f457825116158061141e575b6113f4578460005261016081527fffffffff000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffff000000000000000067ffffffff000000006040600020968951169387549651901b16935160401b16931617171790557f5837d55897cfc337f160a71d7b63a047abd50a3a8834f1c5d70f338846358c6d604051806113ef33958291909160406001600160a01b0381606084019563ffffffff8082511686526020820151166020860152015116910152565b0390a3005b60046040517f0d9b92f1000000000000000000000000000000000000000000000000000000008152fd5b50855184161515806113215750838351161515611321565b6064868360405191634baa2a4d60e01b835233600484015260248301526044820152fd5b90506000805282526040600020336000528252602260406000205416151588611306565b346105f7576020806003193601126105f75760043567ffffffffffffffff81116105f7576114b36114b9913690600401614121565b90615df8565b6040519082820192808352815180945260408301938160408260051b8601019301916000955b8287106114ec5785850386f35b909192938280611526837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08a600196030186528851613ed7565b96019201960195929190926114df565b346105f75760006003193601126105f757602060405160108152f35b346105f75760406003193601126105f75761156b613e88565b602435908115158092036105f7576001600160a01b0316908133146115df57336000526098602052604060002082600052602052604060002060ff1981541660ff83161790556040519081527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a3005b60046040517fd67f41b2000000000000000000000000000000000000000000000000000000008152fd5b346105f75760006003193601126105f757604051604081019080821067ffffffffffffffff83111761083d5761092391604052600581527f312e342e300000000000000000000000000000000000000000000000000000006020820152604051918291602083526020830190613ed7565b60a06003193601126105f75761168e613e88565b6024359060443560643567ffffffffffffffff81116105f7576116b59036906004016140f3565b926084356001600160a01b039485821682036105f75761170b60009287611744956116de6145c4565b16976116ea8a8a614942565b6116f2614f3e565b8a86526102316020526040862054821691168834614f59565b9360405193849283927f6890e5b300000000000000000000000000000000000000000000000000000000845287898c3360048801614eff565b038183885af1918215610b755761176692869260009161179f575b5051615308565b6040519081523460208201527fb362243af1e2070d7d5bf8d713f2e0fab64203f1b71462afbe20572909788c5e60403392a46001606555005b6117bc91503d806000833e6117b48183613f80565b810190614dd7565b8761175f565b346105f75760406003193601126105f75760043560243567ffffffffffffffff81116105f7576000916001600160a01b0361181561180585943690600401613ff6565b926118108133614822565b615ccc565b1682602083519301915af16118286141fb565b901561183057005b6104e7906040519182917fa5fa8d2b000000000000000000000000000000000000000000000000000000008352602060048401526024830190613ed7565b346105f75760006003193601126105f75760405160208082528160605191828183015260005b8381106118b6575050601f19601f836000604080968601015201168101030190f35b6080810151858201604001528492508101611894565b346105f75760006003193601126105f7576020604051818152f35b346105f7576118f5366140c9565b916119008133614d30565b806000526101fe92836020526001600160a01b03604060002093169283600052602052604060002054179281600052602052604060002082600052602052826040600020557f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca600080a4005b346105f75760006003193601126105f75760206001600160a01b036101c95416604051908152f35b346105f75760206003193601126105f7576000604080516119b481613efc565b6060815282602082015201526004356000526101c660205261092360406000206002604051916119e383613efc565b6119ec8161451d565b8352600181015460208401520154604082015260405191829182614152565b346105f75760e06003193601126105f75760043567ffffffffffffffff81116105f757611a3c903690600401613ff6565b60243567ffffffffffffffff81116105f757611a5c903690600401613ff6565b60607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc3601126105f757604051611a9281613efc565b60443563ffffffff811681036105f757815260643563ffffffff811681036105f75760208201526084356001600160a01b03811681036105f75760408201526001600160a01b0360a4351660a435036105f75760c43567ffffffffffffffff81116105f757611b05903690600401614121565b9091611b0f6145c4565b60005493600885901c60ff1615801590611ffb575b80611fe3575b611fb957600160ff1986161760005560ff8560081c1615611f8a575b60ff60005460081c1615611f60576001606555611b6d6001600160a01b0360a43516615c65565b6101c89081549160018301905560405190611b8782613efc565b81526000602082015260006040820152816000526101c66020526040600020815180519067ffffffffffffffff821161083d578190611bc684546144e3565b601f8111611f10575b50602090601f8311600114611ea457600092611e99575b50506000198260011b9260031b1c19161781555b60208201516001820155600260408301519101557f5086d1bcea28999da9875111e3592688fbfa821db63214c695ca35768080c2fe60405180611c3e339482614152565b0390a3600163ffffffff825116146113f4576001600160a01b036040820151161580611e76575b6113f45760ff94611d709160008052610160602052604060002063ffffffff82511681549067ffffffff00000000602085015160201b16907fffffffff000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffff0000000000000000604087015160401b169316171717905560007f5837d55897cfc337f160a71d7b63a047abd50a3a8834f1c5d70f338846358c6d60405180611d4933958291909160406001600160a01b0381606084019563ffffffff8082511686526020820151166020860152015116910152565b0390a3611d606001600160a01b0360a43516615aed565b611d6b60a435615bc8565b614619565b80611de0575b505060081c1615611d88576001606555005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff600054166000557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160018152a1610f1a565b611df291611ded33615c65565b615df8565b503360008181527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040812080547ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd169081905591907f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca8180a48280611d76565b50805163ffffffff16151580611c65575063ffffffff6020820151161515611c65565b015190508a80611be6565b9250836000526020600020906000935b601f1984168510611ef5576001945083601f19811610611edc575b505050811b018155611bfa565b015160001960f88460031b161c191690558a8080611ecf565b81810151835560209485019460019093019290910190611eb4565b909150836000526020600020601f840160051c810160208510611f59575b90849392915b601f830160051c82018110611f4a575050611bcf565b60008155859450600101611f34565b5080611f2e565b60046040517f96bfb100000000000000000000000000000000000000000000000000000000008152fd5b6101017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000861617600055611b46565b60046040517f7ab84482000000000000000000000000000000000000000000000000000000008152fd5b50303b151580611b2a5750600160ff86161415611b2a565b5060ff85161515611b24565b346105f75760606003193601126105f757612029604435602435600435615d7e565b604080516001600160a01b03939093168352602083019190915290f35b346105f75760206003193601126105f75760043560005261016060205260606040600020546001600160a01b036040519163ffffffff80821684528160201c16602084015260401c166040820152f35b346105f75760206003193601126105f7576004356001600160a01b0381168091036105f7576120c433614c98565b8061215e575b6101cb9073ffffffffffffffffffffffffffffffffffffffff1982541617905560026040517f3be6d3a1d957610f7e900c66889b874cdc9f0c22901aa8be6ec3d2d04c14ca0f3391806113ef819060c082019160a06101c9546001600160a01b03908181168452821c60208401526101ca548181166040850152821c60608401526101cb549081166080840152811c910152565b6040516301ffc9a760e01b8152634058856760e11b6004820152602081602481855afa908115610b75576000916121c6575b506120ca57602490604051907f17ce95600000000000000000000000000000000000000000000000000000000082526004820152fd5b6121de915060203d8111610b6e57610b608183613f80565b82612190565b346105f75760206003193601126105f75760043560005261023160205260206001600160a01b0360406000205416604051908152f35b346105f75760006003193601126105f75760c06101c9546101ca54906101cb5490604051926001600160a01b0391828116855260a01c6020850152818116604085015260a01c60608401528116608083015260a01c60a0820152f35b346105f75760006003193601126105f75760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b346105f75760006003193601126105f75760206101c854604051908152f35b60806003193601126105f7576122ed613e88565b6024359060443560643567ffffffffffffffff81116105f7576123149036906004016140f3565b61231f9391936145c4565b6001600160a01b03809216936123358686614942565b34927f00000000000000000000000000000000000000000000000000000000000000009081166123a0575b506117449160009160405193849283927f6890e5b300000000000000000000000000000000000000000000000000000000845287898c3360048801614eff565b926123d56123ce867f00000000000000000000000000000000000000000000000000000000000000006143e4565b8092614f31565b93600080808085856201adb0f16123ea6141fb565b50156123f65750612360565b6040517f4b789d360000000000000000000000000000000000000000000000000000000081526001600160a01b039190911660048201526024810191909152604490fd5b346105f75760206003193601126105f757610923612459600435614422565b6040519182918291909160808060a0830194805184526020810151602085015260408101516040850152606081015160608501520151910152565b346105f7576003196060813601126105f7576124ae613e88565b67ffffffffffffffff6024358181116105f7576124cf903690600401614121565b9390916044359081116105f7576124ea903690600401614121565b926001600160a01b039586861695338714158061272a575b6126e8575061251f929161251791369161402c565b93369161402c565b9383156126be578251918551830361112d576040519161253e83613f64565b600083526101cb54169182612625575b50505060005b8181106125a05750507f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb6125926000946040519182913395836142b9565b0390a4610486604051613f64565b6125aa8184614282565b51906125b68187614282565b5182600052609760208181526040600020886000528152604060002054918383106125fb57600195600052815260406000209088600052520360406000205501612554565b60046040517f5f896ec2000000000000000000000000000000000000000000000000000000008152fd5b823b156105f757869285600088612699829661267a9661268a6040519a8b998a988997634058856760e11b89523060048a01523360248a0152604489015288606489015260e0608489015260e4880190614095565b90848783030160a4880152614095565b918483030160c4850152613ed7565b03925af18015610b75576126af575b808061254e565b6126b890613f50565b846126a8565b60046040517f45d40ad5000000000000000000000000000000000000000000000000000000008152fd5b6040517f839c23f20000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b03919091166024820152604490fd5b5086600052609860205260406000203360005260205260ff6040600020541615612502565b346105f75760206003193601126105f7576004356000526101c760205260206001600160a01b0360406000205416604051908152f35b346105f75760606003193601126105f75760043567ffffffffffffffff81116105f7576127b69036906004016140f3565b90604435906001600160a01b0382168092036105f7576020926127dc91610d03336148aa565b9081600052610231835260406000209073ffffffffffffffffffffffffffffffffffffffff198254161790556001606555604051908152f35b346105f75760406003193601126105f7576004356024356001600160a01b0381168091036105f7576128456145c4565b61284f8233614822565b8160005260209061012d825260406000208173ffffffffffffffffffffffffffffffffffffffff1982541617905580612919575b6040513382857f5010f780a0de79bcfb9f3d6fec3cfe29758ef5c5800d575af709bc590bd78ade600080a4836128e557507f56e810c8cae84731149f628981d25769a084570b9ba6eebf3c32879e3dce56099250604051908152a16001606555005b604091506000837f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b948352820152a2610f1a565b6040516301ffc9a760e01b81527f7bc7e6460000000000000000000000000000000000000000000000000000000060048201528281602481855afa908115610b7557600091612999575b5061288357602490604051907fda755beb0000000000000000000000000000000000000000000000000000000082526004820152fd5b6129b09150833d8511610b6e57610b608183613f80565b84612963565b346105f75760006003193601126105f7576020610945614f3e565b346105f7576129df366140c9565b6129eb83929333614d30565b60008281526101fe602081815260408084206001600160a01b039788168086529083529084208054951990951694859055909491939092839083907f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca9080a4159182612b4b575b82612b26575b5050612a6057005b7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09160006040926101c99283549373ffffffffffffffffffffffffffffffffffffffff1985169055845193168352820152a160006040517f3be6d3a1d957610f7e900c66889b874cdc9f0c22901aa8be6ec3d2d04c14ca0f3391806113ef819060c082019160a06101c9546001600160a01b03908181168452821c60208401526101ca548181166040850152821c60608401526101cb549081166080840152811c910152565b9091506000805282526040600020906000528152600260406000205416158380612a58565b6101c954851682149250612a52565b346105f75760206003193601126105f757610923612459600435614483565b346105f75760006003193601126105f7576001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003612be45760206040517f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8152f35b60046040517f5e4c25f1000000000000000000000000000000000000000000000000000000008152fd5b60406003193601126105f757612c22613e88565b60243567ffffffffffffffff81116105f757612c42903690600401613ff6565b906001600160a01b03807f00000000000000000000000000000000000000000000000000000000000000001690813014612f0b577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc9080825416928303612ee1578392612cae33614c98565b6040517f21f743470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201529316602484015260209283816044817f000000000000000000000000000000000000000000000000000000000000000086165afa908115610b7557600091612ec4575b50156105f7577f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612d64575050506104869150614181565b8316906040517f52d1902d0000000000000000000000000000000000000000000000000000000081528381600481865afa60009181612e95575b50612dcd5760046040517fe5ec1769000000000000000000000000000000000000000000000000000000008152fd5b03612e6b57612ddb83614181565b604051907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a2835115801590612e63575b612e1557005b823b15612e3b575082600092839261048695519201905af4612e356141fb565b906143a3565b807f369891e70000000000000000000000000000000000000000000000000000000060049252fd5b506001612e0f565b60046040517f8373ebf0000000000000000000000000000000000000000000000000000000008152fd5b9091508481813d8311612ebd575b612ead8183613f80565b810103126105f757519087612d9e565b503d612ea3565b612edb9150843d8611610b6e57610b608183613f80565b86612d27565b60046040517f64cd8d19000000000000000000000000000000000000000000000000000000008152fd5b60046040517f1932df45000000000000000000000000000000000000000000000000000000008152fd5b346105f75760406003193601126105f75760043567ffffffffffffffff8082116105f757366023830112156105f757816004013590612f7382614014565b92612f816040519485613f80565b82845260209260248486019160051b830101913683116105f757602401905b82821061307c575050506024359081116105f757612fc290369060040161407a565b8251908051820361305257612fd682614014565b93612fe46040519586613f80565b828552601f19612ff384614014565b01368587013760005b838110613016576040518581528061092381880189614095565b806130416001600160a01b0361302e60019486614282565b511661303a8387614282565b519061422b565b61304b8289614282565b5201612ffc565b60046040517f4ce4cfdc000000000000000000000000000000000000000000000000000000008152fd5b81356001600160a01b03811681036105f7578152908401908401612fa0565b346105f75760406003193601126105f7576130b4613e9e565b6004356000526101fe6020526001600160a01b03604060002091166000526020526020604060002054604051908152f35b346105f75760206003193601126105f7576602c2ad68fd900060043581810291811591830414171561311c57602090604051908152f35b634e487b7160e01b600052601160045260246000fd5b346105f75760006003193601126105f7573360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf650860205260409020546022161515801561320e575b156131e957476001600160a01b03906101ca91600080808085858854166204baf0f16131a86141fb565b50156131b057005b604492541690604051917fa489930c00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b6064604051634baa2a4d60e01b81523360048201526000602482015260206044820152fd5b503360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040902054602216151561317e565b346105f7576020806003193601126105f757613262613e88565b6001600160a01b0391827f000000000000000000000000000000000000000000000000000000000000000016803014612f0b577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc9084825416908103612ee157828461331a926132d133614c98565b6040517f21f743470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201529116602482015291829081906044820190565b0381887f0000000000000000000000000000000000000000000000000000000000000000165afa908115610b7557600091613485575b50156105f7576040519361336385613f64565b600085527f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561339e575050506104869150614181565b8316906040517f52d1902d0000000000000000000000000000000000000000000000000000000081528381600481865afa60009181613456575b506134075760046040517fe5ec1769000000000000000000000000000000000000000000000000000000008152fd5b03612e6b5761341583614181565b604051907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a283511580159061344e57612e1557005b506000612e0f565b9091508481813d831161347e575b61346e8183613f80565b810103126105f7575190876133d8565b503d613464565b61349c9150833d8511610b6e57610b608183613f80565b85613350565b346105f75760031960a0813601126105f7576134bc613e88565b906134c5613e9e565b9167ffffffffffffffff6044358181116105f7576134e790369060040161407a565b916064358281116105f75761350090369060040161407a565b916084359081116105f757613519903690600401613ff6565b6001600160a01b038092169533871415806137e8575b6105a8578451845181036130525783821693841561057e576101cb541680613756575b5060005b8181106136d557505082876040517f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb3391806135938a8c836142b9565b0390a43b61359d57005b6000602094613617613608976135f894604051998a98899788967fbc197c81000000000000000000000000000000000000000000000000000000009e8f89523360048a0152602489015260a0604489015260a4880190614095565b9084878303016064880152614095565b91848303016084850152613ed7565b03925af1600091816136b5575b5061367d5750506001613635614316565b6308c379a014613646575b61048857005b61364e614334565b806136595750613640565b6104e79060405191829162461bcd60e51b8352602060048401526024830190613ed7565b7fffffffff000000000000000000000000000000000000000000000000000000001614610486576004604051633fbfe7f560e21b8152fd5b6136ce91925060203d811161054d5761053e8183613f80565b9083613624565b6136df8188614282565b51906136eb8188614282565b518260005260206097815260406000208c60005281526040600020549082821061055457846001956000526097825260406000208a600052825260406000206137358582546142ac565b9055600052609781526040600020908d600052520360406000205501613556565b803b156105f7576000876137aa9287838d6137ca8e6137ba8e6040519a8b998a988997634058856760e11b89523060048a01523360248a01526044890152606488015260e0608488015260e4870190614095565b90838683030160a4870152614095565b908382030160c48401528b613ed7565b03925af18015610b755715613552576137e290613f50565b88613552565b5086600052609860205260406000203360005260205260ff604060002054161561352f565b346105f75760406003193601126105f757613829600435615cff565b6001600160a01b03604061387361384c60243563ffffffff6020870151166143e4565b7f00000000000000000000000000000000000000000000000000000000000000009061578f565b9201511661092360405192839283602090939291936001600160a01b0360408201951681520152565b346105f75760606003193601126105f7576138b5613e88565b6024356000526101fe6020526001600160a01b03604060002091166000526020526020604435600217604060002054161515604051908152f35b346105f75760406003193601126105f75767ffffffffffffffff6004356024358281116105f757613924903690600401613ff6565b9161392f8233614822565b81156105f75760405191807f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b6020948581528061396e87820189613ed7565b0390a26000526101c68252604060002091835191821161083d5761399283546144e3565b601f8111613a3a575b5080601f83116001146139d757508192936000926139cc575b50506000198260011b9260031b1c1916179055600080f35b0151905083806139b4565b90601f198316948460005282600020926000905b878210613a22575050836001959610613a09575b505050811b019055005b015160001960f88460031b161c191690558380806139ff565b806001859682949686015181550195019301906139eb565b8360005281600020601f840160051c810191838510613a76575b601f0160051c01905b818110613a6a575061399b565b60008155600101613a5d565b9091508190613a54565b346105f75760006003193601126105f757602060405160088152f35b346105f75760406003193601126105f757600435613ab8613e9e565b9080600052610231806020526001600160a01b039182604060002054163303613b09576000526020526040600020911673ffffffffffffffffffffffffffffffffffffffff19825416179055600080f35b60046040517f2afb0ecf000000000000000000000000000000000000000000000000000000008152fd5b346105f75760206003193601126105f757613b4c613e88565b613b5533614c98565b6001600160a01b03811660009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf6508602052604090205460021615613b9e5761048690615aed565b60046040517f98ee9d38000000000000000000000000000000000000000000000000000000008152fd5b346105f75760006003193601126105f75760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b346105f75760206003193601126105f757610486613c1f613e88565b613c2833614764565b615bc8565b346105f75760206003193601126105f75761092361090f600435615a62565b346105f75760006003193601126105f75760405160006101938054613c70816144e3565b80855291600191808316908115613cf65750600114613c9a575b6109238561090f81870382613f80565b600090815292507ffc8af01f449989052b52093a58fc9f42d0b11f0c6dd5dca0463dab62346ccc685b828410613cde57505050810160200161090f82610923613c8a565b80546020858701810191909152909301928101613cc3565b8695506109239693506020925061090f94915060ff191682840152151560051b8201019293613c8a565b346105f75760206003193601126105f7576004357fffffffff0000000000000000000000000000000000000000000000000000000081168091036105f757807f2a55205a0000000000000000000000000000000000000000000000000000000060209214908115613e13575b8115613d9e575b506040519015158152f35b7fd9b67a2600000000000000000000000000000000000000000000000000000000811491508115613de9575b8115613dd8575b5082613d93565b6301ffc9a760e01b91501482613dd1565b7f0e89341c0000000000000000000000000000000000000000000000000000000081149150613dca565b7f2920ca160000000000000000000000000000000000000000000000000000000081149150613d8c565b346105f75760006003193601126105f757602060405160008152f35b346105f75760406003193601126105f7576020613e80613e77613e88565b6024359061422b565b604051908152f35b600435906001600160a01b03821682036105f757565b602435906001600160a01b03821682036105f757565b60005b838110613ec75750506000910152565b8181015183820152602001613eb7565b90601f19601f602093613ef581518092818752878088019101613eb4565b0116010190565b6060810190811067ffffffffffffffff82111761083d57604052565b60a0810190811067ffffffffffffffff82111761083d57604052565b6040810190811067ffffffffffffffff82111761083d57604052565b67ffffffffffffffff811161083d57604052565b6020810190811067ffffffffffffffff82111761083d57604052565b90601f601f19910116810190811067ffffffffffffffff82111761083d57604052565b67ffffffffffffffff811161083d57601f01601f191660200190565b929192613fcb82613fa3565b91613fd96040519384613f80565b8294818452818301116105f7578281602093846000960137010152565b9080601f830112156105f75781602061401193359101613fbf565b90565b67ffffffffffffffff811161083d5760051b60200190565b929161403782614014565b916140456040519384613f80565b829481845260208094019160051b81019283116105f757905b82821061406b5750505050565b8135815290830190830161405e565b9080601f830112156105f7578160206140119335910161402c565b90815180825260208080930193019160005b8281106140b5575050505090565b8351855293810193928101926001016140a7565b60031960609101126105f757600435906024356001600160a01b03811681036105f7579060443590565b9181601f840112156105f75782359167ffffffffffffffff83116105f757602083818601950101116105f757565b9181601f840112156105f75782359167ffffffffffffffff83116105f7576020808501948460051b0101116105f757565b602081526060604061416f84518360208601526080850190613ed7565b93602081015182850152015191015290565b803b156141d1576001600160a01b037f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc911673ffffffffffffffffffffffffffffffffffffffff19825416179055565b60046040517f529880eb000000000000000000000000000000000000000000000000000000008152fd5b3d15614226573d9061420c82613fa3565b9161421a6040519384613f80565b82523d6000602084013e565b606090565b6001600160a01b031690811561425857600052609760205260406000209060005260205260406000205490565b60046040517f8620cc34000000000000000000000000000000000000000000000000000000008152fd5b80518210156142965760209160051b010190565b634e487b7160e01b600052603260045260246000fd5b9190820180921161311c57565b90916142d061401193604084526040840190614095565b916020818403910152614095565b908160209103126105f757517fffffffff00000000000000000000000000000000000000000000000000000000811681036105f75790565b60009060033d1161432357565b905060046000803e60005160e01c90565b600060443d106140115760405160031991823d016004833e815167ffffffffffffffff918282113d6024840111176143925781840194855193841161439a573d85010160208487010111614392575061401192910160200190613f80565b949350505050565b50949350505050565b156143ab5790565b8051156143ba57805190602001fd5b60046040517fa1451936000000000000000000000000000000000000000000000000000000008152fd5b8181029291811591840414171561311c57565b6040519061440482613f18565b60006080838281528260208201528260408201528260608201520152565b61442a6143f7565b5066012edc9ab5d00090818102918115908284041481171561311c576564f43391f00080830292830414171561311c576040519161446783613f18565b8252806020830152806040830152806060830152608082015290565b61448b6143f7565b5065c9e86723e000808202908215908383041481171561311c576564f43391f00080840293840414171561311c57604051916144c683613f18565b600083528160208401528160408401526060830152608082015290565b90600182811c92168015614513575b60208310146144fd57565b634e487b7160e01b600052602260045260246000fd5b91607f16916144f2565b9060405191826000825492614531846144e3565b9081845260019485811690816000146145a0575060011461455d575b505061455b92500383613f80565b565b9093915060005260209081600020936000915b81831061458857505061455b9350820101388061454d565b85548884018501529485019487945091830191614570565b905061455b95506020935060ff1991501682840152151560051b820101388061454d565b6002606554146145d5576002606555565b606460405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b90815167ffffffffffffffff811161083d576101939061463982546144e3565b601f81116146ff575b50602080601f831160011461467e575081929394600092614673575b50506000198260011b9260031b1c1916179055565b01519050388061465e565b90601f19831695846000527ffc8af01f449989052b52093a58fc9f42d0b11f0c6dd5dca0463dab62346ccc68926000905b8882106146e7575050836001959697106146ce575b505050811b019055565b015160001960f88460031b161c191690553880806146c4565b806001859682949686015181550195019301906146af565b60008381527ffc8af01f449989052b52093a58fc9f42d0b11f0c6dd5dca0463dab62346ccc68601f840160051c8101926020851061475a575b601f0160051c01915b82811061474f575050614642565b818155600101614741565b9092508290614738565b6001600160a01b03811660009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040902054602216151580156147df575b156147b05750565b6064906001600160a01b0360405191634baa2a4d60e01b83521660048201526000602482015260206044820152fd5b506001600160a01b03811660009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf6508602052604090205460221615156147a8565b9060008181526101fe90816020526001600160a01b036040822094169384825260205260126040822054161591821592614887575b505015614862575050565b6064925060405191634baa2a4d60e01b83526004830152602482015260106044820152fd5b601292509060409181805260205281812085825260205220541615153880614857565b6001600160a01b031660008181527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040812054600616158015906101fe90614920575b50156148fb575050565b6064925060405191634baa2a4d60e01b83526004830152602482015260046044820152fd5b90508180526020526040812082825260205260066040822054161515386148f1565b9060008181526101fe90816020526001600160a01b036040822094169384825260205260066040822054161591821592614982575b5050156148fb575050565b600692509060409181805260205281812085825260205220541615153880614977565b601f8260209493601f19938186528686013760008582860101520116010190565b93929091936149d6368483613fbf565b906101c893845494600186019055604051926149f184613efc565b835286602084015260006040840152846000526101c6602052604060002096835197885167ffffffffffffffff811161083d57614a2e82546144e3565b99601f8b11614c54575b88999a5060009896979850602090601f8311600114614bbf579180889993927f1b944478023872bf91b25a13fdba3a686fdb1bf4dbb872f850240fad4b8cc068999593600092614bb4575b50506000198260011b9260031b1c19161781555b60208201516001820155600260408301519101557f5086d1bcea28999da9875111e3592688fbfa821db63214c695ca35768080c2fe60405180614adb339482614152565b0390a3846000526101fe806020526001600160a01b0360406000209716968760005260205260026040600020541790866000526020526040600020876000526020528060406000205586867f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca600080a481614b74575b614b686040519384936040855260408501916149a5565b9060208301520390a390565b847f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b6040516020815280614bac6020820187896149a5565b0390a2614b51565b015190503880614a83565b979291908260005260206000209860005b601f1984168110614c3957509188996001927f1b944478023872bf91b25a13fdba3a686fdb1bf4dbb872f850240fad4b8cc0689a96959483601f19811610614c20575b505050811b018155614a97565b015160001960f88460031b161c19169055388080614c13565b828201518b556001909a01998c995060209283019201614bd0565b826000526020600020601f830160051c810160208410614c91575b601f8d0160051c82018110614c85575050614a38565b60008155600101614c6f565b5080614c6f565b6001600160a01b031660008181527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040812054600216158015906101fe90614d0e575b5015614ce9575050565b6064925060405191634baa2a4d60e01b83526004830152602482015260026044820152fd5b9050818052602052604081208282526020526002604082205416151538614cdf565b9060008181526101fe90816020526001600160a01b036040822094169384825260205260026040822054161591821592614d70575b505015614ce9575050565b600292509060409181805260205281812085825260205220541615153880614d65565b600019811461311c5760010190565b90929192614daf81613fa3565b91614dbd6040519384613f80565b8294828452828201116105f757602061455b930190613eb4565b60209081818403126105f757805167ffffffffffffffff918282116105f757019060409081838603126105f757815194614e1086613f34565b83518281116105f75784019181601f840112156105f757825190614e3382614014565b94614e4081519687613f80565b828652878087019360051b860101948486116105f757908189809998979695949301935b868510614e7d5750505050505050845201519082015290565b9091929380959697989950518481116105f75782019083601f1983890301126105f757835191614eac83613f34565b8b81015160038110156105f757835284810151908682116105f757019087603f830112156105f7578b92614ee889848887809701519101614da2565b838201528152019401929190899897969594614e64565b919260a0936001600160a01b0361401198969316845260208401526040830152606082015281608082015201916149a5565b9190820391821161311c57565b6101ca546001600160a01b03168015614f545790565b503090565b909194939460009283946602c2ad68fd9000938483029483860414831517156152c05784811015614fae5760046040517fede1d8dc000000000000000000000000000000000000000000000000000000008152fd5b80850361513657508093614fc28993614422565b986001600160a01b038093161561510e575b8216156150e6575b817f000000000000000000000000000000000000000000000000000000000000000016928951948a6020810151926080606060408401519301519d015193873b156150e25791868094928c9d9e9f948260409e9d9e519e8f9d8e9c8d987ffaa3516f000000000000000000000000000000000000000000000000000000008a521660048199015260248d01521660448b015260648a015216608488015260a487015260c486015260e48501527f0000000000000000000000000000000000000000000000000000000000000000166101048401526101248301525a9261014493f180156150d7576150cc57505090565b614011919250613f50565b6040513d84823e3d90fd5b8a80fd5b7f00000000000000000000000000000000000000000000000000000000000000009250614fdc565b7f00000000000000000000000000000000000000000000000000000000000000009550614fd4565b955091908297949396979261514b8692614483565b906001600160a01b03968780921615615298575b1615615270575b857f000000000000000000000000000000000000000000000000000000000000000016926020820151926040830151906080606085015194015194863b1561526c57928897969594928a80959381946040519d8e9b7ffaa3516f000000000000000000000000000000000000000000000000000000008d528d8d816004820152602401521660448c015260648b015216608489015260a48801521660c486015260e48501527f00000000000000000000000000000000000000000000000000000000000000001661010484015261012483015281875a9261014493f1908115615260575061525357500390565b61525c90613f50565b0390565b604051903d90823e3d90fd5b8880fd5b7f00000000000000000000000000000000000000000000000000000000000000009150615166565b7f0000000000000000000000000000000000000000000000000000000000000000955061515f565b602486634e487b7160e01b81526011600452fd5b600311156152de57565b634e487b7160e01b600052602160045260246000fd5b51906001600160a01b03821682036105f757565b929160005b84518110156154b4576153208186614282565b515161532b816152d4565b615334816152d4565b600181036153f7575060208061534a8388614282565b51015160409182828051810103126105f757615368839183016152f4565b910151908186116153ce5760008080936001600160a01b038294166204baf0f16153906141fb565b50156153a557506153a090614d93565b61530d565b600490517fe373ab5c000000000000000000000000000000000000000000000000000000008152fd5b600483517f644f3cdc000000000000000000000000000000000000000000000000000000008152fd5b806154036002926152d4565b036154ab576020806154158388614282565b51015160609182828051810103126105f7576154329082016152f4565b9160409081830151920151918580151591826154a0575b50506154775791610e0391856001600160a01b036153a09695519361546d85613f64565b60008552166154d3565b600490517f4cdcfbf9000000000000000000000000000000000000000000000000000000008152fd5b141590508538615449565b6153a090614d93565b5050509050565b908160209103126105f7575180151581036105f75790565b9092916155036155089382866154ea838383615799565b956154fe6154f888856142ac565b836156fb565b615529565b6142ac565b906000526101c660205261552560026040600020019182546142ac565b9055565b9291906001600160a01b0384168015611157576000928284526020946097865260409687862084875287528786206155628482546142ac565b905583868951878152858a8201527fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628b3392a43b6155a4575b50505050505050565b6155ff9286928689518096819582947ff23a6e61000000000000000000000000000000000000000000000000000000009a8b85523360048601528560248601526044850152606484015260a0608484015260a4830190613ed7565b03925af18391816156dc575b5061569b57505060019161561d614316565b6308c379a014615665575b505061563c57505b3880808080808061559b565b600490517fefab6922000000000000000000000000000000000000000000000000000000008152fd5b61566d614334565b91826156795750615628565b846104e791505192839262461bcd60e51b845260048401526024830190613ed7565b7fffffffff00000000000000000000000000000000000000000000000000000000160391506156cc90505750615630565b60049051633fbfe7f560e21b8152fd5b6156f4919250853d871161054d5761053e8183613f80565b903861560b565b90816000526101c6602052604060002090600282015490600161571e82846142ac565b93015480931161572e5750505050565b60849450604051937f1255c8fd0000000000000000000000000000000000000000000000000000000085526004850152602484015260448301526064820152fd5b8115615779570690565b634e487b7160e01b600052601260045260246000fd5b8115615779570490565b92919092600093818552610160948560205263ffffffff916040928084842054169081156158a0575b508015615896578483526101c6602052600184842001549060028585200154906157f56157ef828461576f565b856142ac565b60001982019182116152c057916158136158199261581f959461578f565b946142ac565b90614f31565b8082101561588e5750955b86615837575b5050505050565b8382526020526001600160a01b038083832054841c1692831561587b575b50821615615874575061586a92918591615529565b3880808080615830565b9450505050565b82805280832054901c8116925038615855565b90509561582a565b5090955050505050565b90508280528383205416386157c2565b6020818303126105f75780519067ffffffffffffffff82116105f757019080601f830112156105f757815161401192602001614da2565b6000805261012d6020527fa581b17bfc4d6578e300cafbf34fd2dc1fef0270d8c73f88a99dcde2859a6639546001600160a01b039081168015615992575b168061593457506140116159a0565b6000600491604051928380927fe8a3d4850000000000000000000000000000000000000000000000000000000082525afa908115610b7557600091615977575090565b614011913d8091833e61598a8183613f80565b8101906158b0565b508060406000205416615925565b60008080526101c690816020526040916159bc838320546144e3565b615a52575080805261012d6020526001600160a01b0390808284822054168015615a46575b60248551809581937f0e89341c000000000000000000000000000000000000000000000000000000008352856004840152165afa928315615a3c57508092615a2857505090565b61401192503d8091833e61598a8183613f80565b51903d90823e3d90fd5b508284822054166159e1565b818052602052206140119061451d565b6000908082526101c680602052615a7c60408420546144e3565b615ada5750816001600160a01b03615a9383615ccc565b16916024604051809481937f0e89341c00000000000000000000000000000000000000000000000000000000835260048301525afa918215615260578092615a2857505090565b916140119260409282526020522061451d565b6101c980546001600160a01b0392831673ffffffffffffffffffffffffffffffffffffffff19821681179092556040805193909116835260208301919091527f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a160006040517f3be6d3a1d957610f7e900c66889b874cdc9f0c22901aa8be6ec3d2d04c14ca0f339180615bc3819060c082019160a06101c9546001600160a01b03908181168452821c60208401526101ca548181166040850152821c60608401526101cb549081166080840152811c910152565b0390a3565b6001600160a01b036101ca911673ffffffffffffffffffffffffffffffffffffffff1982541617905560016040517f3be6d3a1d957610f7e900c66889b874cdc9f0c22901aa8be6ec3d2d04c14ca0f339180615bc3819060c082019160a06101c9546001600160a01b03908181168452821c60208401526101ca548181166040850152821c60608401526101cb549081166080840152811c910152565b6001600160a01b031660008181527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040812080546002179081905591907f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca8180a4565b60005261012d6020526001600160a01b03908160406000205416918215615cf05750565b60008080526040902054169150565b6040805191615d0d83613efc565b600090818452818360209582878201520152815281610160918285526001600160a01b03928383832054841c16615d6f5781805285522092825193615d5185613efc565b549063ffffffff808316865282821c1690850152821c169082015290565b502092825193615d5185613efc565b615d8a90939293615cff565b9263ffffffff9182855116908115615ddf57615db09291615daa9161576f565b906142ac565b90600019818551160181811161311c576001600160a01b0392604092615dd792169061578f565b930151169190565b505050509060406001600160a01b039101511690600090565b9190615e0381614014565b90604091615e1383519182613f80565b818152601f19615e2283614014565b0160005b818110615f3e575050809460005b838110615e42575050505050565b8060051b8201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1833603018112156105f75782019081359167ffffffffffffffff83116105f75760208091019083360382136105f757600080615eae615f1e94615f39973691613fbf565b8a5193615eba85613efc565b602785527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c818601527f206661696c6564000000000000000000000000000000000000000000000000008c86015281519101305af4615f176141fb565b9030615f4f565b615f288286614282565b52615f338185614282565b50614d93565b615e34565b806060602080938601015201615e26565b91929015615fb05750815115615f63575090565b3b15615f6c5790565b606460405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b8251909150156136595750805190602001fdfea26469706673582212209d661661ec61b1198babb33ada415cf81d60c9ed199bd8d15eac67510139096b64736f6c634300081100330000000000000000000000000000000000000000000000000002c2ad68fd90000000000000000000000000007a810dcd0f8d83b20212326813db6ef7e9fd030c00000000000000000000000078b524931e9d847c40bcbf225c25e154a7b05fda0000000000000000000000007777777f279eba3d3ad8f4e708545291a6fdba8b
Deployed Bytecode
0x6080604052600436101561001257600080fd5b60003560e01c8062fdd58e14613e595780630114420114613e3d57806301ffc9a714613d2057806306fdde0314613c4c5780630e89341c14613c2d57806310a7eb5d14613c0357806313966db514613bc857806313af403514613b3357806317bd48bb14613a9c57806318711c7d14613a8057806318e97fd1146138ef57806323bd03861461389c5780632a55205a1461380d5780632eb2c2d6146134a2578063300ecdb91461309b5780633659cfe6146132485780633ccfd60b146131325780634132239b146130e55780634913162d1461309b5780634e1273f414612f355780634f1ef28614612c0e57806352d1902d14612b795780635c04608414612b5a5780635d0f6cba146129d157806364ea3835146129b65780636661a9ba14612815578063674cbae61461278557806369a5b3021461274f5780636b20c45414612494578063722933f71461243a578063731133e9146122d957806375794a3c146122ba578063765b0c361461227657806379502c551461221a5780637dafae4d146121e45780637f2dc61c146120965780637f77f574146120465780638621ea4b146120075780638a08eb4c14611a0b5780638c7a63ae146119945780638da5cb5b1461196c5780638ec998a0146118e7578063929a7128146118cc57806395d89b411461186e5780639c5c63c9146117c25780639dbb844d1461167a578063a0a8e46014611609578063a22cb46514611552578063a453eaf014611536578063ac9650d81461147e578063afed7e9e14611250578063bb3bafd6146111f9578063c0464356146111dd578063c238d1ee14611181578063d1ad846b14610d23578063d258609a14610cc3578063d6ef7af014610bca578063d904b94a146109e8578063dd15e05f146109b2578063e72878b414610956578063e74d86c214610927578063e8a3d485146108f3578063e985e9c51461089c578063ef71c82e14610618578063f1b0d6bb146105fc5763f242432a146102f157600080fd5b346105f75760a06003193601126105f75761030a613e88565b610312613e9e565b9060643560443560843567ffffffffffffffff81116105f757610339903690600401613ff6565b6001600160a01b038094169333851415806105d2575b6105a8578516801561057e578260005260209560978752604060002086600052875260406000205485811061055457859085600052609789526040600020886000528952036040600020558360005260978752604060002082600052875260406000206103bd8682546142ac565b90558186604051868152878a8201527fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260403392a43b6103f957005b6104569360008794604051968795869485937ff23a6e61000000000000000000000000000000000000000000000000000000009b8c865233600487015260248601526044850152606484015260a0608484015260a4830190613ed7565b03925af160009181610525575b506104eb575050600190610475614316565b6308c379a0146104b2575b50610488575b005b60046040517fefab6922000000000000000000000000000000000000000000000000000000008152fd5b6104ba614334565b90816104c65750610480565b6104e760405192839262461bcd60e51b845260048401526024830190613ed7565b0390fd5b7fffffffff0000000000000000000000000000000000000000000000000000000016149050610486576004604051633fbfe7f560e21b8152fd5b610546919250843d861161054d575b61053e8183613f80565b8101906142de565b9038610463565b503d610534565b60046040517fdd543d52000000000000000000000000000000000000000000000000000000008152fd5b60046040517f714fd844000000000000000000000000000000000000000000000000000000008152fd5b60046040517ff8ba8054000000000000000000000000000000000000000000000000000000008152fd5b5084600052609860205260406000203360005260205260ff604060002054161561034f565b600080fd5b346105f75760006003193601126105f757602060405160048152f35b346105f75760406003193601126105f75767ffffffffffffffff6004358181116105f75761064a903690600401613ff6565b6024358281116105f757610662903690600401613ff6565b3360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf6508602090815260409091205491939091601216158015906101fe90610878575b501561085357600080526101c68252604060002090835190811161083d576106d082546144e3565b601f81116107f7575b5082601f821160011461076a57927f74b7c2afa3f89c562b59674a101e2c48bceeb27cdb620afefa14446f1ffa487b94928261075a9361074b9660009161075f575b506000198260011b9260031b1c19161790555b61073786614619565b604051938493604085526040850190613ed7565b90838203908401523395613ed7565b0390a2005b90508501518961071b565b601f1982169083600052846000209160005b8181106107e057508361074b96937f74b7c2afa3f89c562b59674a101e2c48bceeb27cdb620afefa14446f1ffa487b98969361075a96600194106107c7575b5050811b01905561072e565b87015160001960f88460031b161c1916905589806107bb565b91928660018192868b01518155019401920161077c565b8260005283600020601f830160051c810191858410610833575b601f0160051c01905b81811061082757506106d9565b6000815560010161081a565b9091508190610811565b634e487b7160e01b600052604160045260246000fd5b6064604051634baa2a4d60e01b81523360048201526000602482015260106044820152fd5b905060008052825260406000203360005282526012604060002054161515856106a8565b346105f75760406003193601126105f7576108b5613e88565b6108bd613e9e565b906001600160a01b03809116600052609860205260406000209116600052602052602060ff604060002054166040519015158152f35b346105f75760006003193601126105f75761092361090f6158e7565b604051918291602083526020830190613ed7565b0390f35b346105f75760206003193601126105f7576020610945600435615ccc565b6001600160a01b0360405191168152f35b346105f75760206003193601126105f7576004356000196101c854019080820361097c57005b604491604051917f4fa09b3f00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b346105f75760206003193601126105f75760043560005261012d60205260206001600160a01b0360406000205416604051908152f35b346105f75760606003193601126105f757600435610a04613e9e565b9060443567ffffffffffffffff81116105f757610a25903690600401613ff6565b90806000526101fe926020938085526040600020336000528552600a604060002054161590811591610ba6575b5015610b81576001600160a01b03610a6c91169182614942565b6040516301ffc9a760e01b81527f6890e5b30000000000000000000000000000000000000000000000000000000060048201528381602481855afa908115610b7557600091610b48575b5015610b1757816000929183858194519301915af190610ad46141fb565b9115610adc57005b6104e76040519283927fa5fa8d2b00000000000000000000000000000000000000000000000000000000845260048401526024830190613ed7565b602490604051907fe15b8e060000000000000000000000000000000000000000000000000000000082526004820152fd5b610b689150843d8611610b6e575b610b608183613f80565b8101906154bb565b84610ab6565b503d610b56565b6040513d6000823e3d90fd5b60648260405190634baa2a4d60e01b8252336004830152602482015260086044820152fd5b90506000805284526040600020336000528452600a60406000205416151585610a52565b346105f75760406003193601126105f757610be3613e88565b60243590610bf033614764565b6040517ff3fef3a300000000000000000000000000000000000000000000000000000000602082019081526001600160a01b03831660248301526044808301859052825292906000908190610c46606482613f80565b516001600160a01b039582877f0000000000000000000000007777777f279eba3d3ad8f4e708545291a6fdba8b165af1610c7e6141fb565b5015610c8657005b606492604051927f424cf2e30000000000000000000000000000000000000000000000000000000084523360048501521660248301526044820152fd5b346105f75760406003193601126105f75760043567ffffffffffffffff81116105f757610d16610cf960209236906004016140f3565b90610d03336148aa565b610d0b6145c4565b3391602435916149c6565b6001606555604051908152f35b346105f7576003196080813601126105f757610d3d613e88565b67ffffffffffffffff6024358181116105f757610d5e90369060040161407a565b906044358181116105f757610d7790369060040161407a565b906064359081116105f757610d90903690600401613ff6565b90610d996145c4565b3360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020908152604082205460061615969092915b8551811015610e0857610dea9088610def57614d93565b610dd3565b610e03610dfc8289614282565b5133614942565b614d93565b50908491866001600160a01b0390818116918215611157578551908551820361112d576101cb54168061109b575b5060005b8181106110585750508160006040517f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb339180610e788a8c836142b9565b0390a43b610f21575b505060005b8251811015610f1a5780610ee8610eb687610ea4610f159588614282565b51610eaf8588614282565b5190615799565b610ede610ec38488614282565b51610ed883610ed2878a614282565b516142ac565b906156fb565b610ed28386614282565b610ef28286614282565b516000526101c68652610f0e60026040600020019182546142ac565b9055614d93565b610e86565b6001606555005b84604051809281600081610f977fbc197c81000000000000000000000000000000000000000000000000000000009889835233600484015283602484015260a06044840152610f87610f778d60a4860190614095565b828582030160648601528c614095565b908382030160848401528d613ed7565b03925af160009181611039575b506110015750506001610fb5614316565b6308c379a014610fcc575b610488575b8480610e81565b610fd4614334565b80610fdf5750610fc0565b846104e760405192839262461bcd60e51b845260048401526024830190613ed7565b7fffffffff000000000000000000000000000000000000000000000000000000001614610fc5576004604051633fbfe7f560e21b8152fd5b611051919250863d881161054d5761053e8183613f80565b9087610fa4565b8061106560019288614282565b51611070828a614282565b5160005260978a526040600020866000528a5261109360406000209182546142ac565b905501610e3a565b803b156105f75760006110f0879289838861110f8f6110ff8d6040519a8b998a988997634058856760e11b89523060048a01523360248a01528960448a0152606489015260e0608489015260e4880190614095565b918683030160a4870152614095565b908d8483030160c4850152613ed7565b03925af18015610b755715610e365761112790613f50565b88610e36565b60046040517ff9532c39000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8113ddc8000000000000000000000000000000000000000000000000000000008152fd5b346105f75760806003193601126105f75761119a613e88565b6024356064359167ffffffffffffffff83116105f7576111c1610f1a933690600401613ff6565b916111ca6145c4565b6111d48133614942565b604435916154d3565b346105f75760006003193601126105f757602060405160028152f35b346105f75760206003193601126105f757610923611218600435615cff565b6040519182918291909160406001600160a01b0381606084019563ffffffff8082511686526020820151166020860152015116910152565b346105f75760806003193601126105f75760043560607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc3601126105f7576040519061129b82613efc565b63ffffffff60243581811681036105f757835260443581811681036105f7576020808501918252606435906001600160a01b0380831683036105f75760408701928352856000526101fe8083526040600020336000528352602260406000205416159081159161145a575b501561143657600185885116146113f457825116158061141e575b6113f4578460005261016081527fffffffff000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffff000000000000000067ffffffff000000006040600020968951169387549651901b16935160401b16931617171790557f5837d55897cfc337f160a71d7b63a047abd50a3a8834f1c5d70f338846358c6d604051806113ef33958291909160406001600160a01b0381606084019563ffffffff8082511686526020820151166020860152015116910152565b0390a3005b60046040517f0d9b92f1000000000000000000000000000000000000000000000000000000008152fd5b50855184161515806113215750838351161515611321565b6064868360405191634baa2a4d60e01b835233600484015260248301526044820152fd5b90506000805282526040600020336000528252602260406000205416151588611306565b346105f7576020806003193601126105f75760043567ffffffffffffffff81116105f7576114b36114b9913690600401614121565b90615df8565b6040519082820192808352815180945260408301938160408260051b8601019301916000955b8287106114ec5785850386f35b909192938280611526837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08a600196030186528851613ed7565b96019201960195929190926114df565b346105f75760006003193601126105f757602060405160108152f35b346105f75760406003193601126105f75761156b613e88565b602435908115158092036105f7576001600160a01b0316908133146115df57336000526098602052604060002082600052602052604060002060ff1981541660ff83161790556040519081527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a3005b60046040517fd67f41b2000000000000000000000000000000000000000000000000000000008152fd5b346105f75760006003193601126105f757604051604081019080821067ffffffffffffffff83111761083d5761092391604052600581527f312e342e300000000000000000000000000000000000000000000000000000006020820152604051918291602083526020830190613ed7565b60a06003193601126105f75761168e613e88565b6024359060443560643567ffffffffffffffff81116105f7576116b59036906004016140f3565b926084356001600160a01b039485821682036105f75761170b60009287611744956116de6145c4565b16976116ea8a8a614942565b6116f2614f3e565b8a86526102316020526040862054821691168834614f59565b9360405193849283927f6890e5b300000000000000000000000000000000000000000000000000000000845287898c3360048801614eff565b038183885af1918215610b755761176692869260009161179f575b5051615308565b6040519081523460208201527fb362243af1e2070d7d5bf8d713f2e0fab64203f1b71462afbe20572909788c5e60403392a46001606555005b6117bc91503d806000833e6117b48183613f80565b810190614dd7565b8761175f565b346105f75760406003193601126105f75760043560243567ffffffffffffffff81116105f7576000916001600160a01b0361181561180585943690600401613ff6565b926118108133614822565b615ccc565b1682602083519301915af16118286141fb565b901561183057005b6104e7906040519182917fa5fa8d2b000000000000000000000000000000000000000000000000000000008352602060048401526024830190613ed7565b346105f75760006003193601126105f75760405160208082528160605191828183015260005b8381106118b6575050601f19601f836000604080968601015201168101030190f35b6080810151858201604001528492508101611894565b346105f75760006003193601126105f7576020604051818152f35b346105f7576118f5366140c9565b916119008133614d30565b806000526101fe92836020526001600160a01b03604060002093169283600052602052604060002054179281600052602052604060002082600052602052826040600020557f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca600080a4005b346105f75760006003193601126105f75760206001600160a01b036101c95416604051908152f35b346105f75760206003193601126105f7576000604080516119b481613efc565b6060815282602082015201526004356000526101c660205261092360406000206002604051916119e383613efc565b6119ec8161451d565b8352600181015460208401520154604082015260405191829182614152565b346105f75760e06003193601126105f75760043567ffffffffffffffff81116105f757611a3c903690600401613ff6565b60243567ffffffffffffffff81116105f757611a5c903690600401613ff6565b60607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc3601126105f757604051611a9281613efc565b60443563ffffffff811681036105f757815260643563ffffffff811681036105f75760208201526084356001600160a01b03811681036105f75760408201526001600160a01b0360a4351660a435036105f75760c43567ffffffffffffffff81116105f757611b05903690600401614121565b9091611b0f6145c4565b60005493600885901c60ff1615801590611ffb575b80611fe3575b611fb957600160ff1986161760005560ff8560081c1615611f8a575b60ff60005460081c1615611f60576001606555611b6d6001600160a01b0360a43516615c65565b6101c89081549160018301905560405190611b8782613efc565b81526000602082015260006040820152816000526101c66020526040600020815180519067ffffffffffffffff821161083d578190611bc684546144e3565b601f8111611f10575b50602090601f8311600114611ea457600092611e99575b50506000198260011b9260031b1c19161781555b60208201516001820155600260408301519101557f5086d1bcea28999da9875111e3592688fbfa821db63214c695ca35768080c2fe60405180611c3e339482614152565b0390a3600163ffffffff825116146113f4576001600160a01b036040820151161580611e76575b6113f45760ff94611d709160008052610160602052604060002063ffffffff82511681549067ffffffff00000000602085015160201b16907fffffffff000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffff0000000000000000604087015160401b169316171717905560007f5837d55897cfc337f160a71d7b63a047abd50a3a8834f1c5d70f338846358c6d60405180611d4933958291909160406001600160a01b0381606084019563ffffffff8082511686526020820151166020860152015116910152565b0390a3611d606001600160a01b0360a43516615aed565b611d6b60a435615bc8565b614619565b80611de0575b505060081c1615611d88576001606555005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff600054166000557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160018152a1610f1a565b611df291611ded33615c65565b615df8565b503360008181527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040812080547ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd169081905591907f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca8180a48280611d76565b50805163ffffffff16151580611c65575063ffffffff6020820151161515611c65565b015190508a80611be6565b9250836000526020600020906000935b601f1984168510611ef5576001945083601f19811610611edc575b505050811b018155611bfa565b015160001960f88460031b161c191690558a8080611ecf565b81810151835560209485019460019093019290910190611eb4565b909150836000526020600020601f840160051c810160208510611f59575b90849392915b601f830160051c82018110611f4a575050611bcf565b60008155859450600101611f34565b5080611f2e565b60046040517f96bfb100000000000000000000000000000000000000000000000000000000008152fd5b6101017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000861617600055611b46565b60046040517f7ab84482000000000000000000000000000000000000000000000000000000008152fd5b50303b151580611b2a5750600160ff86161415611b2a565b5060ff85161515611b24565b346105f75760606003193601126105f757612029604435602435600435615d7e565b604080516001600160a01b03939093168352602083019190915290f35b346105f75760206003193601126105f75760043560005261016060205260606040600020546001600160a01b036040519163ffffffff80821684528160201c16602084015260401c166040820152f35b346105f75760206003193601126105f7576004356001600160a01b0381168091036105f7576120c433614c98565b8061215e575b6101cb9073ffffffffffffffffffffffffffffffffffffffff1982541617905560026040517f3be6d3a1d957610f7e900c66889b874cdc9f0c22901aa8be6ec3d2d04c14ca0f3391806113ef819060c082019160a06101c9546001600160a01b03908181168452821c60208401526101ca548181166040850152821c60608401526101cb549081166080840152811c910152565b6040516301ffc9a760e01b8152634058856760e11b6004820152602081602481855afa908115610b75576000916121c6575b506120ca57602490604051907f17ce95600000000000000000000000000000000000000000000000000000000082526004820152fd5b6121de915060203d8111610b6e57610b608183613f80565b82612190565b346105f75760206003193601126105f75760043560005261023160205260206001600160a01b0360406000205416604051908152f35b346105f75760006003193601126105f75760c06101c9546101ca54906101cb5490604051926001600160a01b0391828116855260a01c6020850152818116604085015260a01c60608401528116608083015260a01c60a0820152f35b346105f75760006003193601126105f75760206040516001600160a01b037f0000000000000000000000007a810dcd0f8d83b20212326813db6ef7e9fd030c168152f35b346105f75760006003193601126105f75760206101c854604051908152f35b60806003193601126105f7576122ed613e88565b6024359060443560643567ffffffffffffffff81116105f7576123149036906004016140f3565b61231f9391936145c4565b6001600160a01b03809216936123358686614942565b34927f0000000000000000000000007a810dcd0f8d83b20212326813db6ef7e9fd030c9081166123a0575b506117449160009160405193849283927f6890e5b300000000000000000000000000000000000000000000000000000000845287898c3360048801614eff565b926123d56123ce867f0000000000000000000000000000000000000000000000000002c2ad68fd90006143e4565b8092614f31565b93600080808085856201adb0f16123ea6141fb565b50156123f65750612360565b6040517f4b789d360000000000000000000000000000000000000000000000000000000081526001600160a01b039190911660048201526024810191909152604490fd5b346105f75760206003193601126105f757610923612459600435614422565b6040519182918291909160808060a0830194805184526020810151602085015260408101516040850152606081015160608501520151910152565b346105f7576003196060813601126105f7576124ae613e88565b67ffffffffffffffff6024358181116105f7576124cf903690600401614121565b9390916044359081116105f7576124ea903690600401614121565b926001600160a01b039586861695338714158061272a575b6126e8575061251f929161251791369161402c565b93369161402c565b9383156126be578251918551830361112d576040519161253e83613f64565b600083526101cb54169182612625575b50505060005b8181106125a05750507f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb6125926000946040519182913395836142b9565b0390a4610486604051613f64565b6125aa8184614282565b51906125b68187614282565b5182600052609760208181526040600020886000528152604060002054918383106125fb57600195600052815260406000209088600052520360406000205501612554565b60046040517f5f896ec2000000000000000000000000000000000000000000000000000000008152fd5b823b156105f757869285600088612699829661267a9661268a6040519a8b998a988997634058856760e11b89523060048a01523360248a0152604489015288606489015260e0608489015260e4880190614095565b90848783030160a4880152614095565b918483030160c4850152613ed7565b03925af18015610b75576126af575b808061254e565b6126b890613f50565b846126a8565b60046040517f45d40ad5000000000000000000000000000000000000000000000000000000008152fd5b6040517f839c23f20000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b03919091166024820152604490fd5b5086600052609860205260406000203360005260205260ff6040600020541615612502565b346105f75760206003193601126105f7576004356000526101c760205260206001600160a01b0360406000205416604051908152f35b346105f75760606003193601126105f75760043567ffffffffffffffff81116105f7576127b69036906004016140f3565b90604435906001600160a01b0382168092036105f7576020926127dc91610d03336148aa565b9081600052610231835260406000209073ffffffffffffffffffffffffffffffffffffffff198254161790556001606555604051908152f35b346105f75760406003193601126105f7576004356024356001600160a01b0381168091036105f7576128456145c4565b61284f8233614822565b8160005260209061012d825260406000208173ffffffffffffffffffffffffffffffffffffffff1982541617905580612919575b6040513382857f5010f780a0de79bcfb9f3d6fec3cfe29758ef5c5800d575af709bc590bd78ade600080a4836128e557507f56e810c8cae84731149f628981d25769a084570b9ba6eebf3c32879e3dce56099250604051908152a16001606555005b604091506000837f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b948352820152a2610f1a565b6040516301ffc9a760e01b81527f7bc7e6460000000000000000000000000000000000000000000000000000000060048201528281602481855afa908115610b7557600091612999575b5061288357602490604051907fda755beb0000000000000000000000000000000000000000000000000000000082526004820152fd5b6129b09150833d8511610b6e57610b608183613f80565b84612963565b346105f75760006003193601126105f7576020610945614f3e565b346105f7576129df366140c9565b6129eb83929333614d30565b60008281526101fe602081815260408084206001600160a01b039788168086529083529084208054951990951694859055909491939092839083907f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca9080a4159182612b4b575b82612b26575b5050612a6057005b7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09160006040926101c99283549373ffffffffffffffffffffffffffffffffffffffff1985169055845193168352820152a160006040517f3be6d3a1d957610f7e900c66889b874cdc9f0c22901aa8be6ec3d2d04c14ca0f3391806113ef819060c082019160a06101c9546001600160a01b03908181168452821c60208401526101ca548181166040850152821c60608401526101cb549081166080840152811c910152565b9091506000805282526040600020906000528152600260406000205416158380612a58565b6101c954851682149250612a52565b346105f75760206003193601126105f757610923612459600435614483565b346105f75760006003193601126105f7576001600160a01b037f000000000000000000000000eb29a4e5b84fef428c072deba2444e93c080ce87163003612be45760206040517f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8152f35b60046040517f5e4c25f1000000000000000000000000000000000000000000000000000000008152fd5b60406003193601126105f757612c22613e88565b60243567ffffffffffffffff81116105f757612c42903690600401613ff6565b906001600160a01b03807f000000000000000000000000eb29a4e5b84fef428c072deba2444e93c080ce871690813014612f0b577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc9080825416928303612ee1578392612cae33614c98565b6040517f21f743470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201529316602484015260209283816044817f00000000000000000000000078b524931e9d847c40bcbf225c25e154a7b05fda86165afa908115610b7557600091612ec4575b50156105f7577f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612d64575050506104869150614181565b8316906040517f52d1902d0000000000000000000000000000000000000000000000000000000081528381600481865afa60009181612e95575b50612dcd5760046040517fe5ec1769000000000000000000000000000000000000000000000000000000008152fd5b03612e6b57612ddb83614181565b604051907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a2835115801590612e63575b612e1557005b823b15612e3b575082600092839261048695519201905af4612e356141fb565b906143a3565b807f369891e70000000000000000000000000000000000000000000000000000000060049252fd5b506001612e0f565b60046040517f8373ebf0000000000000000000000000000000000000000000000000000000008152fd5b9091508481813d8311612ebd575b612ead8183613f80565b810103126105f757519087612d9e565b503d612ea3565b612edb9150843d8611610b6e57610b608183613f80565b86612d27565b60046040517f64cd8d19000000000000000000000000000000000000000000000000000000008152fd5b60046040517f1932df45000000000000000000000000000000000000000000000000000000008152fd5b346105f75760406003193601126105f75760043567ffffffffffffffff8082116105f757366023830112156105f757816004013590612f7382614014565b92612f816040519485613f80565b82845260209260248486019160051b830101913683116105f757602401905b82821061307c575050506024359081116105f757612fc290369060040161407a565b8251908051820361305257612fd682614014565b93612fe46040519586613f80565b828552601f19612ff384614014565b01368587013760005b838110613016576040518581528061092381880189614095565b806130416001600160a01b0361302e60019486614282565b511661303a8387614282565b519061422b565b61304b8289614282565b5201612ffc565b60046040517f4ce4cfdc000000000000000000000000000000000000000000000000000000008152fd5b81356001600160a01b03811681036105f7578152908401908401612fa0565b346105f75760406003193601126105f7576130b4613e9e565b6004356000526101fe6020526001600160a01b03604060002091166000526020526020604060002054604051908152f35b346105f75760206003193601126105f7576602c2ad68fd900060043581810291811591830414171561311c57602090604051908152f35b634e487b7160e01b600052601160045260246000fd5b346105f75760006003193601126105f7573360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf650860205260409020546022161515801561320e575b156131e957476001600160a01b03906101ca91600080808085858854166204baf0f16131a86141fb565b50156131b057005b604492541690604051917fa489930c00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b6064604051634baa2a4d60e01b81523360048201526000602482015260206044820152fd5b503360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040902054602216151561317e565b346105f7576020806003193601126105f757613262613e88565b6001600160a01b0391827f000000000000000000000000eb29a4e5b84fef428c072deba2444e93c080ce8716803014612f0b577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc9084825416908103612ee157828461331a926132d133614c98565b6040517f21f743470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201529116602482015291829081906044820190565b0381887f00000000000000000000000078b524931e9d847c40bcbf225c25e154a7b05fda165afa908115610b7557600091613485575b50156105f7576040519361336385613f64565b600085527f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561339e575050506104869150614181565b8316906040517f52d1902d0000000000000000000000000000000000000000000000000000000081528381600481865afa60009181613456575b506134075760046040517fe5ec1769000000000000000000000000000000000000000000000000000000008152fd5b03612e6b5761341583614181565b604051907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a283511580159061344e57612e1557005b506000612e0f565b9091508481813d831161347e575b61346e8183613f80565b810103126105f7575190876133d8565b503d613464565b61349c9150833d8511610b6e57610b608183613f80565b85613350565b346105f75760031960a0813601126105f7576134bc613e88565b906134c5613e9e565b9167ffffffffffffffff6044358181116105f7576134e790369060040161407a565b916064358281116105f75761350090369060040161407a565b916084359081116105f757613519903690600401613ff6565b6001600160a01b038092169533871415806137e8575b6105a8578451845181036130525783821693841561057e576101cb541680613756575b5060005b8181106136d557505082876040517f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb3391806135938a8c836142b9565b0390a43b61359d57005b6000602094613617613608976135f894604051998a98899788967fbc197c81000000000000000000000000000000000000000000000000000000009e8f89523360048a0152602489015260a0604489015260a4880190614095565b9084878303016064880152614095565b91848303016084850152613ed7565b03925af1600091816136b5575b5061367d5750506001613635614316565b6308c379a014613646575b61048857005b61364e614334565b806136595750613640565b6104e79060405191829162461bcd60e51b8352602060048401526024830190613ed7565b7fffffffff000000000000000000000000000000000000000000000000000000001614610486576004604051633fbfe7f560e21b8152fd5b6136ce91925060203d811161054d5761053e8183613f80565b9083613624565b6136df8188614282565b51906136eb8188614282565b518260005260206097815260406000208c60005281526040600020549082821061055457846001956000526097825260406000208a600052825260406000206137358582546142ac565b9055600052609781526040600020908d600052520360406000205501613556565b803b156105f7576000876137aa9287838d6137ca8e6137ba8e6040519a8b998a988997634058856760e11b89523060048a01523360248a01526044890152606488015260e0608488015260e4870190614095565b90838683030160a4870152614095565b908382030160c48401528b613ed7565b03925af18015610b755715613552576137e290613f50565b88613552565b5086600052609860205260406000203360005260205260ff604060002054161561352f565b346105f75760406003193601126105f757613829600435615cff565b6001600160a01b03604061387361384c60243563ffffffff6020870151166143e4565b7f00000000000000000000000000000000000000000000000000000000000027109061578f565b9201511661092360405192839283602090939291936001600160a01b0360408201951681520152565b346105f75760606003193601126105f7576138b5613e88565b6024356000526101fe6020526001600160a01b03604060002091166000526020526020604435600217604060002054161515604051908152f35b346105f75760406003193601126105f75767ffffffffffffffff6004356024358281116105f757613924903690600401613ff6565b9161392f8233614822565b81156105f75760405191807f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b6020948581528061396e87820189613ed7565b0390a26000526101c68252604060002091835191821161083d5761399283546144e3565b601f8111613a3a575b5080601f83116001146139d757508192936000926139cc575b50506000198260011b9260031b1c1916179055600080f35b0151905083806139b4565b90601f198316948460005282600020926000905b878210613a22575050836001959610613a09575b505050811b019055005b015160001960f88460031b161c191690558380806139ff565b806001859682949686015181550195019301906139eb565b8360005281600020601f840160051c810191838510613a76575b601f0160051c01905b818110613a6a575061399b565b60008155600101613a5d565b9091508190613a54565b346105f75760006003193601126105f757602060405160088152f35b346105f75760406003193601126105f757600435613ab8613e9e565b9080600052610231806020526001600160a01b039182604060002054163303613b09576000526020526040600020911673ffffffffffffffffffffffffffffffffffffffff19825416179055600080f35b60046040517f2afb0ecf000000000000000000000000000000000000000000000000000000008152fd5b346105f75760206003193601126105f757613b4c613e88565b613b5533614c98565b6001600160a01b03811660009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf6508602052604090205460021615613b9e5761048690615aed565b60046040517f98ee9d38000000000000000000000000000000000000000000000000000000008152fd5b346105f75760006003193601126105f75760206040517f0000000000000000000000000000000000000000000000000002c2ad68fd90008152f35b346105f75760206003193601126105f757610486613c1f613e88565b613c2833614764565b615bc8565b346105f75760206003193601126105f75761092361090f600435615a62565b346105f75760006003193601126105f75760405160006101938054613c70816144e3565b80855291600191808316908115613cf65750600114613c9a575b6109238561090f81870382613f80565b600090815292507ffc8af01f449989052b52093a58fc9f42d0b11f0c6dd5dca0463dab62346ccc685b828410613cde57505050810160200161090f82610923613c8a565b80546020858701810191909152909301928101613cc3565b8695506109239693506020925061090f94915060ff191682840152151560051b8201019293613c8a565b346105f75760206003193601126105f7576004357fffffffff0000000000000000000000000000000000000000000000000000000081168091036105f757807f2a55205a0000000000000000000000000000000000000000000000000000000060209214908115613e13575b8115613d9e575b506040519015158152f35b7fd9b67a2600000000000000000000000000000000000000000000000000000000811491508115613de9575b8115613dd8575b5082613d93565b6301ffc9a760e01b91501482613dd1565b7f0e89341c0000000000000000000000000000000000000000000000000000000081149150613dca565b7f2920ca160000000000000000000000000000000000000000000000000000000081149150613d8c565b346105f75760006003193601126105f757602060405160008152f35b346105f75760406003193601126105f7576020613e80613e77613e88565b6024359061422b565b604051908152f35b600435906001600160a01b03821682036105f757565b602435906001600160a01b03821682036105f757565b60005b838110613ec75750506000910152565b8181015183820152602001613eb7565b90601f19601f602093613ef581518092818752878088019101613eb4565b0116010190565b6060810190811067ffffffffffffffff82111761083d57604052565b60a0810190811067ffffffffffffffff82111761083d57604052565b6040810190811067ffffffffffffffff82111761083d57604052565b67ffffffffffffffff811161083d57604052565b6020810190811067ffffffffffffffff82111761083d57604052565b90601f601f19910116810190811067ffffffffffffffff82111761083d57604052565b67ffffffffffffffff811161083d57601f01601f191660200190565b929192613fcb82613fa3565b91613fd96040519384613f80565b8294818452818301116105f7578281602093846000960137010152565b9080601f830112156105f75781602061401193359101613fbf565b90565b67ffffffffffffffff811161083d5760051b60200190565b929161403782614014565b916140456040519384613f80565b829481845260208094019160051b81019283116105f757905b82821061406b5750505050565b8135815290830190830161405e565b9080601f830112156105f7578160206140119335910161402c565b90815180825260208080930193019160005b8281106140b5575050505090565b8351855293810193928101926001016140a7565b60031960609101126105f757600435906024356001600160a01b03811681036105f7579060443590565b9181601f840112156105f75782359167ffffffffffffffff83116105f757602083818601950101116105f757565b9181601f840112156105f75782359167ffffffffffffffff83116105f7576020808501948460051b0101116105f757565b602081526060604061416f84518360208601526080850190613ed7565b93602081015182850152015191015290565b803b156141d1576001600160a01b037f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc911673ffffffffffffffffffffffffffffffffffffffff19825416179055565b60046040517f529880eb000000000000000000000000000000000000000000000000000000008152fd5b3d15614226573d9061420c82613fa3565b9161421a6040519384613f80565b82523d6000602084013e565b606090565b6001600160a01b031690811561425857600052609760205260406000209060005260205260406000205490565b60046040517f8620cc34000000000000000000000000000000000000000000000000000000008152fd5b80518210156142965760209160051b010190565b634e487b7160e01b600052603260045260246000fd5b9190820180921161311c57565b90916142d061401193604084526040840190614095565b916020818403910152614095565b908160209103126105f757517fffffffff00000000000000000000000000000000000000000000000000000000811681036105f75790565b60009060033d1161432357565b905060046000803e60005160e01c90565b600060443d106140115760405160031991823d016004833e815167ffffffffffffffff918282113d6024840111176143925781840194855193841161439a573d85010160208487010111614392575061401192910160200190613f80565b949350505050565b50949350505050565b156143ab5790565b8051156143ba57805190602001fd5b60046040517fa1451936000000000000000000000000000000000000000000000000000000008152fd5b8181029291811591840414171561311c57565b6040519061440482613f18565b60006080838281528260208201528260408201528260608201520152565b61442a6143f7565b5066012edc9ab5d00090818102918115908284041481171561311c576564f43391f00080830292830414171561311c576040519161446783613f18565b8252806020830152806040830152806060830152608082015290565b61448b6143f7565b5065c9e86723e000808202908215908383041481171561311c576564f43391f00080840293840414171561311c57604051916144c683613f18565b600083528160208401528160408401526060830152608082015290565b90600182811c92168015614513575b60208310146144fd57565b634e487b7160e01b600052602260045260246000fd5b91607f16916144f2565b9060405191826000825492614531846144e3565b9081845260019485811690816000146145a0575060011461455d575b505061455b92500383613f80565b565b9093915060005260209081600020936000915b81831061458857505061455b9350820101388061454d565b85548884018501529485019487945091830191614570565b905061455b95506020935060ff1991501682840152151560051b820101388061454d565b6002606554146145d5576002606555565b606460405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b90815167ffffffffffffffff811161083d576101939061463982546144e3565b601f81116146ff575b50602080601f831160011461467e575081929394600092614673575b50506000198260011b9260031b1c1916179055565b01519050388061465e565b90601f19831695846000527ffc8af01f449989052b52093a58fc9f42d0b11f0c6dd5dca0463dab62346ccc68926000905b8882106146e7575050836001959697106146ce575b505050811b019055565b015160001960f88460031b161c191690553880806146c4565b806001859682949686015181550195019301906146af565b60008381527ffc8af01f449989052b52093a58fc9f42d0b11f0c6dd5dca0463dab62346ccc68601f840160051c8101926020851061475a575b601f0160051c01915b82811061474f575050614642565b818155600101614741565b9092508290614738565b6001600160a01b03811660009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040902054602216151580156147df575b156147b05750565b6064906001600160a01b0360405191634baa2a4d60e01b83521660048201526000602482015260206044820152fd5b506001600160a01b03811660009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf6508602052604090205460221615156147a8565b9060008181526101fe90816020526001600160a01b036040822094169384825260205260126040822054161591821592614887575b505015614862575050565b6064925060405191634baa2a4d60e01b83526004830152602482015260106044820152fd5b601292509060409181805260205281812085825260205220541615153880614857565b6001600160a01b031660008181527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040812054600616158015906101fe90614920575b50156148fb575050565b6064925060405191634baa2a4d60e01b83526004830152602482015260046044820152fd5b90508180526020526040812082825260205260066040822054161515386148f1565b9060008181526101fe90816020526001600160a01b036040822094169384825260205260066040822054161591821592614982575b5050156148fb575050565b600692509060409181805260205281812085825260205220541615153880614977565b601f8260209493601f19938186528686013760008582860101520116010190565b93929091936149d6368483613fbf565b906101c893845494600186019055604051926149f184613efc565b835286602084015260006040840152846000526101c6602052604060002096835197885167ffffffffffffffff811161083d57614a2e82546144e3565b99601f8b11614c54575b88999a5060009896979850602090601f8311600114614bbf579180889993927f1b944478023872bf91b25a13fdba3a686fdb1bf4dbb872f850240fad4b8cc068999593600092614bb4575b50506000198260011b9260031b1c19161781555b60208201516001820155600260408301519101557f5086d1bcea28999da9875111e3592688fbfa821db63214c695ca35768080c2fe60405180614adb339482614152565b0390a3846000526101fe806020526001600160a01b0360406000209716968760005260205260026040600020541790866000526020526040600020876000526020528060406000205586867f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca600080a481614b74575b614b686040519384936040855260408501916149a5565b9060208301520390a390565b847f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b6040516020815280614bac6020820187896149a5565b0390a2614b51565b015190503880614a83565b979291908260005260206000209860005b601f1984168110614c3957509188996001927f1b944478023872bf91b25a13fdba3a686fdb1bf4dbb872f850240fad4b8cc0689a96959483601f19811610614c20575b505050811b018155614a97565b015160001960f88460031b161c19169055388080614c13565b828201518b556001909a01998c995060209283019201614bd0565b826000526020600020601f830160051c810160208410614c91575b601f8d0160051c82018110614c85575050614a38565b60008155600101614c6f565b5080614c6f565b6001600160a01b031660008181527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040812054600216158015906101fe90614d0e575b5015614ce9575050565b6064925060405191634baa2a4d60e01b83526004830152602482015260026044820152fd5b9050818052602052604081208282526020526002604082205416151538614cdf565b9060008181526101fe90816020526001600160a01b036040822094169384825260205260026040822054161591821592614d70575b505015614ce9575050565b600292509060409181805260205281812085825260205220541615153880614d65565b600019811461311c5760010190565b90929192614daf81613fa3565b91614dbd6040519384613f80565b8294828452828201116105f757602061455b930190613eb4565b60209081818403126105f757805167ffffffffffffffff918282116105f757019060409081838603126105f757815194614e1086613f34565b83518281116105f75784019181601f840112156105f757825190614e3382614014565b94614e4081519687613f80565b828652878087019360051b860101948486116105f757908189809998979695949301935b868510614e7d5750505050505050845201519082015290565b9091929380959697989950518481116105f75782019083601f1983890301126105f757835191614eac83613f34565b8b81015160038110156105f757835284810151908682116105f757019087603f830112156105f7578b92614ee889848887809701519101614da2565b838201528152019401929190899897969594614e64565b919260a0936001600160a01b0361401198969316845260208401526040830152606082015281608082015201916149a5565b9190820391821161311c57565b6101ca546001600160a01b03168015614f545790565b503090565b909194939460009283946602c2ad68fd9000938483029483860414831517156152c05784811015614fae5760046040517fede1d8dc000000000000000000000000000000000000000000000000000000008152fd5b80850361513657508093614fc28993614422565b986001600160a01b038093161561510e575b8216156150e6575b817f0000000000000000000000007777777f279eba3d3ad8f4e708545291a6fdba8b16928951948a6020810151926080606060408401519301519d015193873b156150e25791868094928c9d9e9f948260409e9d9e519e8f9d8e9c8d987ffaa3516f000000000000000000000000000000000000000000000000000000008a521660048199015260248d01521660448b015260648a015216608488015260a487015260c486015260e48501527f0000000000000000000000007a810dcd0f8d83b20212326813db6ef7e9fd030c166101048401526101248301525a9261014493f180156150d7576150cc57505090565b614011919250613f50565b6040513d84823e3d90fd5b8a80fd5b7f0000000000000000000000007a810dcd0f8d83b20212326813db6ef7e9fd030c9250614fdc565b7f0000000000000000000000007a810dcd0f8d83b20212326813db6ef7e9fd030c9550614fd4565b955091908297949396979261514b8692614483565b906001600160a01b03968780921615615298575b1615615270575b857f0000000000000000000000007777777f279eba3d3ad8f4e708545291a6fdba8b16926020820151926040830151906080606085015194015194863b1561526c57928897969594928a80959381946040519d8e9b7ffaa3516f000000000000000000000000000000000000000000000000000000008d528d8d816004820152602401521660448c015260648b015216608489015260a48801521660c486015260e48501527f0000000000000000000000007a810dcd0f8d83b20212326813db6ef7e9fd030c1661010484015261012483015281875a9261014493f1908115615260575061525357500390565b61525c90613f50565b0390565b604051903d90823e3d90fd5b8880fd5b7f0000000000000000000000007a810dcd0f8d83b20212326813db6ef7e9fd030c9150615166565b7f0000000000000000000000007a810dcd0f8d83b20212326813db6ef7e9fd030c955061515f565b602486634e487b7160e01b81526011600452fd5b600311156152de57565b634e487b7160e01b600052602160045260246000fd5b51906001600160a01b03821682036105f757565b929160005b84518110156154b4576153208186614282565b515161532b816152d4565b615334816152d4565b600181036153f7575060208061534a8388614282565b51015160409182828051810103126105f757615368839183016152f4565b910151908186116153ce5760008080936001600160a01b038294166204baf0f16153906141fb565b50156153a557506153a090614d93565b61530d565b600490517fe373ab5c000000000000000000000000000000000000000000000000000000008152fd5b600483517f644f3cdc000000000000000000000000000000000000000000000000000000008152fd5b806154036002926152d4565b036154ab576020806154158388614282565b51015160609182828051810103126105f7576154329082016152f4565b9160409081830151920151918580151591826154a0575b50506154775791610e0391856001600160a01b036153a09695519361546d85613f64565b60008552166154d3565b600490517f4cdcfbf9000000000000000000000000000000000000000000000000000000008152fd5b141590508538615449565b6153a090614d93565b5050509050565b908160209103126105f7575180151581036105f75790565b9092916155036155089382866154ea838383615799565b956154fe6154f888856142ac565b836156fb565b615529565b6142ac565b906000526101c660205261552560026040600020019182546142ac565b9055565b9291906001600160a01b0384168015611157576000928284526020946097865260409687862084875287528786206155628482546142ac565b905583868951878152858a8201527fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628b3392a43b6155a4575b50505050505050565b6155ff9286928689518096819582947ff23a6e61000000000000000000000000000000000000000000000000000000009a8b85523360048601528560248601526044850152606484015260a0608484015260a4830190613ed7565b03925af18391816156dc575b5061569b57505060019161561d614316565b6308c379a014615665575b505061563c57505b3880808080808061559b565b600490517fefab6922000000000000000000000000000000000000000000000000000000008152fd5b61566d614334565b91826156795750615628565b846104e791505192839262461bcd60e51b845260048401526024830190613ed7565b7fffffffff00000000000000000000000000000000000000000000000000000000160391506156cc90505750615630565b60049051633fbfe7f560e21b8152fd5b6156f4919250853d871161054d5761053e8183613f80565b903861560b565b90816000526101c6602052604060002090600282015490600161571e82846142ac565b93015480931161572e5750505050565b60849450604051937f1255c8fd0000000000000000000000000000000000000000000000000000000085526004850152602484015260448301526064820152fd5b8115615779570690565b634e487b7160e01b600052601260045260246000fd5b8115615779570490565b92919092600093818552610160948560205263ffffffff916040928084842054169081156158a0575b508015615896578483526101c6602052600184842001549060028585200154906157f56157ef828461576f565b856142ac565b60001982019182116152c057916158136158199261581f959461578f565b946142ac565b90614f31565b8082101561588e5750955b86615837575b5050505050565b8382526020526001600160a01b038083832054841c1692831561587b575b50821615615874575061586a92918591615529565b3880808080615830565b9450505050565b82805280832054901c8116925038615855565b90509561582a565b5090955050505050565b90508280528383205416386157c2565b6020818303126105f75780519067ffffffffffffffff82116105f757019080601f830112156105f757815161401192602001614da2565b6000805261012d6020527fa581b17bfc4d6578e300cafbf34fd2dc1fef0270d8c73f88a99dcde2859a6639546001600160a01b039081168015615992575b168061593457506140116159a0565b6000600491604051928380927fe8a3d4850000000000000000000000000000000000000000000000000000000082525afa908115610b7557600091615977575090565b614011913d8091833e61598a8183613f80565b8101906158b0565b508060406000205416615925565b60008080526101c690816020526040916159bc838320546144e3565b615a52575080805261012d6020526001600160a01b0390808284822054168015615a46575b60248551809581937f0e89341c000000000000000000000000000000000000000000000000000000008352856004840152165afa928315615a3c57508092615a2857505090565b61401192503d8091833e61598a8183613f80565b51903d90823e3d90fd5b508284822054166159e1565b818052602052206140119061451d565b6000908082526101c680602052615a7c60408420546144e3565b615ada5750816001600160a01b03615a9383615ccc565b16916024604051809481937f0e89341c00000000000000000000000000000000000000000000000000000000835260048301525afa918215615260578092615a2857505090565b916140119260409282526020522061451d565b6101c980546001600160a01b0392831673ffffffffffffffffffffffffffffffffffffffff19821681179092556040805193909116835260208301919091527f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a160006040517f3be6d3a1d957610f7e900c66889b874cdc9f0c22901aa8be6ec3d2d04c14ca0f339180615bc3819060c082019160a06101c9546001600160a01b03908181168452821c60208401526101ca548181166040850152821c60608401526101cb549081166080840152811c910152565b0390a3565b6001600160a01b036101ca911673ffffffffffffffffffffffffffffffffffffffff1982541617905560016040517f3be6d3a1d957610f7e900c66889b874cdc9f0c22901aa8be6ec3d2d04c14ca0f339180615bc3819060c082019160a06101c9546001600160a01b03908181168452821c60208401526101ca548181166040850152821c60608401526101cb549081166080840152811c910152565b6001600160a01b031660008181527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040812080546002179081905591907f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca8180a4565b60005261012d6020526001600160a01b03908160406000205416918215615cf05750565b60008080526040902054169150565b6040805191615d0d83613efc565b600090818452818360209582878201520152815281610160918285526001600160a01b03928383832054841c16615d6f5781805285522092825193615d5185613efc565b549063ffffffff808316865282821c1690850152821c169082015290565b502092825193615d5185613efc565b615d8a90939293615cff565b9263ffffffff9182855116908115615ddf57615db09291615daa9161576f565b906142ac565b90600019818551160181811161311c576001600160a01b0392604092615dd792169061578f565b930151169190565b505050509060406001600160a01b039101511690600090565b9190615e0381614014565b90604091615e1383519182613f80565b818152601f19615e2283614014565b0160005b818110615f3e575050809460005b838110615e42575050505050565b8060051b8201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1833603018112156105f75782019081359167ffffffffffffffff83116105f75760208091019083360382136105f757600080615eae615f1e94615f39973691613fbf565b8a5193615eba85613efc565b602785527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c818601527f206661696c6564000000000000000000000000000000000000000000000000008c86015281519101305af4615f176141fb565b9030615f4f565b615f288286614282565b52615f338185614282565b50614d93565b615e34565b806060602080938601015201615e26565b91929015615fb05750815115615f63575090565b3b15615f6c5790565b606460405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b8251909150156136595750805190602001fdfea26469706673582212209d661661ec61b1198babb33ada415cf81d60c9ed199bd8d15eac67510139096b64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000002c2ad68fd90000000000000000000000000007a810dcd0f8d83b20212326813db6ef7e9fd030c00000000000000000000000078b524931e9d847c40bcbf225c25e154a7b05fda0000000000000000000000007777777f279eba3d3ad8f4e708545291a6fdba8b
-----Decoded View---------------
Arg [0] : _mintFeeAmount (uint256): 777000000000000
Arg [1] : _mintFeeRecipient (address): 0x7A810DCd0f8d83B20212326813Db6EF7E9FD030c
Arg [2] : _factory (address): 0x78b524931e9d847c40BcBf225c25e154a7B05fDA
Arg [3] : _protocolRewards (address): 0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000002c2ad68fd9000
Arg [1] : 0000000000000000000000007a810dcd0f8d83b20212326813db6ef7e9fd030c
Arg [2] : 00000000000000000000000078b524931e9d847c40bcbf225c25e154a7b05fda
Arg [3] : 0000000000000000000000007777777f279eba3d3ad8f4e708545291a6fdba8b
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.