@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.
Files changed (120) hide show
  1. package/README.md +2 -2
  2. package/artifacts/contracts/AdminACLV1.sol/AdminACLV1.json +2 -2
  3. package/artifacts/contracts/DependencyRegistryV0.sol/DependencyRegistryV0.json +97 -10
  4. package/artifacts/contracts/GenArt721CoreV3.sol/GenArt721CoreV3.json +4 -4
  5. package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine.sol/GenArt721CoreV3_Engine.json +4 -9
  6. package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol/GenArt721CoreV3_Engine_Flex.json +4 -9
  7. package/artifacts/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol/GenArt721CoreV3_Engine_Flex_PROOF.json +4 -9
  8. package/artifacts/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol/GenArt721CoreV3_Engine_Flex_PROHIBITION.json +4 -9
  9. package/artifacts/contracts/engine-registry/CoreRegistryV1.sol/CoreRegistryV1.json +12 -12
  10. package/artifacts/contracts/explorations/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +4 -4
  11. package/artifacts/contracts/interfaces/v0.8.x/ICoreRegistryV1.sol/ICoreRegistryV1.json +6 -6
  12. package/artifacts/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol/IDependencyRegistryV0.json +19 -0
  13. package/artifacts/contracts/interfaces/v0.8.x/IMinterFilterV1.sol/IMinterFilterV1.json +22 -22
  14. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol/ISharedMinterDAExpSettlementV0.json +8 -101
  15. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAExpV0.sol/ISharedMinterDAExpV0.json +1 -57
  16. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDALinV0.sol/ISharedMinterDALinV0.json +1 -57
  17. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAV0.sol/ISharedMinterDAV0.json +2 -21
  18. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterHolderERC20V0.sol/ISharedMinterHolderERC20V0.json +158 -0
  19. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterHolderV0.sol/ISharedMinterHolderV0.json +15 -90
  20. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterMerkleV0.sol/ISharedMinterMerkleV0.json +10 -36
  21. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterSEAV0.sol/ISharedMinterSEAV0.json +4 -236
  22. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterSimplePurchaseV0.sol/ISharedMinterSimplePurchaseV0.json +5 -5
  23. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterV0.sol/ISharedMinterV0.json +7 -423
  24. package/artifacts/contracts/interfaces/v0.8.x/ISharedRandomizerV0.sol/ISharedRandomizerV0.json +17 -17
  25. package/artifacts/contracts/libs/v0.8.x/ABHelpers.sol/ABHelpers.json +2 -2
  26. package/artifacts/contracts/libs/v0.8.x/AuthLib.sol/AuthLib.json +2 -2
  27. package/artifacts/contracts/libs/v0.8.x/Bytes32Strings.sol/Bytes32Strings.json +2 -2
  28. package/artifacts/contracts/libs/v0.8.x/minter-libs/DAExpLib.sol/DAExpLib.json +60 -3
  29. package/artifacts/contracts/libs/v0.8.x/minter-libs/DALib.sol/DALib.json +30 -0
  30. package/artifacts/contracts/libs/v0.8.x/minter-libs/DALinLib.sol/DALinLib.json +60 -3
  31. package/artifacts/contracts/libs/v0.8.x/minter-libs/GenericMinterEventsLib.sol/GenericMinterEventsLib.json +346 -0
  32. package/artifacts/contracts/libs/v0.8.x/minter-libs/MaxInvocationsLib.sol/MaxInvocationsLib.json +29 -3
  33. package/artifacts/contracts/libs/v0.8.x/minter-libs/MerkleLib.sol/MerkleLib.json +30 -3
  34. package/artifacts/contracts/libs/v0.8.x/minter-libs/PolyptychLib.sol/PolyptychLib.json +2 -2
  35. package/artifacts/contracts/libs/v0.8.x/minter-libs/SEALib.sol/SEALib.json +254 -3
  36. package/artifacts/contracts/libs/v0.8.x/minter-libs/SetPriceLib.sol/SetPriceLib.json +48 -3
  37. package/artifacts/contracts/libs/v0.8.x/minter-libs/SettlementExpLib.sol/SettlementExpLib.json +41 -3
  38. package/artifacts/contracts/libs/v0.8.x/minter-libs/SplitFundsLib.sol/SplitFundsLib.json +35 -3
  39. package/artifacts/contracts/libs/v0.8.x/minter-libs/TokenHolderLib.sol/TokenHolderLib.json +79 -3
  40. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV1.sol/MinterFilterV1.json +2 -2
  41. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV2.sol/MinterFilterV2.json +41 -41
  42. package/artifacts/contracts/minter-suite/Minters/MinterDAExpHolderV5.sol/MinterDAExpHolderV5.json +66 -632
  43. package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV2.sol/MinterDAExpSettlementV2.json +2 -20
  44. package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV3.sol/MinterDAExpSettlementV3.json +67 -594
  45. package/artifacts/contracts/minter-suite/Minters/MinterDAExpV5.sol/MinterDAExpV5.json +33 -524
  46. package/artifacts/contracts/minter-suite/Minters/MinterDALinHolderV5.sol/MinterDALinHolderV5.json +66 -632
  47. package/artifacts/contracts/minter-suite/Minters/MinterDALinV5.sol/MinterDALinV5.json +33 -524
  48. package/artifacts/contracts/minter-suite/Minters/MinterSEAV1.sol/MinterSEAV1.json +51 -717
  49. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20V5.sol/MinterSetPriceERC20V5.json +58 -454
  50. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceHolderV5.sol/MinterSetPriceHolderV5.json +61 -552
  51. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceMerkleV5.sol/MinterSetPriceMerkleV5.json +55 -497
  52. package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychERC20V5.sol/MinterSetPricePolyptychERC20V5.json +110 -571
  53. package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychV5.sol/MinterSetPricePolyptychV5.json +69 -560
  54. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceV5.sol/MinterSetPriceV5.json +28 -444
  55. package/artifacts/contracts/mock/DummySharedMinter.sol/DummySharedMinter.json +2 -2
  56. package/artifacts/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol/GenArt721CoreV3_Engine_IncorrectCoreType.json +4 -9
  57. package/artifacts/contracts/mock/OriginRegisterMock.sol/OriginRegisterMock.json +2 -2
  58. package/artifacts/contracts/mock/ReentrancyHolderMockShared.sol/ReentrancyHolderMockShared.json +136 -0
  59. package/artifacts/contracts/mock/ReentrancyMerkleMockShared.sol/ReentrancyMerkleMockShared.json +105 -0
  60. package/artifacts/contracts/mock/ReentrancyMockShared.sol/ReentrancyMockShared.json +100 -0
  61. package/artifacts/contracts/mock/ReentrancySEAMockShared.sol/ReentrancySEAAutoBidderMockShared.json +69 -0
  62. package/artifacts/contracts/randomizer/shared/SharedRandomizerV0.sol/SharedRandomizerV0.json +19 -19
  63. package/contracts/DependencyRegistryV0.sol +84 -16
  64. package/contracts/archive/readme.md +16 -0
  65. package/contracts/engine/README.md +21 -0
  66. package/contracts/engine/V3/GenArt721CoreV3_Engine.sol +4 -10
  67. package/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol +4 -10
  68. package/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol +4 -10
  69. package/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol +4 -10
  70. package/contracts/engine-registry/CoreRegistryV1.sol +58 -65
  71. package/contracts/interfaces/v0.8.x/ICoreRegistryV1.sol +6 -8
  72. package/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol +3 -0
  73. package/contracts/interfaces/v0.8.x/IMinterFilterV1.sol +25 -25
  74. package/contracts/interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol +11 -20
  75. package/contracts/interfaces/v0.8.x/ISharedMinterDAExpV0.sol +1 -14
  76. package/contracts/interfaces/v0.8.x/ISharedMinterDALinV0.sol +1 -15
  77. package/contracts/interfaces/v0.8.x/ISharedMinterDAV0.sol +2 -8
  78. package/contracts/interfaces/v0.8.x/ISharedMinterHolderERC20V0.sol +47 -0
  79. package/contracts/interfaces/v0.8.x/ISharedMinterHolderV0.sol +15 -43
  80. package/contracts/interfaces/v0.8.x/ISharedMinterMerkleV0.sol +10 -20
  81. package/contracts/interfaces/v0.8.x/ISharedMinterSEAV0.sol +4 -67
  82. package/contracts/interfaces/v0.8.x/ISharedMinterSimplePurchaseV0.sol +5 -5
  83. package/contracts/interfaces/v0.8.x/ISharedMinterV0.sol +7 -155
  84. package/contracts/interfaces/v0.8.x/ISharedRandomizerV0.sol +37 -37
  85. package/contracts/libs/v0.8.x/ABHelpers.sol +14 -14
  86. package/contracts/libs/v0.8.x/AuthLib.sol +101 -102
  87. package/contracts/libs/v0.8.x/Bytes32Strings.sol +5 -5
  88. package/contracts/libs/v0.8.x/minter-libs/DAExpLib.sol +163 -38
  89. package/contracts/libs/v0.8.x/minter-libs/DALib.sol +26 -0
  90. package/contracts/libs/v0.8.x/minter-libs/DALinLib.sol +144 -37
  91. package/contracts/libs/v0.8.x/minter-libs/GenericMinterEventsLib.sol +171 -0
  92. package/contracts/libs/v0.8.x/minter-libs/MaxInvocationsLib.sol +250 -110
  93. package/contracts/libs/v0.8.x/minter-libs/MerkleLib.sol +257 -48
  94. package/contracts/libs/v0.8.x/minter-libs/PolyptychLib.sol +138 -58
  95. package/contracts/libs/v0.8.x/minter-libs/SEALib.sol +778 -103
  96. package/contracts/libs/v0.8.x/minter-libs/SetPriceLib.sol +135 -13
  97. package/contracts/libs/v0.8.x/minter-libs/SettlementExpLib.sol +567 -187
  98. package/contracts/libs/v0.8.x/minter-libs/SplitFundsLib.sol +480 -322
  99. package/contracts/libs/v0.8.x/minter-libs/TokenHolderLib.sol +214 -76
  100. package/contracts/minter-suite/MinterFilter/MinterFilterV2.sol +347 -304
  101. package/contracts/minter-suite/Minters/MinterDAExpHolderV5.sol +391 -491
  102. package/contracts/minter-suite/Minters/MinterDAExpSettlementV2.sol +1 -54
  103. package/contracts/minter-suite/Minters/MinterDAExpSettlementV3.sol +388 -628
  104. package/contracts/minter-suite/Minters/MinterDAExpV5.sol +212 -273
  105. package/contracts/minter-suite/Minters/MinterDALinHolderV5.sol +393 -488
  106. package/contracts/minter-suite/Minters/MinterDALinV5.sol +220 -277
  107. package/contracts/minter-suite/Minters/MinterSEAV1.sol +327 -664
  108. package/contracts/minter-suite/Minters/MinterSetPriceERC20V5.sol +278 -303
  109. package/contracts/minter-suite/Minters/MinterSetPriceHolderV5.sol +355 -446
  110. package/contracts/minter-suite/Minters/MinterSetPriceMerkleV5.sol +328 -416
  111. package/contracts/minter-suite/Minters/MinterSetPricePolyptychERC20V5.sol +538 -622
  112. package/contracts/minter-suite/Minters/MinterSetPricePolyptychV5.sol +429 -553
  113. package/contracts/minter-suite/Minters/MinterSetPriceV5.sol +180 -227
  114. package/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol +3 -10
  115. package/contracts/mock/ReentrancyHolderMockShared.sol +59 -0
  116. package/contracts/mock/ReentrancyMerkleMockShared.sol +58 -0
  117. package/contracts/mock/ReentrancyMockShared.sol +48 -0
  118. package/contracts/mock/ReentrancySEAMockShared.sol +40 -0
  119. package/contracts/randomizer/shared/SharedRandomizerV0.sol +78 -70
  120. package/package.json +39 -33
