@artblocks/contracts 1.0.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/artifacts/contracts/AdminACLV1.sol/AdminACLV1.json +2 -2
- package/artifacts/contracts/DependencyRegistryV0.sol/DependencyRegistryV0.json +97 -10
- package/artifacts/contracts/GenArt721CoreV3.sol/GenArt721CoreV3.json +4 -4
- package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine.sol/GenArt721CoreV3_Engine.json +4 -9
- package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol/GenArt721CoreV3_Engine_Flex.json +4 -9
- package/artifacts/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol/GenArt721CoreV3_Engine_Flex_PROOF.json +4 -9
- package/artifacts/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol/GenArt721CoreV3_Engine_Flex_PROHIBITION.json +4 -9
- package/artifacts/contracts/engine-registry/CoreRegistryV1.sol/CoreRegistryV1.json +12 -12
- package/artifacts/contracts/explorations/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +4 -4
- package/artifacts/contracts/interfaces/v0.8.x/ICoreRegistryV1.sol/ICoreRegistryV1.json +6 -6
- package/artifacts/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol/IDependencyRegistryV0.json +19 -0
- package/artifacts/contracts/interfaces/v0.8.x/IMinterFilterV1.sol/IMinterFilterV1.json +22 -22
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol/ISharedMinterDAExpSettlementV0.json +8 -101
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAExpV0.sol/ISharedMinterDAExpV0.json +1 -57
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDALinV0.sol/ISharedMinterDALinV0.json +1 -57
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAV0.sol/ISharedMinterDAV0.json +2 -21
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterHolderERC20V0.sol/ISharedMinterHolderERC20V0.json +158 -0
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterHolderV0.sol/ISharedMinterHolderV0.json +15 -90
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterMerkleV0.sol/ISharedMinterMerkleV0.json +10 -36
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterSEAV0.sol/ISharedMinterSEAV0.json +4 -236
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterSimplePurchaseV0.sol/ISharedMinterSimplePurchaseV0.json +5 -5
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterV0.sol/ISharedMinterV0.json +7 -423
- package/artifacts/contracts/interfaces/v0.8.x/ISharedRandomizerV0.sol/ISharedRandomizerV0.json +17 -17
- package/artifacts/contracts/libs/v0.8.x/ABHelpers.sol/ABHelpers.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/AuthLib.sol/AuthLib.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/Bytes32Strings.sol/Bytes32Strings.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/minter-libs/DAExpLib.sol/DAExpLib.json +60 -3
- package/artifacts/contracts/libs/v0.8.x/minter-libs/DALib.sol/DALib.json +30 -0
- package/artifacts/contracts/libs/v0.8.x/minter-libs/DALinLib.sol/DALinLib.json +60 -3
- package/artifacts/contracts/libs/v0.8.x/minter-libs/GenericMinterEventsLib.sol/GenericMinterEventsLib.json +346 -0
- package/artifacts/contracts/libs/v0.8.x/minter-libs/MaxInvocationsLib.sol/MaxInvocationsLib.json +29 -3
- package/artifacts/contracts/libs/v0.8.x/minter-libs/MerkleLib.sol/MerkleLib.json +30 -3
- package/artifacts/contracts/libs/v0.8.x/minter-libs/PolyptychLib.sol/PolyptychLib.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/minter-libs/SEALib.sol/SEALib.json +254 -3
- package/artifacts/contracts/libs/v0.8.x/minter-libs/SetPriceLib.sol/SetPriceLib.json +48 -3
- package/artifacts/contracts/libs/v0.8.x/minter-libs/SettlementExpLib.sol/SettlementExpLib.json +41 -3
- package/artifacts/contracts/libs/v0.8.x/minter-libs/SplitFundsLib.sol/SplitFundsLib.json +35 -3
- package/artifacts/contracts/libs/v0.8.x/minter-libs/TokenHolderLib.sol/TokenHolderLib.json +79 -3
- package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV1.sol/MinterFilterV1.json +2 -2
- package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV2.sol/MinterFilterV2.json +41 -41
- package/artifacts/contracts/minter-suite/Minters/MinterDAExpHolderV5.sol/MinterDAExpHolderV5.json +66 -632
- package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV2.sol/MinterDAExpSettlementV2.json +2 -20
- package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV3.sol/MinterDAExpSettlementV3.json +67 -594
- package/artifacts/contracts/minter-suite/Minters/MinterDAExpV5.sol/MinterDAExpV5.json +33 -524
- package/artifacts/contracts/minter-suite/Minters/MinterDALinHolderV5.sol/MinterDALinHolderV5.json +66 -632
- package/artifacts/contracts/minter-suite/Minters/MinterDALinV5.sol/MinterDALinV5.json +33 -524
- package/artifacts/contracts/minter-suite/Minters/MinterSEAV1.sol/MinterSEAV1.json +51 -717
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20V5.sol/MinterSetPriceERC20V5.json +58 -454
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceHolderV5.sol/MinterSetPriceHolderV5.json +61 -552
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceMerkleV5.sol/MinterSetPriceMerkleV5.json +55 -497
- package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychERC20V5.sol/MinterSetPricePolyptychERC20V5.json +110 -571
- package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychV5.sol/MinterSetPricePolyptychV5.json +69 -560
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceV5.sol/MinterSetPriceV5.json +28 -444
- package/artifacts/contracts/mock/DummySharedMinter.sol/DummySharedMinter.json +2 -2
- package/artifacts/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol/GenArt721CoreV3_Engine_IncorrectCoreType.json +4 -9
- package/artifacts/contracts/mock/OriginRegisterMock.sol/OriginRegisterMock.json +2 -2
- package/artifacts/contracts/mock/ReentrancyHolderMockShared.sol/ReentrancyHolderMockShared.json +136 -0
- package/artifacts/contracts/mock/ReentrancyMerkleMockShared.sol/ReentrancyMerkleMockShared.json +105 -0
- package/artifacts/contracts/mock/ReentrancyMockShared.sol/ReentrancyMockShared.json +100 -0
- package/artifacts/contracts/mock/ReentrancySEAMockShared.sol/ReentrancySEAAutoBidderMockShared.json +69 -0
- package/artifacts/contracts/randomizer/shared/SharedRandomizerV0.sol/SharedRandomizerV0.json +19 -19
- package/contracts/DependencyRegistryV0.sol +84 -16
- package/contracts/archive/readme.md +16 -0
- package/contracts/engine/README.md +21 -0
- package/contracts/engine/V3/GenArt721CoreV3_Engine.sol +4 -10
- package/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol +4 -10
- package/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol +4 -10
- package/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol +4 -10
- package/contracts/engine-registry/CoreRegistryV1.sol +58 -65
- package/contracts/interfaces/v0.8.x/ICoreRegistryV1.sol +6 -8
- package/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol +3 -0
- package/contracts/interfaces/v0.8.x/IMinterFilterV1.sol +25 -25
- package/contracts/interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol +11 -20
- package/contracts/interfaces/v0.8.x/ISharedMinterDAExpV0.sol +1 -14
- package/contracts/interfaces/v0.8.x/ISharedMinterDALinV0.sol +1 -15
- package/contracts/interfaces/v0.8.x/ISharedMinterDAV0.sol +2 -8
- package/contracts/interfaces/v0.8.x/ISharedMinterHolderERC20V0.sol +47 -0
- package/contracts/interfaces/v0.8.x/ISharedMinterHolderV0.sol +15 -43
- package/contracts/interfaces/v0.8.x/ISharedMinterMerkleV0.sol +10 -20
- package/contracts/interfaces/v0.8.x/ISharedMinterSEAV0.sol +4 -67
- package/contracts/interfaces/v0.8.x/ISharedMinterSimplePurchaseV0.sol +5 -5
- package/contracts/interfaces/v0.8.x/ISharedMinterV0.sol +7 -155
- package/contracts/interfaces/v0.8.x/ISharedRandomizerV0.sol +37 -37
- package/contracts/libs/v0.8.x/ABHelpers.sol +14 -14
- package/contracts/libs/v0.8.x/AuthLib.sol +101 -102
- package/contracts/libs/v0.8.x/Bytes32Strings.sol +5 -5
- package/contracts/libs/v0.8.x/minter-libs/DAExpLib.sol +163 -38
- package/contracts/libs/v0.8.x/minter-libs/DALib.sol +26 -0
- package/contracts/libs/v0.8.x/minter-libs/DALinLib.sol +144 -37
- package/contracts/libs/v0.8.x/minter-libs/GenericMinterEventsLib.sol +171 -0
- package/contracts/libs/v0.8.x/minter-libs/MaxInvocationsLib.sol +250 -110
- package/contracts/libs/v0.8.x/minter-libs/MerkleLib.sol +257 -48
- package/contracts/libs/v0.8.x/minter-libs/PolyptychLib.sol +138 -58
- package/contracts/libs/v0.8.x/minter-libs/SEALib.sol +778 -103
- package/contracts/libs/v0.8.x/minter-libs/SetPriceLib.sol +135 -13
- package/contracts/libs/v0.8.x/minter-libs/SettlementExpLib.sol +567 -187
- package/contracts/libs/v0.8.x/minter-libs/SplitFundsLib.sol +480 -322
- package/contracts/libs/v0.8.x/minter-libs/TokenHolderLib.sol +214 -76
- package/contracts/minter-suite/MinterFilter/MinterFilterV2.sol +347 -304
- package/contracts/minter-suite/Minters/MinterDAExpHolderV5.sol +391 -491
- package/contracts/minter-suite/Minters/MinterDAExpSettlementV2.sol +1 -54
- package/contracts/minter-suite/Minters/MinterDAExpSettlementV3.sol +388 -628
- package/contracts/minter-suite/Minters/MinterDAExpV5.sol +212 -273
- package/contracts/minter-suite/Minters/MinterDALinHolderV5.sol +393 -488
- package/contracts/minter-suite/Minters/MinterDALinV5.sol +220 -277
- package/contracts/minter-suite/Minters/MinterSEAV1.sol +327 -664
- package/contracts/minter-suite/Minters/MinterSetPriceERC20V5.sol +278 -303
- package/contracts/minter-suite/Minters/MinterSetPriceHolderV5.sol +355 -446
- package/contracts/minter-suite/Minters/MinterSetPriceMerkleV5.sol +328 -416
- package/contracts/minter-suite/Minters/MinterSetPricePolyptychERC20V5.sol +538 -622
- package/contracts/minter-suite/Minters/MinterSetPricePolyptychV5.sol +429 -553
- package/contracts/minter-suite/Minters/MinterSetPriceV5.sol +180 -227
- package/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol +3 -10
- package/contracts/mock/ReentrancyHolderMockShared.sol +59 -0
- package/contracts/mock/ReentrancyMerkleMockShared.sol +58 -0
- package/contracts/mock/ReentrancyMockShared.sol +48 -0
- package/contracts/mock/ReentrancySEAMockShared.sol +40 -0
- package/contracts/randomizer/shared/SharedRandomizerV0.sol +78 -70
- package/package.json +39 -33
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
2
2
|
// Created By: Art Blocks Inc.
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
pragma solidity ^0.8.0;
|
|
5
5
|
|
|
6
|
-
import "
|
|
6
|
+
import {IGenArt721CoreContractV3_Base} from "../../../interfaces/v0.8.x/IGenArt721CoreContractV3_Base.sol";
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
import {ABHelpers} from "../ABHelpers.sol";
|
|
9
|
+
|
|
10
|
+
import {Math} from "@openzeppelin-4.7/contracts/utils/math/Math.sol";
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
13
|
* @title Art Blocks Max Invocations Library
|
|
@@ -19,6 +21,24 @@ pragma solidity ^0.8.0;
|
|
|
19
21
|
*/
|
|
20
22
|
|
|
21
23
|
library MaxInvocationsLib {
|
|
24
|
+
/**
|
|
25
|
+
* @notice Local max invocations for project `projectId`, tied to core contract `coreContractAddress`,
|
|
26
|
+
* updated to `maxInvocations`.
|
|
27
|
+
* @param projectId The id of the project.
|
|
28
|
+
* @param coreContract The address of the core contract.
|
|
29
|
+
* @param maxInvocations The new max invocations limit.
|
|
30
|
+
*/
|
|
31
|
+
event ProjectMaxInvocationsLimitUpdated(
|
|
32
|
+
uint256 indexed projectId,
|
|
33
|
+
address indexed coreContract,
|
|
34
|
+
uint256 maxInvocations
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
// position of Max Invocations Lib storage, using a diamond storage pattern
|
|
38
|
+
// for this library
|
|
39
|
+
bytes32 constant MAX_INVOCATIONS_LIB_STORAGE_POSITION =
|
|
40
|
+
keccak256("maxinvocationslib.storage");
|
|
41
|
+
|
|
22
42
|
uint256 internal constant ONE_MILLION = 1_000_000;
|
|
23
43
|
|
|
24
44
|
/**
|
|
@@ -29,66 +49,92 @@ library MaxInvocationsLib {
|
|
|
29
49
|
uint24 maxInvocations;
|
|
30
50
|
}
|
|
31
51
|
|
|
52
|
+
// Diamond storage pattern is used in this library
|
|
53
|
+
struct MaxInvocationsLibStorage {
|
|
54
|
+
mapping(address coreContract => mapping(uint256 projectId => MaxInvocationsProjectConfig)) maxInvocationsProjectConfigs;
|
|
55
|
+
}
|
|
56
|
+
|
|
32
57
|
/**
|
|
33
58
|
* @notice Syncs project's max invocations to core contract value.
|
|
34
|
-
* @param
|
|
35
|
-
* @param
|
|
36
|
-
* @param maxInvocationsProjectConfig Data structure that holds max invocations project configuration.
|
|
37
|
-
* @return uint256 the updated max invocations.
|
|
59
|
+
* @param projectId The id of the project.
|
|
60
|
+
* @param coreContract The address of the core contract.
|
|
38
61
|
*/
|
|
39
62
|
function syncProjectMaxInvocationsToCore(
|
|
40
|
-
uint256
|
|
41
|
-
address
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
63
|
+
uint256 projectId,
|
|
64
|
+
address coreContract
|
|
65
|
+
) internal {
|
|
66
|
+
(
|
|
67
|
+
uint256 coreInvocations,
|
|
68
|
+
uint256 coreMaxInvocations
|
|
69
|
+
) = coreContractInvocationData({
|
|
70
|
+
projectId: projectId,
|
|
71
|
+
coreContract: coreContract
|
|
72
|
+
});
|
|
49
73
|
// update storage with results
|
|
50
|
-
|
|
74
|
+
MaxInvocationsProjectConfig
|
|
75
|
+
storage maxInvocationsProjectConfig = getMaxInvocationsProjectConfig({
|
|
76
|
+
projectId: projectId,
|
|
77
|
+
coreContract: coreContract
|
|
78
|
+
});
|
|
79
|
+
maxInvocationsProjectConfig.maxInvocations = uint24(coreMaxInvocations);
|
|
51
80
|
|
|
52
81
|
// We need to ensure maxHasBeenInvoked is correctly set after manually syncing the
|
|
53
82
|
// local maxInvocations value with the core contract's maxInvocations value.
|
|
54
83
|
// This synced value of maxInvocations from the core contract will always be greater
|
|
55
84
|
// than or equal to the previous value of maxInvocations stored locally.
|
|
56
85
|
maxInvocationsProjectConfig.maxHasBeenInvoked =
|
|
57
|
-
|
|
58
|
-
|
|
86
|
+
coreInvocations == coreMaxInvocations;
|
|
87
|
+
|
|
88
|
+
emit ProjectMaxInvocationsLimitUpdated({
|
|
89
|
+
projectId: projectId,
|
|
90
|
+
coreContract: coreContract,
|
|
91
|
+
maxInvocations: coreMaxInvocations
|
|
92
|
+
});
|
|
59
93
|
}
|
|
60
94
|
|
|
61
95
|
/**
|
|
62
96
|
* @notice Manually limits project's max invocations.
|
|
63
|
-
* @param
|
|
64
|
-
* @param
|
|
65
|
-
* @param
|
|
66
|
-
* @param maxInvocationsProjectConfig Data structure that holds max invocations project configuration.
|
|
97
|
+
* @param projectId The id of the project.
|
|
98
|
+
* @param coreContract The address of the core contract.
|
|
99
|
+
* @param maxInvocations The new max invocations limit.
|
|
67
100
|
*/
|
|
68
101
|
function manuallyLimitProjectMaxInvocations(
|
|
69
|
-
uint256
|
|
70
|
-
address
|
|
71
|
-
uint24
|
|
72
|
-
MaxInvocationsProjectConfig storage maxInvocationsProjectConfig
|
|
102
|
+
uint256 projectId,
|
|
103
|
+
address coreContract,
|
|
104
|
+
uint24 maxInvocations
|
|
73
105
|
) internal {
|
|
74
106
|
// CHECKS
|
|
75
107
|
(
|
|
76
108
|
uint256 coreInvocations,
|
|
77
109
|
uint256 coreMaxInvocations
|
|
78
|
-
) = coreContractInvocationData(
|
|
110
|
+
) = coreContractInvocationData({
|
|
111
|
+
projectId: projectId,
|
|
112
|
+
coreContract: coreContract
|
|
113
|
+
});
|
|
79
114
|
require(
|
|
80
|
-
|
|
115
|
+
maxInvocations <= coreMaxInvocations,
|
|
81
116
|
"Invalid max invocations"
|
|
82
117
|
);
|
|
83
|
-
require(
|
|
118
|
+
require(maxInvocations >= coreInvocations, "Invalid max invocations");
|
|
84
119
|
|
|
85
120
|
// EFFECTS
|
|
121
|
+
MaxInvocationsProjectConfig
|
|
122
|
+
storage maxInvocationsProjectConfig = getMaxInvocationsProjectConfig({
|
|
123
|
+
projectId: projectId,
|
|
124
|
+
coreContract: coreContract
|
|
125
|
+
});
|
|
86
126
|
// update storage with results
|
|
87
|
-
maxInvocationsProjectConfig.maxInvocations = uint24(
|
|
127
|
+
maxInvocationsProjectConfig.maxInvocations = uint24(maxInvocations);
|
|
88
128
|
// We need to ensure maxHasBeenInvoked is correctly set after manually setting the
|
|
89
129
|
// local maxInvocations value.
|
|
90
130
|
maxInvocationsProjectConfig.maxHasBeenInvoked =
|
|
91
|
-
coreInvocations ==
|
|
131
|
+
coreInvocations == maxInvocations;
|
|
132
|
+
|
|
133
|
+
emit ProjectMaxInvocationsLimitUpdated({
|
|
134
|
+
projectId: projectId,
|
|
135
|
+
coreContract: coreContract,
|
|
136
|
+
maxInvocations: maxInvocations
|
|
137
|
+
});
|
|
92
138
|
}
|
|
93
139
|
|
|
94
140
|
/**
|
|
@@ -98,19 +144,24 @@ library MaxInvocationsLib {
|
|
|
98
144
|
* @dev This function checks that the token invocation is less than or
|
|
99
145
|
* equal to the local max invocations, and also updates the local
|
|
100
146
|
* maxHasBeenInvoked value.
|
|
101
|
-
* @param
|
|
102
|
-
* @param
|
|
103
|
-
* invocations project configuration.
|
|
147
|
+
* @param tokenId The id of the token.
|
|
148
|
+
* @param coreContract The address of the core contract.
|
|
104
149
|
*/
|
|
105
150
|
function validatePurchaseEffectsInvocations(
|
|
106
|
-
uint256
|
|
107
|
-
|
|
151
|
+
uint256 tokenId,
|
|
152
|
+
address coreContract
|
|
108
153
|
) internal {
|
|
154
|
+
uint256 projectId = ABHelpers.tokenIdToProjectId(tokenId);
|
|
155
|
+
MaxInvocationsProjectConfig
|
|
156
|
+
storage maxInvocationsProjectConfig = getMaxInvocationsProjectConfig({
|
|
157
|
+
projectId: projectId,
|
|
158
|
+
coreContract: coreContract
|
|
159
|
+
});
|
|
109
160
|
// invocation is token number plus one, and will never overflow due to
|
|
110
161
|
// limit of 1e6 invocations per project. block scope for gas efficiency
|
|
111
162
|
// (i.e. avoid an unnecessary var initialization to 0).
|
|
112
163
|
unchecked {
|
|
113
|
-
uint256 tokenInvocation = (
|
|
164
|
+
uint256 tokenInvocation = (tokenId % ONE_MILLION) + 1;
|
|
114
165
|
uint256 localMaxInvocations = maxInvocationsProjectConfig
|
|
115
166
|
.maxInvocations;
|
|
116
167
|
// handle the case where the token invocation == minter local max
|
|
@@ -132,10 +183,34 @@ library MaxInvocationsLib {
|
|
|
132
183
|
}
|
|
133
184
|
|
|
134
185
|
/**
|
|
135
|
-
*
|
|
186
|
+
* Checks that the max invocations have not been reached for a given
|
|
187
|
+
* project. This only checks the minter's local max invocations, and does
|
|
188
|
+
* not consider the core contract's max invocations.
|
|
189
|
+
* The function reverts if the max invocations have been reached.
|
|
190
|
+
* @param projectId The id of the project.
|
|
191
|
+
* @param coreContract The address of the core contract.
|
|
192
|
+
*/
|
|
193
|
+
function preMintChecks(
|
|
194
|
+
uint256 projectId,
|
|
195
|
+
address coreContract
|
|
196
|
+
) internal view {
|
|
197
|
+
// check that max invocations have not been reached
|
|
198
|
+
MaxInvocationsProjectConfig
|
|
199
|
+
storage maxInvocationsProjectConfig = getMaxInvocationsProjectConfig({
|
|
200
|
+
projectId: projectId,
|
|
201
|
+
coreContract: coreContract
|
|
202
|
+
});
|
|
203
|
+
require(
|
|
204
|
+
!maxInvocationsProjectConfig.maxHasBeenInvoked,
|
|
205
|
+
"Max invocations reached"
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* @notice Helper function to check if max invocations has not been initialized.
|
|
136
211
|
* Returns true if not initialized, false if initialized.
|
|
137
|
-
* @param
|
|
138
|
-
*
|
|
212
|
+
* @param projectId The id of the project.
|
|
213
|
+
* @param coreContract The address of the core contract.
|
|
139
214
|
* @return bool
|
|
140
215
|
* @dev We know a project's max invocations have never been initialized if
|
|
141
216
|
* both max invocations and maxHasBeenInvoked are still initial values.
|
|
@@ -143,62 +218,68 @@ library MaxInvocationsLib {
|
|
|
143
218
|
* maxHasBeenInvoked would be set to true.
|
|
144
219
|
*/
|
|
145
220
|
function maxInvocationsIsUnconfigured(
|
|
146
|
-
|
|
221
|
+
uint256 projectId,
|
|
222
|
+
address coreContract
|
|
147
223
|
) internal view returns (bool) {
|
|
224
|
+
MaxInvocationsProjectConfig
|
|
225
|
+
storage maxInvocationsProjectConfig = getMaxInvocationsProjectConfig({
|
|
226
|
+
projectId: projectId,
|
|
227
|
+
coreContract: coreContract
|
|
228
|
+
});
|
|
148
229
|
return
|
|
149
|
-
|
|
150
|
-
!
|
|
230
|
+
maxInvocationsProjectConfig.maxInvocations == 0 &&
|
|
231
|
+
!maxInvocationsProjectConfig.maxHasBeenInvoked;
|
|
151
232
|
}
|
|
152
233
|
|
|
153
234
|
/**
|
|
154
|
-
*
|
|
235
|
+
* @notice Function returns if invocations remain available for a given project.
|
|
155
236
|
* This function calls the core contract to get the most up-to-date
|
|
156
237
|
* invocation data (which may be useful to avoid reverts during mint).
|
|
157
238
|
* This function considers core contract max invocations, and minter local
|
|
158
239
|
* max invocations, and returns a response based on the most limiting
|
|
159
240
|
* max invocations value.
|
|
160
|
-
* @param
|
|
161
|
-
*
|
|
162
|
-
* @param _projectId The id of the project.
|
|
163
|
-
* @param _coreContract The address of the core contract.
|
|
241
|
+
* @param projectId The id of the project.
|
|
242
|
+
* @param coreContract The address of the core contract.
|
|
164
243
|
*/
|
|
165
244
|
function invocationsRemain(
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
address _coreContract
|
|
245
|
+
uint256 projectId,
|
|
246
|
+
address coreContract
|
|
169
247
|
) internal view returns (bool) {
|
|
170
248
|
// get up-to-data invocation data from core contract
|
|
171
249
|
(
|
|
172
250
|
uint256 coreInvocations,
|
|
173
251
|
uint256 coreMaxInvocations
|
|
174
|
-
) =
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
);
|
|
252
|
+
) = coreContractInvocationData({
|
|
253
|
+
projectId: projectId,
|
|
254
|
+
coreContract: coreContract
|
|
255
|
+
});
|
|
178
256
|
// load minter-local max invocations into memory
|
|
179
|
-
|
|
180
|
-
|
|
257
|
+
MaxInvocationsProjectConfig
|
|
258
|
+
storage maxInvocationsProjectConfig = getMaxInvocationsProjectConfig({
|
|
259
|
+
projectId: projectId,
|
|
260
|
+
coreContract: coreContract
|
|
261
|
+
});
|
|
181
262
|
// invocations remain available if the core contract has not reached
|
|
182
263
|
// the most limiting max invocations, either on minter or core contract
|
|
183
264
|
uint256 limitingMaxInvocations = Math.min(
|
|
184
265
|
coreMaxInvocations,
|
|
185
|
-
|
|
266
|
+
maxInvocationsProjectConfig.maxInvocations // local max invocations
|
|
186
267
|
);
|
|
187
268
|
return coreInvocations < limitingMaxInvocations;
|
|
188
269
|
}
|
|
189
270
|
|
|
190
271
|
/**
|
|
191
|
-
* Pulls core contract invocation data for a given project.
|
|
272
|
+
* @notice Pulls core contract invocation data for a given project.
|
|
192
273
|
* @dev This function calls the core contract to get the invocation data
|
|
193
|
-
* @param
|
|
194
|
-
* @param
|
|
274
|
+
* @param projectId The id of the project.
|
|
275
|
+
* @param coreContract The address of the core contract.
|
|
195
276
|
* @return coreInvocations The number of invocations for the project.
|
|
196
277
|
* @return coreMaxInvocations The max invocations for the project, as
|
|
197
278
|
* defined on the core contract.
|
|
198
279
|
*/
|
|
199
280
|
function coreContractInvocationData(
|
|
200
|
-
uint256
|
|
201
|
-
address
|
|
281
|
+
uint256 projectId,
|
|
282
|
+
address coreContract
|
|
202
283
|
)
|
|
203
284
|
internal
|
|
204
285
|
view
|
|
@@ -211,54 +292,75 @@ library MaxInvocationsLib {
|
|
|
211
292
|
,
|
|
212
293
|
,
|
|
213
294
|
|
|
214
|
-
) = IGenArt721CoreContractV3_Base(
|
|
215
|
-
|
|
295
|
+
) = IGenArt721CoreContractV3_Base(coreContract).projectStateData(
|
|
296
|
+
projectId
|
|
216
297
|
);
|
|
217
298
|
}
|
|
218
299
|
|
|
219
300
|
/**
|
|
220
|
-
*
|
|
221
|
-
* @param
|
|
301
|
+
* @notice Function returns the max invocations for a given project.
|
|
302
|
+
* @param projectId The id of the project.
|
|
303
|
+
* @param coreContract The address of the core contract.
|
|
222
304
|
* to be queried.
|
|
223
305
|
*/
|
|
224
306
|
function getMaxInvocations(
|
|
225
|
-
|
|
307
|
+
uint256 projectId,
|
|
308
|
+
address coreContract
|
|
226
309
|
) internal view returns (uint256) {
|
|
227
|
-
|
|
310
|
+
MaxInvocationsProjectConfig
|
|
311
|
+
storage maxInvocationsProjectConfig = getMaxInvocationsProjectConfig({
|
|
312
|
+
projectId: projectId,
|
|
313
|
+
coreContract: coreContract
|
|
314
|
+
});
|
|
315
|
+
return maxInvocationsProjectConfig.maxInvocations;
|
|
228
316
|
}
|
|
229
317
|
|
|
230
318
|
/**
|
|
231
|
-
*
|
|
232
|
-
* @param
|
|
319
|
+
* @notice Function returns if max has been invoked for a given project.
|
|
320
|
+
* @param projectId The id of the project.
|
|
321
|
+
* @param coreContract The address of the core contract.
|
|
233
322
|
* to be queried.
|
|
234
323
|
*/
|
|
235
324
|
function getMaxHasBeenInvoked(
|
|
236
|
-
|
|
325
|
+
uint256 projectId,
|
|
326
|
+
address coreContract
|
|
237
327
|
) internal view returns (bool) {
|
|
238
|
-
|
|
328
|
+
MaxInvocationsProjectConfig
|
|
329
|
+
storage maxInvocationsProjectConfig = getMaxInvocationsProjectConfig({
|
|
330
|
+
projectId: projectId,
|
|
331
|
+
coreContract: coreContract
|
|
332
|
+
});
|
|
333
|
+
return maxInvocationsProjectConfig.maxHasBeenInvoked;
|
|
239
334
|
}
|
|
240
335
|
|
|
241
336
|
/**
|
|
242
|
-
*
|
|
243
|
-
* Function is
|
|
337
|
+
* @notice Function returns if a project has reached its max invocations.
|
|
338
|
+
* Function is labelled as "safe" because it checks the core contract's
|
|
244
339
|
* invocations and max invocations. If the local max invocations is greater
|
|
245
340
|
* than the core contract's max invocations, it will defer to the core
|
|
246
341
|
* contract's max invocations (since those are the limiting factor).
|
|
247
|
-
* @param
|
|
248
|
-
* @param
|
|
249
|
-
* @param _maxInvocationsProjectConfig MaxInvocationsProjectConfig struct
|
|
342
|
+
* @param projectId The id of the project.
|
|
343
|
+
* @param coreContract The address of the core contract.
|
|
250
344
|
*/
|
|
251
345
|
function projectMaxHasBeenInvokedSafe(
|
|
252
|
-
uint256
|
|
253
|
-
address
|
|
254
|
-
MaxInvocationsProjectConfig storage _maxInvocationsProjectConfig
|
|
346
|
+
uint256 projectId,
|
|
347
|
+
address coreContract
|
|
255
348
|
) internal view returns (bool) {
|
|
256
349
|
// get max invocations from core contract
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
350
|
+
(
|
|
351
|
+
uint256 coreInvocations,
|
|
352
|
+
uint256 coreMaxInvocations
|
|
353
|
+
) = coreContractInvocationData({
|
|
354
|
+
projectId: projectId,
|
|
355
|
+
coreContract: coreContract
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
MaxInvocationsProjectConfig
|
|
359
|
+
storage maxInvocationsProjectConfig = getMaxInvocationsProjectConfig({
|
|
360
|
+
projectId: projectId,
|
|
361
|
+
coreContract: coreContract
|
|
362
|
+
});
|
|
363
|
+
uint256 localMaxInvocations = maxInvocationsProjectConfig
|
|
262
364
|
.maxInvocations;
|
|
263
365
|
// value is locally defined, and could be out of date.
|
|
264
366
|
// only possible illogical state is if local max invocations is
|
|
@@ -292,30 +394,36 @@ library MaxInvocationsLib {
|
|
|
292
394
|
* be more restrictive than the core contract.
|
|
293
395
|
* @dev assumes core contract's max invocations may only be reduced, which
|
|
294
396
|
* is the case for all V3 core contracts
|
|
397
|
+
* @param projectId The id of the project.
|
|
398
|
+
* @param coreContract The address of the core contract.
|
|
295
399
|
*/
|
|
296
400
|
function refreshMaxInvocations(
|
|
297
|
-
uint256
|
|
298
|
-
address
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
401
|
+
uint256 projectId,
|
|
402
|
+
address coreContract
|
|
403
|
+
) internal {
|
|
404
|
+
MaxInvocationsProjectConfig
|
|
405
|
+
storage maxInvocationsProjectConfig = getMaxInvocationsProjectConfig({
|
|
406
|
+
projectId: projectId,
|
|
407
|
+
coreContract: coreContract
|
|
408
|
+
});
|
|
409
|
+
if (maxInvocationsIsUnconfigured(projectId, coreContract)) {
|
|
302
410
|
// populate the minter max invocation state to equal the values on
|
|
303
411
|
// the core contract (least restrictive state)
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
);
|
|
309
|
-
// return true to indicate max invocation state update
|
|
310
|
-
maxInvocationsUpdated = true;
|
|
412
|
+
syncProjectMaxInvocationsToCore({
|
|
413
|
+
projectId: projectId,
|
|
414
|
+
coreContract: coreContract
|
|
415
|
+
});
|
|
311
416
|
} else {
|
|
312
417
|
// if local max invocations were already populated, validate the local state
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
418
|
+
(
|
|
419
|
+
uint256 coreInvocations,
|
|
420
|
+
uint256 coreMaxInvocations
|
|
421
|
+
) = coreContractInvocationData({
|
|
422
|
+
projectId: projectId,
|
|
423
|
+
coreContract: coreContract
|
|
424
|
+
});
|
|
317
425
|
|
|
318
|
-
uint256 localMaxInvocations =
|
|
426
|
+
uint256 localMaxInvocations = maxInvocationsProjectConfig
|
|
319
427
|
.maxInvocations;
|
|
320
428
|
if (localMaxInvocations > coreMaxInvocations) {
|
|
321
429
|
// if local max invocations are greater than core max invocations, make
|
|
@@ -324,25 +432,57 @@ library MaxInvocationsLib {
|
|
|
324
432
|
// have been reduced since the minter's max invocations were last
|
|
325
433
|
// updated
|
|
326
434
|
// set local max invocations to core contract's max invocations
|
|
327
|
-
|
|
435
|
+
maxInvocationsProjectConfig.maxInvocations = uint24(
|
|
328
436
|
coreMaxInvocations
|
|
329
437
|
);
|
|
330
438
|
// update the minter's `maxHasBeenInvoked` state
|
|
331
|
-
|
|
439
|
+
maxInvocationsProjectConfig
|
|
332
440
|
.maxHasBeenInvoked = (coreMaxInvocations ==
|
|
333
441
|
coreInvocations);
|
|
334
|
-
|
|
335
|
-
|
|
442
|
+
emit ProjectMaxInvocationsLimitUpdated({
|
|
443
|
+
projectId: projectId,
|
|
444
|
+
coreContract: coreContract,
|
|
445
|
+
maxInvocations: coreMaxInvocations
|
|
446
|
+
});
|
|
336
447
|
} else if (coreInvocations >= localMaxInvocations) {
|
|
337
448
|
// core invocations are greater than this minter's max
|
|
338
449
|
// invocations, indicating that minting must have occurred on
|
|
339
450
|
// another minter. update the minter's `maxHasBeenInvoked` to
|
|
340
451
|
// true to prevent any false negatives on
|
|
341
452
|
// `getMaxHasBeenInvoked'
|
|
342
|
-
|
|
343
|
-
// @dev do not
|
|
453
|
+
maxInvocationsProjectConfig.maxHasBeenInvoked = true;
|
|
454
|
+
// @dev do not emit event, because we did not change the value
|
|
344
455
|
// of minter-local max invocations
|
|
345
456
|
}
|
|
346
457
|
}
|
|
347
458
|
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* @notice Loads the MaxInvocationsProjectConfig for a given project and core
|
|
462
|
+
* contract.
|
|
463
|
+
* @param projectId Project Id to get config for
|
|
464
|
+
* @param coreContract Core contract address to get config for
|
|
465
|
+
*/
|
|
466
|
+
function getMaxInvocationsProjectConfig(
|
|
467
|
+
uint256 projectId,
|
|
468
|
+
address coreContract
|
|
469
|
+
) internal view returns (MaxInvocationsProjectConfig storage) {
|
|
470
|
+
return s().maxInvocationsProjectConfigs[coreContract][projectId];
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* @notice Return the storage struct for reading and writing. This library
|
|
475
|
+
* uses a diamond storage pattern when managing storage.
|
|
476
|
+
* @return storageStruct The MaxInvocationsLibStorage struct.
|
|
477
|
+
*/
|
|
478
|
+
function s()
|
|
479
|
+
internal
|
|
480
|
+
pure
|
|
481
|
+
returns (MaxInvocationsLibStorage storage storageStruct)
|
|
482
|
+
{
|
|
483
|
+
bytes32 position = MAX_INVOCATIONS_LIB_STORAGE_POSITION;
|
|
484
|
+
assembly ("memory-safe") {
|
|
485
|
+
storageStruct.slot := position
|
|
486
|
+
}
|
|
487
|
+
}
|
|
348
488
|
}
|