Source Code
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
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 5000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
import {ERC1155Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol";
import {IERC1155MetadataURIUpgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/IERC1155MetadataURIUpgradeable.sol";
import {IERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/IERC165Upgradeable.sol";
import {IZoraCreator1155} from "../interfaces/IZoraCreator1155.sol";
import {IZoraCreator1155Initializer} from "../interfaces/IZoraCreator1155Initializer.sol";
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.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
{
/// @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) MintFeeManager(_mintFeeAmount, _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))) {
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 memory newURI,
uint256 maxSupply
) public onlyAdminOrRole(CONTRACT_BASE_ID, PERMISSION_BIT_MINTER) nonReentrant returns (uint256) {
uint256 tokenId = _setupNewToken(newURI, maxSupply);
// Allow the token creator to administrate this token
_addPermission(tokenId, msg.sender, PERMISSION_BIT_ADMIN);
if (bytes(newURI).length > 0) {
emit URI(newURI, tokenId);
}
emit SetupNewToken(tokenId, msg.sender, 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(address(this), 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;
}
totalRoyaltyMints = (mintAmount + (tokens[tokenId].totalMinted % royaltyMintSchedule)) / (royaltyMintSchedule - 1);
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 _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal override {
super._beforeTokenTransfer(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 Internal no-checks set funds recipient address
/// @param fundsRecipient new funds recipient address
function setFundsRecipient(address payable fundsRecipient) external onlyAdminOrRole(CONTRACT_BASE_ID, PERMISSION_BIT_FUNDS_MANAGER) {
config.fundsRecipient = fundsRecipient;
emit ConfigUpdated(msg.sender, ConfigUpdate.FUNDS_RECIPIENT, config);
}
/// @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 Withdraws all ETH from the contract to the message sender
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);
}
}
/// ///
/// 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
// OpenZeppelin Contracts (last updated v4.6.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
// OpenZeppelin Contracts (last updated v4.8.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
* ====
*
* [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://diligence.consensys.net/posts/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 {
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 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT // 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
// 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";
/**
* @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._
*
* @custom:oz-upgrades-unsafe-allow delegatecall
*/
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 {
require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a 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) {
require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID");
} catch {
revert("ERC1967Upgrade: new implementation is 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 {
require(newAdmin != address(0), "ERC1967: new admin is the 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 {
require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract");
require(
AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),
"ERC1967: beacon implementation is not a 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) {
require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed");
}
/**
* @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 (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.8.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
import "../../utils/AddressUpgradeable.sol";
/**
* @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]
* ```
* 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;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is 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) {
require(!_initializing && _initialized < version, "Initializable: contract is 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() {
require(_initializing, "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 {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized < type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Internal function that returns the initialized version. Returns `_initialized`
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Internal function that returns the initialized version. Returns `_initializing`
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}// 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";
/**
* @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() {
require(address(this) != __self, "Function must be called through delegatecall");
require(_getImplementation() == __self, "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() {
require(address(this) == __self, "UUPSUpgradeable: 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.
*/
function upgradeTo(address newImplementation) external 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.
*/
function upgradeToAndCall(address newImplementation, bytes memory data) external 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 (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 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) (token/ERC1155/ERC1155.sol)
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";
/**
* @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) {
require(account != address(0), "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)
{
require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts[i], ids[i]);
}
return batchBalances;
}
/**
* @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 {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"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 {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"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 {
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "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, ids, amounts, 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 {
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
}
emit TransferBatch(operator, from, to, ids, amounts);
_afterTokenTransfer(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 {
require(to != address(0), "ERC1155: mint to the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
_balances[id][to] += amount;
emit TransferSingle(operator, address(0), to, id, amount);
_afterTokenTransfer(operator, address(0), to, ids, amounts, 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 {
require(to != address(0), "ERC1155: mint to the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; i++) {
_balances[ids[i]][to] += amounts[i];
}
emit TransferBatch(operator, address(0), to, ids, amounts);
_afterTokenTransfer(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 {
require(from != address(0), "ERC1155: burn from the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
emit TransferSingle(operator, from, address(0), id, amount);
_afterTokenTransfer(operator, from, address(0), ids, amounts, "");
}
/**
* @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 {
require(from != address(0), "ERC1155: burn from the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
for (uint256 i = 0; i < ids.length; i++) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
}
emit TransferBatch(operator, from, address(0), ids, amounts);
_afterTokenTransfer(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 {
require(owner != operator, "ERC1155: setting approval status for self");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning, as well as batched variants.
*
* The same hook is called on both single and batched variants. For single
* transfers, the length of the `ids` and `amounts` arrays will be 1.
*
* Calling conditions (for each `id` and `amount` pair):
*
* - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* of token type `id` will be transferred to `to`.
* - When `from` is zero, `amount` tokens of token type `id` will be minted
* for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
* will be burned.
* - `from` and `to` are never both zero.
* - `ids` and `amounts` have the same, non-zero length.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {}
/**
* @dev Hook that is called after any token transfer. This includes minting
* and burning, as well as batched variants.
*
* The same hook is called on both single and batched variants. For single
* transfers, the length of the `id` and `amount` arrays will be 1.
*
* Calling conditions (for each `id` and `amount` pair):
*
* - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* of token type `id` will be transferred to `to`.
* - When `from` is zero, `amount` tokens of token type `id` will be minted
* for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
* will be burned.
* - `from` and `to` are never both zero.
* - `ids` and `amounts` have the same, non-zero length.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
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");
}
}
}
function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
uint256[] memory array = new uint256[](1);
array[0] = element;
return array;
}
/**
* @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.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 (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 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;
/**
* @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
* ====
*
* [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://diligence.consensys.net/posts/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 {
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 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 (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 (last updated v4.7.0) (utils/StorageSlot.sol)
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:
* ```
* 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`, and `uint256`._
*/
library StorageSlotUpgradeable {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 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
}
}
}// 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 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 {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;
/// @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;
/// @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 {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
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;
/// @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;
interface ILegacyNaming {
function name() external returns (string memory);
function symbol() external returns (string memory);
}// 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
pragma solidity 0.8.17;
import {IERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/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;
interface IOwnable {
function owner() external returns (address);
event OwnershipTransferred(address lastOwner, address newOwner);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
import {IERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/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 "@openzeppelin/contracts-upgradeable/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;
interface IVersionedContract {
function contractVersion() external returns (string memory);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
import {IERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/IERC165Upgradeable.sol";
import {IERC1155MetadataURIUpgradeable} from "@openzeppelin/contracts-upgradeable/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 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
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;
contract LegacyNamingStorageV1 {
string internal _name;
uint256[50] private __gap;
}// 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;
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 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
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;
/// 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;
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 {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 {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;
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
pragma solidity 0.8.17;
contract SharedBaseConstants {
uint256 public constant CONTRACT_BASE_ID = 0;
}// 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;
/// @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 {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.1.0";
}
}{
"remappings": [
"@openzeppelin/=node_modules/@openzeppelin/",
"@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/",
"@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
"_imagine/=_imagine/",
"ds-test/=node_modules/ds-test/src/",
"forge-std/=node_modules/forge-std/src/",
"mint/=_imagine/mint/"
],
"optimizer": {
"enabled": true,
"runs": 5000
},
"metadata": {
"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"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"Burn_NotOwnerOrApproved","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":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ETHWithdrawFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"contractValue","type":"uint256"}],"name":"FundsWithdrawInsolvent","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":[{"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":[{"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":"","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":[],"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":"customRenderers","outputs":[{"internalType":"contract IRenderer1155","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":"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":"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"},{"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"}]Contract Creation Code
610120346200024157601f620061de38819003918201601f1916830191906001600160401b0383118484101762000246578160609285926040958652833981010312620002415781519162000064826200005c602084016200025c565b92016200025c565b9267016345785d8a00008110156200022a576001600160a01b0391808316158062000220575b6200020f5760a0526080523060c05261271060e0526000549060ff8260081c16159182809362000201575b8015620001e8575b156200018d5760ff198116600117600055826200017a575b50610100931683526200013f575b51615f6c91826200027283396080518281816127d50152614062015260a0518281816122c60152612380015260c051828181612f8b015281816130860152613722015260e05182613d6701525181818161313401526137db0152f35b61ff0019600054166000557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986020825160018152a1620000e3565b61ffff19166101011760005538620000d5565b835162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608490fd5b50303b158015620000bd5750600160ff821614620000bd565b50600160ff821610620000b5565b835163c64a448960e01b8152600490fd5b508115156200008a565b602490835190637f19df9f60e11b82526004820152fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b0382168203620002415756fe6080604052600436101561001257600080fd5b60003560e01c8062fdd58e14614366578063011442011461434a57806301ffc9a71461421457806306fdde03146141405780630e89341c1461412157806310a7eb5d1461408557806313966db51461404a57806313af403514613fb557806318711c7d14613f9957806318e97fd114613e0857806323bd038614613db55780632a55205a14613d265780632eb2c2d6146139a3578063300ecdb91461359c5780633659cfe6146136fc5780633ccfd60b146135e65780634913162d1461359c5780634e1273f4146133eb5780634f1ef2861461304557806352d1902d14612f705780635d0f6cba14612ddc5780636661a9ba14612c1757806369a5b30214612be15780636b20c4541461287f578063731133e91461230957806375794a3c146122ea578063765b0c36146122a65780637f2dc61c1461211b5780637f77f574146120cb5780638621ea4b1461208c5780638a08eb4c14611a6f5780638c7a63ae146119f85780638da5cb5b146119d05780638ec998a01461194b578063929a71281461193057806395d89b41146118d25780639c5c63c914611826578063a0a8e460146117c8578063a22cb465146116d1578063a453eaf0146116b5578063ac9650d8146115fd578063afed7e9e146113cf578063bb3bafd614611378578063c04643561461135c578063c238d1ee14611300578063d1ad846b14610f23578063d258609a14610bc4578063d904b94a146109c9578063dd15e05f14610993578063e72878b414610937578063e74d86c214610908578063e8a3d485146108d4578063e985e9c51461087d578063ef71c82e146105f9578063f1b0d6bb146105dd5763f242432a1461028357600080fd5b346105d85760a06003193601126105d85761029c614395565b6102a46143ab565b9060643560443560843567ffffffffffffffff81116105d8576102cb9036906004016144e7565b6001600160a01b0393610317828683169633881480156105af575b6102ef9061494a565b8816926102fd8415156149bb565b61030686614c05565b8961031089614c05565b92336157a1565b826000526020956097875260406000208660005287528460406000205461034082821015614a2c565b856000526097895260406000208860005289520360406000205583600052609787526040600020826000528752604060002061037d868254614a9d565b90558186604051868152878a8201527fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260403392a43b6103b957005b6104169360008794604051968795869485937ff23a6e61000000000000000000000000000000000000000000000000000000009b8c865233600487015260248601526044850152606484015260a0608484015260a48301906143e4565b03925af160009181610580575b506104ec575050600190610435614b78565b6308c379a0146104b7575b50610448575b005b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560448201527f526563656976657220696d706c656d656e7465720000000000000000000000006064820152608490fd5b0390fd5b6104bf614b96565b90816104cb5750610440565b6104b360405192839262461bcd60e51b8452600484015260248301906143e4565b7fffffffff00000000000000000000000000000000000000000000000000000000161490506104465760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608490fd5b6105a1919250843d86116105a8575b6105998183614471565b810190614b40565b9038610423565b503d61058f565b508760005260986020526040600020336000526020526102ef60ff6040600020541690506102e6565b600080fd5b346105d85760006003193601126105d857602060405160048152f35b346105d85760406003193601126105d85767ffffffffffffffff6004358181116105d85761062b9036906004016144e7565b6024358281116105d8576106439036906004016144e7565b3360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf6508602090815260409091205491939091601216158015906101fe90610859575b501561083457600080526101c68252604060002090835190811161081e576106b18254614c59565b601f81116107d8575b5082601f821160011461074b57927f74b7c2afa3f89c562b59674a101e2c48bceeb27cdb620afefa14446f1ffa487b94928261073b9361072c96600091610740575b506000198260011b9260031b1c19161790555b61071886614dfe565b6040519384936040855260408501906143e4565b908382039084015233956143e4565b0390a2005b9050850151896106fc565b601f1982169083600052846000209160005b8181106107c157508361072c96937f74b7c2afa3f89c562b59674a101e2c48bceeb27cdb620afefa14446f1ffa487b98969361073b96600194106107a8575b5050811b01905561070f565b87015160001960f88460031b161c19169055898061079c565b91928660018192868b01518155019401920161075d565b8260005283600020601f830160051c810191858410610814575b601f0160051c01905b81811061080857506106ba565b600081556001016107fb565b90915081906107f2565b634e487b7160e01b600052604160045260246000fd5b6064604051634baa2a4d60e01b81523360048201526000602482015260106044820152fd5b90506000805282526040600020336000528252600260406000205416151585610689565b346105d85760406003193601126105d857610896614395565b61089e6143ab565b906001600160a01b03809116600052609860205260406000209116600052602052602060ff604060002054166040519015158152f35b346105d85760006003193601126105d8576109046108f0615895565b6040519182916020835260208301906143e4565b0390f35b346105d85760206003193601126105d8576020610926600435615c9c565b6001600160a01b0360405191168152f35b346105d85760206003193601126105d8576004356000196101c854019080820361095d57005b604491604051917f4fa09b3f00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b346105d85760206003193601126105d85760043560005261012d60205260206001600160a01b0360406000205416604051908152f35b346105d85760606003193601126105d8576004356109e56143ab565b9060443567ffffffffffffffff81116105d857610a069036906004016144e7565b90806000526101fe926020938085526040600020336000528552600a604060002054161590811591610ba0575b5015610b7b576001600160a01b03610a4d91169182614fd1565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f6890e5b30000000000000000000000000000000000000000000000000000000060048201528381602481855afa908115610b6f57600091610b42575b5015610b1157816000929183858194519301915af190610ace6147eb565b9115610ad657005b6104b36040519283927fa5fa8d2b000000000000000000000000000000000000000000000000000000008452600484015260248301906143e4565b602490604051907fe15b8e060000000000000000000000000000000000000000000000000000000082526004820152fd5b610b629150843d8611610b68575b610b5a8183614471565b8101906151d0565b84610ab0565b503d610b50565b6040513d6000823e3d90fd5b60648260405190634baa2a4d60e01b8252336004830152602482015260086044820152fd5b90506000805284526040600020336000528452600260406000205416151585610a33565b346105d85760406003193601126105d85767ffffffffffffffff6004358181116105d857610bf69036906004016144e7565b3360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf6508602052604090205460061615801590610ee9575b15610ec457610c3e614da9565b6101c89081549160018301905560405192610c5884614425565b818452602435602085015260006040850152826000526101c66020526040600020908451805191821161081e57610c8f8354614c59565b601f8111610e7c575b50916020959185938790601f8311600114610e11576000919083610e06575b50506000198260011b9260031b1c19161781555b858201516001820155600260408301519101557f5086d1bcea28999da9875111e3592688fbfa821db63214c695ca35768080c2fe60405180610d0e339482614615565b0390a3816000526101fe83526040600020336000528352600260406000205417826000526101fe845260406000203360005284528060406000205533837f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca600080a48051610dc9575b817f1b944478023872bf91b25a13fdba3a686fdb1bf4dbb872f850240fad4b8cc068610dae604051936040855260408501906143e4565b92602435868201528033940390a36001606555604051908152f35b817f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b60405185815280610dfe878201866143e4565b0390a2610d77565b015190508880610cb7565b9083600052886000209160005b601f1985168110610e6257509083929183601f196001961610610e49575b505050811b018155610ccb565b015160001960f88460031b161c19169055888080610e3c565b818301518455899750600190930192918a01918a01610e1e565b836000526020600020601f840160051c81019160208510610eba575b601f0160051c01905b818110610eae5750610c98565b60008155600101610ea1565b9091508190610e98565b6064604051634baa2a4d60e01b81523360048201526000602482015260046044820152fd5b503360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf650860205260409020546002161515610c31565b346105d8576003196080813601126105d857610f3d614395565b67ffffffffffffffff916024358381116105d857610f5f90369060040161456b565b906044358481116105d857610f7890369060040161456b565b936064359081116105d857610f919036906004016144e7565b92610f9a614da9565b3360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020908152604082205460061615969093915b855181101561100957610feb9088610ff057614911565b610fd4565b611004610ffd8289614920565b5133614fd1565b614911565b50908491866001600160a01b0385169261102484151561523e565b6110318551845114614aaa565b61103e82848789336156d6565b60005b8551811015611092578061105861108d9286614920565b516110638289614920565b5160005260978a526040600020876000528a526110866040600020918254614a9d565b9055614911565b611041565b5091929095948160006040517f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb3391806110cd8a8c83614b1b565b0390a43b61116f575b505060005b8251811015611168578061113d61110b876110f96111639588614920565b516111048588614920565b51906155db565b6111336111188488614920565b5161112d83611127878a614920565b51614a9d565b9061553d565b6111278386614920565b6111478286614920565b516000526101c686526110866002604060002001918254614a9d565b6110db565b6001606555005b846040518092816000816111e57fbc197c81000000000000000000000000000000000000000000000000000000009889835233600484015283602484015260a060448401526111d56111c58d60a4860190614586565b828582030160648601528c614586565b908382030160848401528d6143e4565b03925af1600091816112e1575b5061124f5750506001611203614b78565b6308c379a01461121a575b610448575b84806110d6565b611222614b96565b8061122d575061120e565b846104b360405192839262461bcd60e51b8452600484015260248301906143e4565b7fffffffff0000000000000000000000000000000000000000000000000000000016146112135760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608490fd5b6112f9919250863d88116105a8576105998183614471565b90876111f2565b346105d85760806003193601126105d857611319614395565b6024356064359167ffffffffffffffff83116105d8576113406111689336906004016144e7565b91611349614da9565b6113538133614fd1565b604435916151e8565b346105d85760006003193601126105d857602060405160028152f35b346105d85760206003193601126105d857610904611397600435615ccf565b6040519182918291909160406001600160a01b0381606084019563ffffffff8082511686526020820151166020860152015116910152565b346105d85760806003193601126105d85760043560607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc3601126105d8576040519061141a82614425565b63ffffffff60243581811681036105d857835260443581811681036105d8576020808501918252606435906001600160a01b0380831683036105d85760408701928352856000526101fe808352604060002033600052835260226040600020541615908115916115d9575b50156115b5576001858851161461157357825116158061159d575b611573578460005261016081527fffffffff000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffff000000000000000067ffffffff000000006040600020968951169387549651901b16935160401b16931617171790557f5837d55897cfc337f160a71d7b63a047abd50a3a8834f1c5d70f338846358c6d6040518061156e33958291909160406001600160a01b0381606084019563ffffffff8082511686526020820151166020860152015116910152565b0390a3005b60046040517f0d9b92f1000000000000000000000000000000000000000000000000000000008152fd5b50855184161515806114a057508383511615156114a0565b6064868360405191634baa2a4d60e01b835233600484015260248301526044820152fd5b90506000805282526040600020336000528252600260406000205416151588611485565b346105d8576020806003193601126105d85760043567ffffffffffffffff81116105d8576116326116389136906004016145e4565b90615dc2565b6040519082820192808352815180945260408301938160408260051b8601019301916000955b82871061166b5785850386f35b9091929382806116a5837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08a6001960301865288516143e4565b960192019601959291909261165e565b346105d85760006003193601126105d857602060405160108152f35b346105d85760406003193601126105d8576116ea614395565b602435908115158092036105d8576001600160a01b03169081331461175e57336000526098602052604060002082600052602052604060002060ff1981541660ff83161790556040519081527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a3005b608460405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c6600000000000000000000000000000000000000000000006064820152fd5b346105d85760006003193601126105d8576109046040516117e881614409565b600581527f312e312e3000000000000000000000000000000000000000000000000000000060208201526040519182916020835260208301906143e4565b346105d85760406003193601126105d85760043560243567ffffffffffffffff81116105d8576000916001600160a01b03611879611869859436906004016144e7565b926118748133614f49565b615c9c565b1682602083519301915af161188c6147eb565b901561189457005b6104b3906040519182917fa5fa8d2b0000000000000000000000000000000000000000000000000000000083526020600484015260248301906143e4565b346105d85760006003193601126105d85760405160208082528160605191828183015260005b83811061191a575050601f19601f836000604080968601015201168101030190f35b60808101518582016040015284925081016118f8565b346105d85760006003193601126105d8576020604051818152f35b346105d857611959366145ba565b9161196481336150f1565b806000526101fe92836020526001600160a01b03604060002093169283600052602052604060002054179281600052602052604060002082600052602052826040600020557f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca600080a4005b346105d85760006003193601126105d85760206001600160a01b036101c95416604051908152f35b346105d85760206003193601126105d857600060408051611a1881614425565b6060815282602082015201526004356000526101c66020526109046040600020600260405191611a4783614425565b611a5081614c93565b8352600181015460208401520154604082015260405191829182614615565b346105d85760e06003193601126105d85760043567ffffffffffffffff81116105d857611aa09036906004016144e7565b60243567ffffffffffffffff81116105d857611ac09036906004016144e7565b9060607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc3601126105d857604051611af781614425565b60443563ffffffff811681036105d857815260643563ffffffff811681036105d85760208201526084356001600160a01b03811681036105d85760408201526001600160a01b0360a4351660a435036105d85760c43567ffffffffffffffff81116105d857611b6a9036906004016145e4565b919092611b75614da9565b6000549460ff8660081c16159586809761207f575b8015612068575b15611ffe5786600160ff19831617600055611fcf575b50611bcb60ff60005460081c16611bbd81614d38565b611bc681614d38565b614d38565b6001606555611be46001600160a01b0360a43516615c35565b6101c89081549160018301905560405190611bfe82614425565b81526000602082015260006040820152816000526101c66020526040600020815180519067ffffffffffffffff821161081e578190611c3d8454614c59565b601f8111611f7f575b50602090601f8311600114611f1357600092611f08575b50506000198260011b9260031b1c19161781555b60208201516001820155600260408301519101557f5086d1bcea28999da9875111e3592688fbfa821db63214c695ca35768080c2fe60405180611cb5339482614615565b0390a3600163ffffffff83511614611573576001600160a01b036040830151161580611ee5575b61157357611de49160008052610160602052604060002063ffffffff82511681549067ffffffff00000000602085015160201b16907fffffffff000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffff0000000000000000604087015160401b169316171717905560007f5837d55897cfc337f160a71d7b63a047abd50a3a8834f1c5d70f338846358c6d60405180611dbd33958291909160406001600160a01b0381606084019563ffffffff8082511686526020820151166020860152015116910152565b0390a3611dd46001600160a01b0360a43516615aa7565b611ddf60a435615b8d565b614dfe565b80611e4f575b5050611df7576001606555005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff600054166000557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160018152a1611168565b611e6191611e5c33615c35565b615dc2565b503360008181527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040812080547ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd169081905591907f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca8180a48180611dea565b50815163ffffffff16151580611cdc575063ffffffff6020830151161515611cdc565b015190508a80611c5d565b9250836000526020600020906000935b601f1984168510611f64576001945083601f19811610611f4b575b505050811b018155611c71565b015160001960f88460031b161c191690558a8080611f3e565b81810151835560209485019460019093019290910190611f23565b909150836000526020600020601f840160051c810160208510611fc8575b90849392915b601f830160051c82018110611fb9575050611c46565b60008155859450600101611fa3565b5080611f9d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011760005586611ba7565b608460405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152fd5b50303b158015611b915750600160ff821614611b91565b50600160ff821610611b8a565b346105d85760606003193601126105d8576120ae604435602435600435615d4e565b604080516001600160a01b03939093168352602083019190915290f35b346105d85760206003193601126105d85760043560005261016060205260606040600020546001600160a01b036040519163ffffffff80821684528160201c16602084015260401c166040820152f35b346105d85760206003193601126105d8576004356001600160a01b0381168091036105d85761214933615059565b806121ee575b6101cb907fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905560026040517f3be6d3a1d957610f7e900c66889b874cdc9f0c22901aa8be6ec3d2d04c14ca0f33918061156e819060c082019160a06101c9546001600160a01b03908181168452821c60208401526101ca548181166040850152821c60608401526101cb549081166080840152811c910152565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f80b10ace000000000000000000000000000000000000000000000000000000006004820152602081602481855afa908115610b6f57600091612288575b5061214f57602490604051907f17ce95600000000000000000000000000000000000000000000000000000000082526004820152fd5b6122a0915060203d8111610b6857610b5a8183614471565b82612252565b346105d85760006003193601126105d85760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b346105d85760006003193601126105d85760206101c854604051908152f35b60806003193601126105d85761231d614395565b604435906064359067ffffffffffffffff82116105d857366023830112156105d857816004013567ffffffffffffffff81116105d85736602482850101116105d857612367614da9565b61237c6024356001600160a01b038416614fd1565b34927f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0381166127ce575b50602460c4600092601f19601f8660405197889687957f6890e5b30000000000000000000000000000000000000000000000000000000087523060048801528135828801528d60448801528c606488015260a060848801528260a488015201868601378685828601015201168101030181836001600160a01b0387165af1908115610b6f57600091612637575b50519060005b82518110156125ee576124548184614920565b515161245f8161519c565b6124688161519c565b6001810361252c575060208061247e8386614920565b510151906040828051810103126105d85761249c60409183016151bc565b910151908186116125025760008080936001600160a01b038294166204baf0f16124c46147eb565b50156124d8576124d390614911565b612441565b60046040517fe373ab5c000000000000000000000000000000000000000000000000000000008152fd5b60046040517f644f3cdc000000000000000000000000000000000000000000000000000000008152fd5b8061253860029261519c565b036125e5576020908161254b8286614920565b51015160609283828051810103126105d8576125689082016151bc565b92604082015191015190602435151590816125d8575b506125ae576124d392611004916040519161259883614455565b600083526001600160a01b0360243591166151e8565b60046040517f4cdcfbf9000000000000000000000000000000000000000000000000000000008152fd5b905060243514158861257e565b6124d390614911565b50836040519081523460208201526001600160a01b036024359216907fb362243af1e2070d7d5bf8d713f2e0fab64203f1b71462afbe20572909788c5e60403392a46001606555005b3d9150816000823e6126498282614471565b60208183810103126105d85780519067ffffffffffffffff82116105d857604082820184830103126105d8576040519261268284614409565b828201519067ffffffffffffffff82116105d857808301601f83868601010112156105d8578184840101516126b681614505565b926126c46040519485614471565b818452602084019083860160208460051b838a8a01010101116105d8576020818888010101915b60208460051b838a8a0101010183106127185750505050509060209291845201015160208201528461243b565b82519067ffffffffffffffff82116105d8576040601f1983858c8c010101888b010301126105d8576040519161274d83614409565b602081858c8c010101015160038110156105d8578352604081858c8c01010101519167ffffffffffffffff83116105d857878a018b8b01860183018401603f0112156105d8576020936127bd8c8c6040889788978b8f8501958a848484848a010101010151950101010101615154565b8382015281520193019290506126eb565b936127f9867f0000000000000000000000000000000000000000000000000000000000000000615189565b908181039081116128695794600080808085856201adb0f16128196147eb565b501561282557506123ae565b6040517f4b789d360000000000000000000000000000000000000000000000000000000081526001600160a01b039190911660048201526024810191909152604490fd5b634e487b7160e01b600052601160045260246000fd5b346105d8576003196060813601126105d857612899614395565b60249167ffffffffffffffff83358181116105d8576128bc9036906004016145e4565b60449491949283359081116105d8576128d99036906004016145e4565b956001600160a01b0392838516943386141580612bbc575b612b7a575061290e929161290691369161451d565b96369161451d565b938215612b11576129228651865114614aaa565b6040519161292f83614455565b600083526101cb54169182612a60575b50505060005b8451811015612a1b576129588186614920565b516129638286614920565b51908060005260976020908082526040600020866000528252604060002054928484106129b457906129af95949392916000528152604060002090866000525203604060002055614911565b612945565b6084837f455243313135353a206275726e20616d6f756e7420657863656564732062616c8a8e6040519362461bcd60e51b85526004850152808401528201527f616e6365000000000000000000000000000000000000000000000000000000006064820152fd5b600082867f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb612a5288604051918291339583614b1b565b0390a4610446604051614455565b823b156105d85786928560008a612aec82968996612add8d612acd6040519c8d9b8c9a8b997f80b10ace000000000000000000000000000000000000000000000000000000008b523060048c015233908b015289015288606489015260e0608489015260e4880190614586565b90848783030160a4880152614586565b918483030160c48501526143e4565b03925af18015610b6f57612b02575b808061293f565b612b0b90614441565b85612afb565b6084877f455243313135353a206275726e2066726f6d20746865207a65726f20616464728660236040519362461bcd60e51b8552602060048601528401528201527f65737300000000000000000000000000000000000000000000000000000000006064820152fd5b6040517f839c23f20000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b03919091166024820152604490fd5b5085600052609860205260406000203360005260205260ff60406000205416156128f1565b346105d85760206003193601126105d8576004356000526101c760205260206001600160a01b0360406000205416604051908152f35b346105d85760406003193601126105d8576004356024356001600160a01b0381168091036105d857612c47614da9565b612c518233614f49565b8160005260209061012d82526040600020817fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905580612d26575b6040513382857f5010f780a0de79bcfb9f3d6fec3cfe29758ef5c5800d575af709bc590bd78ade600080a483612cf257507f56e810c8cae84731149f628981d25769a084570b9ba6eebf3c32879e3dce56099250604051908152a16001606555005b604091506000837f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b948352820152a2611168565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f7bc7e6460000000000000000000000000000000000000000000000000000000060048201528281602481855afa908115610b6f57600091612dbf575b50612c9057602490604051907fda755beb0000000000000000000000000000000000000000000000000000000082526004820152fd5b612dd69150833d8511610b6857610b5a8183614471565b84612d89565b346105d857612dea366145ba565b612df6839293336150f1565b60008281526101fe602081815260408084206001600160a01b039788168086529083529084208054951990951694859055909491939092839083907f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca9080a4159182612f61575b82612f3c575b5050612e6b57005b7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09160006040926101c9928354937fffffffffffffffffffffffff000000000000000000000000000000000000000085169055845193168352820152a160006040517f3be6d3a1d957610f7e900c66889b874cdc9f0c22901aa8be6ec3d2d04c14ca0f33918061156e819060c082019160a06101c9546001600160a01b03908181168452821c60208401526101ca548181166040850152821c60608401526101cb549081166080840152811c910152565b9091506000805282526040600020906000528152600260406000205416158380612e63565b6101c954851682149250612e5d565b346105d85760006003193601126105d8576001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003612fdb5760206040517f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8152f35b608460405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152fd5b60406003193601126105d857613059614395565b60243567ffffffffffffffff81116105d8576130799036906004016144e7565b90806001600160a01b03807f000000000000000000000000000000000000000000000000000000000000000016906130b382301415614644565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc916130e4828454169182146146b5565b6130ed33615059565b6040517f21f743470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201529316602484015260209283816044817f000000000000000000000000000000000000000000000000000000000000000086165afa908115610b6f576000916133ce575b50156105d8577f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156131a3575050506104469150614726565b83929316906040517f52d1902d0000000000000000000000000000000000000000000000000000000081528481600481865afa6000918161339f575b5061324e576084856040519062461bcd60e51b82526004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f7420555550530000000000000000000000000000000000006064820152fd5b939293036133355761325f83614726565b604051907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a283511580159061332d575b61329957005b823b156132c7575082600092839261044695519201905af46132b96147eb565b6132c161481b565b91614c2a565b60849162461bcd60e51b82526004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e747261637400000000000000000000000000000000000000000000000000006064820152fd5b506001613293565b6084826040519062461bcd60e51b82526004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c655555494400000000000000000000000000000000000000000000006064820152fd5b9091508581813d83116133c7575b6133b78183614471565b810103126105d8575190876131df565b503d6133ad565b6133e59150843d8611610b6857610b5a8183614471565b86613166565b346105d85760406003193601126105d85760043567ffffffffffffffff8082116105d857366023830112156105d85781600401359061342982614505565b926134376040519485614471565b82845260209260248486019160051b830101913683116105d857602401905b82821061357d575050506024359081116105d85761347890369060040161456b565b825181510361351357825192601f196134a961349386614505565b956134a16040519788614471565b808752614505565b01368486013760005b81518110156134fc57806134e76001600160a01b036134d46134f79486614920565b51166134e08387614920565b519061487a565b6134f18288614920565b52614911565b6134b2565b505050610904604051928284938452830190614586565b6084826040519062461bcd60e51b82526004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d6174636800000000000000000000000000000000000000000000006064820152fd5b81356001600160a01b03811681036105d8578152908401908401613456565b346105d85760406003193601126105d8576135b56143ab565b6004356000526101fe6020526001600160a01b03604060002091166000526020526020604060002054604051908152f35b346105d85760006003193601126105d8573360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040902054602216151580156136c2575b1561369d57476001600160a01b03906101ca91600080808085858854166204baf0f161365c6147eb565b501561366457005b604492541690604051917fa489930c00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b6064604051634baa2a4d60e01b81523360048201526000602482015260206044820152fd5b503360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf650860205260409020546002161515613632565b346105d8576020806003193601126105d857613716614395565b6001600160a01b0391827f00000000000000000000000000000000000000000000000000000000000000001661374e81301415614644565b6137d682847f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc93613784888654169182146146b5565b61378d33615059565b6040517f21f743470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201529116602482015291829081906044820190565b0381887f0000000000000000000000000000000000000000000000000000000000000000165afa908115610b6f57600091613986575b50156105d8576040519361381f85614455565b600085527f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561385a575050506104469150614726565b83929316906040517f52d1902d0000000000000000000000000000000000000000000000000000000081528481600481865afa60009181613957575b50613905576084856040519062461bcd60e51b82526004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f7420555550530000000000000000000000000000000000006064820152fd5b939293036133355761391683614726565b604051907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a283511580159061394f5761329957005b506000613293565b9091508581813d831161397f575b61396f8183614471565b810103126105d857519087613896565b503d613965565b61399d9150833d8511610b6857610b5a8183614471565b8561380c565b346105d85760031960a0813601126105d8576139bd614395565b906139c66143ab565b9067ffffffffffffffff906044358281116105d8576139e990369060040161456b565b6064358381116105d857613a0190369060040161456b565b926084359081116105d857613a1a9036906004016144e7565b91336001600160a01b038716148015613cf4575b613a379061494a565b613a448251855114614aaa565b6001600160a01b03851692613a5a8415156149bb565b613a68818685898b336157a1565b60005b8351811015613b0c5780613a82613b079286614920565b51613a8d8289614920565b51908060005260976020918183528c6001600160a01b03604060002091166000528352838d60406000205490613ac583831015614a2c565b836000528486526001600160a01b0360406000209116600052855203604060002055600052815260406000209088600052526110866040600020918254614a9d565b613a6b565b509094939293846040516001600160a01b038916907f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb339180613b508a8a83614b1b565b0390a43b613b5a57005b60405194859384937fbc197c8100000000000000000000000000000000000000000000000000000000988986523360048701526001600160a01b031660248601526044850160a0905260a48501613bb091614586565b82858203016064860152613bc391614586565b90838203016084840152613bd6916143e4565b03815a602094600091f160009181613cd4575b50613c425750506001613bfa614b78565b6308c379a014613c0b575b61044857005b613c13614b96565b80613c1e5750613c05565b6104b39060405191829162461bcd60e51b83526020600484015260248301906143e4565b7fffffffff0000000000000000000000000000000000000000000000000000000016146104465760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608490fd5b613ced91925060203d81116105a8576105998183614471565b9083613be9565b506001600160a01b0386166000526098602052604060002033600052602052613a3760ff604060002054169050613a2e565b346105d85760406003193601126105d857613d42600435615ccf565b6001600160a01b036040613d8c613d6560243563ffffffff602087015116615189565b7f0000000000000000000000000000000000000000000000000000000000000000906155d1565b9201511661090460405192839283602090939291936001600160a01b0360408201951681520152565b346105d85760606003193601126105d857613dce614395565b6024356000526101fe6020526001600160a01b03604060002091166000526020526020604435600217604060002054161515604051908152f35b346105d85760406003193601126105d85767ffffffffffffffff6004356024358281116105d857613e3d9036906004016144e7565b91613e488233614f49565b81156105d85760405191807f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b60209485815280613e87878201896143e4565b0390a26000526101c68252604060002091835191821161081e57613eab8354614c59565b601f8111613f53575b5080601f8311600114613ef05750819293600092613ee5575b50506000198260011b9260031b1c1916179055600080f35b015190508380613ecd565b90601f198316948460005282600020926000905b878210613f3b575050836001959610613f22575b505050811b019055005b015160001960f88460031b161c19169055838080613f18565b80600185968294968601518155019501930190613f04565b8360005281600020601f840160051c810191838510613f8f575b601f0160051c01905b818110613f835750613eb4565b60008155600101613f76565b9091508190613f6d565b346105d85760006003193601126105d857602060405160088152f35b346105d85760206003193601126105d857613fce614395565b613fd733615059565b6001600160a01b03811660009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040902054600216156140205761044690615aa7565b60046040517f98ee9d38000000000000000000000000000000000000000000000000000000008152fd5b346105d85760006003193601126105d85760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b346105d85760206003193601126105d85761409e614395565b3360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040902054602216151580156140e7575b1561369d5761044690615b8d565b503360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf6508602052604090205460021615156140d9565b346105d85760206003193601126105d8576109046108f0600435615a10565b346105d85760006003193601126105d8576040516000610193805461416481614c59565b808552916001918083169081156141ea575060011461418e575b610904856108f081870382614471565b600090815292507ffc8af01f449989052b52093a58fc9f42d0b11f0c6dd5dca0463dab62346ccc685b8284106141d25750505081016020016108f08261090461417e565b805460208587018101919091529093019281016141b7565b869550610904969350602092506108f094915060ff191682840152151560051b820101929361417e565b346105d85760206003193601126105d8576004357fffffffff0000000000000000000000000000000000000000000000000000000081168091036105d857807f2a55205a0000000000000000000000000000000000000000000000000000000060209214908115614320575b8115614292575b506040519015158152f35b7fd9b67a26000000000000000000000000000000000000000000000000000000008114915081156142f6575b81156142cc575b5082614287565b7f01ffc9a700000000000000000000000000000000000000000000000000000000915014826142c5565b7f0e89341c00000000000000000000000000000000000000000000000000000000811491506142be565b7f2920ca160000000000000000000000000000000000000000000000000000000081149150614280565b346105d85760006003193601126105d857602060405160008152f35b346105d85760406003193601126105d857602061438d614384614395565b6024359061487a565b604051908152f35b600435906001600160a01b03821682036105d857565b602435906001600160a01b03821682036105d857565b60005b8381106143d45750506000910152565b81810151838201526020016143c4565b90601f19601f602093614402815180928187528780880191016143c1565b0116010190565b6040810190811067ffffffffffffffff82111761081e57604052565b6060810190811067ffffffffffffffff82111761081e57604052565b67ffffffffffffffff811161081e57604052565b6020810190811067ffffffffffffffff82111761081e57604052565b90601f601f19910116810190811067ffffffffffffffff82111761081e57604052565b67ffffffffffffffff811161081e57601f01601f191660200190565b9291926144bc82614494565b916144ca6040519384614471565b8294818452818301116105d8578281602093846000960137010152565b9080601f830112156105d857816020614502933591016144b0565b90565b67ffffffffffffffff811161081e5760051b60200190565b929161452882614505565b916145366040519384614471565b829481845260208094019160051b81019283116105d857905b82821061455c5750505050565b8135815290830190830161454f565b9080601f830112156105d8578160206145029335910161451d565b90815180825260208080930193019160005b8281106145a6575050505090565b835185529381019392810192600101614598565b60031960609101126105d857600435906024356001600160a01b03811681036105d8579060443590565b9181601f840112156105d85782359167ffffffffffffffff83116105d8576020808501948460051b0101116105d857565b6020815260606040614632845183602086015260808501906143e4565b93602081015182850152015191015290565b1561464b57565b608460405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152fd5b156146bc57565b608460405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152fd5b803b15614781576001600160a01b037f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc91167fffffffffffffffffffffffff0000000000000000000000000000000000000000825416179055565b608460405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152fd5b3d15614816573d906147fc82614494565b9161480a6040519384614471565b82523d6000602084013e565b606090565b6040519061482882614425565b602782527f206661696c6564000000000000000000000000000000000000000000000000006040837f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c60208201520152565b6001600160a01b03169081156148a757600052609760205260406000209060005260205260406000205490565b608460405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201527f616c6964206f776e6572000000000000000000000000000000000000000000006064820152fd5b60001981146128695760010190565b80518210156149345760209160051b010190565b634e487b7160e01b600052603260045260246000fd5b1561495157565b608460405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f7665640000000000000000000000000000000000006064820152fd5b156149c257565b608460405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152fd5b15614a3357565b608460405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201527f72207472616e73666572000000000000000000000000000000000000000000006064820152fd5b9190820180921161286957565b15614ab157565b608460405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060448201527f6d69736d617463680000000000000000000000000000000000000000000000006064820152fd5b9091614b3261450293604084526040840190614586565b916020818403910152614586565b908160209103126105d857517fffffffff00000000000000000000000000000000000000000000000000000000811681036105d85790565b60009060033d11614b8557565b905060046000803e60005160e01c90565b600060443d106145025760405160031991823d016004833e815167ffffffffffffffff918282113d602484011117614bf457818401948551938411614bfc573d85010160208487010111614bf4575061450292910160200190614471565b949350505050565b50949350505050565b60405190614c1282614409565b60018252602082016020368237825115614934575290565b909160609115614c3957505090565b614c44919392614c46565b565b805190925015613c1e5750805190602001fd5b90600182811c92168015614c89575b6020831014614c7357565b634e487b7160e01b600052602260045260246000fd5b91607f1691614c68565b9060405191826000825492614ca784614c59565b908184526001948581169081600014614d145750600114614cd1575b5050614c4492500383614471565b9093915060005260209081600020936000915b818310614cfc575050614c4493508201013880614cc3565b85548884018501529485019487945091830191614ce4565b9050614c4495506020935060ff1991501682840152151560051b8201013880614cc3565b15614d3f57565b608460405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152fd5b600260655414614dba576002606555565b606460405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b90815167ffffffffffffffff811161081e5761019390614e1e8254614c59565b601f8111614ee4575b50602080601f8311600114614e63575081929394600092614e58575b50506000198260011b9260031b1c1916179055565b015190503880614e43565b90601f19831695846000527ffc8af01f449989052b52093a58fc9f42d0b11f0c6dd5dca0463dab62346ccc68926000905b888210614ecc57505083600195969710614eb3575b505050811b019055565b015160001960f88460031b161c19169055388080614ea9565b80600185968294968601518155019501930190614e94565b60008381527ffc8af01f449989052b52093a58fc9f42d0b11f0c6dd5dca0463dab62346ccc68601f840160051c81019260208510614f3f575b601f0160051c01915b828110614f34575050614e27565b818155600101614f26565b9092508290614f1d565b9060008181526101fe90816020526001600160a01b036040822094169384825260205260126040822054161591821592614fae575b505015614f89575050565b6064925060405191634baa2a4d60e01b83526004830152602482015260106044820152fd5b600292509060409181805260205281812085825260205220541615153880614f7e565b9060008181526101fe90816020526001600160a01b036040822094169384825260205260066040822054161591821592615036575b505015615011575050565b6064925060405191634baa2a4d60e01b83526004830152602482015260046044820152fd5b600292509060409181805260205281812085825260205220541615153880615006565b6001600160a01b031660008181527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040812054600216158015906101fe906150cf575b50156150aa575050565b6064925060405191634baa2a4d60e01b83526004830152602482015260026044820152fd5b90508180526020526040812082825260205260026040822054161515386150a0565b9060008181526101fe90816020526001600160a01b036040822094169384825260205260026040822054161591821592615131575b5050156150aa575050565b600292509060409181805260205281812085825260205220541615153880615126565b9092919261516181614494565b9161516f6040519384614471565b8294828452828201116105d8576020614c449301906143c1565b8181029291811591840414171561286957565b600311156151a657565b634e487b7160e01b600052602160045260246000fd5b51906001600160a01b03821682036105d857565b908160209103126105d8575180151581036105d85790565b90929161521861521d9382866151ff8383836155db565b9561521361520d8885614a9d565b8361553d565b6152af565b614a9d565b906000526101c660205261523a6002604060002001918254614a9d565b9055565b1561524557565b608460405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152fd5b9291906001600160a01b0384166152c781151561523e565b6152e5846152d484614c05565b6152dd86614c05565b9088336156d6565b60009282845260209460978652604096878620848752875287862061530b848254614a9d565b905583868951878152858a8201527fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628b3392a43b61534d575b50505050505050565b6153a89286928689518096819582947ff23a6e61000000000000000000000000000000000000000000000000000000009a8b85523360048601528560248601526044850152606484015260a0608484015260a48301906143e4565b03925af183918161551e575b506154845750506001916153c6614b78565b6308c379a01461544e575b50506153e557505b38808080808080615344565b5162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560448201527f526563656976657220696d706c656d656e7465720000000000000000000000006064820152608490fd5b615456614b96565b918261546257506153d1565b846104b391505192839262461bcd60e51b8452600484015260248301906143e4565b7fffffffff00000000000000000000000000000000000000000000000000000000160391506154b5905057506153d9565b5162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608490fd5b615536919250853d87116105a8576105998183614471565b90386153b4565b90816000526101c660205260406000209060028201549060016155608284614a9d565b9301548093116155705750505050565b60849450604051937f1255c8fd0000000000000000000000000000000000000000000000000000000085526004850152602484015260448301526064820152fd5b81156155bb570690565b634e487b7160e01b600052601260045260246000fd5b81156155bb570490565b92919092600093818552610160948560205263ffffffff6040928184842054169182156156c6575b5081156156bc5761562d908584526101c660205261562783600287872001546155b1565b90614a9d565b60001982019182116156a85790615643916155d1565b9586615651575b5050505050565b8382526020526001600160a01b038083832054841c16928315615695575b5082161561568e5750615684929185916152af565b388080808061564a565b9450505050565b82805280832054901c811692503861566f565b602483634e487b7160e01b81526011600452fd5b5090955050505050565b8380528484205416915038615603565b9091926001600160a01b0394856101cb541692836156f75750505050505050565b833b156105d857615778879360009793612add6157658a966040519c8d9b8c9a8b997f80b10ace000000000000000000000000000000000000000000000000000000008b523060048c01521660248a01528960448a015216606488015260e0608488015260e4870190614586565b60031993848783030160a4880152614586565b03925af18015610b6f57615792575b808080808080615344565b61579b90614441565b38615787565b9490926001600160a01b0395866101cb541693846157c4575b5050505050505050565b843b156105d8576000968894612add6157658a9688615834966040519e8f9d8e9c8d9b7f80b10ace000000000000000000000000000000000000000000000000000000008d528c6004309101521660248c01521660448a015216606488015260e0608488015260e4870190614586565b03925af18015610b6f5761584f575b808080808080806157ba565b61585890614441565b38615843565b6020818303126105d85780519067ffffffffffffffff82116105d857019080601f830112156105d857815161450292602001615154565b6000805261012d6020527fa581b17bfc4d6578e300cafbf34fd2dc1fef0270d8c73f88a99dcde2859a6639546001600160a01b039081168015615940575b16806158e2575061450261594e565b6000600491604051928380927fe8a3d4850000000000000000000000000000000000000000000000000000000082525afa908115610b6f57600091615925575090565b614502913d8091833e6159388183614471565b81019061585e565b5080604060002054166158d3565b60008080526101c6908160205260409161596a83832054614c59565b615a00575080805261012d6020526001600160a01b03908082848220541680156159f4575b60248551809581937f0e89341c000000000000000000000000000000000000000000000000000000008352856004840152165afa9283156159ea575080926159d657505090565b61450292503d8091833e6159388183614471565b51903d90823e3d90fd5b5082848220541661598f565b8180526020522061450290614c93565b6000908082526101c680602052615a2a6040842054614c59565b615a945750816001600160a01b03615a4183615c9c565b16916024604051809481937f0e89341c00000000000000000000000000000000000000000000000000000000835260048301525afa918215615a885780926159d657505090565b604051903d90823e3d90fd5b9161450292604092825260205220614c93565b6101c980546001600160a01b039283167fffffffffffffffffffffffff0000000000000000000000000000000000000000821681179092556040805193909116835260208301919091527f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a160006040517f3be6d3a1d957610f7e900c66889b874cdc9f0c22901aa8be6ec3d2d04c14ca0f339180615b88819060c082019160a06101c9546001600160a01b03908181168452821c60208401526101ca548181166040850152821c60608401526101cb549081166080840152811c910152565b0390a3565b6001600160a01b036101ca91167fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905560016040517f3be6d3a1d957610f7e900c66889b874cdc9f0c22901aa8be6ec3d2d04c14ca0f339180615b88819060c082019160a06101c9546001600160a01b03908181168452821c60208401526101ca548181166040850152821c60608401526101cb549081166080840152811c910152565b6001600160a01b031660008181527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040812080546002179081905591907f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca8180a4565b60005261012d6020526001600160a01b03908160406000205416918215615cc05750565b60008080526040902054169150565b6040805191615cdd83614425565b600090818452818360209582878201520152815281610160918285526001600160a01b03928383832054841c16615d3f5781805285522092825193615d2185614425565b549063ffffffff808316865282821c1690850152821c169082015290565b502092825193615d2185614425565b615d5a90939293615ccf565b9263ffffffff9182855116908115615da957615d7a9291615627916155b1565b906000198185511601818111612869576001600160a01b0392604092615da19216906155d1565b930151169190565b505050509060406001600160a01b039101511690600090565b9190615dcd81614505565b90615ddb6040519283614471565b808252601f19615dea82614505565b0160005b818110615eb4575050819360005b828110615e095750505050565b8060051b8201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1833603018112156105d85782019081359167ffffffffffffffff83116105d85760208091019083360382136105d857600080615e75615e9494615eaf9736916144b0565b615e7d61481b565b9381519101305af4615e8d6147eb565b9030615ec5565b615e9e8287614920565b52615ea98186614920565b50614911565b615dfc565b806060602080938701015201615dee565b919260609115615f29575050815115615edc575090565b3b15615ee55790565b606460405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b909392614c449250614c4656fea2646970667358221220de8880bd438009fffedd6c53218c03ccd90634b7002c3ed1caacf008b91e928c64736f6c634300081100330000000000000000000000000000000000000000000000000002c2ad68fd9000000000000000000000000000d1d1d4e36117ab794ec5d4c78cbd3a8904e691d0000000000000000000000000784a410b891ee92612102521281a3e222a6e326d
Deployed Bytecode
0x6080604052600436101561001257600080fd5b60003560e01c8062fdd58e14614366578063011442011461434a57806301ffc9a71461421457806306fdde03146141405780630e89341c1461412157806310a7eb5d1461408557806313966db51461404a57806313af403514613fb557806318711c7d14613f9957806318e97fd114613e0857806323bd038614613db55780632a55205a14613d265780632eb2c2d6146139a3578063300ecdb91461359c5780633659cfe6146136fc5780633ccfd60b146135e65780634913162d1461359c5780634e1273f4146133eb5780634f1ef2861461304557806352d1902d14612f705780635d0f6cba14612ddc5780636661a9ba14612c1757806369a5b30214612be15780636b20c4541461287f578063731133e91461230957806375794a3c146122ea578063765b0c36146122a65780637f2dc61c1461211b5780637f77f574146120cb5780638621ea4b1461208c5780638a08eb4c14611a6f5780638c7a63ae146119f85780638da5cb5b146119d05780638ec998a01461194b578063929a71281461193057806395d89b41146118d25780639c5c63c914611826578063a0a8e460146117c8578063a22cb465146116d1578063a453eaf0146116b5578063ac9650d8146115fd578063afed7e9e146113cf578063bb3bafd614611378578063c04643561461135c578063c238d1ee14611300578063d1ad846b14610f23578063d258609a14610bc4578063d904b94a146109c9578063dd15e05f14610993578063e72878b414610937578063e74d86c214610908578063e8a3d485146108d4578063e985e9c51461087d578063ef71c82e146105f9578063f1b0d6bb146105dd5763f242432a1461028357600080fd5b346105d85760a06003193601126105d85761029c614395565b6102a46143ab565b9060643560443560843567ffffffffffffffff81116105d8576102cb9036906004016144e7565b6001600160a01b0393610317828683169633881480156105af575b6102ef9061494a565b8816926102fd8415156149bb565b61030686614c05565b8961031089614c05565b92336157a1565b826000526020956097875260406000208660005287528460406000205461034082821015614a2c565b856000526097895260406000208860005289520360406000205583600052609787526040600020826000528752604060002061037d868254614a9d565b90558186604051868152878a8201527fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260403392a43b6103b957005b6104169360008794604051968795869485937ff23a6e61000000000000000000000000000000000000000000000000000000009b8c865233600487015260248601526044850152606484015260a0608484015260a48301906143e4565b03925af160009181610580575b506104ec575050600190610435614b78565b6308c379a0146104b7575b50610448575b005b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560448201527f526563656976657220696d706c656d656e7465720000000000000000000000006064820152608490fd5b0390fd5b6104bf614b96565b90816104cb5750610440565b6104b360405192839262461bcd60e51b8452600484015260248301906143e4565b7fffffffff00000000000000000000000000000000000000000000000000000000161490506104465760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608490fd5b6105a1919250843d86116105a8575b6105998183614471565b810190614b40565b9038610423565b503d61058f565b508760005260986020526040600020336000526020526102ef60ff6040600020541690506102e6565b600080fd5b346105d85760006003193601126105d857602060405160048152f35b346105d85760406003193601126105d85767ffffffffffffffff6004358181116105d85761062b9036906004016144e7565b6024358281116105d8576106439036906004016144e7565b3360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf6508602090815260409091205491939091601216158015906101fe90610859575b501561083457600080526101c68252604060002090835190811161081e576106b18254614c59565b601f81116107d8575b5082601f821160011461074b57927f74b7c2afa3f89c562b59674a101e2c48bceeb27cdb620afefa14446f1ffa487b94928261073b9361072c96600091610740575b506000198260011b9260031b1c19161790555b61071886614dfe565b6040519384936040855260408501906143e4565b908382039084015233956143e4565b0390a2005b9050850151896106fc565b601f1982169083600052846000209160005b8181106107c157508361072c96937f74b7c2afa3f89c562b59674a101e2c48bceeb27cdb620afefa14446f1ffa487b98969361073b96600194106107a8575b5050811b01905561070f565b87015160001960f88460031b161c19169055898061079c565b91928660018192868b01518155019401920161075d565b8260005283600020601f830160051c810191858410610814575b601f0160051c01905b81811061080857506106ba565b600081556001016107fb565b90915081906107f2565b634e487b7160e01b600052604160045260246000fd5b6064604051634baa2a4d60e01b81523360048201526000602482015260106044820152fd5b90506000805282526040600020336000528252600260406000205416151585610689565b346105d85760406003193601126105d857610896614395565b61089e6143ab565b906001600160a01b03809116600052609860205260406000209116600052602052602060ff604060002054166040519015158152f35b346105d85760006003193601126105d8576109046108f0615895565b6040519182916020835260208301906143e4565b0390f35b346105d85760206003193601126105d8576020610926600435615c9c565b6001600160a01b0360405191168152f35b346105d85760206003193601126105d8576004356000196101c854019080820361095d57005b604491604051917f4fa09b3f00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b346105d85760206003193601126105d85760043560005261012d60205260206001600160a01b0360406000205416604051908152f35b346105d85760606003193601126105d8576004356109e56143ab565b9060443567ffffffffffffffff81116105d857610a069036906004016144e7565b90806000526101fe926020938085526040600020336000528552600a604060002054161590811591610ba0575b5015610b7b576001600160a01b03610a4d91169182614fd1565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f6890e5b30000000000000000000000000000000000000000000000000000000060048201528381602481855afa908115610b6f57600091610b42575b5015610b1157816000929183858194519301915af190610ace6147eb565b9115610ad657005b6104b36040519283927fa5fa8d2b000000000000000000000000000000000000000000000000000000008452600484015260248301906143e4565b602490604051907fe15b8e060000000000000000000000000000000000000000000000000000000082526004820152fd5b610b629150843d8611610b68575b610b5a8183614471565b8101906151d0565b84610ab0565b503d610b50565b6040513d6000823e3d90fd5b60648260405190634baa2a4d60e01b8252336004830152602482015260086044820152fd5b90506000805284526040600020336000528452600260406000205416151585610a33565b346105d85760406003193601126105d85767ffffffffffffffff6004358181116105d857610bf69036906004016144e7565b3360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf6508602052604090205460061615801590610ee9575b15610ec457610c3e614da9565b6101c89081549160018301905560405192610c5884614425565b818452602435602085015260006040850152826000526101c66020526040600020908451805191821161081e57610c8f8354614c59565b601f8111610e7c575b50916020959185938790601f8311600114610e11576000919083610e06575b50506000198260011b9260031b1c19161781555b858201516001820155600260408301519101557f5086d1bcea28999da9875111e3592688fbfa821db63214c695ca35768080c2fe60405180610d0e339482614615565b0390a3816000526101fe83526040600020336000528352600260406000205417826000526101fe845260406000203360005284528060406000205533837f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca600080a48051610dc9575b817f1b944478023872bf91b25a13fdba3a686fdb1bf4dbb872f850240fad4b8cc068610dae604051936040855260408501906143e4565b92602435868201528033940390a36001606555604051908152f35b817f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b60405185815280610dfe878201866143e4565b0390a2610d77565b015190508880610cb7565b9083600052886000209160005b601f1985168110610e6257509083929183601f196001961610610e49575b505050811b018155610ccb565b015160001960f88460031b161c19169055888080610e3c565b818301518455899750600190930192918a01918a01610e1e565b836000526020600020601f840160051c81019160208510610eba575b601f0160051c01905b818110610eae5750610c98565b60008155600101610ea1565b9091508190610e98565b6064604051634baa2a4d60e01b81523360048201526000602482015260046044820152fd5b503360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf650860205260409020546002161515610c31565b346105d8576003196080813601126105d857610f3d614395565b67ffffffffffffffff916024358381116105d857610f5f90369060040161456b565b906044358481116105d857610f7890369060040161456b565b936064359081116105d857610f919036906004016144e7565b92610f9a614da9565b3360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020908152604082205460061615969093915b855181101561100957610feb9088610ff057614911565b610fd4565b611004610ffd8289614920565b5133614fd1565b614911565b50908491866001600160a01b0385169261102484151561523e565b6110318551845114614aaa565b61103e82848789336156d6565b60005b8551811015611092578061105861108d9286614920565b516110638289614920565b5160005260978a526040600020876000528a526110866040600020918254614a9d565b9055614911565b611041565b5091929095948160006040517f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb3391806110cd8a8c83614b1b565b0390a43b61116f575b505060005b8251811015611168578061113d61110b876110f96111639588614920565b516111048588614920565b51906155db565b6111336111188488614920565b5161112d83611127878a614920565b51614a9d565b9061553d565b6111278386614920565b6111478286614920565b516000526101c686526110866002604060002001918254614a9d565b6110db565b6001606555005b846040518092816000816111e57fbc197c81000000000000000000000000000000000000000000000000000000009889835233600484015283602484015260a060448401526111d56111c58d60a4860190614586565b828582030160648601528c614586565b908382030160848401528d6143e4565b03925af1600091816112e1575b5061124f5750506001611203614b78565b6308c379a01461121a575b610448575b84806110d6565b611222614b96565b8061122d575061120e565b846104b360405192839262461bcd60e51b8452600484015260248301906143e4565b7fffffffff0000000000000000000000000000000000000000000000000000000016146112135760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608490fd5b6112f9919250863d88116105a8576105998183614471565b90876111f2565b346105d85760806003193601126105d857611319614395565b6024356064359167ffffffffffffffff83116105d8576113406111689336906004016144e7565b91611349614da9565b6113538133614fd1565b604435916151e8565b346105d85760006003193601126105d857602060405160028152f35b346105d85760206003193601126105d857610904611397600435615ccf565b6040519182918291909160406001600160a01b0381606084019563ffffffff8082511686526020820151166020860152015116910152565b346105d85760806003193601126105d85760043560607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc3601126105d8576040519061141a82614425565b63ffffffff60243581811681036105d857835260443581811681036105d8576020808501918252606435906001600160a01b0380831683036105d85760408701928352856000526101fe808352604060002033600052835260226040600020541615908115916115d9575b50156115b5576001858851161461157357825116158061159d575b611573578460005261016081527fffffffff000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffff000000000000000067ffffffff000000006040600020968951169387549651901b16935160401b16931617171790557f5837d55897cfc337f160a71d7b63a047abd50a3a8834f1c5d70f338846358c6d6040518061156e33958291909160406001600160a01b0381606084019563ffffffff8082511686526020820151166020860152015116910152565b0390a3005b60046040517f0d9b92f1000000000000000000000000000000000000000000000000000000008152fd5b50855184161515806114a057508383511615156114a0565b6064868360405191634baa2a4d60e01b835233600484015260248301526044820152fd5b90506000805282526040600020336000528252600260406000205416151588611485565b346105d8576020806003193601126105d85760043567ffffffffffffffff81116105d8576116326116389136906004016145e4565b90615dc2565b6040519082820192808352815180945260408301938160408260051b8601019301916000955b82871061166b5785850386f35b9091929382806116a5837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08a6001960301865288516143e4565b960192019601959291909261165e565b346105d85760006003193601126105d857602060405160108152f35b346105d85760406003193601126105d8576116ea614395565b602435908115158092036105d8576001600160a01b03169081331461175e57336000526098602052604060002082600052602052604060002060ff1981541660ff83161790556040519081527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a3005b608460405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c6600000000000000000000000000000000000000000000006064820152fd5b346105d85760006003193601126105d8576109046040516117e881614409565b600581527f312e312e3000000000000000000000000000000000000000000000000000000060208201526040519182916020835260208301906143e4565b346105d85760406003193601126105d85760043560243567ffffffffffffffff81116105d8576000916001600160a01b03611879611869859436906004016144e7565b926118748133614f49565b615c9c565b1682602083519301915af161188c6147eb565b901561189457005b6104b3906040519182917fa5fa8d2b0000000000000000000000000000000000000000000000000000000083526020600484015260248301906143e4565b346105d85760006003193601126105d85760405160208082528160605191828183015260005b83811061191a575050601f19601f836000604080968601015201168101030190f35b60808101518582016040015284925081016118f8565b346105d85760006003193601126105d8576020604051818152f35b346105d857611959366145ba565b9161196481336150f1565b806000526101fe92836020526001600160a01b03604060002093169283600052602052604060002054179281600052602052604060002082600052602052826040600020557f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca600080a4005b346105d85760006003193601126105d85760206001600160a01b036101c95416604051908152f35b346105d85760206003193601126105d857600060408051611a1881614425565b6060815282602082015201526004356000526101c66020526109046040600020600260405191611a4783614425565b611a5081614c93565b8352600181015460208401520154604082015260405191829182614615565b346105d85760e06003193601126105d85760043567ffffffffffffffff81116105d857611aa09036906004016144e7565b60243567ffffffffffffffff81116105d857611ac09036906004016144e7565b9060607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc3601126105d857604051611af781614425565b60443563ffffffff811681036105d857815260643563ffffffff811681036105d85760208201526084356001600160a01b03811681036105d85760408201526001600160a01b0360a4351660a435036105d85760c43567ffffffffffffffff81116105d857611b6a9036906004016145e4565b919092611b75614da9565b6000549460ff8660081c16159586809761207f575b8015612068575b15611ffe5786600160ff19831617600055611fcf575b50611bcb60ff60005460081c16611bbd81614d38565b611bc681614d38565b614d38565b6001606555611be46001600160a01b0360a43516615c35565b6101c89081549160018301905560405190611bfe82614425565b81526000602082015260006040820152816000526101c66020526040600020815180519067ffffffffffffffff821161081e578190611c3d8454614c59565b601f8111611f7f575b50602090601f8311600114611f1357600092611f08575b50506000198260011b9260031b1c19161781555b60208201516001820155600260408301519101557f5086d1bcea28999da9875111e3592688fbfa821db63214c695ca35768080c2fe60405180611cb5339482614615565b0390a3600163ffffffff83511614611573576001600160a01b036040830151161580611ee5575b61157357611de49160008052610160602052604060002063ffffffff82511681549067ffffffff00000000602085015160201b16907fffffffff000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffff0000000000000000604087015160401b169316171717905560007f5837d55897cfc337f160a71d7b63a047abd50a3a8834f1c5d70f338846358c6d60405180611dbd33958291909160406001600160a01b0381606084019563ffffffff8082511686526020820151166020860152015116910152565b0390a3611dd46001600160a01b0360a43516615aa7565b611ddf60a435615b8d565b614dfe565b80611e4f575b5050611df7576001606555005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff600054166000557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160018152a1611168565b611e6191611e5c33615c35565b615dc2565b503360008181527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040812080547ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd169081905591907f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca8180a48180611dea565b50815163ffffffff16151580611cdc575063ffffffff6020830151161515611cdc565b015190508a80611c5d565b9250836000526020600020906000935b601f1984168510611f64576001945083601f19811610611f4b575b505050811b018155611c71565b015160001960f88460031b161c191690558a8080611f3e565b81810151835560209485019460019093019290910190611f23565b909150836000526020600020601f840160051c810160208510611fc8575b90849392915b601f830160051c82018110611fb9575050611c46565b60008155859450600101611fa3565b5080611f9d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011760005586611ba7565b608460405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152fd5b50303b158015611b915750600160ff821614611b91565b50600160ff821610611b8a565b346105d85760606003193601126105d8576120ae604435602435600435615d4e565b604080516001600160a01b03939093168352602083019190915290f35b346105d85760206003193601126105d85760043560005261016060205260606040600020546001600160a01b036040519163ffffffff80821684528160201c16602084015260401c166040820152f35b346105d85760206003193601126105d8576004356001600160a01b0381168091036105d85761214933615059565b806121ee575b6101cb907fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905560026040517f3be6d3a1d957610f7e900c66889b874cdc9f0c22901aa8be6ec3d2d04c14ca0f33918061156e819060c082019160a06101c9546001600160a01b03908181168452821c60208401526101ca548181166040850152821c60608401526101cb549081166080840152811c910152565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f80b10ace000000000000000000000000000000000000000000000000000000006004820152602081602481855afa908115610b6f57600091612288575b5061214f57602490604051907f17ce95600000000000000000000000000000000000000000000000000000000082526004820152fd5b6122a0915060203d8111610b6857610b5a8183614471565b82612252565b346105d85760006003193601126105d85760206040516001600160a01b037f000000000000000000000000d1d1d4e36117ab794ec5d4c78cbd3a8904e691d0168152f35b346105d85760006003193601126105d85760206101c854604051908152f35b60806003193601126105d85761231d614395565b604435906064359067ffffffffffffffff82116105d857366023830112156105d857816004013567ffffffffffffffff81116105d85736602482850101116105d857612367614da9565b61237c6024356001600160a01b038416614fd1565b34927f000000000000000000000000d1d1d4e36117ab794ec5d4c78cbd3a8904e691d06001600160a01b0381166127ce575b50602460c4600092601f19601f8660405197889687957f6890e5b30000000000000000000000000000000000000000000000000000000087523060048801528135828801528d60448801528c606488015260a060848801528260a488015201868601378685828601015201168101030181836001600160a01b0387165af1908115610b6f57600091612637575b50519060005b82518110156125ee576124548184614920565b515161245f8161519c565b6124688161519c565b6001810361252c575060208061247e8386614920565b510151906040828051810103126105d85761249c60409183016151bc565b910151908186116125025760008080936001600160a01b038294166204baf0f16124c46147eb565b50156124d8576124d390614911565b612441565b60046040517fe373ab5c000000000000000000000000000000000000000000000000000000008152fd5b60046040517f644f3cdc000000000000000000000000000000000000000000000000000000008152fd5b8061253860029261519c565b036125e5576020908161254b8286614920565b51015160609283828051810103126105d8576125689082016151bc565b92604082015191015190602435151590816125d8575b506125ae576124d392611004916040519161259883614455565b600083526001600160a01b0360243591166151e8565b60046040517f4cdcfbf9000000000000000000000000000000000000000000000000000000008152fd5b905060243514158861257e565b6124d390614911565b50836040519081523460208201526001600160a01b036024359216907fb362243af1e2070d7d5bf8d713f2e0fab64203f1b71462afbe20572909788c5e60403392a46001606555005b3d9150816000823e6126498282614471565b60208183810103126105d85780519067ffffffffffffffff82116105d857604082820184830103126105d8576040519261268284614409565b828201519067ffffffffffffffff82116105d857808301601f83868601010112156105d8578184840101516126b681614505565b926126c46040519485614471565b818452602084019083860160208460051b838a8a01010101116105d8576020818888010101915b60208460051b838a8a0101010183106127185750505050509060209291845201015160208201528461243b565b82519067ffffffffffffffff82116105d8576040601f1983858c8c010101888b010301126105d8576040519161274d83614409565b602081858c8c010101015160038110156105d8578352604081858c8c01010101519167ffffffffffffffff83116105d857878a018b8b01860183018401603f0112156105d8576020936127bd8c8c6040889788978b8f8501958a848484848a010101010151950101010101615154565b8382015281520193019290506126eb565b936127f9867f0000000000000000000000000000000000000000000000000002c2ad68fd9000615189565b908181039081116128695794600080808085856201adb0f16128196147eb565b501561282557506123ae565b6040517f4b789d360000000000000000000000000000000000000000000000000000000081526001600160a01b039190911660048201526024810191909152604490fd5b634e487b7160e01b600052601160045260246000fd5b346105d8576003196060813601126105d857612899614395565b60249167ffffffffffffffff83358181116105d8576128bc9036906004016145e4565b60449491949283359081116105d8576128d99036906004016145e4565b956001600160a01b0392838516943386141580612bbc575b612b7a575061290e929161290691369161451d565b96369161451d565b938215612b11576129228651865114614aaa565b6040519161292f83614455565b600083526101cb54169182612a60575b50505060005b8451811015612a1b576129588186614920565b516129638286614920565b51908060005260976020908082526040600020866000528252604060002054928484106129b457906129af95949392916000528152604060002090866000525203604060002055614911565b612945565b6084837f455243313135353a206275726e20616d6f756e7420657863656564732062616c8a8e6040519362461bcd60e51b85526004850152808401528201527f616e6365000000000000000000000000000000000000000000000000000000006064820152fd5b600082867f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb612a5288604051918291339583614b1b565b0390a4610446604051614455565b823b156105d85786928560008a612aec82968996612add8d612acd6040519c8d9b8c9a8b997f80b10ace000000000000000000000000000000000000000000000000000000008b523060048c015233908b015289015288606489015260e0608489015260e4880190614586565b90848783030160a4880152614586565b918483030160c48501526143e4565b03925af18015610b6f57612b02575b808061293f565b612b0b90614441565b85612afb565b6084877f455243313135353a206275726e2066726f6d20746865207a65726f20616464728660236040519362461bcd60e51b8552602060048601528401528201527f65737300000000000000000000000000000000000000000000000000000000006064820152fd5b6040517f839c23f20000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b03919091166024820152604490fd5b5085600052609860205260406000203360005260205260ff60406000205416156128f1565b346105d85760206003193601126105d8576004356000526101c760205260206001600160a01b0360406000205416604051908152f35b346105d85760406003193601126105d8576004356024356001600160a01b0381168091036105d857612c47614da9565b612c518233614f49565b8160005260209061012d82526040600020817fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905580612d26575b6040513382857f5010f780a0de79bcfb9f3d6fec3cfe29758ef5c5800d575af709bc590bd78ade600080a483612cf257507f56e810c8cae84731149f628981d25769a084570b9ba6eebf3c32879e3dce56099250604051908152a16001606555005b604091506000837f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b948352820152a2611168565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f7bc7e6460000000000000000000000000000000000000000000000000000000060048201528281602481855afa908115610b6f57600091612dbf575b50612c9057602490604051907fda755beb0000000000000000000000000000000000000000000000000000000082526004820152fd5b612dd69150833d8511610b6857610b5a8183614471565b84612d89565b346105d857612dea366145ba565b612df6839293336150f1565b60008281526101fe602081815260408084206001600160a01b039788168086529083529084208054951990951694859055909491939092839083907f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca9080a4159182612f61575b82612f3c575b5050612e6b57005b7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09160006040926101c9928354937fffffffffffffffffffffffff000000000000000000000000000000000000000085169055845193168352820152a160006040517f3be6d3a1d957610f7e900c66889b874cdc9f0c22901aa8be6ec3d2d04c14ca0f33918061156e819060c082019160a06101c9546001600160a01b03908181168452821c60208401526101ca548181166040850152821c60608401526101cb549081166080840152811c910152565b9091506000805282526040600020906000528152600260406000205416158380612e63565b6101c954851682149250612e5d565b346105d85760006003193601126105d8576001600160a01b037f0000000000000000000000004482c5929618b848a46e3da830a3d71085a5de07163003612fdb5760206040517f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8152f35b608460405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152fd5b60406003193601126105d857613059614395565b60243567ffffffffffffffff81116105d8576130799036906004016144e7565b90806001600160a01b03807f0000000000000000000000004482c5929618b848a46e3da830a3d71085a5de0716906130b382301415614644565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc916130e4828454169182146146b5565b6130ed33615059565b6040517f21f743470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201529316602484015260209283816044817f000000000000000000000000784a410b891ee92612102521281a3e222a6e326d86165afa908115610b6f576000916133ce575b50156105d8577f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156131a3575050506104469150614726565b83929316906040517f52d1902d0000000000000000000000000000000000000000000000000000000081528481600481865afa6000918161339f575b5061324e576084856040519062461bcd60e51b82526004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f7420555550530000000000000000000000000000000000006064820152fd5b939293036133355761325f83614726565b604051907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a283511580159061332d575b61329957005b823b156132c7575082600092839261044695519201905af46132b96147eb565b6132c161481b565b91614c2a565b60849162461bcd60e51b82526004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e747261637400000000000000000000000000000000000000000000000000006064820152fd5b506001613293565b6084826040519062461bcd60e51b82526004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c655555494400000000000000000000000000000000000000000000006064820152fd5b9091508581813d83116133c7575b6133b78183614471565b810103126105d8575190876131df565b503d6133ad565b6133e59150843d8611610b6857610b5a8183614471565b86613166565b346105d85760406003193601126105d85760043567ffffffffffffffff8082116105d857366023830112156105d85781600401359061342982614505565b926134376040519485614471565b82845260209260248486019160051b830101913683116105d857602401905b82821061357d575050506024359081116105d85761347890369060040161456b565b825181510361351357825192601f196134a961349386614505565b956134a16040519788614471565b808752614505565b01368486013760005b81518110156134fc57806134e76001600160a01b036134d46134f79486614920565b51166134e08387614920565b519061487a565b6134f18288614920565b52614911565b6134b2565b505050610904604051928284938452830190614586565b6084826040519062461bcd60e51b82526004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d6174636800000000000000000000000000000000000000000000006064820152fd5b81356001600160a01b03811681036105d8578152908401908401613456565b346105d85760406003193601126105d8576135b56143ab565b6004356000526101fe6020526001600160a01b03604060002091166000526020526020604060002054604051908152f35b346105d85760006003193601126105d8573360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040902054602216151580156136c2575b1561369d57476001600160a01b03906101ca91600080808085858854166204baf0f161365c6147eb565b501561366457005b604492541690604051917fa489930c00000000000000000000000000000000000000000000000000000000835260048301526024820152fd5b6064604051634baa2a4d60e01b81523360048201526000602482015260206044820152fd5b503360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf650860205260409020546002161515613632565b346105d8576020806003193601126105d857613716614395565b6001600160a01b0391827f0000000000000000000000004482c5929618b848a46e3da830a3d71085a5de071661374e81301415614644565b6137d682847f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc93613784888654169182146146b5565b61378d33615059565b6040517f21f743470000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201529116602482015291829081906044820190565b0381887f000000000000000000000000784a410b891ee92612102521281a3e222a6e326d165afa908115610b6f57600091613986575b50156105d8576040519361381f85614455565b600085527f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561385a575050506104469150614726565b83929316906040517f52d1902d0000000000000000000000000000000000000000000000000000000081528481600481865afa60009181613957575b50613905576084856040519062461bcd60e51b82526004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f7420555550530000000000000000000000000000000000006064820152fd5b939293036133355761391683614726565b604051907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a283511580159061394f5761329957005b506000613293565b9091508581813d831161397f575b61396f8183614471565b810103126105d857519087613896565b503d613965565b61399d9150833d8511610b6857610b5a8183614471565b8561380c565b346105d85760031960a0813601126105d8576139bd614395565b906139c66143ab565b9067ffffffffffffffff906044358281116105d8576139e990369060040161456b565b6064358381116105d857613a0190369060040161456b565b926084359081116105d857613a1a9036906004016144e7565b91336001600160a01b038716148015613cf4575b613a379061494a565b613a448251855114614aaa565b6001600160a01b03851692613a5a8415156149bb565b613a68818685898b336157a1565b60005b8351811015613b0c5780613a82613b079286614920565b51613a8d8289614920565b51908060005260976020918183528c6001600160a01b03604060002091166000528352838d60406000205490613ac583831015614a2c565b836000528486526001600160a01b0360406000209116600052855203604060002055600052815260406000209088600052526110866040600020918254614a9d565b613a6b565b509094939293846040516001600160a01b038916907f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb339180613b508a8a83614b1b565b0390a43b613b5a57005b60405194859384937fbc197c8100000000000000000000000000000000000000000000000000000000988986523360048701526001600160a01b031660248601526044850160a0905260a48501613bb091614586565b82858203016064860152613bc391614586565b90838203016084840152613bd6916143e4565b03815a602094600091f160009181613cd4575b50613c425750506001613bfa614b78565b6308c379a014613c0b575b61044857005b613c13614b96565b80613c1e5750613c05565b6104b39060405191829162461bcd60e51b83526020600484015260248301906143e4565b7fffffffff0000000000000000000000000000000000000000000000000000000016146104465760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608490fd5b613ced91925060203d81116105a8576105998183614471565b9083613be9565b506001600160a01b0386166000526098602052604060002033600052602052613a3760ff604060002054169050613a2e565b346105d85760406003193601126105d857613d42600435615ccf565b6001600160a01b036040613d8c613d6560243563ffffffff602087015116615189565b7f0000000000000000000000000000000000000000000000000000000000002710906155d1565b9201511661090460405192839283602090939291936001600160a01b0360408201951681520152565b346105d85760606003193601126105d857613dce614395565b6024356000526101fe6020526001600160a01b03604060002091166000526020526020604435600217604060002054161515604051908152f35b346105d85760406003193601126105d85767ffffffffffffffff6004356024358281116105d857613e3d9036906004016144e7565b91613e488233614f49565b81156105d85760405191807f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b60209485815280613e87878201896143e4565b0390a26000526101c68252604060002091835191821161081e57613eab8354614c59565b601f8111613f53575b5080601f8311600114613ef05750819293600092613ee5575b50506000198260011b9260031b1c1916179055600080f35b015190508380613ecd565b90601f198316948460005282600020926000905b878210613f3b575050836001959610613f22575b505050811b019055005b015160001960f88460031b161c19169055838080613f18565b80600185968294968601518155019501930190613f04565b8360005281600020601f840160051c810191838510613f8f575b601f0160051c01905b818110613f835750613eb4565b60008155600101613f76565b9091508190613f6d565b346105d85760006003193601126105d857602060405160088152f35b346105d85760206003193601126105d857613fce614395565b613fd733615059565b6001600160a01b03811660009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040902054600216156140205761044690615aa7565b60046040517f98ee9d38000000000000000000000000000000000000000000000000000000008152fd5b346105d85760006003193601126105d85760206040517f0000000000000000000000000000000000000000000000000002c2ad68fd90008152f35b346105d85760206003193601126105d85761409e614395565b3360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040902054602216151580156140e7575b1561369d5761044690615b8d565b503360009081527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf6508602052604090205460021615156140d9565b346105d85760206003193601126105d8576109046108f0600435615a10565b346105d85760006003193601126105d8576040516000610193805461416481614c59565b808552916001918083169081156141ea575060011461418e575b610904856108f081870382614471565b600090815292507ffc8af01f449989052b52093a58fc9f42d0b11f0c6dd5dca0463dab62346ccc685b8284106141d25750505081016020016108f08261090461417e565b805460208587018101919091529093019281016141b7565b869550610904969350602092506108f094915060ff191682840152151560051b820101929361417e565b346105d85760206003193601126105d8576004357fffffffff0000000000000000000000000000000000000000000000000000000081168091036105d857807f2a55205a0000000000000000000000000000000000000000000000000000000060209214908115614320575b8115614292575b506040519015158152f35b7fd9b67a26000000000000000000000000000000000000000000000000000000008114915081156142f6575b81156142cc575b5082614287565b7f01ffc9a700000000000000000000000000000000000000000000000000000000915014826142c5565b7f0e89341c00000000000000000000000000000000000000000000000000000000811491506142be565b7f2920ca160000000000000000000000000000000000000000000000000000000081149150614280565b346105d85760006003193601126105d857602060405160008152f35b346105d85760406003193601126105d857602061438d614384614395565b6024359061487a565b604051908152f35b600435906001600160a01b03821682036105d857565b602435906001600160a01b03821682036105d857565b60005b8381106143d45750506000910152565b81810151838201526020016143c4565b90601f19601f602093614402815180928187528780880191016143c1565b0116010190565b6040810190811067ffffffffffffffff82111761081e57604052565b6060810190811067ffffffffffffffff82111761081e57604052565b67ffffffffffffffff811161081e57604052565b6020810190811067ffffffffffffffff82111761081e57604052565b90601f601f19910116810190811067ffffffffffffffff82111761081e57604052565b67ffffffffffffffff811161081e57601f01601f191660200190565b9291926144bc82614494565b916144ca6040519384614471565b8294818452818301116105d8578281602093846000960137010152565b9080601f830112156105d857816020614502933591016144b0565b90565b67ffffffffffffffff811161081e5760051b60200190565b929161452882614505565b916145366040519384614471565b829481845260208094019160051b81019283116105d857905b82821061455c5750505050565b8135815290830190830161454f565b9080601f830112156105d8578160206145029335910161451d565b90815180825260208080930193019160005b8281106145a6575050505090565b835185529381019392810192600101614598565b60031960609101126105d857600435906024356001600160a01b03811681036105d8579060443590565b9181601f840112156105d85782359167ffffffffffffffff83116105d8576020808501948460051b0101116105d857565b6020815260606040614632845183602086015260808501906143e4565b93602081015182850152015191015290565b1561464b57565b608460405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152fd5b156146bc57565b608460405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152fd5b803b15614781576001600160a01b037f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc91167fffffffffffffffffffffffff0000000000000000000000000000000000000000825416179055565b608460405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152fd5b3d15614816573d906147fc82614494565b9161480a6040519384614471565b82523d6000602084013e565b606090565b6040519061482882614425565b602782527f206661696c6564000000000000000000000000000000000000000000000000006040837f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c60208201520152565b6001600160a01b03169081156148a757600052609760205260406000209060005260205260406000205490565b608460405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201527f616c6964206f776e6572000000000000000000000000000000000000000000006064820152fd5b60001981146128695760010190565b80518210156149345760209160051b010190565b634e487b7160e01b600052603260045260246000fd5b1561495157565b608460405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f7665640000000000000000000000000000000000006064820152fd5b156149c257565b608460405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152fd5b15614a3357565b608460405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201527f72207472616e73666572000000000000000000000000000000000000000000006064820152fd5b9190820180921161286957565b15614ab157565b608460405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060448201527f6d69736d617463680000000000000000000000000000000000000000000000006064820152fd5b9091614b3261450293604084526040840190614586565b916020818403910152614586565b908160209103126105d857517fffffffff00000000000000000000000000000000000000000000000000000000811681036105d85790565b60009060033d11614b8557565b905060046000803e60005160e01c90565b600060443d106145025760405160031991823d016004833e815167ffffffffffffffff918282113d602484011117614bf457818401948551938411614bfc573d85010160208487010111614bf4575061450292910160200190614471565b949350505050565b50949350505050565b60405190614c1282614409565b60018252602082016020368237825115614934575290565b909160609115614c3957505090565b614c44919392614c46565b565b805190925015613c1e5750805190602001fd5b90600182811c92168015614c89575b6020831014614c7357565b634e487b7160e01b600052602260045260246000fd5b91607f1691614c68565b9060405191826000825492614ca784614c59565b908184526001948581169081600014614d145750600114614cd1575b5050614c4492500383614471565b9093915060005260209081600020936000915b818310614cfc575050614c4493508201013880614cc3565b85548884018501529485019487945091830191614ce4565b9050614c4495506020935060ff1991501682840152151560051b8201013880614cc3565b15614d3f57565b608460405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152fd5b600260655414614dba576002606555565b606460405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b90815167ffffffffffffffff811161081e5761019390614e1e8254614c59565b601f8111614ee4575b50602080601f8311600114614e63575081929394600092614e58575b50506000198260011b9260031b1c1916179055565b015190503880614e43565b90601f19831695846000527ffc8af01f449989052b52093a58fc9f42d0b11f0c6dd5dca0463dab62346ccc68926000905b888210614ecc57505083600195969710614eb3575b505050811b019055565b015160001960f88460031b161c19169055388080614ea9565b80600185968294968601518155019501930190614e94565b60008381527ffc8af01f449989052b52093a58fc9f42d0b11f0c6dd5dca0463dab62346ccc68601f840160051c81019260208510614f3f575b601f0160051c01915b828110614f34575050614e27565b818155600101614f26565b9092508290614f1d565b9060008181526101fe90816020526001600160a01b036040822094169384825260205260126040822054161591821592614fae575b505015614f89575050565b6064925060405191634baa2a4d60e01b83526004830152602482015260106044820152fd5b600292509060409181805260205281812085825260205220541615153880614f7e565b9060008181526101fe90816020526001600160a01b036040822094169384825260205260066040822054161591821592615036575b505015615011575050565b6064925060405191634baa2a4d60e01b83526004830152602482015260046044820152fd5b600292509060409181805260205281812085825260205220541615153880615006565b6001600160a01b031660008181527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040812054600216158015906101fe906150cf575b50156150aa575050565b6064925060405191634baa2a4d60e01b83526004830152602482015260026044820152fd5b90508180526020526040812082825260205260026040822054161515386150a0565b9060008181526101fe90816020526001600160a01b036040822094169384825260205260026040822054161591821592615131575b5050156150aa575050565b600292509060409181805260205281812085825260205220541615153880615126565b9092919261516181614494565b9161516f6040519384614471565b8294828452828201116105d8576020614c449301906143c1565b8181029291811591840414171561286957565b600311156151a657565b634e487b7160e01b600052602160045260246000fd5b51906001600160a01b03821682036105d857565b908160209103126105d8575180151581036105d85790565b90929161521861521d9382866151ff8383836155db565b9561521361520d8885614a9d565b8361553d565b6152af565b614a9d565b906000526101c660205261523a6002604060002001918254614a9d565b9055565b1561524557565b608460405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152fd5b9291906001600160a01b0384166152c781151561523e565b6152e5846152d484614c05565b6152dd86614c05565b9088336156d6565b60009282845260209460978652604096878620848752875287862061530b848254614a9d565b905583868951878152858a8201527fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628b3392a43b61534d575b50505050505050565b6153a89286928689518096819582947ff23a6e61000000000000000000000000000000000000000000000000000000009a8b85523360048601528560248601526044850152606484015260a0608484015260a48301906143e4565b03925af183918161551e575b506154845750506001916153c6614b78565b6308c379a01461544e575b50506153e557505b38808080808080615344565b5162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560448201527f526563656976657220696d706c656d656e7465720000000000000000000000006064820152608490fd5b615456614b96565b918261546257506153d1565b846104b391505192839262461bcd60e51b8452600484015260248301906143e4565b7fffffffff00000000000000000000000000000000000000000000000000000000160391506154b5905057506153d9565b5162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e730000000000000000000000000000000000000000000000006064820152608490fd5b615536919250853d87116105a8576105998183614471565b90386153b4565b90816000526101c660205260406000209060028201549060016155608284614a9d565b9301548093116155705750505050565b60849450604051937f1255c8fd0000000000000000000000000000000000000000000000000000000085526004850152602484015260448301526064820152fd5b81156155bb570690565b634e487b7160e01b600052601260045260246000fd5b81156155bb570490565b92919092600093818552610160948560205263ffffffff6040928184842054169182156156c6575b5081156156bc5761562d908584526101c660205261562783600287872001546155b1565b90614a9d565b60001982019182116156a85790615643916155d1565b9586615651575b5050505050565b8382526020526001600160a01b038083832054841c16928315615695575b5082161561568e5750615684929185916152af565b388080808061564a565b9450505050565b82805280832054901c811692503861566f565b602483634e487b7160e01b81526011600452fd5b5090955050505050565b8380528484205416915038615603565b9091926001600160a01b0394856101cb541692836156f75750505050505050565b833b156105d857615778879360009793612add6157658a966040519c8d9b8c9a8b997f80b10ace000000000000000000000000000000000000000000000000000000008b523060048c01521660248a01528960448a015216606488015260e0608488015260e4870190614586565b60031993848783030160a4880152614586565b03925af18015610b6f57615792575b808080808080615344565b61579b90614441565b38615787565b9490926001600160a01b0395866101cb541693846157c4575b5050505050505050565b843b156105d8576000968894612add6157658a9688615834966040519e8f9d8e9c8d9b7f80b10ace000000000000000000000000000000000000000000000000000000008d528c6004309101521660248c01521660448a015216606488015260e0608488015260e4870190614586565b03925af18015610b6f5761584f575b808080808080806157ba565b61585890614441565b38615843565b6020818303126105d85780519067ffffffffffffffff82116105d857019080601f830112156105d857815161450292602001615154565b6000805261012d6020527fa581b17bfc4d6578e300cafbf34fd2dc1fef0270d8c73f88a99dcde2859a6639546001600160a01b039081168015615940575b16806158e2575061450261594e565b6000600491604051928380927fe8a3d4850000000000000000000000000000000000000000000000000000000082525afa908115610b6f57600091615925575090565b614502913d8091833e6159388183614471565b81019061585e565b5080604060002054166158d3565b60008080526101c6908160205260409161596a83832054614c59565b615a00575080805261012d6020526001600160a01b03908082848220541680156159f4575b60248551809581937f0e89341c000000000000000000000000000000000000000000000000000000008352856004840152165afa9283156159ea575080926159d657505090565b61450292503d8091833e6159388183614471565b51903d90823e3d90fd5b5082848220541661598f565b8180526020522061450290614c93565b6000908082526101c680602052615a2a6040842054614c59565b615a945750816001600160a01b03615a4183615c9c565b16916024604051809481937f0e89341c00000000000000000000000000000000000000000000000000000000835260048301525afa918215615a885780926159d657505090565b604051903d90823e3d90fd5b9161450292604092825260205220614c93565b6101c980546001600160a01b039283167fffffffffffffffffffffffff0000000000000000000000000000000000000000821681179092556040805193909116835260208301919091527f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a160006040517f3be6d3a1d957610f7e900c66889b874cdc9f0c22901aa8be6ec3d2d04c14ca0f339180615b88819060c082019160a06101c9546001600160a01b03908181168452821c60208401526101ca548181166040850152821c60608401526101cb549081166080840152811c910152565b0390a3565b6001600160a01b036101ca91167fffffffffffffffffffffffff000000000000000000000000000000000000000082541617905560016040517f3be6d3a1d957610f7e900c66889b874cdc9f0c22901aa8be6ec3d2d04c14ca0f339180615b88819060c082019160a06101c9546001600160a01b03908181168452821c60208401526101ca548181166040850152821c60608401526101cb549081166080840152811c910152565b6001600160a01b031660008181527f5f4301e3e862ad13c0503d3de32ba4e2e40c90733d1da23c9df4d0addbcf65086020526040812080546002179081905591907f35fb03d0d293ef5b362761900725ce891f8f766b5a662cdd445372355448e7ca8180a4565b60005261012d6020526001600160a01b03908160406000205416918215615cc05750565b60008080526040902054169150565b6040805191615cdd83614425565b600090818452818360209582878201520152815281610160918285526001600160a01b03928383832054841c16615d3f5781805285522092825193615d2185614425565b549063ffffffff808316865282821c1690850152821c169082015290565b502092825193615d2185614425565b615d5a90939293615ccf565b9263ffffffff9182855116908115615da957615d7a9291615627916155b1565b906000198185511601818111612869576001600160a01b0392604092615da19216906155d1565b930151169190565b505050509060406001600160a01b039101511690600090565b9190615dcd81614505565b90615ddb6040519283614471565b808252601f19615dea82614505565b0160005b818110615eb4575050819360005b828110615e095750505050565b8060051b8201357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1833603018112156105d85782019081359167ffffffffffffffff83116105d85760208091019083360382136105d857600080615e75615e9494615eaf9736916144b0565b615e7d61481b565b9381519101305af4615e8d6147eb565b9030615ec5565b615e9e8287614920565b52615ea98186614920565b50614911565b615dfc565b806060602080938701015201615dee565b919260609115615f29575050815115615edc575090565b3b15615ee55790565b606460405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152fd5b909392614c449250614c4656fea2646970667358221220de8880bd438009fffedd6c53218c03ccd90634b7002c3ed1caacf008b91e928c64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000002c2ad68fd9000000000000000000000000000d1d1d4e36117ab794ec5d4c78cbd3a8904e691d0000000000000000000000000784a410b891ee92612102521281a3e222a6e326d
-----Decoded View---------------
Arg [0] : _mintFeeAmount (uint256): 777000000000000
Arg [1] : _mintFeeRecipient (address): 0xd1d1D4e36117aB794ec5d4c78cBD3a8904E691D0
Arg [2] : _factory (address): 0x784A410B891EE92612102521281a3e222a6E326D
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000002c2ad68fd9000
Arg [1] : 000000000000000000000000d1d1d4e36117ab794ec5d4c78cbd3a8904e691d0
Arg [2] : 000000000000000000000000784a410b891ee92612102521281a3e222a6e326d
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.