@@ -1,22 +1,23 @@
1
1
  // SPDX-License-Identifier: LGPL-3.0-only
2
2
  // Created By: Art Blocks Inc.
3
3
 
4
+ // @dev fixed to specific solidity version for clarity and for more clear
5
+ // source code verification purposes.
4
6
  pragma solidity 0.8.19;
5
7
 
6
- import "../../interfaces/v0.8.x/ISharedMinterV0.sol";
7
- import "../../interfaces/v0.8.x/ISharedMinterSEAV0.sol";
8
- import "../../interfaces/v0.8.x/IMinterFilterV1.sol";
8
+ import {ISharedMinterV0} from "../../interfaces/v0.8.x/ISharedMinterV0.sol";
9
+ import {ISharedMinterSEAV0} from "../../interfaces/v0.8.x/ISharedMinterSEAV0.sol";
10
+ import {IMinterFilterV1} from "../../interfaces/v0.8.x/IMinterFilterV1.sol";
9
11
 
10
- import "../../libs/v0.8.x/ABHelpers.sol";
11
- import "../../libs/v0.8.x/AuthLib.sol";
12
- import "../../libs/v0.8.x/minter-libs/SEALib.sol";
13
- import "../../libs/v0.8.x/minter-libs/SplitFundsLib.sol";
14
- import "../../libs/v0.8.x/minter-libs/MaxInvocationsLib.sol";
12
+ import {ABHelpers} from "../../libs/v0.8.x/ABHelpers.sol";
13
+ import {AuthLib} from "../../libs/v0.8.x/AuthLib.sol";
14
+ import {SEALib} from "../../libs/v0.8.x/minter-libs/SEALib.sol";
15
+ import {SplitFundsLib} from "../../libs/v0.8.x/minter-libs/SplitFundsLib.sol";
16
+ import {MaxInvocationsLib} from "../../libs/v0.8.x/minter-libs/MaxInvocationsLib.sol";
15
17
 
16
- import "@openzeppelin-4.7/contracts/token/ERC721/IERC721.sol";
17
- import "@openzeppelin-4.7/contracts/security/ReentrancyGuard.sol";
18
- import "@openzeppelin-4.7/contracts/utils/math/SafeCast.sol";
19
- import "@openzeppelin-4.7/contracts/utils/math/Math.sol";
18
+ import {ReentrancyGuard} from "@openzeppelin-4.7/contracts/security/ReentrancyGuard.sol";
19
+ import {SafeCast} from "@openzeppelin-4.7/contracts/utils/math/SafeCast.sol";
20
+ import {Math} from "@openzeppelin-4.7/contracts/utils/math/Math.sol";
20
21
 
21
22
  /**
22
23
  * @title Filtered Minter contract that allows tokens to be minted with ETH.
@@ -90,6 +91,13 @@ import "@openzeppelin-4.7/contracts/utils/math/Math.sol";
90
91
  * ----------------------------------------------------------------------------
91
92
  * Additional admin and artist privileged roles may be described on other
92
93
  * contracts that this minter integrates with.
94
+ * ----------------------------------------------------------------------------
95
+ * @notice Caution: While Engine projects must be registered on the Art Blocks
96
+ * Core Registry to assign this minter, this minter does not enforce that a
97
+ * project is registered when configured or queried. This is primarily for gas
98
+ * optimization purposes. It is, therefore, possible that fake projects may be
99
+ * configured on this minter, but they will not be able to mint tokens due to
100
+ * checks performed by this minter's Minter Filter.
93
101
  *
94
102
  * @dev Note that while this minter makes use of `block.timestamp` and it is
95
103
  * technically possible that this value is manipulated by block producers, such
@@ -102,73 +110,39 @@ import "@openzeppelin-4.7/contracts/utils/math/Math.sol";
102
110
  contract MinterSEAV1 is ReentrancyGuard, ISharedMinterV0, ISharedMinterSEAV0 {
103
111
  using SafeCast for uint256;
104
112
 
105
- /// Minter filter address this minter interacts with
113
+ /// @notice Minter filter address this minter interacts with
106
114
  address public immutable minterFilterAddress;
107
115
 
108
- /// Minter filter this minter may interact with.
109
- IMinterFilterV1 private immutable minterFilter;
116
+ /// @notice Minter filter this minter may interact with.
117
+ IMinterFilterV1 private immutable _minterFilter;
110
118
 
111
- /// minterType for this minter
119
+ /// @notice minterType for this minter
112
120
  string public constant minterType = "MinterSEAV1";
113
121
 
114
- /// minter version for this minter
122
+ /// @notice minter version for this minter
115
123
  string public constant minterVersion = "v1.0.0";
116
124
 
125
+ /// @notice Minimum auction duration
117
126
  uint256 public constant MIN_AUCTION_DURATION_SECONDS = 60; // seconds
118
127
 
119
128
  // minter-wide, AdminACL-configurable parameters, where AdminACL is the
120
129
  // admin of this minter's MinterFilter.
121
130
  // ----------------------------------------
122
- // minimum time remaining in auction after a new bid is placed
123
- // configureable by admin, default to 120 seconds
124
- // max uint32 ~= 4.3e9 sec ~= 136 years
125
- // @dev used when determining the buffer time for any new bid on the
126
- // minter, across all projects
127
- uint32 minterTimeBufferSeconds = 120;
128
- // gas limit for refunding ETH to bidders
129
- // configurable by admin, default to 30,000
130
- // max uint24 ~= 16 million gas, more than enough for a refund
131
- // @dev SENDALL fallback is used to refund ETH if this limit is exceeded
132
- uint24 minterRefundGasLimit = 30_000;
133
-
134
- // storage mappings for project and contract configs
135
- // @dev base minter project config is not used on this minter, therefore no
136
- // mapping is declared here to ProjectConfig structs
137
-
138
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
139
- // STATE VARIABLES FOR SplitFundsLib begin here
140
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
141
-
142
- // contractAddress => IsEngineCache
143
- mapping(address => SplitFundsLib.IsEngineCache) private _isEngineCaches;
144
-
145
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
146
- // STATE VARIABLES FOR SplitFundsLib end here
147
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
148
-
149
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
150
- // STATE VARIABLES FOR MaxInvocationsLib begin here
151
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
152
-
153
- // contractAddress => projectId => max invocations specific project config
154
- mapping(address => mapping(uint256 => MaxInvocationsLib.MaxInvocationsProjectConfig))
155
- private _maxInvocationsProjectConfigMapping;
156
-
157
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
158
- // STATE VARIABLES FOR MaxInvocationsLib end here
159
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
160
131
 
161
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
162
- // STATE VARIABLES FOR SEALib begin here
163
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
164
-
165
- // contractAddress => projectId => SEA project config
166
- mapping(address => mapping(uint256 => SEALib.SEAProjectConfig))
167
- private _SEAProjectConfigs;
132
+ /** @notice minimum time remaining in auction after a new bid is placed
133
+ * configureable by admin, default to 120 seconds
134
+ * max uint32 ~= 4.3e9 sec ~= 136 years
135
+ * @dev used when determining the buffer time for any new bid on the
136
+ * minter, across all projects
137
+ */
138
+ uint32 internal _minterTimeBufferSeconds = 120;
168
139
 
