|
| 1 | +//SPDX-License-Identifier: MIT |
| 2 | + |
| 3 | +pragma solidity ^0.8.22; |
| 4 | + |
| 5 | +import {ERC1155MInitializableV1_0_2} from "./ERC1155MInitializableV1_0_2.sol"; |
| 6 | +import {ERC1155MStorage} from "./ERC1155MStorage.sol"; |
| 7 | +import {MintStageInfo1155} from "../../common/Structs.sol"; |
| 8 | +import {AuthorizedMinterControl} from "../../common/AuthorizedMinterControl.sol"; |
| 9 | +import {LAUNCHPAD_MINT_FEE_RECEIVER} from "../../utils/Constants.sol"; |
| 10 | +import {CreatorTokenBase} from "@limitbreak/creator-token-standards/src/utils/CreatorTokenBase.sol"; |
| 11 | +import {AutomaticValidatorTransferApproval} from |
| 12 | + "@limitbreak/creator-token-standards/src/utils/AutomaticValidatorTransferApproval.sol"; |
| 13 | +import {ICreatorToken} from "@limitbreak/creator-token-standards/src/interfaces/ICreatorToken.sol"; |
| 14 | +import {TOKEN_TYPE_ERC1155} from "@limitbreak/permit-c/Constants.sol"; |
| 15 | +import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; |
| 16 | +import {Context} from "@openzeppelin/contracts/utils/Context.sol"; |
| 17 | + |
| 18 | +/// @title ERC1155CMInitializableV1_0_2 |
| 19 | +/// @notice An initializable ERC1155 contract with multi-stage minting, royalties, authorized minters, and Creator Token functionality |
| 20 | +/// @dev Extends ERC1155MInitializableV1_0_2 with Creator Token functionality for use with upgradeable proxies |
| 21 | + |
| 22 | +contract ERC1155CMInitializableV1_0_2 is |
| 23 | + ERC1155MInitializableV1_0_2, |
| 24 | + CreatorTokenBase, |
| 25 | + AutomaticValidatorTransferApproval |
| 26 | +{ |
| 27 | + /*============================================================== |
| 28 | + = INITIALIZERS = |
| 29 | + ==============================================================*/ |
| 30 | + |
| 31 | + /// @dev Disables initializers for the implementation contract. |
| 32 | + constructor() { |
| 33 | + _disableInitializers(); |
| 34 | + } |
| 35 | + |
| 36 | + /// @notice Initializes the contract |
| 37 | + /// @param name_ The name of the token collection |
| 38 | + /// @param symbol_ The symbol of the token collection |
| 39 | + /// @param initialOwner The address of the initial owner |
| 40 | + /// @param mintFee The mint fee for the contract |
| 41 | + function initialize(string calldata name_, string calldata symbol_, address initialOwner, uint256 mintFee) |
| 42 | + external |
| 43 | + override |
| 44 | + initializer |
| 45 | + { |
| 46 | + if (initialOwner == address(0)) { |
| 47 | + revert InitialOwnerCannotBeZero(); |
| 48 | + } |
| 49 | + |
| 50 | + name = name_; |
| 51 | + symbol = symbol_; |
| 52 | + __ERC1155_init(""); |
| 53 | + _initializeOwner(initialOwner); |
| 54 | + _mintFee = mintFee; |
| 55 | + |
| 56 | + // Initialize CreatorTokenBase |
| 57 | + _emitDefaultTransferValidator(); |
| 58 | + _registerTokenType(getTransferValidator()); |
| 59 | + } |
| 60 | + |
| 61 | + /*============================================================== |
| 62 | + = META = |
| 63 | + ==============================================================*/ |
| 64 | + |
| 65 | + /// @notice Returns the contract name and version |
| 66 | + /// @return The contract name and version as strings |
| 67 | + function contractNameAndVersion() public pure virtual override returns (string memory, string memory) { |
| 68 | + return ("ERC1155CMInitializable", "1.0.2"); |
| 69 | + } |
| 70 | + |
| 71 | + /// @notice Returns the transfer validator selector used during transaction simulation. |
| 72 | + /// @dev Indicates whether the validation function is view-only. |
| 73 | + /// @return functionSignature Selector for `validateTransfer(address,address,address,uint256,uint256)` |
| 74 | + /// @return isViewFunction False because `validateTransfer` is not a view function |
| 75 | + function getTransferValidationFunction() external pure returns (bytes4 functionSignature, bool isViewFunction) { |
| 76 | + functionSignature = bytes4(keccak256("validateTransfer(address,address,address,uint256,uint256)")); |
| 77 | + isViewFunction = false; |
| 78 | + } |
| 79 | + |
| 80 | + function _tokenType() internal pure override returns (uint16) { |
| 81 | + return uint16(TOKEN_TYPE_ERC1155); |
| 82 | + } |
| 83 | + |
| 84 | + /// @notice Checks if the contract supports a given interface |
| 85 | + /// @param interfaceId The interface identifier |
| 86 | + /// @return True if the contract supports the interface, false otherwise |
| 87 | + function supportsInterface(bytes4 interfaceId) |
| 88 | + public |
| 89 | + view |
| 90 | + virtual |
| 91 | + override(ERC1155MInitializableV1_0_2) |
| 92 | + returns (bool) |
| 93 | + { |
| 94 | + return interfaceId == type(ICreatorToken).interfaceId || super.supportsInterface(interfaceId); |
| 95 | + } |
| 96 | + |
| 97 | + /// @notice Overrides behavior of isApprovedForAll such that if an operator is not explicitly approved |
| 98 | + /// @notice for all, the contract owner can optionally auto-approve the transfer validator for transfers. |
| 99 | + function isApprovedForAll(address owner, address operator) public view virtual override returns (bool isApproved) { |
| 100 | + isApproved = super.isApprovedForAll(owner, operator); |
| 101 | + |
| 102 | + if (!isApproved) { |
| 103 | + if (autoApproveTransfersFromValidator) { |
| 104 | + isApproved = operator == address(getTransferValidator()); |
| 105 | + } |
| 106 | + } |
| 107 | + } |
| 108 | + |
| 109 | + /// @dev Overrides the _afterTokenTransfer function to add Creator Token validation |
| 110 | + /// @param operator The address performing the transfer |
| 111 | + /// @param from The address transferring the tokens |
| 112 | + /// @param to The address receiving the tokens |
| 113 | + /// @param ids The IDs of the tokens being transferred |
| 114 | + /// @param amounts The quantities of the tokens being transferred |
| 115 | + /// @param data Additional data with no specified format |
| 116 | + function _afterTokenTransfer( |
| 117 | + address operator, |
| 118 | + address from, |
| 119 | + address to, |
| 120 | + uint256[] memory ids, |
| 121 | + uint256[] memory amounts, |
| 122 | + bytes memory data |
| 123 | + ) internal virtual override { |
| 124 | + super._afterTokenTransfer(operator, from, to, ids, amounts, data); |
| 125 | + |
| 126 | + // Add Creator Token validation for each token ID |
| 127 | + uint256 idsArrayLength = ids.length; |
| 128 | + for (uint256 i = 0; i < idsArrayLength;) { |
| 129 | + _validateAfterTransfer(from, to, ids[i], amounts[i]); |
| 130 | + |
| 131 | + unchecked { |
| 132 | + ++i; |
| 133 | + } |
| 134 | + } |
| 135 | + } |
| 136 | + |
| 137 | + /// @dev Overrides the _beforeTokenTransfer function to add Creator Token validation |
| 138 | + /// @param operator The address performing the transfer |
| 139 | + /// @param from The address transferring the tokens |
| 140 | + /// @param to The address receiving the tokens |
| 141 | + /// @param ids The IDs of the tokens being transferred |
| 142 | + /// @param amounts The quantities of the tokens being transferred |
| 143 | + /// @param data Additional data with no specified format |
| 144 | + function _beforeTokenTransfer( |
| 145 | + address operator, |
| 146 | + address from, |
| 147 | + address to, |
| 148 | + uint256[] memory ids, |
| 149 | + uint256[] memory amounts, |
| 150 | + bytes memory data |
| 151 | + ) internal virtual override { |
| 152 | + // Call ERC1155MInitializableV1_0_2 first for transferable check |
| 153 | + super._beforeTokenTransfer(operator, from, to, ids, amounts, data); |
| 154 | + |
| 155 | + // Then add Creator Token validation for each token ID |
| 156 | + uint256 idsArrayLength = ids.length; |
| 157 | + for (uint256 i = 0; i < idsArrayLength;) { |
| 158 | + _validateBeforeTransfer(from, to, ids[i], amounts[i]); |
| 159 | + |
| 160 | + unchecked { |
| 161 | + ++i; |
| 162 | + } |
| 163 | + } |
| 164 | + } |
| 165 | + |
| 166 | + /// @dev Override to prevent double-initialization of the owner |
| 167 | + function _requireCallerIsContractOwner() internal view override { |
| 168 | + _checkOwner(); |
| 169 | + } |
| 170 | + |
| 171 | + /// @dev Resolve Context conflict between ContextUpgradeable (from ERC1155Upgradeable) and Context (from CreatorTokenBase) |
| 172 | + /// @dev Use ContextUpgradeable version for upgradeable contracts |
| 173 | + function _msgSender() internal view override(ContextUpgradeable, Context) returns (address) { |
| 174 | + return ContextUpgradeable._msgSender(); |
| 175 | + } |
| 176 | + |
| 177 | + function _msgData() internal view override(ContextUpgradeable, Context) returns (bytes calldata) { |
| 178 | + return ContextUpgradeable._msgData(); |
| 179 | + } |
| 180 | +} |
| 181 | + |
0 commit comments