Skip to content

Commit eeb0715

Browse files
committed
1155cm
1 parent c12450e commit eeb0715

File tree

3 files changed

+749
-0
lines changed

3 files changed

+749
-0
lines changed
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
//SPDX-License-Identifier: MIT
2+
3+
pragma solidity ^0.8.22;
4+
5+
import {ERC1155M} from "./ERC1155M.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+
/// @title ERC1155CM
16+
/// @notice An ERC1155 contract with multi-stage minting, royalties, authorized minters, and Creator Token functionality
17+
/// @dev Extends ERC1155C with ERC1155M functionality
18+
19+
contract ERC1155CM is ERC1155M, CreatorTokenBase, AutomaticValidatorTransferApproval {
20+
/*==============================================================
21+
= CONSTRUCTOR =
22+
==============================================================*/
23+
24+
constructor(
25+
string memory collectionName,
26+
string memory collectionSymbol,
27+
string memory uri,
28+
uint256[] memory maxMintableSupply,
29+
uint256[] memory globalWalletLimit,
30+
address mintCurrency,
31+
address fundReceiver,
32+
address royaltyReceiver,
33+
uint96 royaltyFeeNumerator,
34+
uint256 mintFee
35+
)
36+
ERC1155M(
37+
collectionName,
38+
collectionSymbol,
39+
uri,
40+
maxMintableSupply,
41+
globalWalletLimit,
42+
mintCurrency,
43+
fundReceiver,
44+
royaltyReceiver,
45+
royaltyFeeNumerator,
46+
mintFee
47+
)
48+
{}
49+
50+
51+
/*==============================================================
52+
= META =
53+
==============================================================*/
54+
55+
/// @notice Returns the contract name and version
56+
/// @return The contract name and version as strings
57+
function contractNameAndVersion() public pure returns (string memory, string memory) {
58+
return ("ERC1155CM", "1.0.0");
59+
}
60+
61+
/// @notice Returns the transfer validator selector used during transaction simulation.
62+
/// @dev Indicates whether the validation function is view-only.
63+
/// @return functionSignature Selector for `validateTransfer(address,address,address,uint256,uint256)`
64+
/// @return isViewFunction False because `validateTransfer` is not a view function
65+
function getTransferValidationFunction() external pure returns (bytes4 functionSignature, bool isViewFunction) {
66+
functionSignature = bytes4(keccak256("validateTransfer(address,address,address,uint256,uint256)"));
67+
isViewFunction = false;
68+
}
69+
70+
function _tokenType() internal pure override returns (uint16) {
71+
return uint16(TOKEN_TYPE_ERC1155);
72+
}
73+
74+
/// @notice Checks if the contract supports a given interface
75+
/// @param interfaceId The interface identifier
76+
/// @return True if the contract supports the interface, false otherwise
77+
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC1155M) returns (bool) {
78+
return interfaceId == type(ICreatorToken).interfaceId || super.supportsInterface(interfaceId);
79+
}
80+
81+
/// @notice Overrides behavior of isApprovedForAll such that if an operator is not explicitly approved
82+
/// @notice for all, the contract owner can optionally auto-approve the transfer validator for transfers.
83+
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool isApproved) {
84+
isApproved = super.isApprovedForAll(owner, operator);
85+
86+
if (!isApproved) {
87+
if (autoApproveTransfersFromValidator) {
88+
isApproved = operator == address(getTransferValidator());
89+
}
90+
}
91+
}
92+
93+
/// @dev Overrides the _afterTokenTransfer function to add Creator Token validation
94+
/// @param operator The address performing the transfer
95+
/// @param from The address transferring the tokens
96+
/// @param to The address receiving the tokens
97+
/// @param ids The IDs of the tokens being transferred
98+
/// @param amounts The quantities of the tokens being transferred
99+
/// @param data Additional data with no specified format
100+
function _afterTokenTransfer(
101+
address operator,
102+
address from,
103+
address to,
104+
uint256[] memory ids,
105+
uint256[] memory amounts,
106+
bytes memory data
107+
) internal virtual override {
108+
super._afterTokenTransfer(operator, from, to, ids, amounts, data);
109+
110+
// Add Creator Token validation for each token ID
111+
uint256 idsArrayLength = ids.length;
112+
for (uint256 i = 0; i < idsArrayLength;) {
113+
_validateAfterTransfer(from, to, ids[i], amounts[i]);
114+
115+
unchecked {
116+
++i;
117+
}
118+
}
119+
}
120+
121+
/// @dev Overrides the _beforeTokenTransfer function to add Creator Token validation
122+
/// @param operator The address performing the transfer
123+
/// @param from The address transferring the tokens
124+
/// @param to The address receiving the tokens
125+
/// @param ids The IDs of the tokens being transferred
126+
/// @param amounts The quantities of the tokens being transferred
127+
/// @param data Additional data with no specified format
128+
function _beforeTokenTransfer(
129+
address operator,
130+
address from,
131+
address to,
132+
uint256[] memory ids,
133+
uint256[] memory amounts,
134+
bytes memory data
135+
) internal virtual override {
136+
// Call ERC1155M first for transferable check
137+
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
138+
139+
// Then add Creator Token validation for each token ID
140+
uint256 idsArrayLength = ids.length;
141+
for (uint256 i = 0; i < idsArrayLength;) {
142+
_validateBeforeTransfer(from, to, ids[i], amounts[i]);
143+
144+
unchecked {
145+
++i;
146+
}
147+
}
148+
}
149+
150+
/// @dev Override to prevent double-initialization of the owner
151+
function _requireCallerIsContractOwner() internal view override {
152+
_checkOwner();
153+
}
154+
}
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
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

Comments
 (0)