169
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
170
- // STATE VARIABLES FOR SEALib end here
171
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
140
+ /** @notice Gas limit for refunding ETH to bidders
141
+ * configurable by admin, default to 30,000
142
+ * max uint24 ~= 16 million gas, more than enough for a refund
143
+ * @dev SENDALL fallback is used to refund ETH if this limit is exceeded
144
+ */
145
+ uint24 internal _minterRefundGasLimit = 30_000;
172
146
 
173
147
  // MODIFIERS
174
148
  // @dev contract uses modifier-like internal functions instead of modifiers
@@ -182,56 +156,56 @@ contract MinterSEAV1 is ReentrancyGuard, ISharedMinterV0, ISharedMinterSEAV0 {
182
156
 
183
157
  /**
184
158
  * @notice Initializes contract to be a shared, filtered minter for
185
- * minter filter `_minterFilter`
186
- * @param _minterFilter Minter filter for which this will be a minter
159
+ * minter filter `minterFilter`
160
+ * @param minterFilter Minter filter for which this will be a minter
187
161
  */
188
- constructor(address _minterFilter) ReentrancyGuard() {
189
- minterFilterAddress = _minterFilter;
190
- minterFilter = IMinterFilterV1(_minterFilter);
162
+ constructor(address minterFilter) ReentrancyGuard() {
163
+ minterFilterAddress = minterFilter;
164
+ _minterFilter = IMinterFilterV1(minterFilter);
191
165
  // emit events indicating default minter configuration values
192
- emit MinAuctionDurationSecondsUpdated(MIN_AUCTION_DURATION_SECONDS);
193
- emit MinterTimeBufferUpdated(minterTimeBufferSeconds);
194
- emit MinterRefundGasLimitUpdated(minterRefundGasLimit);
166
+ emit SEALib.MinAuctionDurationSecondsUpdated(
167
+ MIN_AUCTION_DURATION_SECONDS
168
+ );
169
+ emit SEALib.MinterTimeBufferUpdated(_minterTimeBufferSeconds);
170
+ emit SEALib.MinterRefundGasLimitUpdated(_minterRefundGasLimit);
195
171
  }
196
172
 
197
173
  /**
198
- * @notice Manually sets the local maximum invocations of project `_projectId`
199
- * with the provided `_maxInvocations`, checking that `_maxInvocations` is less
200
- * than or equal to the value of project `_project_id`'s maximum invocations that is
174
+ * @notice Manually sets the local maximum invocations of project `projectId`
175
+ * with the provided `maxInvocations`, checking that `maxInvocations` is less
176
+ * than or equal to the value of project `project_id`'s maximum invocations that is
201
177
  * set on the core contract.
202
- * @dev Note that a `_maxInvocations` of 0 can only be set if the current `invocations`
178
+ * @dev Note that a `maxInvocations` of 0 can only be set if the current `invocations`
203
179
  * value is also 0 and this would also set `maxHasBeenInvoked` to true, correctly short-circuiting
204
180
  * this minter's purchase function, avoiding extra gas costs from the core contract's maxInvocations check.
205
- * @param _projectId Project ID to set the maximum invocations for.
206
- * @param _coreContract Core contract address for the given project.
207
- * @param _maxInvocations Maximum invocations to set for the project.
181
+ * @param projectId Project ID to set the maximum invocations for.
182
+ * @param coreContract Core contract address for the given project.
183
+ * @param maxInvocations Maximum invocations to set for the project.
208
184
  */
209
185
  function manuallyLimitProjectMaxInvocations(
210
- uint256 _projectId,
211
- address _coreContract,
212
- uint24 _maxInvocations
186
+ uint256 projectId,
187
+ address coreContract,
188
+ uint24 maxInvocations
213
189
  ) external {
214
190
  AuthLib.onlyArtist({
215
- _projectId: _projectId,
216
- _coreContract: _coreContract,
217
- _sender: msg.sender
191
+ projectId: projectId,
192
+ coreContract: coreContract,
193
+ sender: msg.sender
194
+ });
195
+ MaxInvocationsLib.manuallyLimitProjectMaxInvocations({
196
+ projectId: projectId,
197
+ coreContract: coreContract,
198
+ maxInvocations: maxInvocations
218
199
  });
219
- MaxInvocationsLib.manuallyLimitProjectMaxInvocations(
220
- _projectId,
221
- _coreContract,
222
- _maxInvocations,
223
- _maxInvocationsProjectConfigMapping[_coreContract][_projectId]
224
- );
225
- emit ProjectMaxInvocationsLimitUpdated(
226
- _projectId,
227
- _coreContract,
228
- _maxInvocations
229
- );
230
200
 
231
201
  // @dev the following is unique behavior to this minter
232
202
  // for convenience, try to mint and assign a token to the project's
233
203
  // next slot
234
- _tryMintTokenToNextSlot(_projectId, _coreContract);
204
+ SEALib.tryMintTokenToNextSlot({
205
+ projectId: projectId,
206
+ coreContract: coreContract,
207
+ minterFilter: _minterFilter
208
+ });
235
209
  }
236
210
 
237
211
  /**
@@ -239,22 +213,22 @@ contract MinterSEAV1 is ReentrancyGuard, ISharedMinterV0, ISharedMinterSEAV0 {
239
213
  * the minimum amount of time that must pass between the final bid and the
240
214
  * the end of an auction. Auctions are extended if a new bid is placed
241
215
  * within this time buffer of the auction end time.
242
- * @param _minterTimeBufferSeconds Time buffer in seconds.
216
+ * @param minterTimeBufferSeconds Time buffer in seconds.
243
217
  */
244
218
  function updateMinterTimeBufferSeconds(
245
- uint32 _minterTimeBufferSeconds
219
+ uint32 minterTimeBufferSeconds
246
220
  ) external {
247
221
  // CHECKS
248
- _onlyNonZero(_minterTimeBufferSeconds);
222
+ _onlyNonZero(minterTimeBufferSeconds);
249
223
  AuthLib.onlyMinterFilterAdminACL({
250
- _minterFilterAddress: minterFilterAddress,
251
- _sender: msg.sender,
252
- _contract: address(this),
253
- _selector: this.updateMinterTimeBufferSeconds.selector
224
+ minterFilterAddress: minterFilterAddress,
225
+ sender: msg.sender,
226
+ contract_: address(this),
227
+ selector: this.updateMinterTimeBufferSeconds.selector
254
228
  });
255
229
  // EFFECTS
256
- minterTimeBufferSeconds = _minterTimeBufferSeconds;
257
- emit MinterTimeBufferUpdated(_minterTimeBufferSeconds);
230
+ _minterTimeBufferSeconds = minterTimeBufferSeconds;
231
+ emit SEALib.MinterTimeBufferUpdated(minterTimeBufferSeconds);
258
232
  }
259
233
 
260
234
  /**
@@ -265,95 +239,76 @@ contract MinterSEAV1 is ReentrancyGuard, ISharedMinterV0, ISharedMinterSEAV0 {
265
239
  * bid.
266
240
  * @dev max gas limit is ~16M, which is considered well over a future-safe
267
241
  * upper bound.
268
- * @param _minterRefundGasLimit Gas limit to set for refunds. Must be
242
+ * @param minterRefundGasLimit Gas limit to set for refunds. Must be
269
243
  * between 7,000 and max uint24 (~16M).
270
244
  */
271
- function updateRefundGasLimit(uint24 _minterRefundGasLimit) external {
245
+ function updateRefundGasLimit(uint24 minterRefundGasLimit) external {
272
246
  // CHECKS
273
247
  AuthLib.onlyMinterFilterAdminACL({
274
- _minterFilterAddress: minterFilterAddress,
275
- _sender: msg.sender,
276
- _contract: address(this),
277
- _selector: this.updateRefundGasLimit.selector
248
+ minterFilterAddress: minterFilterAddress,
249
+ sender: msg.sender,
250
+ contract_: address(this),
251
+ selector: this.updateRefundGasLimit.selector
278
252
  });
279
- // @dev max gas limit implicitly checked by using uint16 input arg
253
+ // @dev max gas limit implicitly checked by using uint24 input arg
280
254
  // @dev min gas limit is based on rounding up current cost to send ETH
281
255
  // to a Gnosis Safe wallet, which accesses cold address and emits event
282
- require(_minterRefundGasLimit >= 7_000, "Only gte 7_000");
256
+ require(minterRefundGasLimit >= 7_000, "Only gte 7_000");
283
257
  // EFFECTS
284
- minterRefundGasLimit = _minterRefundGasLimit;
285
- emit MinterRefundGasLimitUpdated(_minterRefundGasLimit);
258
+ _minterRefundGasLimit = minterRefundGasLimit;
259
+ emit SEALib.MinterRefundGasLimitUpdated(minterRefundGasLimit);
286
260
  }
287
261
 
288
262
  /**
289
- * @notice Sets auction details for project `_projectId`.
263
+ * @notice Sets auction details for project `projectId`.
290
264
  * If project does not have a "next token" assigned, this function attempts
291
265
  * to mint a token and assign it to the project's next token slot.
292
- * @param _projectId Project ID to set future auction details for.
293
- * @param _coreContract Core contract address for the given project.
294
- * @param _timestampStart Timestamp after which new auctions may be
266
+ * @param projectId Project ID to set future auction details for.
267
+ * @param coreContract Core contract address for the given project.
268
+ * @param timestampStart Timestamp after which new auctions may be
295
269
  * started. Note that this is not the timestamp of the auction start, but
296
270
  * rather the timestamp after which a auction may be started. Also note
297
271
  * that the passed value here must either be in the future, or `0` (which
298
272
  * indicates that auctions are immediately startable).
299
- * @param _auctionDurationSeconds Duration of new auctions, in seconds,
273
+ * @param auctionDurationSeconds Duration of new auctions, in seconds,
300
274
  * before any extensions due to bids being placed inside buffer period near
301
275
  * the end of an auction.
302
- * @param _basePrice reserve price (minimum starting bid price), in wei.
276
+ * @param basePrice reserve price (minimum starting bid price), in wei.
303
277
  * Must be greater than 0, but may be as low as 1 wei.
304
- * @param _minBidIncrementPercentage Minimum percentage amount that a new
278
+ * @param minBidIncrementPercentage Minimum percentage amount that a new
305
279
  * bid must be over the previous bid. Must be greater than 0, and may be as
306
280
  * high as 255. Recommended value is 5%. Values represent whole
307
281
  * percentages, so a value of 5 represents 5%.
308
- * @dev `_basePrice` of zero not allowed to prevent accidental
282
+ * @dev `basePrice` of zero not allowed to prevent accidental
309
283
  * misconfiguration of auctions
310
284
  */
311
285
  function configureFutureAuctions(
312
- uint256 _projectId,
313
- address _coreContract,
314
- uint256 _timestampStart,
315
- uint256 _auctionDurationSeconds,
316
- uint256 _basePrice,
317
- uint8 _minBidIncrementPercentage
286
+ uint256 projectId,
287
+ address coreContract,
288
+ uint256 timestampStart,
289
+ uint256 auctionDurationSeconds,
290
+ uint256 basePrice,
291
+ uint8 minBidIncrementPercentage
318
292
  ) external {
319
293
  // CHECKS
320
- _onlyNonZero(_basePrice);
321
- _onlyNonZero(_minBidIncrementPercentage);
294
+ _onlyNonZero(basePrice);
295
+ _onlyNonZero(minBidIncrementPercentage);
322
296
  AuthLib.onlyArtist({
323
- _projectId: _projectId,
324
- _coreContract: _coreContract,
325
- _sender: msg.sender
297
+ projectId: projectId,
298
+ coreContract: coreContract,
299
+ sender: msg.sender
326
300
  });
327
- SEALib.SEAProjectConfig storage _SEAProjectConfig = _SEAProjectConfigs[
328
- _coreContract
329
- ][_projectId];
330
- MaxInvocationsLib.MaxInvocationsProjectConfig
331
- storage _maxInvocationsProjectConfig = _maxInvocationsProjectConfigMapping[
332
- _coreContract
333
- ][_projectId];
334
301
  require(
335
- _timestampStart == 0 || block.timestamp < _timestampStart,
336
- "Only future start times or 0"
337
- );
338
- require(
339
- _auctionDurationSeconds >= MIN_AUCTION_DURATION_SECONDS,
302
+ auctionDurationSeconds >= MIN_AUCTION_DURATION_SECONDS,
340
303
  "Auction duration below minimum"
341
304
  );
342
- // EFFECTS
343
- _SEAProjectConfig.timestampStart = _timestampStart.toUint64();
344
- _SEAProjectConfig.auctionDurationSeconds = _auctionDurationSeconds
345
- .toUint32();
346
- _SEAProjectConfig.basePrice = _basePrice;
347
- _SEAProjectConfig
348
- .minBidIncrementPercentage = _minBidIncrementPercentage;
349
-
350
- emit ConfiguredFutureAuctions({
351
- projectId: _projectId,
352
- coreContract: _coreContract,
353
- timestampStart: _timestampStart.toUint64(),
354
- auctionDurationSeconds: _auctionDurationSeconds.toUint32(),
355
- basePrice: _basePrice,
356
- minBidIncrementPercentage: _minBidIncrementPercentage
305
+ SEALib.configureFutureAuctions({
306
+ projectId: projectId,
307
+ coreContract: coreContract,
308
+ timestampStart: timestampStart,
309
+ auctionDurationSeconds: auctionDurationSeconds,
310
+ basePrice: basePrice,
311
+ minBidIncrementPercentage: minBidIncrementPercentage
357
312
  });
358
313
 
359
314
  // for convenience, sync local max invocations to the core contract if
@@ -363,22 +318,30 @@ contract MinterSEAV1 is ReentrancyGuard, ISharedMinterV0, ISharedMinterSEAV0 {
363
318
  // intentionally less than the core contract's max invocations.
364
319
  // sync local max invocations if not initially populated
365
320
  if (
366
- MaxInvocationsLib.maxInvocationsIsUnconfigured(
367
- _maxInvocationsProjectConfig
368
- )
321
+ MaxInvocationsLib.maxInvocationsIsUnconfigured({
322
+ projectId: projectId,
323
+ coreContract: coreContract
324
+ })
369
325
  ) {
370
- syncProjectMaxInvocationsToCore(_projectId, _coreContract);
326
+ syncProjectMaxInvocationsToCore({
327
+ projectId: projectId,
328
+ coreContract: coreContract
329
+ });
371
330
  // @dev syncProjectMaxInvocationsToCore function calls
372
- // _tryMintTokenToNextSlot, so we do not call it here.
331
+ // SEALib.tryMintTokenToNextSlot, so we do not call it here.
373
332
  } else {
374
333
  // for convenience, try to mint to next token slot
375
- _tryMintTokenToNextSlot(_projectId, _coreContract);
334
+ SEALib.tryMintTokenToNextSlot({
335
+ projectId: projectId,
336
+ coreContract: coreContract,
337
+ minterFilter: _minterFilter
338
+ });
376
339
  }
377
340
  }
378
341
 
379
342
  /**
380
- * @notice Resets future auction configuration for project `_projectId` on
381
- * core contract `_coreContract`, zero-ing out all details having to do
343
+ * @notice Resets future auction configuration for project `projectId` on
344
+ * core contract `coreContract`, zero-ing out all details having to do
382
345
  * with future auction parameters.
383
346
  * This is not intended to be used in normal operation, but rather only in
384
347
  * case of the need to halt the creation of any future auctions.
@@ -386,36 +349,35 @@ contract MinterSEAV1 is ReentrancyGuard, ISharedMinterV0, ISharedMinterSEAV0 {
386
349
  * Does not affect any project next token details (i.e. if a next token is
387
350
  * assigned, it will remain assigned and held by the minter until auction
388
351
  * details are reconfigured).
389
- * @param _projectId Project ID to reset future auction configuration
352
+ * @param projectId Project ID to reset future auction configuration
390
353
  * details for.
391
- * @param _coreContract Core contract address for the given project.
354
+ * @param coreContract Core contract address for the given project.
392
355
  */
393
356
  function resetFutureAuctionDetails(
394
- uint256 _projectId,
395
- address _coreContract
357
+ uint256 projectId,
358
+ address coreContract
396
359
  ) external {
397
360
  AuthLib.onlyCoreAdminACLOrArtist({
398
- _projectId: _projectId,
399
- _coreContract: _coreContract,
400
- _sender: msg.sender,
401
- _contract: address(this),
402
- _selector: this.resetFutureAuctionDetails.selector
361
+ projectId: projectId,
362
+ coreContract: coreContract,
363
+ sender: msg.sender,
364
+ contract_: address(this),
365
+ selector: this.resetFutureAuctionDetails.selector
403
366
  });
404
- SEALib.SEAProjectConfig storage _SEAProjectConfig = _SEAProjectConfigs[
405
- _coreContract
406
- ][_projectId];
407
367
  // reset to initial values
408
- SEALib.resetFutureAuctionDetails(_SEAProjectConfig);
368
+ SEALib.resetFutureAuctionDetails({
369
+ projectId: projectId,
370
+ coreContract: coreContract
371
+ });
409
372
  // @dev do not affect next token or max invocations
410
- emit ResetAuctionDetails(_projectId, _coreContract);
411
373
  }
412
374
 
413
375
  /**
414
376
  * @notice Admin-only function that ejects a project's "next token" from
415
- * the minter and sends it to the input `_to` address.
377
+ * the minter and sends it to the input `to` address.
416
378
  * This function is only intended for use in the edge case where the minter
417
379
  * has a "next token" assigned to a project, but the project has been reset
418
- * via `resetAuctionDetails`, and the artist does not want an auction to be
380
+ * via `resetFutureAuctionDetails`, and the artist does not want an auction to be
419
381
  * started for the "next token". This function also protects against the
420
382
  * unforseen case where the minter is in an unexpected state where it has a
421
383
  * "next token" assigned to a project, but for some reason the project is
@@ -425,129 +387,109 @@ contract MinterSEAV1 is ReentrancyGuard, ISharedMinterV0, ISharedMinterSEAV0 {
425
387
  * no further tokens will be assigned to the project's "next token" slot,
426
388
  * unless the project is subsequently reconfigured via an artist call to
427
389
  * `configureFutureAuctions`.
428
- * @param _projectId Project ID to eject next token for.
429
- * @param _coreContract Core contract address for the given project.
430
- * @param _to Address to send the ejected token to.
390
+ * @param projectId Project ID to eject next token for.
391
+ * @param coreContract Core contract address for the given project.
392
+ * @param to Address to send the ejected token to.
431
393
  */
432
394
  function ejectNextTokenTo(
433
- uint256 _projectId,
434
- address _coreContract,
435
- address _to
395
+ uint256 projectId,
396
+ address coreContract,
397
+ address to
436
398
  ) external {
437
399
  AuthLib.onlyCoreAdminACL({
438
- _coreContract: _coreContract,
439
- _sender: msg.sender,
440
- _contract: address(this),
441
- _selector: this.ejectNextTokenTo.selector
400
+ coreContract: coreContract,
401
+ sender: msg.sender,
402
+ contract_: address(this),
403
+ selector: this.ejectNextTokenTo.selector
442
404
  });
443
- SEALib.SEAProjectConfig storage _SEAProjectConfig = _SEAProjectConfigs[
444
- _coreContract
445
- ][_projectId];
446
- // CHECKS
447
- // only if project is not configured (i.e. artist called
448
- // `resetAuctionDetails`)
449
- require(
450
- !SEALib.projectIsConfigured(_SEAProjectConfig),
451
- "Only unconfigured projects"
452
- );
453
- // only if project has a next token assigned
454
- require(
455
- _SEAProjectConfig.nextTokenNumberIsPopulated == true,
456
- "No next token"
457
- );
458
- // EFFECTS
459
- _SEAProjectConfig.nextTokenNumberIsPopulated = false;
460
- // INTERACTIONS
461
- // @dev overflow automatically handled by Sol ^0.8.0
462
- uint256 nextTokenId = ABHelpers.tokenIdFromProjectIdAndTokenNumber({
463
- _projectId: _projectId,
464
- _tokenNumber: _SEAProjectConfig.nextTokenNumber
465
- });
466
- IERC721(_coreContract).transferFrom({
467
- from: address(this),
468
- to: _to,
469
- tokenId: nextTokenId
405
+ SEALib.ejectNextTokenTo({
406
+ projectId: projectId,
407
+ coreContract: coreContract,
408
+ to: to
470
409
  });
471
- emit ProjectNextTokenEjected(_projectId, _coreContract);
472
410
  }
473
411
 
474
412
  /**
475
- * @notice Settles any complete auction for token `_settleTokenId` (if
413
+ * @notice Settles any complete auction for token `settleTokenId` (if
476
414
  * applicable), then attempts to create a bid for token
477
- * `_bidTokenId` with bid amount and bidder address equal to
415
+ * `bidTokenId` with bid amount and bidder address equal to
478
416
  * `msg.value` and `msg.sender`, respectively.
479
417
  * Intended to gracefully handle the case where a user is front-run by
480
418
  * one or more transactions to settle and/or initialize a new auction,
481
419
  * potentially still placing a bid on the auction for the token ID if the
482
420
  * bid value is sufficiently higher than the current highest bid.
483
- * Note that the use of `_bidTokenId` is to prevent the possibility of
421
+ * Note that the use of `bidTokenId` is to prevent the possibility of
484
422
  * transactions that are stuck in the pending pool for long periods of time
485
423
  * from unintentionally bidding on auctions for future tokens.
486
424
  * Note that calls to `settleAuction` and `createBid` are possible
487
425
  * to be called in separate transactions, but this function is provided for
488
426
  * convenience and executes both of those functions in a single
489
427
  * transaction, while handling front-running as gracefully as possible.
490
- * @param _settleTokenId Token ID to settle auction for.
491
- * @param _bidTokenId Token ID to bid on.
492
- * @param _coreContract Core contract address for the given project.
428
+ * @param settleTokenId Token ID to settle auction for.
429
+ * @param bidTokenId Token ID to bid on.
430
+ * @param coreContract Core contract address for the given project.
493
431
  * @dev this function is not non-reentrant, but the underlying calls are
494
432
  * to non-reentrant functions.
495
433
  */
496
434
  function settleAuctionAndCreateBid(
497
- uint256 _settleTokenId,
498
- uint256 _bidTokenId,
499
- address _coreContract
435
+ uint256 settleTokenId,
436
+ uint256 bidTokenId,
437
+ address coreContract
500
438
  ) external payable {
501
439
  // ensure tokens are in the same project
502
440
  require(
503
- ABHelpers.tokenIdToProjectId(_settleTokenId) ==
504
- ABHelpers.tokenIdToProjectId(_bidTokenId),
441
+ ABHelpers.tokenIdToProjectId(settleTokenId) ==
442
+ ABHelpers.tokenIdToProjectId(bidTokenId),
505
443
  "Only tokens in same project"
506
444
  );
507
445
  // settle completed auction, if applicable
508
- settleAuction(_settleTokenId, _coreContract);
446
+ settleAuction({tokenId: settleTokenId, coreContract: coreContract});
509
447
  // attempt to bid on next token
510
- createBid(_bidTokenId, _coreContract);
448
+ createBid({tokenId: bidTokenId, coreContract: coreContract});
511
449
  }
512
450
 
513
451
  /**
514
452
  * @notice View function to return the current minter-level configuration
515
453
  * details.
516
- * @return minAuctionDurationSeconds_ Minimum auction duration in seconds.
454
+ * @return minAuctionDurationSeconds Minimum auction duration in seconds.
517
455
  * Note that this value is a constant on this version of the minter.
518
- * @return minterTimeBufferSeconds_ Buffer time in seconds
519
- * @return minterRefundGasLimit_ Gas limit for refunding ETH
456
+ * @return minterTimeBufferSeconds Buffer time in seconds
457
+ * @return minterRefundGasLimit Gas limit for refunding ETH
520
458
  */
521
459
  function minterConfigurationDetails()
522
460
  external
523
461
  view
524
462
  returns (
525
- uint256 minAuctionDurationSeconds_,
526
- uint32 minterTimeBufferSeconds_,
527
- uint24 minterRefundGasLimit_
463
+ uint256 minAuctionDurationSeconds,
464
+ uint32 minterTimeBufferSeconds,
465
+ uint24 minterRefundGasLimit
528
466
  )
529
467
  {
530
- minAuctionDurationSeconds_ = MIN_AUCTION_DURATION_SECONDS;
531
- minterTimeBufferSeconds_ = minterTimeBufferSeconds;
532
- minterRefundGasLimit_ = minterRefundGasLimit;
468
+ minAuctionDurationSeconds = MIN_AUCTION_DURATION_SECONDS;
469
+ minterTimeBufferSeconds = _minterTimeBufferSeconds;
470
+ minterRefundGasLimit = _minterRefundGasLimit;
533
471
  }
534
472
 
535
473
  /**
536
474
  * @notice Gets the maximum invocations project configuration.
537
- * @param _projectId The ID of the project whose data needs to be fetched.
538
- * @param _coreContract The address of the core contract.
475
+ * @param projectId The ID of the project whose data needs to be fetched.
476
+ * @param coreContract The address of the core contract.
539
477
  * @return MaxInvocationsLib.MaxInvocationsProjectConfig instance with the
540
478
  * configuration data.
541
479
  */
542
480
  function maxInvocationsProjectConfig(
543
- uint256 _projectId,
544
- address _coreContract
481
+ uint256 projectId,
482
+ address coreContract
545
483
  )
546
484
  external
547
485
  view
548
486
  returns (MaxInvocationsLib.MaxInvocationsProjectConfig memory)
549
487
  {
550
- return _maxInvocationsProjectConfigMapping[_coreContract][_projectId];
488
+ return
489
+ MaxInvocationsLib.getMaxInvocationsProjectConfig({
490
+ projectId: projectId,
491
+ coreContract: coreContract
492
+ });
551
493
  }
552
494
 
553
495
  /**
@@ -561,17 +503,18 @@ contract MinterSEAV1 is ReentrancyGuard, ISharedMinterV0, ISharedMinterSEAV0 {
561
503
  * possible because the V3 core contract only allows maximum invocations
562
504
  * to be reduced, not increased. Based on this rationale, we intentionally
563
505
  * do not do input validation in this method as to whether or not the input
564
- * @param `_projectId` is an existing project ID.
565
- * @param `_coreContract` is an existing core contract address.
506
+ * @param projectId is an existing project ID.
507
+ * @param coreContract is an existing core contract address.
566
508
  */
567
509
  function projectMaxHasBeenInvoked(
568
- uint256 _projectId,
569
- address _coreContract
510
+ uint256 projectId,
511
+ address coreContract
570
512
  ) external view returns (bool) {
571
513
  return
572
- MaxInvocationsLib.getMaxHasBeenInvoked(
573
- _maxInvocationsProjectConfigMapping[_coreContract][_projectId]
574
- );
514
+ MaxInvocationsLib.getMaxHasBeenInvoked({
515
+ projectId: projectId,
516
+ coreContract: coreContract
517
+ });
575
518
  }
576
519
 
577
520
  /**
@@ -590,41 +533,41 @@ contract MinterSEAV1 is ReentrancyGuard, ISharedMinterV0, ISharedMinterSEAV0 {
590
533
  * increased. When this happens, the minter will enable minting, allowing
591
534
  * the core contract to enforce the max invocations check. Based on this
592
535
  * rationale, we intentionally do not do input validation in this method as
593
- * to whether or not the input `_projectId` is an existing project ID.
594
- * @param `_projectId` is an existing project ID.
595
- * @param `_coreContract` is an existing core contract address.
536
+ * to whether or not the input `projectId` is an existing project ID.
537
+ * @param projectId is an existing project ID.
538
+ * @param coreContract is an existing core contract address.
596
539
  */
597
540
  function projectMaxInvocations(
598
- uint256 _projectId,
599
- address _coreContract
541
+ uint256 projectId,
542
+ address coreContract
600
543
  ) external view returns (uint256) {
601
544
  return
602
- MaxInvocationsLib.getMaxInvocations(
603
- _maxInvocationsProjectConfigMapping[_coreContract][_projectId]
604
- );
545
+ MaxInvocationsLib.getMaxInvocations({
546
+ projectId: projectId,
547
+ coreContract: coreContract
548
+ });
605
549
  }
606
550
 
607
551
  /**
608
- * @notice Checks if the specified `_coreContract` is a valid engine contract.
609
- * @dev This function retrieves the cached value of `_isEngine` from
552
+ * @notice Checks if the specified `coreContract` is a valid engine contract.
553
+ * @dev This function retrieves the cached value of `isEngine` from
610
554
  * the `isEngineCache` mapping. If the cached value is already set, it
611
- * returns the cached value. Otherwise, it calls the `getV3CoreIsEngine`
612
- * function from the `SplitFundsLib` library to check if `_coreContract`
555
+ * returns the cached value. Otherwise, it calls the `getV3CoreIsEngineView`
556
+ * function from the `SplitFundsLib` library to check if `coreContract`
613
557
  * is a valid engine contract.
614
- * @dev This function will revert if the provided `_coreContract` is not
558
+ * @dev This function will revert if the provided `coreContract` is not
615
559
  * a valid Engine or V3 Flagship contract.
616
- * @param _coreContract The address of the contract to check.
617
- * @return bool indicating if `_coreContract` is a valid engine contract.
560
+ * @param coreContract The address of the contract to check.
561
+ * @return bool indicating if `coreContract` is a valid engine contract.
618
562
  */
619
- function isEngineView(address _coreContract) external view returns (bool) {
620
- SplitFundsLib.IsEngineCache storage isEngineCache = _isEngineCaches[
621
- _coreContract
622
- ];
563
+ function isEngineView(address coreContract) external view returns (bool) {
564
+ SplitFundsLib.IsEngineCache storage isEngineCache = SplitFundsLib
565
+ .getIsEngineCacheConfig(coreContract);
623
566
  if (isEngineCache.isCached) {
624
567
  return isEngineCache.isEngine;
625
568
  } else {
626
- // @dev this calls the non-modifying variant of getV3CoreIsEngine
627
- return SplitFundsLib.getV3CoreIsEngineView(_coreContract);
569
+ // @dev this calls the non-state-modifying variant of isEngine
570
+ return SplitFundsLib.getV3CoreIsEngineView(coreContract);
628
571
  }
629
572
  }
630
573
 
@@ -632,36 +575,40 @@ contract MinterSEAV1 is ReentrancyGuard, ISharedMinterV0, ISharedMinterSEAV0 {
632
575
  * @notice projectId => SEA project configuration details.
633
576
  * Note that in the case of no auction being initialized for the project,
634
577
  * the returned `auction` will be the default struct.
635
- * @param _projectId The project ID
636
- * @param _coreContract The core contract address
637
- * @return _SEAProjectConfig The SEA project configuration details
578
+ * @param projectId The project ID
579
+ * @param coreContract The core contract address
580
+ * @return SEAProjectConfig_ The SEA project configuration details
638
581
  */
639
582
  function SEAProjectConfigurationDetails(
640
- uint256 _projectId,
641
- address _coreContract
642
- ) external view returns (SEALib.SEAProjectConfig memory _SEAProjectConfig) {
643
- _SEAProjectConfig = _SEAProjectConfigs[_coreContract][_projectId];
583
+ uint256 projectId,
584
+ address coreContract
585
+ ) external view returns (SEALib.SEAProjectConfig memory SEAProjectConfig_) {
586
+ SEAProjectConfig_ = SEALib.getSEAProjectConfig({
587
+ projectId: projectId,
588
+ coreContract: coreContract
589
+ });
644
590
  // clean up next token number to handle case where it is stale
645
- _SEAProjectConfig.nextTokenNumber = _SEAProjectConfig
591
+ SEAProjectConfig_.nextTokenNumber = SEAProjectConfig_
646
592
  .nextTokenNumberIsPopulated
647
- ? _SEAProjectConfig.nextTokenNumber
593
+ ? SEAProjectConfig_.nextTokenNumber
648
594
  : 0;
649
595
  }
650
596
 
651
597
  /**
652
598
  * @notice projectId => active auction details.
653
599
  * @dev reverts if no auction exists for the project.
654
- * @param _projectId The project ID
655
- * @param _coreContract The core contract address
600
+ * @param projectId The project ID
601
+ * @param coreContract The core contract address
656
602
  */
657
603
  function projectActiveAuctionDetails(
658
- uint256 _projectId,
659
- address _coreContract
604
+ uint256 projectId,
605
+ address coreContract
660
606
  ) external view returns (SEALib.Auction memory auction) {
661
- SEALib.SEAProjectConfig storage _SEAProjectConfig = _SEAProjectConfigs[
662
- _coreContract
663
- ][_projectId];
664
- return SEALib.projectActiveAuctionDetails(_SEAProjectConfig);
607
+ return
608
+ SEALib.projectActiveAuctionDetails({
609
+ projectId: projectId,
610
+ coreContract: coreContract
611
+ });
665
612
  }
666
613
 
667
614
  /**
@@ -674,37 +621,39 @@ contract MinterSEAV1 is ReentrancyGuard, ISharedMinterV0, ISharedMinterSEAV0 {
674
621
  * target bid token ID to be passed in as an argument.
675
622
  * The function reverts if a project does not have an active auction and
676
623
  * the next expected token ID has not been populated.
677
- * @param _projectId The project ID being queried
678
- * @param _coreContract The core contract address
624
+ * @param projectId The project ID being queried
625
+ * @param coreContract The core contract address
679
626
  * @return The current token ID being auctioned, or the next token ID to be
680
627
  * auctioned if a new auction is ready to be created.
681
628
  */
682
629
  function getTokenToBid(
683
- uint256 _projectId,
684
- address _coreContract
630
+ uint256 projectId,
631
+ address coreContract
685
632
  ) external view returns (uint256) {
686
- SEALib.SEAProjectConfig storage _SEAProjectConfig = _SEAProjectConfigs[
687
- _coreContract
688
- ][_projectId];
689
- return SEALib.getTokenToBid(_SEAProjectConfig, _projectId);
633
+ return
634
+ SEALib.getTokenToBid({
635
+ projectId: projectId,
636
+ coreContract: coreContract
637
+ });
690
638
  }
691
639
 
692
640
  /**
693
641
  * @notice View function that returns the next token ID to be auctioned
694
- * by this minter for project `_projectId`.
642
+ * by this minter for project `projectId`.
695
643
  * Reverts if the next token ID has not been populated for the project.
696
- * @param _projectId The project ID being queried
697
- * @param _coreContract The core contract address
644
+ * @param projectId The project ID being queried
645
+ * @param coreContract The core contract address
698
646
  * @return nextTokenId The next token ID to be auctioned by this minter
699
647
  */
700
648
  function getNextTokenId(
701
- uint256 _projectId,
702
- address _coreContract
649
+ uint256 projectId,
650
+ address coreContract
703
651
  ) external view returns (uint256 nextTokenId) {
704
- SEALib.SEAProjectConfig storage _SEAProjectConfig = _SEAProjectConfigs[
705
- _coreContract
706
- ][_projectId];
707
- return SEALib.getNextTokenId(_SEAProjectConfig, _projectId);
652
+ return
653
+ SEALib.getNextTokenId({
654
+ projectId: projectId,
655
+ coreContract: coreContract
656
+ });
708
657
  }
709
658
 
710
659
  /**
@@ -722,8 +671,8 @@ contract MinterSEAV1 is ReentrancyGuard, ISharedMinterV0, ISharedMinterSEAV0 {
722
671
  * token auction.
723
672
  * Also returns currency symbol and address to be being used as payment,
724
673
  * which for this minter is ETH only.
725
- * @param _projectId Project ID to get price information for.
726
- * @param _coreContract Core contract to get price information for.
674
+ * @param projectId Project ID to get price information for.
675
+ * @param coreContract Core contract to get price information for.
727
676
  * @return isConfigured true only if project auctions are configured.
728
677
  * @return tokenPriceInWei price in wei to become the leading bidder on a
729
678
  * token auction.
@@ -733,8 +682,8 @@ contract MinterSEAV1 is ReentrancyGuard, ISharedMinterV0, ISharedMinterSEAV0 {
733
682
  * this minter. This minter always returns null address, reserved for ether
734
683
  */
735
684
  function getPriceInfo(
736
- uint256 _projectId,
737
- address _coreContract
685
+ uint256 projectId,
686
+ address coreContract
738
687
  )
739
688
  external
740
689
  view
@@ -745,55 +694,51 @@ contract MinterSEAV1 is ReentrancyGuard, ISharedMinterV0, ISharedMinterSEAV0 {
745
694
  address currencyAddress
746
695
  )
747
696
  {
748
- SEALib.SEAProjectConfig storage _SEAProjectConfig = _SEAProjectConfigs[
749
- _coreContract
750
- ][_projectId];
751
- (isConfigured, tokenPriceInWei) = SEALib
752
- .getPriceInfoFromSEAProjectConfig(_SEAProjectConfig);
697
+ (isConfigured, tokenPriceInWei) = SEALib.getPriceInfo({
698
+ projectId: projectId,
699
+ coreContract: coreContract
700
+ });
753
701
  // currency is always ETH
754
702
  currencySymbol = "ETH";
755
703
  currencyAddress = address(0);
756
704
  }
757
705
 
758
706
  /**
759
- * @notice Syncs local maximum invocations of project `_projectId` based on
707
+ * @notice Syncs local maximum invocations of project `projectId` based on
760
708
  * the value currently defined in the core contract.
761
- * @param _projectId Project ID to set the maximum invocations for.
762
- * @param _coreContract Core contract address for the given project.
709
+ * @param projectId Project ID to set the maximum invocations for.
710
+ * @param coreContract Core contract address for the given project.
763
711
  * @dev this enables gas reduction after maxInvocations have been reached -
764
712
  * core contracts shall still enforce a maxInvocation check during mint.
765
713
  */
766
714
  function syncProjectMaxInvocationsToCore(
767
- uint256 _projectId,
768
- address _coreContract
715
+ uint256 projectId,
716
+ address coreContract
769
717
  ) public {
770
718
  AuthLib.onlyArtist({
771
- _projectId: _projectId,
772
- _coreContract: _coreContract,
773
- _sender: msg.sender
719
+ projectId: projectId,
720
+ coreContract: coreContract,
721
+ sender: msg.sender
774
722
  });
775
723
 
776
- uint256 maxInvocations = MaxInvocationsLib
777
- .syncProjectMaxInvocationsToCore(
778
- _projectId,
779
- _coreContract,
780
- _maxInvocationsProjectConfigMapping[_coreContract][_projectId]
781
- );
782
- emit ProjectMaxInvocationsLimitUpdated(
783
- _projectId,
784
- _coreContract,
785
- maxInvocations
786
- );
724
+ MaxInvocationsLib.syncProjectMaxInvocationsToCore({
725
+ projectId: projectId,
726
+ coreContract: coreContract
727
+ });
787
728
 
788
729
  // for convenience, try to mint and assign a token to the project's
789
730
  // next slot
790
- _tryMintTokenToNextSlot(_projectId, _coreContract);
731
+ SEALib.tryMintTokenToNextSlot({
732
+ projectId: projectId,
733
+ coreContract: coreContract,
734
+ minterFilter: _minterFilter
735
+ });
791
736
  }
792
737
 
793
738
  /**
794
739
  * @notice Emergency, Artist-only function that attempts to mint a new
795
740
  * token and set it as the the next token to be auctioned for project
796
- * `_projectId`.
741
+ * `projectId`.
797
742
  * Note: This function is only included for emergency, unforseen use cases,
798
743
  * and should not be used in normal operation. It is here only for
799
744
  * redundant protection against an unforseen edge case where the minter
@@ -806,105 +751,60 @@ contract MinterSEAV1 is ReentrancyGuard, ISharedMinterV0, ISharedMinterSEAV0 {
806
751
  * or minter
807
752
  * @dev This function is gated to only the project's artist to prevent
808
753
  * early minting of tokens by other users.
809
- * @param _projectId The project ID
810
- * @param _coreContract The core contract address for the given project.
754
+ * @param projectId The project ID
755
+ * @param coreContract The core contract address for the given project.
811
756
  */
812
757
  function tryPopulateNextToken(
813
- uint256 _projectId,
814
- address _coreContract
758
+ uint256 projectId,
759
+ address coreContract
815
760
  ) public nonReentrant {
816
761
  AuthLib.onlyArtist({
817
- _projectId: _projectId,
818
- _coreContract: _coreContract,
819
- _sender: msg.sender
762
+ projectId: projectId,
763
+ coreContract: coreContract,
764
+ sender: msg.sender
820
765
  });
821
766
  // CHECKS
822
767
  // revert if project is not configured on this minter
823
- SEALib.SEAProjectConfig storage _SEAProjectConfig = _SEAProjectConfigs[
824
- _coreContract
825
- ][_projectId];
826
768
  require(
827
- SEALib.projectIsConfigured(_SEAProjectConfig),
769
+ SEALib.projectIsConfigured({
770
+ projectId: projectId,
771
+ coreContract: coreContract
772
+ }),
828
773
  "Project not configured"
829
774
  );
830
775
  // INTERACTIONS
831
776
  // attempt to mint new token to this minter contract, only if max
832
777
  // invocations has not been reached
833
- _tryMintTokenToNextSlot(_projectId, _coreContract);
778
+ SEALib.tryMintTokenToNextSlot({
779
+ projectId: projectId,
780
+ coreContract: coreContract,
781
+ minterFilter: _minterFilter
782
+ });
834
783
  }
835
784
 
836
785
  /**
837
- * @notice Settles a completed auction for `_tokenId`, if it exists and is
786
+ * @notice Settles a completed auction for `tokenId`, if it exists and is
838
787
  * not yet settled.
839
- * Returns early (does not modify state) if
840
- * - there is no initialized auction for the project
788
+ * Function reverts if there is no initialized auction for the project.
789
+ * Function returns early (does not modify state) if
841
790
  * - there is an auction that has already been settled for the project
842
791
  * - there is an auction for a different token ID on the project
843
792
  * (likely due to a front-run)
844
- * This function reverts if the auction for `_tokenId` exists, but has not
793
+ * This function reverts if the auction for `tokenId` exists, but has not
845
794
  * yet ended.
846
- * @param _tokenId Token ID to settle auction for.
847
- * @param _coreContract Core contract address for the given project.
795
+ * @param tokenId Token ID to settle auction for.
796
+ * @param coreContract Core contract address for the given token.
848
797
  */
849
798
  function settleAuction(
850
- uint256 _tokenId,
851
- address _coreContract
799
+ uint256 tokenId,
800
+ address coreContract
852
801
  ) public nonReentrant {
853
- uint256 _projectId = ABHelpers.tokenIdToProjectId(_tokenId);
854
- SEALib.SEAProjectConfig storage _SEAProjectConfig = _SEAProjectConfigs[
855
- _coreContract
856
- ][_projectId];
857
- SEALib.Auction storage _auction = _SEAProjectConfig.activeAuction;
858
- // load from storage to memory for gas efficiency
859
- address currentBidder = _auction.currentBidder;
860
- uint256 currentBid = _auction.currentBid;
861
- // CHECKS
862
- // @dev this check is not strictly necessary, but is included for
863
- // clear error messaging
864
- require(
865
- SEALib.auctionIsInitialized(_auction),
866
- "Auction not initialized"
867
- );
868
- if (_auction.settled || (_auction.tokenId != _tokenId)) {
869
- // auction already settled or is for a different token ID, so
870
- // return early and do not modify state
871
- return;
872
- }
873
- // @dev important that the following check is after the early return
874
- // block above to maintain desired behavior
875
- require(block.timestamp >= _auction.endTime, "Auction not yet ended");
876
- // EFFECTS
877
- _auction.settled = true;
878
- // INTERACTIONS
879
- // send token to the winning bidder
880
- IERC721(_coreContract).transferFrom({
881
- from: address(this),
882
- to: currentBidder,
883
- tokenId: _tokenId
884
- });
885
- // distribute revenues from auction
886
- bool isEngine = SplitFundsLib.isEngine(
887
- _coreContract,
888
- _isEngineCaches[_coreContract]
889
- );
890
- SplitFundsLib.splitRevenuesETH({
891
- _projectId: _projectId,
892
- _valueInWei: currentBid,
893
- _coreContract: _coreContract,
894
- _isEngine: isEngine
895
- });
896
-
897
- emit AuctionSettled({
898
- tokenId: _tokenId,
899
- coreContract: _coreContract,
900
- winner: currentBidder,
901
- price: currentBid
902
- });
802
+ SEALib.settleAuction({tokenId: tokenId, coreContract: coreContract});
903
803
  }
904
804
 
905
805
  /**
906
- * @notice Enters a bid for token `_tokenId`.
907
- * If an auction for token `_tokenId` does not exist, an auction will be
806
+ * @notice Enters a bid for token `tokenId`.
807
+ * If an auction for token `tokenId` does not exist, an auction will be
908
808
  * initialized as long as any existing auction for the project has been
909
809
  * settled.
910
810
  * In order to successfully place the bid, the token bid must be:
@@ -924,7 +824,7 @@ contract MinterSEAV1 is ReentrancyGuard, ISharedMinterV0, ISharedMinterSEAV0 {
924
824
  * outbid and their funds are returned to the original `msg.sender` address
925
825
  * via SELFDESTRUCT (SENDALL).
926
826
  * ------------------------------------------------------------------------
927
- * Note that the use of `_tokenId` is to prevent the possibility of
827
+ * Note that the use of `tokenId` is to prevent the possibility of
928
828
  * transactions that are stuck in the pending pool for long periods of time
929
829
  * from unintentionally bidding on auctions for future tokens.
930
830
  * If a new auction is initialized during this call, the project's next
@@ -932,259 +832,22 @@ contract MinterSEAV1 is ReentrancyGuard, ISharedMinterV0, ISharedMinterSEAV0 {
932
832
  * it for the next auction. If the project's next token cannot be minted
933
833
  * due to e.g. reaching the maximum invocations on the core contract or
934
834
  * minter, the project's next token will not be minted.
935
- * @param _tokenId Token ID being bid on.
936
- * @param _coreContract Core contract address for the given project.
835
+ * @param tokenId Token ID being bid on.
836
+ * @param coreContract Core contract address for the given project.
937
837
  * @dev nonReentrant modifier is used to prevent reentrancy attacks, e.g.
938
838
  * an an auto-bidder that would be able to atomically outbid a user's
939
839
  * new bid via a reentrant call to createBid.
940
840
  */
941
841
  function createBid(
942
- uint256 _tokenId,
943
- address _coreContract
842
+ uint256 tokenId,
843
+ address coreContract
944
844
  ) public payable nonReentrant {
945
- uint256 _projectId = ABHelpers.tokenIdToProjectId(_tokenId);
946
- SEALib.SEAProjectConfig storage _SEAProjectConfig = _SEAProjectConfigs[
947
- _coreContract
948
- ][_projectId];
949
- SEALib.Auction storage _auction = _SEAProjectConfig.activeAuction;
950
- // CHECKS
951
- // ProjectConfig storage _projectConfig = projectConfig[_projectId];
952
- // load from storage to memory for gas efficiency
953
- uint256 auctionEndTime = _auction.endTime;
954
- uint256 previousBid = _auction.currentBid;
955
-
956
- // if no auction exists, or current auction is already settled, attempt
957
- // to initialize a new auction for the input token ID and immediately
958
- // return
959
- if ((!SEALib.auctionIsInitialized(_auction)) || _auction.settled) {
960
- _initializeAuctionWithBid(_projectId, _coreContract, _tokenId);
961
- return;
962
- }
963
- // @dev this branch is guaranteed to have an initialized auction that
964
- // not settled, so no need to check for initialized or not settled
965
-
966
- // ensure bids for a specific token ID are only applied to the auction
967
- // for that token ID.
968
- require(
969
- _auction.tokenId == _tokenId,
970
- "Token ID does not match auction"
971
- );
972
-
973
- // ensure auction is not already ended
974
- require(auctionEndTime > block.timestamp, "Auction already ended");
975
-
976
- // require bid to be sufficiently greater than current highest bid
977
- // @dev no overflow enforced automatically by solidity ^0.8.0
978
- require(
979
- msg.value >= SEALib.getMinimumNextBid(_auction),
980
- "Bid is too low"
981
- );
982
-
983
- // EFFECTS
984
- // record previous highest bider for refunding
985
- address payable previousBidder = _auction.currentBidder;
986
-
987
- // update auction bid state
988
- SEALib.auctionUpdateBid({
989
- _auction: _auction,
990
- _timeBufferSeconds: minterTimeBufferSeconds,
991
- _bidAmount: msg.value,
992
- _bidder: payable(msg.sender)
993
- });
994
-
995
- // INTERACTIONS
996
- // refund previous highest bidder
997
- SplitFundsLib.forceSafeTransferETH({
998
- _to: previousBidder,
999
- _amount: previousBid,
1000
- _minterRefundGasLimit: minterRefundGasLimit
1001
- });
1002
-
1003
- emit AuctionBid({
1004
- tokenId: _tokenId,
1005
- coreContract: _coreContract,
1006
- bidder: msg.sender,
1007
- bidAmount: msg.value
1008
- });
1009
- }
1010
-
1011
- /**
1012
- * @dev Internal function to initialize an auction for the next token ID
1013
- * on project `_projectId` with a bid of `msg.value` from `msg.sender`.
1014
- * This function reverts in any of the following cases:
1015
- * - project is not configured on this minter
1016
- * - project is configured but has not yet reached its start time
1017
- * - project has a current active auction that is not settled
1018
- * - insufficient bid amount (msg.value < basePrice)
1019
- * - no next token has been minted for the project (artist may need to
1020
- * call `tryPopulateNextToken`)
1021
- * - `_targetTokenId` does not match the next token ID for the project
1022
- * After initializing a new auction, this function attempts to mint a new
1023
- * token and assign it to the project's next token slot, in preparation for
1024
- * a future token auction. However, if the project has reached its maximum
1025
- * invocations on either the core contract or minter, the next token slot
1026
- * for the project will remain empty.
1027
- * @dev This should be executed in a nonReentrant context to provide redundant
1028
- * protection against reentrancy.
1029
- */
1030
- function _initializeAuctionWithBid(
1031
- uint256 _projectId,
1032
- address _coreContract,
1033
- uint256 _targetTokenId
1034
- ) internal {
1035
- SEALib.SEAProjectConfig storage _SEAProjectConfig = _SEAProjectConfigs[
1036
- _coreContract
1037
- ][_projectId];
1038
- SEALib.Auction storage _auction = _SEAProjectConfig.activeAuction;
1039
- // CHECKS
1040
- // ensure project auctions are configured
1041
- // @dev base price of zero indicates auctions are not configured
1042
- // because only base price of gt zero is allowed when configuring
1043
- require(
1044
- SEALib.projectIsConfigured(_SEAProjectConfig),
1045
- "Project not configured"
1046
- );
1047
- // only initialize new auctions if they meet the start time
1048
- // requirement
1049
- require(
1050
- block.timestamp >= _SEAProjectConfig.timestampStart,
1051
- "Only gte project start time"
1052
- );
1053
- // the following require statement is redundant based on how this
1054
- // internal function is called, but it is included for protection
1055
- // against future changes that could easily introduce a bug if this
1056
- // check is not present
1057
- // @dev no cover else branch of next line because unreachable
1058
- require(
1059
- (!SEALib.auctionIsInitialized(_auction)) || _auction.settled,
1060
- "Existing auction not settled"
1061
- );
1062
- // require valid bid value
1063
- require(
1064
- msg.value >= _SEAProjectConfig.basePrice,
1065
- "Insufficient initial bid"
1066
- );
1067
- // require next token number is populated
1068
- // @dev this should only be encountered if the project has reached
1069
- // its maximum invocations on either the core contract or minter
1070
- require(
1071
- _SEAProjectConfig.nextTokenNumberIsPopulated,
1072
- "No next token, check max invocations"
1073
- );
1074
- // require next token number is the target token ID
1075
- require(
1076
- _SEAProjectConfig.nextTokenNumber ==
1077
- ABHelpers.tokenIdToTokenNumber(_targetTokenId),
1078
- "Incorrect target token ID"
1079
- );
1080
-
1081
- // EFFECTS
1082
- // create new auction, overwriting previous auction if it exists
1083
- uint64 endTime = SEALib.overwriteProjectActiveAuction({
1084
- _SEAProjectConfig: _SEAProjectConfig,
1085
- _targetTokenId: _targetTokenId,
1086
- _bidAmount: msg.value,
1087
- _bidder: payable(msg.sender)
1088
- });
1089
- // mark next token number as not populated
1090
- // @dev intentionally not setting nextTokenNumber to zero to avoid
1091
- // unnecessary gas costs
1092
- _SEAProjectConfig.nextTokenNumberIsPopulated = false;
1093
-
1094
- // @dev we intentionally emit event here due to potential of early
1095
- // return in INTERACTIONS section
1096
- emit AuctionInitialized({
1097
- tokenId: _targetTokenId,
1098
- coreContract: _coreContract,
1099
- bidder: msg.sender,
1100
- bidAmount: msg.value,
1101
- endTime: endTime,
1102
- minBidIncrementPercentage: _SEAProjectConfig
1103
- .activeAuction
1104
- .minBidIncrementPercentage
1105
- });
1106
-
1107
- // INTERACTIONS
1108
- // attempt to mint new token to this minter contract, only if max
1109
- // invocations has not been reached
1110
- _tryMintTokenToNextSlot(_projectId, _coreContract);
1111
- }
1112
-
1113
- /**
1114
- * @notice Internal function that attempts to mint a new token to the next
1115
- * token slot for the project `_projectId`.
1116
- * This function returns early and does not modify state if
1117
- * - the project has reached its maximum invocations on either the core
1118
- * contract or minter
1119
- * - the project config's `nextTokenNumberIsPopulated` is already true
1120
- * @param _projectId The ID of the project to mint a new token for.
1121
- * @param _coreContract The core contract address
1122
- * @dev this calls mint with `msg.sender` as the sender, allowing artists
1123
- * to mint tokens to the next token slot for their project while a project
1124
- * is still paused. This happens when an artist is configuring their
1125
- * project's auction parameters or minter max invocations.
1126
- */
1127
- function _tryMintTokenToNextSlot(
1128
- uint256 _projectId,
1129
- address _coreContract
1130
- ) internal {
1131
- SEALib.SEAProjectConfig storage _SEAProjectConfig = _SEAProjectConfigs[
1132
- _coreContract
1133
- ][_projectId];
1134
- MaxInvocationsLib.MaxInvocationsProjectConfig
1135
- storage _maxInvocationProjectConfig = _maxInvocationsProjectConfigMapping[
1136
- _coreContract
1137
- ][_projectId];
1138
- if (_SEAProjectConfig.nextTokenNumberIsPopulated) {
1139
- return;
1140
- }
1141
- // INTERACTIONS
1142
- // attempt to mint new token to this minter contract, only if max
1143
- // invocations has not been reached
1144
- // we require up-to-date invocation data to properly handle last token
1145
- // and avoid revert if relying on core to limit invocations, therefore
1146
- // use MaxInvocationsLib.invocationsRemain, which calls core contract
1147
- // to get latest invocation data
1148
- if (
1149
- !MaxInvocationsLib.invocationsRemain(
1150
- _maxInvocationProjectConfig,
1151
- _projectId,
1152
- _coreContract
1153
- )
1154
- ) {
1155
- // we have reached the max invocations, so we do not mint a new
1156
- // token as the "next token", and leave the next token number as
1157
- // not populated
1158
- return;
1159
- }
1160
- // @dev this is an effect after a trusted contract interaction
1161
- _SEAProjectConfig.nextTokenNumberIsPopulated = true;
1162
- // mint a new token to this project's "next token" slot
1163
- // @dev this is an interaction with a trusted contract
1164
- uint256 nextTokenId = minterFilter.mint_joo(
1165
- address(this),
1166
- _projectId,
1167
- _coreContract,
1168
- msg.sender
1169
- );
1170
- // update state to reflect new token number
1171
- // @dev state changes after trusted contract interaction
1172
- // @dev unchecked is safe because mod 1e6 is guaranteed to be less than
1173
- // max uint24
1174
- unchecked {
1175
- _SEAProjectConfig.nextTokenNumber = uint24(
1176
- ABHelpers.tokenIdToTokenNumber(nextTokenId)
1177
- );
1178
- }
1179
- // update local maxHasBeenInvoked value if necessary
1180
- MaxInvocationsLib.validatePurchaseEffectsInvocations({
1181
- _tokenId: nextTokenId,
1182
- maxInvocationsProjectConfig: _maxInvocationProjectConfig
1183
- });
1184
- emit ProjectNextTokenUpdated({
1185
- projectId: _projectId,
1186
- coreContract: _coreContract,
1187
- tokenId: nextTokenId
845
+ SEALib.createBid({
846
+ tokenId: tokenId,
847
+ coreContract: coreContract,
848
+ minterTimeBufferSeconds: _minterTimeBufferSeconds,
849
+ minterRefundGasLimit: _minterRefundGasLimit,
850
+ minterFilter: _minterFilter
1188
851
  });
1189
852
  }
1190
853
  }