@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,23 +1,25 @@
1
1
  // SPDX-License-Identifier: LGPL-3.0-only
2
2
  // Created By: Art Blocks Inc.
3
3
 
4
- import "../../interfaces/v0.8.x/ISharedMinterSimplePurchaseV0.sol";
5
- import "../../interfaces/v0.8.x/ISharedMinterV0.sol";
6
- import "../../interfaces/v0.8.x/ISharedMinterDAV0.sol";
7
- import "../../interfaces/v0.8.x/ISharedMinterDAExpV0.sol";
8
- import "../../interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol";
9
- import "../../interfaces/v0.8.x/IMinterFilterV1.sol";
4
+ // @dev fixed to specific solidity version for clarity and for more clear
5
+ // source code verification purposes.
6
+ pragma solidity 0.8.19;
10
7
 
11
- import "../../libs/v0.8.x/minter-libs/SettlementExpLib.sol";
12
- import "../../libs/v0.8.x/minter-libs/SplitFundsLib.sol";
13
- import "../../libs/v0.8.x/minter-libs/MaxInvocationsLib.sol";
14
- import "../../libs/v0.8.x/minter-libs/DAExpLib.sol";
15
- import "../../libs/v0.8.x/AuthLib.sol";
8
+ import {ISharedMinterSimplePurchaseV0} from "../../interfaces/v0.8.x/ISharedMinterSimplePurchaseV0.sol";
9
+ import {ISharedMinterV0} from "../../interfaces/v0.8.x/ISharedMinterV0.sol";
10
+ import {ISharedMinterDAV0} from "../../interfaces/v0.8.x/ISharedMinterDAV0.sol";
11
+ import {ISharedMinterDAExpV0} from "../../interfaces/v0.8.x/ISharedMinterDAExpV0.sol";
12
+ import {ISharedMinterDAExpSettlementV0} from "../../interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol";
13
+ import {IMinterFilterV1} from "../../interfaces/v0.8.x/IMinterFilterV1.sol";
16
14
 
17
- import "@openzeppelin-4.7/contracts/utils/math/SafeCast.sol";
18
- import "@openzeppelin-4.5/contracts/security/ReentrancyGuard.sol";
15
+ import {SettlementExpLib} from "../../libs/v0.8.x/minter-libs/SettlementExpLib.sol";
16
+ import {SplitFundsLib} from "../../libs/v0.8.x/minter-libs/SplitFundsLib.sol";
17
+ import {MaxInvocationsLib} from "../../libs/v0.8.x/minter-libs/MaxInvocationsLib.sol";
18
+ import {DAExpLib} from "../../libs/v0.8.x/minter-libs/DAExpLib.sol";
19
+ import {AuthLib} from "../../libs/v0.8.x/AuthLib.sol";
19
20
 
20
- pragma solidity 0.8.19;
21
+ import {SafeCast} from "@openzeppelin-4.7/contracts/utils/math/SafeCast.sol";
22
+ import {ReentrancyGuard} from "@openzeppelin-4.5/contracts/security/ReentrancyGuard.sol";
21
23
 
22
24
  /**
23
25
  * @title Shared, filtered Minter contract that allows tokens to be minted with
@@ -51,7 +53,6 @@ pragma solidity 0.8.19;
51
53
  * contract:
52
54
  * - resetAuctionDetails (note: this will prevent minting until a new auction
53
55
  * is created)
54
- * - adminEmergencyReduceSelloutPrice
55
56
  * ----------------------------------------------------------------------------
56
57
  * The following functions are restricted to a project's artist or the core
57
58
  * contract's Admin ACL contract:
@@ -67,6 +68,13 @@ pragma solidity 0.8.19;
67
68
  * ----------------------------------------------------------------------------
68
69
  * Additional admin and artist privileged roles may be described on other
69
70
  * contracts that this minter integrates with.
71
+ * ----------------------------------------------------------------------------
72
+ * @notice Caution: While Engine projects must be registered on the Art Blocks
73
+ * Core Registry to assign this minter, this minter does not enforce that a
74
+ * project is registered when configured or queried. This is primarily for gas
75
+ * optimization purposes. It is, therefore, possible that fake projects may be
76
+ * configured on this minter, but they will not be able to mint tokens due to
77
+ * checks performed by this minter's Minter Filter.
70
78
  *
71
79
  * @dev Note that while this minter makes use of `block.timestamp` and it is
72
80
  * technically possible that this value is manipulated by block producers via
@@ -86,192 +94,128 @@ contract MinterDAExpSettlementV3 is
86
94
  {
87
95
  using SafeCast for uint256;
88
96
 
89
- /// Minter filter address this minter interacts with
97
+ /// @notice Minter filter address this minter interacts with
90
98
  address public immutable minterFilterAddress;
91
99
 
92
- /// Minter filter this minter may interact with.
93
- IMinterFilterV1 private immutable minterFilter;
100
+ /// @notice Minter filter this minter may interact with.
101
+ IMinterFilterV1 private immutable _minterFilter;
94
102
 
95
- /// minterType for this minter
103
+ /// @notice minterType for this minter
96
104
  string public constant minterType = "MinterDAExpSettlementV3";
97
105
 
98
- /// minter version for this minter
106
+ /// @notice minter version for this minter
99
107
  string public constant minterVersion = "v3.0.0";
100
108
 
101
- /// Minimum price decay half life: price can decay with a half life of a
109
+ /// @notice Minimum price decay half life: price can decay with a half life of a
102
110
  /// minimum of this amount (can cut in half a minimum of every N seconds).
103
111
  uint256 public minimumPriceDecayHalfLifeSeconds = 45; // 45 seconds
104
112
 
105
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
106
- // STATE VARIABLES FOR SplitFundsLib begin here
107
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
108
-
109
- // contractAddress => IsEngineCache
110
- mapping(address => SplitFundsLib.IsEngineCache) private _isEngineCaches;
111
-
112
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
113
- // STATE VARIABLES FOR SplitFundsLib end here
114
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
115
-
116
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
117
- // STATE VARIABLES FOR SettlementExpLib begin here
118
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
119
-
120
- mapping(address => mapping(uint256 => SettlementExpLib.SettlementAuctionProjectConfig))
121
- private _settlementAuctionProjectConfigMapping;
122
-
123
- /// user address => contractAddress => project ID => receipt
124
- mapping(address => mapping(address => mapping(uint256 => SettlementExpLib.Receipt)))
125
- private _receiptsMapping;
126
-
127
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
128
- // STATE VARIABLES FOR SettlementExpLib end here
129
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
130
-
131
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
132
- // STATE VARIABLES FOR DAExpLib begin here
133
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
134
-
135
- mapping(address => mapping(uint256 => DAExpLib.DAProjectConfig))
136
- private _auctionProjectConfigMapping;
137
-
138
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
139
- // STATE VARIABLES FOR DAExpLib end here
140
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
141
-
142
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
143
- // STATE VARIABLES FOR MaxInvocationsLib begin here
144
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
145
-
146
- // contractAddress => projectId => max invocations specific project config
147
- mapping(address => mapping(uint256 => MaxInvocationsLib.MaxInvocationsProjectConfig))
148
- private _maxInvocationsProjectConfigMapping;
149
-
150
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
151
- // STATE VARIABLES FOR MaxInvocationsLib end here
152
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
153
-
154
113
  /**
155
114
  * @notice Initializes contract to be a Filtered Minter for
156
- * `_minterFilter` minter filter.
157
- * @param _minterFilter Minter filter for which this will be a
115
+ * `minterFilter` minter filter.
116
+ * @param minterFilter Minter filter for which this will be a
158
117
  * filtered minter.
159
118
  */
160
- constructor(address _minterFilter) ReentrancyGuard() {
161
- minterFilterAddress = _minterFilter;
162
- minterFilter = IMinterFilterV1(_minterFilter);
163
- emit AuctionMinHalfLifeSecondsUpdated(minimumPriceDecayHalfLifeSeconds);
119
+ constructor(address minterFilter) ReentrancyGuard() {
120
+ minterFilterAddress = minterFilter;
121
+ _minterFilter = IMinterFilterV1(minterFilter);
122
+ emit DAExpLib.AuctionMinHalfLifeSecondsUpdated(
123
+ minimumPriceDecayHalfLifeSeconds
124
+ );
164
125
  }
165
126
 
166
127
  /**
167
- * @notice Manually sets the local maximum invocations of project `_projectId`
168
- * with the provided `_maxInvocations`, checking that `_maxInvocations` is less
169
- * than or equal to the value of project `_project_id`'s maximum invocations that is
128
+ * @notice Manually sets the local maximum invocations of project `projectId`
129
+ * with the provided `maxInvocations`, checking that `maxInvocations` is less
130
+ * than or equal to the value of project `project_id`'s maximum invocations that is
170
131
  * set on the core contract.
171
- * @dev Note that a `_maxInvocations` of 0 can only be set if the current `invocations`
132
+ * @dev Note that a `maxInvocations` of 0 can only be set if the current `invocations`
172
133
  * value is also 0 and this would also set `maxHasBeenInvoked` to true, correctly short-circuiting
173
134
  * this minter's purchase function, avoiding extra gas costs from the core contract's maxInvocations check.
174
- * @param _projectId Project ID to set the maximum invocations for.
175
- * @param _coreContract Core contract address for the given project.
176
- * @param _maxInvocations Maximum invocations to set for the project.
135
+ * @param projectId Project ID to set the maximum invocations for.
136
+ * @param coreContract Core contract address for the given project.
137
+ * @param maxInvocations Maximum invocations to set for the project.
177
138
  */
178
139
  function manuallyLimitProjectMaxInvocations(
179
- uint256 _projectId,
180
- address _coreContract,
181
- uint24 _maxInvocations
140
+ uint256 projectId,
141
+ address coreContract,
142
+ uint24 maxInvocations
182
143
  ) external {
183
144
  AuthLib.onlyArtist({
184
- _projectId: _projectId,
185
- _coreContract: _coreContract,
186
- _sender: msg.sender
145
+ projectId: projectId,
146
+ coreContract: coreContract,
147
+ sender: msg.sender
187
148
  });
149
+ // @dev guard rail to prevent accidentally adjusting max invocations
150
+ // after one or more purchases have been made
151
+ require(
152
+ SettlementExpLib.getNumPurchasesOnMinter({
153
+ projectId: projectId,
154
+ coreContract: coreContract
155
+ }) == 0,
156
+ "Only before purchases"
157
+ );
188
158
  MaxInvocationsLib.manuallyLimitProjectMaxInvocations({
189
- _projectId: _projectId,
190
- _coreContract: _coreContract,
191
- _maxInvocations: _maxInvocations,
192
- maxInvocationsProjectConfig: _maxInvocationsProjectConfigMapping[
193
- _coreContract
194
- ][_projectId]
159
+ projectId: projectId,
160
+ coreContract: coreContract,
161
+ maxInvocations: maxInvocations
195
162
  });
196
-
197
- emit ProjectMaxInvocationsLimitUpdated(
198
- _projectId,
199
- _coreContract,
200
- _maxInvocations
201
- );
202
163
  }
203
164
 
204
165
  /**
205
- * @notice Sets auction details for project `_projectId`.
206
- * @param _projectId Project ID to set auction details for.
207
- * @param _coreContract Core contract address for the given project.
208
- * @param _auctionTimestampStart Timestamp at which to start the auction.
209
- * @param _priceDecayHalfLifeSeconds The half life with which to decay the
166
+ * @notice Sets auction details for project `projectId`.
167
+ * @param projectId Project ID to set auction details for.
168
+ * @param coreContract Core contract address for the given project.
169
+ * @param auctionTimestampStart Timestamp at which to start the auction.
170
+ * @param priceDecayHalfLifeSeconds The half life with which to decay the
210
171
  * price (in seconds).
211
- * @param _startPrice Price at which to start the auction, in Wei.
212
- * @param _basePrice Resting price of the auction, in Wei.
213
- * @dev Note that it is intentionally supported here that the configured
214
- * price may be explicitly set to `0`.
172
+ * @param startPrice Price at which to start the auction, in Wei.
173
+ * @param basePrice Resting price of the auction, in Wei.
174
+ * @dev Note that a basePrice of `0` will cause the transaction to revert.
215
175
  */
216
176
  function setAuctionDetails(
217
- uint256 _projectId,
218
- address _coreContract,
219
- uint40 _auctionTimestampStart,
220
- uint40 _priceDecayHalfLifeSeconds,
221
- uint256 _startPrice,
222
- uint256 _basePrice
177
+ uint256 projectId,
178
+ address coreContract,
179
+ uint40 auctionTimestampStart,
180
+ uint40 priceDecayHalfLifeSeconds,
181
+ uint256 startPrice,
182
+ uint256 basePrice
223
183
  ) external {
224
184
  AuthLib.onlyArtist({
225
- _projectId: _projectId,
226
- _coreContract: _coreContract,
227
- _sender: msg.sender
185
+ projectId: projectId,
186
+ coreContract: coreContract,
187
+ sender: msg.sender
228
188
  });
229
189
  // CHECKS
230
- DAExpLib.DAProjectConfig
231
- storage _auctionProjectConfig = _auctionProjectConfigMapping[
232
- _coreContract
233
- ][_projectId];
234
- SettlementExpLib.SettlementAuctionProjectConfig
235
- storage _settlementAuctionProjectConfig = _settlementAuctionProjectConfigMapping[
236
- _coreContract
237
- ][_projectId];
238
-
239
190
  // require valid start price on a settlement minter
240
191
  require(
241
192
  SettlementExpLib.isValidStartPrice({
242
- _startPrice: _startPrice,
243
- _settlementAuctionProjectConfig: _settlementAuctionProjectConfig
193
+ projectId: projectId,
194
+ coreContract: coreContract,
195
+ startPrice: startPrice
244
196
  }),
245
197
  "Only monotonic decreasing price"
246
198
  );
247
199
  // do not allow a base price of zero (to simplify logic on this minter)
248
- require(_basePrice > 0, "Base price must be non-zero");
200
+ require(basePrice > 0, "Base price must be non-zero");
249
201
  // require valid half life for this minter
250
202
  require(
251
- (_priceDecayHalfLifeSeconds >= minimumPriceDecayHalfLifeSeconds),
203
+ (priceDecayHalfLifeSeconds >= minimumPriceDecayHalfLifeSeconds),
252
204
  "Price decay half life must be greater than min allowable value"
253
205
  );
254
206
 
255
207
  // EFFECTS
256
208
  DAExpLib.setAuctionDetailsExp({
257
- _DAProjectConfig: _auctionProjectConfig,
258
- _auctionTimestampStart: _auctionTimestampStart,
259
- _priceDecayHalfLifeSeconds: _priceDecayHalfLifeSeconds,
260
- _startPrice: _startPrice.toUint88(),
261
- _basePrice: _basePrice.toUint88(),
209
+ projectId: projectId,
210
+ coreContract: coreContract,
211
+ auctionTimestampStart: auctionTimestampStart,
212
+ priceDecayHalfLifeSeconds: priceDecayHalfLifeSeconds,
213
+ startPrice: startPrice.toUint88(),
214
+ basePrice: basePrice.toUint88(),
262
215
  // we set this to false so it prevents artist from altering auction
263
216
  // even after max has been invoked (require explicit auction reset
264
217
  // on settlement minter)
265
- _allowReconfigureAfterStart: false
266
- });
267
-
268
- emit SetAuctionDetailsExp({
269
- _projectId: _projectId,
270
- _coreContract: _coreContract,
271
- _auctionTimestampStart: _auctionTimestampStart,
272
- _priceDecayHalfLifeSeconds: _priceDecayHalfLifeSeconds,
273
- _startPrice: _startPrice,
274
- _basePrice: _basePrice
218
+ allowReconfigureAfterStart: false
275
219
  });
276
220
 
277
221
  // refresh max invocations, ensuring the values are populated, and
@@ -279,154 +223,81 @@ contract MinterDAExpSettlementV3 is
279
223
  // current core contract state.
280
224
  // @dev this refresh enables the guarantee that a project's max
281
225
  // invocation state is always populated if an auction is configured.
282
- MaxInvocationsLib.MaxInvocationsProjectConfig
283
- storage _maxInvocationsProjectConfig = _maxInvocationsProjectConfigMapping[
284
- _coreContract
285
- ][_projectId];
286
226
  // @dev this minter pays the higher gas cost of a full refresh here due
287
227
  // to the more severe ux degredation of a stale minter-local max
288
228
  // invocations state.
289
- bool maxInvocationsUpdated = MaxInvocationsLib.refreshMaxInvocations(
290
- _projectId,
291
- _coreContract,
292
- _maxInvocationsProjectConfig
293
- );
294
-
295
- // emit event to update state
296
- if (maxInvocationsUpdated) {
297
- emit ProjectMaxInvocationsLimitUpdated(
298
- _projectId,
299
- _coreContract,
300
- _maxInvocationsProjectConfig.maxInvocations
301
- );
302
- }
229
+ MaxInvocationsLib.refreshMaxInvocations({
230
+ projectId: projectId,
231
+ coreContract: coreContract
232
+ });
303
233
  }
304
234
 
305
235
  /**
306
236
  * @notice Sets the minimum and maximum values that are settable for
307
- * `_priceDecayHalfLifeSeconds` across all projects.
308
- * @param _minimumPriceDecayHalfLifeSeconds Minimum price decay half life
237
+ * `priceDecayHalfLifeSeconds` across all projects.
238
+ * @param minimumPriceDecayHalfLifeSeconds_ Minimum price decay half life
309
239
  * (in seconds).
310
240
  */
311
241
  function setMinimumPriceDecayHalfLifeSeconds(
312
- uint256 _minimumPriceDecayHalfLifeSeconds
242
+ uint256 minimumPriceDecayHalfLifeSeconds_
313
243
  ) external {
314
244
  AuthLib.onlyMinterFilterAdminACL({
315
- _minterFilterAddress: minterFilterAddress,
316
- _sender: msg.sender,
317
- _contract: address(this),
318
- _selector: this.setMinimumPriceDecayHalfLifeSeconds.selector
245
+ minterFilterAddress: minterFilterAddress,
246
+ sender: msg.sender,
247
+ contract_: address(this),
248
+ selector: this.setMinimumPriceDecayHalfLifeSeconds.selector
319
249
  });
320
250
  require(
321
- _minimumPriceDecayHalfLifeSeconds > 0,
251
+ minimumPriceDecayHalfLifeSeconds_ > 0,
322
252
  "Half life of zero not allowed"
323
253
  );
324
- minimumPriceDecayHalfLifeSeconds = _minimumPriceDecayHalfLifeSeconds;
254
+ minimumPriceDecayHalfLifeSeconds = minimumPriceDecayHalfLifeSeconds_;
325
255
 
326
- emit AuctionMinHalfLifeSecondsUpdated(
327
- _minimumPriceDecayHalfLifeSeconds
256
+ emit DAExpLib.AuctionMinHalfLifeSecondsUpdated(
257
+ minimumPriceDecayHalfLifeSeconds_
328
258
  );
329
259
  }
330
260
 
331
261
  /**
332
- * @notice Resets auction details for project `_projectId`, zero-ing out all
262
+ * @notice Resets auction details for project `projectId`, zero-ing out all
333
263
  * relevant auction fields. Not intended to be used in normal auction
334
264
  * operation, but rather only in case of the need to halt an auction.
335
- * @param _projectId Project ID to set auction details for.
265
+ * @param projectId Project ID to set auction details for.
266
+ * @param coreContract Core contract address for the given project.
336
267
  */
337
268
  function resetAuctionDetails(
338
- uint256 _projectId,
339
- address _coreContract
269
+ uint256 projectId,
270
+ address coreContract
340
271
  ) external {
341
272
  AuthLib.onlyCoreAdminACL({
342
- _coreContract: _coreContract,
343
- _sender: msg.sender,
344
- _contract: address(this),
345
- _selector: this.resetAuctionDetails.selector
273
+ coreContract: coreContract,
274
+ sender: msg.sender,
275
+ contract_: address(this),
276
+ selector: this.resetAuctionDetails.selector
346
277
  });
347
278
 
348
279
  SettlementExpLib.SettlementAuctionProjectConfig
349
- storage _settlementAuctionProjectConfig = _settlementAuctionProjectConfigMapping[
350
- _coreContract
351
- ][_projectId];
280
+ storage settlementAuctionProjectConfig = SettlementExpLib
281
+ .getSettlementAuctionProjectConfig({
282
+ projectId: projectId,
283
+ coreContract: coreContract
284
+ });
352
285
 
353
286
  // no reset after revenues collected, since that solidifies amount due
354
287
  require(
355
- !_settlementAuctionProjectConfig.auctionRevenuesCollected,
288
+ !settlementAuctionProjectConfig.auctionRevenuesCollected,
356
289
  "Only before revenues collected"
357
290
  );
358
291
 
359
292
  // EFFECTS
360
293
  // delete auction parameters
361
- delete _auctionProjectConfigMapping[_coreContract][_projectId];
294
+ DAExpLib.resetAuctionDetails({
295
+ projectId: projectId,
296
+ coreContract: coreContract
297
+ });
362
298
 
363
299
  // @dev do NOT delete settlement parameters, as they are used to
364
300
  // determine settlement amounts even through a reset
365
-
366
- // @dev V3: changed this event to be fully consistent with
367
- // non-settlement minters, as the settlement-specific parameters were
368
- // not being used for any indexing purposes
369
- emit ResetAuctionDetails(_projectId, _coreContract);
370
- }
371
-
372
- /**
373
- * @notice This represents an admin stepping in and reducing the sellout
374
- * price of an auction. This is only callable by the core admin, only
375
- * after the auction is complete, but before project revenues are
376
- * withdrawn.
377
- * This is only intended to be used in the case where for some reason, the
378
- * sellout price was too high.
379
- * @param _projectId Project ID to reduce auction sellout price for.
380
- * @param _newSelloutPrice New sellout price to set for the auction. Must
381
- * be less than the current sellout price.
382
- */
383
- function adminEmergencyReduceSelloutPrice(
384
- uint256 _projectId,
385
- address _coreContract,
386
- uint128 _newSelloutPrice
387
- ) external {
388
- AuthLib.onlyCoreAdminACL({
389
- _coreContract: _coreContract,
390
- _sender: msg.sender,
391
- _contract: address(this),
392
- _selector: this.adminEmergencyReduceSelloutPrice.selector
393
- });
394
-
395
- SettlementExpLib.SettlementAuctionProjectConfig
396
- storage _settlementAuctionProjectConfig = _settlementAuctionProjectConfigMapping[
397
- _coreContract
398
- ][_projectId];
399
- MaxInvocationsLib.MaxInvocationsProjectConfig
400
- storage _maxInvocationsProjectConfig = _maxInvocationsProjectConfigMapping[
401
- _coreContract
402
- ][_projectId];
403
- DAExpLib.DAProjectConfig
404
- storage _auctionProjectConfig = _auctionProjectConfigMapping[
405
- _coreContract
406
- ][_projectId];
407
-
408
- bool maxInvocationsUpdated = SettlementExpLib
409
- .adminEmergencyReduceSelloutPrice({
410
- _projectId: _projectId,
411
- _coreContract: _coreContract,
412
- _newSelloutPrice: _newSelloutPrice,
413
- _settlementAuctionProjectConfig: _settlementAuctionProjectConfig,
414
- _maxInvocationsProjectConfig: _maxInvocationsProjectConfig,
415
- _DAProjectConfig: _auctionProjectConfig
416
- });
417
- emit ConfigValueSet(
418
- _projectId,
419
- _coreContract,
420
- SettlementExpLib.CONFIG_CURRENT_SETTLED_PRICE,
421
- uint256(_newSelloutPrice)
422
- );
423
- if (maxInvocationsUpdated) {
424
- emit ProjectMaxInvocationsLimitUpdated(
425
- _projectId,
426
- _coreContract,
427
- _maxInvocationsProjectConfig.maxInvocations
428
- );
429
- }
430
301
  }
431
302
 
432
303
  /**
@@ -441,70 +312,36 @@ contract MinterDAExpSettlementV3 is
441
312
  * After revenues are collected, auction parameters will never be allowed
442
313
  * to be reset, and excess settlement funds will become immutable and fully
443
314
  * deterministic.
315
+ * @param projectId Project ID to withdraw revenues for.
316
+ * @param coreContract Core contract address for the given project.
444
317
  */
445
318
  function withdrawArtistAndAdminRevenues(
446
- uint256 _projectId,
447
- address _coreContract
319
+ uint256 projectId,
320
+ address coreContract
448
321
  ) external nonReentrant {
449
322
  AuthLib.onlyCoreAdminACLOrArtist({
450
- _projectId: _projectId,
451
- _coreContract: _coreContract,
452
- _sender: msg.sender,
453
- _contract: address(this),
454
- _selector: this.adminEmergencyReduceSelloutPrice.selector
323
+ projectId: projectId,
324
+ coreContract: coreContract,
325
+ sender: msg.sender,
326
+ contract_: address(this),
327
+ selector: this.withdrawArtistAndAdminRevenues.selector
455
328
  });
456
329
 
457
- SettlementExpLib.SettlementAuctionProjectConfig
458
- storage _settlementAuctionProjectConfig = _settlementAuctionProjectConfigMapping[
459
- _coreContract
460
- ][_projectId];
461
- MaxInvocationsLib.MaxInvocationsProjectConfig
462
- storage _maxInvocationsProjectConfig = _maxInvocationsProjectConfigMapping[
463
- _coreContract
464
- ][_projectId];
465
- DAExpLib.DAProjectConfig
466
- storage _auctionProjectConfig = _auctionProjectConfigMapping[
467
- _coreContract
468
- ][_projectId];
469
-
470
330
  // @dev the following function affects settlement state and marks
471
- // revenues as collected. Therefore revenues MUST be subsequently sent
472
- // distributed in this call.
473
- // @dev getting isEngine is considered a potential interaction, but
474
- // with a trusted contract, and therefore may be done prior to some
475
- // checks and effects
476
- bool isEngine = SplitFundsLib.isEngine(
477
- _coreContract,
478
- _isEngineCaches[_coreContract]
479
- );
331
+ // revenues as collected, as well as distributes revenues.
480
332
  // CHECKS-EFFECTS-INTERACTIONS
481
- bool maxInvocationsUpdated = SettlementExpLib
482
- .distributeArtistAndAdminRevenues({
483
- _projectId: _projectId,
484
- _coreContract: _coreContract,
485
- _settlementAuctionProjectConfig: _settlementAuctionProjectConfig,
486
- _maxInvocationsProjectConfig: _maxInvocationsProjectConfig,
487
- _DAProjectConfig: _auctionProjectConfig,
488
- _isEngine: isEngine
489
- });
490
- emit ConfigValueSet(
491
- _projectId,
492
- _coreContract,
493
- SettlementExpLib.CONFIG_AUCTION_REVENUES_COLLECTED,
494
- true
495
- );
496
- if (maxInvocationsUpdated) {
497
- emit ProjectMaxInvocationsLimitUpdated(
498
- _projectId,
499
- _coreContract,
500
- _maxInvocationsProjectConfig.maxInvocations
501
- );
502
- }
333
+ // @dev the following function updates the project's balance and will
334
+ // revert if the project's balance is insufficient to cover the
335
+ // settlement amount (which is expected to not be possible)
336
+ SettlementExpLib.distributeArtistAndAdminRevenues({
337
+ projectId: projectId,
338
+ coreContract: coreContract
339
+ });
503
340
  }
504
341
 
505
342
  /**
506
343
  * @notice Reclaims the sender's payment above current settled price for
507
- * project `_projectId` on core contract `_coreContract`.
344
+ * project `projectId` on core contract `coreContract`.
508
345
  * The current settled price is the the price paid for the most recently
509
346
  * purchased token, or the base price if the artist has withdrawn revenues
510
347
  * after the auction reached base price.
@@ -513,23 +350,23 @@ contract MinterDAExpSettlementV3 is
513
350
  * has been purchased at base price. This minimizes the amount of gas
514
351
  * required to send all excess settlement funds to the sender.
515
352
  * Sends excess settlement funds to msg.sender.
516
- * @param _projectId Project ID to reclaim excess settlement funds on.
517
- * @param _coreContract Contract address of the core contract
353
+ * @param projectId Project ID to reclaim excess settlement funds on.
354
+ * @param coreContract Contract address of the core contract
518
355
  */
519
356
  function reclaimProjectExcessSettlementFunds(
520
- uint256 _projectId,
521
- address _coreContract
357
+ uint256 projectId,
358
+ address coreContract
522
359
  ) external {
523
- reclaimProjectExcessSettlementFundsTo(
524
- payable(msg.sender),
525
- _projectId,
526
- _coreContract
527
- );
360
+ reclaimProjectExcessSettlementFundsTo({
361
+ to: payable(msg.sender),
362
+ projectId: projectId,
363
+ coreContract: coreContract
364
+ });
528
365
  }
529
366
 
530
367
  /**
531
368
  * @notice Reclaims the sender's payment above current settled price for
532
- * projects in `_projectIds`. The current settled price is the the price
369
+ * projects in `projectIds`. The current settled price is the the price
533
370
  * paid for the most recently purchased token, or the base price if the
534
371
  * artist has withdrawn revenues after the auction reached base price.
535
372
  * This function is callable at any point, but is expected to typically be
@@ -539,37 +376,37 @@ contract MinterDAExpSettlementV3 is
539
376
  * Sends total of all excess settlement funds to msg.sender in a single
540
377
  * chunk. Entire transaction reverts if any excess settlement calculation
541
378
  * fails.
542
- * @param _projectIds Array of project IDs to reclaim excess settlement
379
+ * @param projectIds Array of project IDs to reclaim excess settlement
543
380
  * funds on.
544
- * @param _coreContracts Array of core contract addresses for the given
545
- * projects. Must be in the same order as `_projectIds` (aligned by index).
381
+ * @param coreContracts Array of core contract addresses for the given
382
+ * projects. Must be in the same order as `projectIds` (aligned by index).
546
383
  */
547
384
  function reclaimProjectsExcessSettlementFunds(
548
- uint256[] calldata _projectIds,
549
- address[] calldata _coreContracts
385
+ uint256[] calldata projectIds,
386
+ address[] calldata coreContracts
550
387
  ) external {
551
388
  // @dev input validation checks are performed in subcall
552
- reclaimProjectsExcessSettlementFundsTo(
553
- payable(msg.sender),
554
- _projectIds,
555
- _coreContracts
556
- );
389
+ reclaimProjectsExcessSettlementFundsTo({
390
+ to: payable(msg.sender),
391
+ projectIds: projectIds,
392
+ coreContracts: coreContracts
393
+ });
557
394
  }
558
395
 
559
396
  /**
560
- * @notice Purchases a token from project `_projectId`.
561
- * @param _projectId Project ID to mint a token on.
562
- * @param _coreContract Core contract address for the given project.
397
+ * @notice Purchases a token from project `projectId`.
398
+ * @param projectId Project ID to mint a token on.
399
+ * @param coreContract Core contract address for the given project.
563
400
  * @return tokenId Token ID of minted token
564
401
  */
565
402
  function purchase(
566
- uint256 _projectId,
567
- address _coreContract
403
+ uint256 projectId,
404
+ address coreContract
568
405
  ) external payable returns (uint256 tokenId) {
569
406
  tokenId = purchaseTo({
570
- _to: msg.sender,
571
- _projectId: _projectId,
572
- _coreContract: _coreContract
407
+ to: msg.sender,
408
+ projectId: projectId,
409
+ coreContract: coreContract
573
410
  });
574
411
 
575
412
  return tokenId;
@@ -578,26 +415,30 @@ contract MinterDAExpSettlementV3 is
578
415
  // public getter functions
579
416
  /**
580
417
  * @notice Gets the maximum invocations project configuration.
581
- * @param _coreContract The address of the core contract.
582
- * @param _projectId The ID of the project whose data needs to be fetched.
418
+ * @param coreContract The address of the core contract.
419
+ * @param projectId The ID of the project whose data needs to be fetched.
583
420
  * @return MaxInvocationsLib.MaxInvocationsProjectConfig instance with the
584
421
  * configuration data.
585
422
  */
586
423
  function maxInvocationsProjectConfig(
587
- uint256 _projectId,
588
- address _coreContract
424
+ uint256 projectId,
425
+ address coreContract
589
426
  )
590
427
  external
591
428
  view
592
429
  returns (MaxInvocationsLib.MaxInvocationsProjectConfig memory)
593
430
  {
594
- return _maxInvocationsProjectConfigMapping[_coreContract][_projectId];
431
+ return
432
+ MaxInvocationsLib.getMaxInvocationsProjectConfig({
433
+ projectId: projectId,
434
+ coreContract: coreContract
435
+ });
595
436
  }
596
437
 
597
438
  /**
598
439
  * @notice Retrieves the auction parameters for a specific project.
599
- * @param _projectId The unique identifier for the project.
600
- * @param _coreContract The address of the core contract for the project.
440
+ * @param projectId The unique identifier for the project.
441
+ * @param coreContract The address of the core contract for the project.
601
442
  * @return timestampStart The start timestamp for the auction.
602
443
  * @return priceDecayHalfLifeSeconds The half-life for the price decay
603
444
  * during the auction, in seconds.
@@ -605,8 +446,8 @@ contract MinterDAExpSettlementV3 is
605
446
  * @return basePrice The base price of the auction.
606
447
  */
607
448
  function projectAuctionParameters(
608
- uint256 _projectId,
609
- address _coreContract
449
+ uint256 projectId,
450
+ address coreContract
610
451
  )
611
452
  external
612
453
  view
@@ -617,10 +458,11 @@ contract MinterDAExpSettlementV3 is
617
458
  uint256 basePrice
618
459
  )
619
460
  {
620
- DAExpLib.DAProjectConfig
621
- storage _auctionProjectConfig = _auctionProjectConfigMapping[
622
- _coreContract
623
- ][_projectId];
461
+ DAExpLib.DAProjectConfig storage _auctionProjectConfig = DAExpLib
462
+ .getDAProjectConfig({
463
+ projectId: projectId,
464
+ coreContract: coreContract
465
+ });
624
466
  timestampStart = _auctionProjectConfig.timestampStart;
625
467
  priceDecayHalfLifeSeconds = _auctionProjectConfig
626
468
  .priceDecayHalfLifeSeconds;
@@ -629,26 +471,25 @@ contract MinterDAExpSettlementV3 is
629
471
  }
630
472
 
631
473
  /**
632
- * @notice Checks if the specified `_coreContract` is a valid engine contract.
633
- * @dev This function retrieves the cached value of `_coreContract` from
474
+ * @notice Checks if the specified `coreContract` is a valid engine contract.
475
+ * @dev This function retrieves the cached value of `coreContract` from
634
476
  * the `isEngineCache` mapping. If the cached value is already set, it
635
- * returns the cached value. Otherwise, it calls the `getV3CoreIsEngine`
636
- * function from the `SplitFundsLib` library to check if `_coreContract`
477
+ * returns the cached value. Otherwise, it calls the `getV3CoreIsEngineView`
478
+ * function from the `SplitFundsLib` library to check if `coreContract`
637
479
  * is a valid engine contract.
638
- * @dev This function will revert if the provided `_coreContract` is not
480
+ * @dev This function will revert if the provided `coreContract` is not
639
481
  * a valid Engine or V3 Flagship contract.
640
- * @param _coreContract The address of the contract to check.
641
- * @return bool indicating if `_coreContract` is a valid engine contract.
482
+ * @param coreContract The address of the contract to check.
483
+ * @return bool indicating if `coreContract` is a valid engine contract.
642
484
  */
643
- function isEngineView(address _coreContract) external view returns (bool) {
644
- SplitFundsLib.IsEngineCache storage isEngineCache = _isEngineCaches[
645
- _coreContract
646
- ];
485
+ function isEngineView(address coreContract) external view returns (bool) {
486
+ SplitFundsLib.IsEngineCache storage isEngineCache = SplitFundsLib
487
+ .getIsEngineCacheConfig(coreContract);
647
488
  if (isEngineCache.isCached) {
648
489
  return isEngineCache.isEngine;
649
490
  } else {
650
- // @dev this calls the non-modifying variant of getV3CoreIsEngine
651
- return SplitFundsLib.getV3CoreIsEngineView(_coreContract);
491
+ // @dev this calls the non-state-modifying variant of isEngine
492
+ return SplitFundsLib.getV3CoreIsEngineView(coreContract);
652
493
  }
653
494
  }
654
495
 
@@ -659,21 +500,22 @@ contract MinterDAExpSettlementV3 is
659
500
  * intentional, as it only enables gas optimization of mints after a
660
501
  * project's maximum invocations has been reached. A false negative will
661
502
  * only result in a gas cost increase, since the core contract will still
662
- * enforce a maxInvocation check during minting. A false positive is not
663
- * possible because the V3 core contract only allows maximum invocations
664
- * to be reduced, not increased. Based on this rationale, we intentionally
503
+ * enforce a maxInvocation check during minting. A false positive may be possible
504
+ * if function `manuallyLimitProjectMaxInvocations` has been invoked, resulting in
505
+ * `localMaxInvocations` < `coreContractMaxInvocations`. Based on this rationale, we intentionally
665
506
  * do not do input validation in this method as to whether or not the input
666
- * @param `_projectId` is an existing project ID.
667
- * @param `_coreContract` is an existing core contract address.
507
+ * @param projectId is an existing project ID.
508
+ * @param coreContract is an existing core contract address.
668
509
  */
669
510
  function projectMaxHasBeenInvoked(
670
- uint256 _projectId,
671
- address _coreContract
511
+ uint256 projectId,
512
+ address coreContract
672
513
  ) external view returns (bool) {
673
514
  return
674
- MaxInvocationsLib.getMaxHasBeenInvoked(
675
- _maxInvocationsProjectConfigMapping[_coreContract][_projectId]
676
- );
515
+ MaxInvocationsLib.getMaxHasBeenInvoked({
516
+ projectId: projectId,
517
+ coreContract: coreContract
518
+ });
677
519
  }
678
520
 
679
521
  /**
@@ -686,65 +528,94 @@ contract MinterDAExpSettlementV3 is
686
528
  * @dev A number greater than the core contract's project max invocations
687
529
  * will only result in a gas cost increase, since the core contract will
688
530
  * still enforce a maxInvocation check during minting. A number less than
689
- * the core contract's project max invocations is only possible when the
690
- * project's max invocations have not been synced on this minter, since the
531
+ * the core contract's project max invocations is possible if the artist
532
+ * has called manuallyLimitProjectMaxInvocations or when the project's max
533
+ * invocations have not been synced on this minter, since the
691
534
  * V3 core contract only allows maximum invocations to be reduced, not
692
535
  * increased. When this happens, the minter will enable minting, allowing
693
536
  * the core contract to enforce the max invocations check. Based on this
694
537
  * rationale, we intentionally do not do input validation in this method as
695
- * to whether or not the input `_projectId` is an existing project ID.
696
- * @param `_projectId` is an existing project ID.
697
- * @param `_coreContract` is an existing core contract address.
538
+ * to whether or not the input `projectId` is an existing project ID.
539
+ * @param projectId is an existing project ID.
540
+ * @param coreContract is an existing core contract address.
698
541
  */
699
542
  function projectMaxInvocations(
700
- uint256 _projectId,
701
- address _coreContract
543
+ uint256 projectId,
544
+ address coreContract
702
545
  ) external view returns (uint256) {
703
546
  return
704
- MaxInvocationsLib.getMaxInvocations(
705
- _maxInvocationsProjectConfigMapping[_coreContract][_projectId]
706
- );
547
+ MaxInvocationsLib.getMaxInvocations({
548
+ projectId: projectId,
549
+ coreContract: coreContract
550
+ });
707
551
  }
708
552
 
709
553
  /**
710
- * @notice Gets the latest purchase price for project `_projectId`, or 0 if
554
+ * @notice Gets the latest purchase price for project `projectId`, or 0 if
711
555
  * no purchases have been made.
712
- * @param _projectId Project ID to get latest purchase price for.
713
- * @param _coreContract Contract address of the core contract
556
+ * @param projectId Project ID to get latest purchase price for.
557
+ * @param coreContract Contract address of the core contract
558
+ * @return latestPurchasePrice Latest purchase price
714
559
  */
715
560
  function getProjectLatestPurchasePrice(
716
- uint256 _projectId,
717
- address _coreContract
561
+ uint256 projectId,
562
+ address coreContract
718
563
  ) external view returns (uint256 latestPurchasePrice) {
719
564
  SettlementExpLib.SettlementAuctionProjectConfig
720
- storage _settlementAuctionProjectConfig = _settlementAuctionProjectConfigMapping[
721
- _coreContract
722
- ][_projectId];
723
- return _settlementAuctionProjectConfig.latestPurchasePrice;
565
+ storage settlementAuctionProjectConfig = SettlementExpLib
566
+ .getSettlementAuctionProjectConfig({
567
+ projectId: projectId,
568
+ coreContract: coreContract
569
+ });
570
+ return settlementAuctionProjectConfig.latestPurchasePrice;
724
571
  }
725
572
 
726
573
  /**
727
- * @notice Gets the number of settleable invocations for project `_projectId`.
728
- * @param _projectId Project ID to get number of settleable invocations for.
729
- * @param _coreContract Contract address of the core contract
574
+ * @notice Gets the number of settleable invocations for project `projectId`.
575
+ * @param projectId Project ID to get number of settleable invocations for.
576
+ * @param coreContract Contract address of the core contract
577
+ * @return numSettleableInvocations Number of settleable invocations
730
578
  */
731
579
  function getNumSettleableInvocations(
732
- uint256 _projectId,
733
- address _coreContract
580
+ uint256 projectId,
581
+ address coreContract
734
582
  ) external view returns (uint256 numSettleableInvocations) {
735
583
  SettlementExpLib.SettlementAuctionProjectConfig
736
- storage _settlementAuctionProjectConfig = _settlementAuctionProjectConfigMapping[
737
- _coreContract
738
- ][_projectId];
739
- return _settlementAuctionProjectConfig.numSettleableInvocations;
584
+ storage settlementAuctionProjectConfig = SettlementExpLib
585
+ .getSettlementAuctionProjectConfig({
586
+ projectId: projectId,
587
+ coreContract: coreContract
588
+ });
589
+ return settlementAuctionProjectConfig.numSettleableInvocations;
590
+ }
591
+
592
+ /**
593
+ * @notice Gets the balance of ETH, in wei, currently held by the minter
594
+ * for project `projectId`. This value is non-zero if not all purchasers
595
+ * have reclaimed their excess settlement funds, or if an artist/admin has
596
+ * not yet withdrawn their revenues.
597
+ * @param projectId Project ID to get balance for.
598
+ * @param coreContract Contract address of the core contract
599
+ */
600
+ function getProjectBalance(
601
+ uint256 projectId,
602
+ address coreContract
603
+ ) external view returns (uint256 projectBalance) {
604
+ SettlementExpLib.SettlementAuctionProjectConfig
605
+ storage settlementAuctionProjectConfig = SettlementExpLib
606
+ .getSettlementAuctionProjectConfig({
607
+ projectId: projectId,
608
+ coreContract: coreContract
609
+ });
610
+ return settlementAuctionProjectConfig.projectBalance;
740
611
  }
741
612
 
742
613
  /**
743
614
  * @notice Gets if price of token is configured, price of minting a
744
- * token on project `_projectId`, and currency symbol and address to be
615
+ * token on project `projectId`, and currency symbol and address to be
745
616
  * used as payment. Supersedes any core contract price information.
746
- * @param _projectId Project ID to get price information for
747
- * @param _coreContract Contract address of the core contract
617
+ * @param projectId Project ID to get price information for
618
+ * @param coreContract Contract address of the core contract
748
619
  * @return isConfigured true only if token price has been configured on
749
620
  * this minter
750
621
  * @return tokenPriceInWei current price of token on this minter - invalid
@@ -755,8 +626,8 @@ contract MinterDAExpSettlementV3 is
755
626
  * this minter. This minter always returns null address, reserved for ether
756
627
  */
757
628
  function getPriceInfo(
758
- uint256 _projectId,
759
- address _coreContract
629
+ uint256 projectId,
630
+ address coreContract
760
631
  )
761
632
  external
762
633
  view
@@ -767,18 +638,11 @@ contract MinterDAExpSettlementV3 is
767
638
  address currencyAddress
768
639
  )
769
640
  {
770
- SettlementExpLib.SettlementAuctionProjectConfig
771
- storage _settlementAuctionProjectConfig = _settlementAuctionProjectConfigMapping[
772
- _coreContract
773
- ][_projectId];
774
- MaxInvocationsLib.MaxInvocationsProjectConfig
775
- storage _maxInvocationsProjectConfig = _maxInvocationsProjectConfigMapping[
776
- _coreContract
777
- ][_projectId];
778
- DAExpLib.DAProjectConfig
779
- storage auctionProjectConfig = _auctionProjectConfigMapping[
780
- _coreContract
781
- ][_projectId];
641
+ DAExpLib.DAProjectConfig storage auctionProjectConfig = DAExpLib
642
+ .getDAProjectConfig({
643
+ projectId: projectId,
644
+ coreContract: coreContract
645
+ });
782
646
 
783
647
  // take action based on configured state
784
648
  isConfigured = (auctionProjectConfig.startPrice > 0);
@@ -797,11 +661,8 @@ contract MinterDAExpSettlementV3 is
797
661
  // function, and we prefer to use the extra gas to appropriately
798
662
  // correct for the case of a stale minter max invocation state.
799
663
  tokenPriceInWei = SettlementExpLib.getPriceSafe({
800
- _projectId: _projectId,
801
- _coreContract: _coreContract,
802
- _settlementAuctionProjectConfig: _settlementAuctionProjectConfig,
803
- _maxInvocationsProjectConfig: _maxInvocationsProjectConfig,
804
- _DAProjectConfig: auctionProjectConfig
664
+ projectId: projectId,
665
+ coreContract: coreContract
805
666
  });
806
667
  }
807
668
  currencySymbol = "ETH";
@@ -809,45 +670,38 @@ contract MinterDAExpSettlementV3 is
809
670
  }
810
671
 
811
672
  /**
812
- * @notice Gets the current excess settlement funds on project `_projectId`
813
- * for address `_walletAddress`. The returned value is expected to change
673
+ * @notice Gets the current excess settlement funds on project `projectId`
674
+ * for address `walletAddress`. The returned value is expected to change
814
675
  * throughtout an auction, since the latest purchase price is used when
815
676
  * determining excess settlement funds.
816
677
  * A user may claim excess settlement funds by calling the function
817
678
  * `reclaimProjectExcessSettlementFunds(_projectId)`.
818
- * @param _projectId Project ID to query.
819
- * @param _walletAddress Account address for which the excess posted funds
679
+ * @param projectId Project ID to query.
680
+ * @param coreContract Contract address of the core contract
681
+ * @param walletAddress Account address for which the excess posted funds
820
682
  * is being queried.
821
683
  * @return excessSettlementFundsInWei Amount of excess settlement funds, in
822
684
  * wei
823
685
  */
824
686
  function getProjectExcessSettlementFunds(
825
- uint256 _projectId,
826
- address _coreContract,
827
- address _walletAddress
687
+ uint256 projectId,
688
+ address coreContract,
689
+ address walletAddress
828
690
  ) external view returns (uint256 excessSettlementFundsInWei) {
829
691
  // input validation
830
- require(_walletAddress != address(0), "No zero address");
831
-
832
- SettlementExpLib.SettlementAuctionProjectConfig
833
- storage _settlementAuctionProjectConfig = _settlementAuctionProjectConfigMapping[
834
- _coreContract
835
- ][_projectId];
836
- SettlementExpLib.Receipt storage _receipt = _receiptsMapping[
837
- _walletAddress
838
- ][_coreContract][_projectId];
692
+ require(walletAddress != address(0), "No zero address");
839
693
 
840
694
  (excessSettlementFundsInWei, ) = SettlementExpLib
841
695
  .getProjectExcessSettlementFunds({
842
- _settlementAuctionProjectConfig: _settlementAuctionProjectConfig,
843
- _receipt: _receipt
696
+ projectId: projectId,
697
+ coreContract: coreContract,
698
+ walletAddress: walletAddress
844
699
  });
845
- return excessSettlementFundsInWei;
846
700
  }
847
701
 
848
702
  /**
849
703
  * @notice Reclaims the sender's payment above current settled price for
850
- * project `_projectId` on core contract `_coreContract`.
704
+ * project `projectId` on core contract `coreContract`.
851
705
  * The current settled price is the the price paid for the most recently
852
706
  * purchased token, or the base price if the artist has withdrawn revenues
853
707
  * after the auction reached base price.
@@ -855,79 +709,55 @@ contract MinterDAExpSettlementV3 is
855
709
  * called after auction has sold out above base price or after the auction
856
710
  * has been purchased at base price. This minimizes the amount of gas
857
711
  * required to send all excess settlement funds to the sender.
858
- * Sends excess settlement funds to address `_to`.
859
- * @param _to Address to send excess settlement funds to.
860
- * @param _projectId Project ID to reclaim excess settlement funds on.
861
- * @param _coreContract Contract address of the core contract
712
+ * Sends excess settlement funds to address `to`.
713
+ * @param to Address to send excess settlement funds to.
714
+ * @param projectId Project ID to reclaim excess settlement funds on.
715
+ * @param coreContract Contract address of the core contract
862
716
  */
863
717
  function reclaimProjectExcessSettlementFundsTo(
864
- address payable _to,
865
- uint256 _projectId,
866
- address _coreContract
718
+ address payable to,
719
+ uint256 projectId,
720
+ address coreContract
867
721
  ) public nonReentrant {
868
- require(_to != address(0), "No claiming to the zero address");
869
-
870
- SettlementExpLib.SettlementAuctionProjectConfig
871
- storage _settlementAuctionProjectConfig = _settlementAuctionProjectConfigMapping[
872
- _coreContract
873
- ][_projectId];
874
- SettlementExpLib.Receipt storage _receipt = _receiptsMapping[
875
- msg.sender
876
- ][_coreContract][_projectId];
722
+ require(to != address(0), "No claiming to the zero address");
877
723
 
878
- (
879
- uint256 excessSettlementFunds,
880
- uint256 requiredAmountPosted
881
- ) = SettlementExpLib.getProjectExcessSettlementFunds({
882
- _settlementAuctionProjectConfig: _settlementAuctionProjectConfig,
883
- _receipt: _receipt
884
- });
885
- uint232 newNetPosted = requiredAmountPosted.toUint232();
886
- _receipt.netPosted = newNetPosted;
887
-
888
- emit ReceiptUpdated({
889
- _purchaser: msg.sender,
890
- _projectId: _projectId,
891
- _coreContract: _coreContract,
892
- _numPurchased: _receipt.numPurchased,
893
- _netPosted: newNetPosted
724
+ SettlementExpLib.reclaimProjectExcessSettlementFundsTo({
725
+ to: to,
726
+ projectId: projectId,
727
+ coreContract: coreContract,
728
+ purchaserAddress: msg.sender
894
729
  });
895
-
896
- // INTERACTIONS
897
- bool success_;
898
- (success_, ) = _to.call{value: excessSettlementFunds}("");
899
- require(success_, "Reclaiming failed");
900
730
  }
901
731
 
902
732
  /**
903
733
  * @notice Reclaims the sender's payment above current settled price for
904
- * projects in `_projectIds`. The current settled price is the the price
734
+ * projects in `projectIds`. The current settled price is the the price
905
735
  * paid for the most recently purchased token, or the base price if the
906
736
  * artist has withdrawn revenues after the auction reached base price.
907
737
  * This function is callable at any point, but is expected to typically be
908
738
  * called after auction has sold out above base price or after the auction
909
739
  * has been purchased at base price. This minimizes the amount of gas
910
740
  * required to send all excess settlement funds to the sender.
911
- * Sends total of all excess settlement funds to `_to` in a single
741
+ * Sends total of all excess settlement funds to `to` in a single
912
742
  * chunk. Entire transaction reverts if any excess settlement calculation
913
743
  * fails.
914
- * @param _to Address to send excess settlement funds to.
915
- * @param _projectIds Array of project IDs to reclaim excess settlement
744
+ * @param to Address to send excess settlement funds to.
745
+ * @param projectIds Array of project IDs to reclaim excess settlement
916
746
  * funds on.
917
- * @param _coreContracts Array of core contract addresses for the given
918
- * projects. Must be in the same order as `_projectIds` (aligned by index).
747
+ * @param coreContracts Array of core contract addresses for the given
748
+ * projects. Must be in the same order as `projectIds` (aligned by index).
919
749
  */
920
750
  function reclaimProjectsExcessSettlementFundsTo(
921
- address payable _to,
922
- uint256[] calldata _projectIds,
923
- address[] calldata _coreContracts
751
+ address payable to,
752
+ uint256[] calldata projectIds,
753
+ address[] calldata coreContracts
924
754
  ) public nonReentrant {
925
755
  // CHECKS
926
756
  // input validation
927
- require(_to != address(0), "No claiming to the zero address");
928
- uint256 projectIdsLength = _projectIds.length;
757
+ require(to != address(0), "No claiming to the zero address");
758
+ uint256 projectIdsLength = projectIds.length;
929
759
  require(
930
- projectIdsLength == _coreContracts.length,
760
+ projectIdsLength == coreContracts.length,
931
761
  "Array lengths must match"
932
762
  );
933
763
  // EFFECTS
@@ -935,37 +765,13 @@ contract MinterDAExpSettlementV3 is
935
765
  // the receipt in storage
936
766
  uint256 excessSettlementFunds;
937
767
  for (uint256 i; i < projectIdsLength; ) {
938
- uint256 projectId = _projectIds[i];
939
- address coreContract = _coreContracts[i];
940
-
941
- SettlementExpLib.SettlementAuctionProjectConfig
942
- storage _settlementAuctionProjectConfig = _settlementAuctionProjectConfigMapping[
943
- coreContract
944
- ][projectId];
945
- SettlementExpLib.Receipt storage _receipt = _receiptsMapping[
946
- msg.sender
947
- ][coreContract][projectId];
948
-
949
- (
950
- uint256 excessSettlementFundsForProject,
951
- uint256 requiredAmountPosted
952
- ) = SettlementExpLib.getProjectExcessSettlementFunds({
953
- _settlementAuctionProjectConfig: _settlementAuctionProjectConfig,
954
- _receipt: _receipt
955
- });
956
- uint232 newNetPosted = requiredAmountPosted.toUint232();
957
- _receipt.netPosted = newNetPosted;
958
-
959
- excessSettlementFunds += excessSettlementFundsForProject;
960
-
961
- // emit event indicating new receipt state
962
- emit ReceiptUpdated({
963
- _purchaser: msg.sender,
964
- _projectId: projectId,
965
- _coreContract: coreContract,
966
- _numPurchased: _receipt.numPurchased,
967
- _netPosted: newNetPosted
768
+ SettlementExpLib.reclaimProjectExcessSettlementFundsTo({
769
+ to: to,
770
+ projectId: projectIds[i],
771
+ coreContract: coreContracts[i],
772
+ purchaserAddress: msg.sender
968
773
  });
774
+
969
775
  // gas efficiently increment i
970
776
  // won't overflow due to for loop, as well as gas limts
971
777
  unchecked {
@@ -977,68 +783,35 @@ contract MinterDAExpSettlementV3 is
977
783
  // send excess settlement funds in a single chunk for all
978
784
  // projects
979
785
  bool success_;
980
- (success_, ) = _to.call{value: excessSettlementFunds}("");
786
+ (success_, ) = to.call{value: excessSettlementFunds}("");
981
787
  require(success_, "Reclaiming failed");
982
788
  }
983
789
 
984
790
  /**
985
- * @notice This function is intentionally not implemented for this version
986
- * of the minter. Due to potential for unintended consequences, the
987
- * function `manuallyLimitProjectMaxInvocations` should be used to manually
988
- * and explicitly limit the maximum invocations for a project to a value
989
- * other than the core contract's maximum invocations for a project.
990
- * @param _coreContract Core contract address for the given project.
991
- * @param _projectId Project ID to set the maximum invocations for.
992
- */
993
- function syncProjectMaxInvocationsToCore(
994
- uint256 _projectId,
995
- address _coreContract
996
- ) public view {
997
- AuthLib.onlyArtist({
998
- _projectId: _projectId,
999
- _coreContract: _coreContract,
1000
- _sender: msg.sender
1001
- });
1002
- revert("Not implemented");
1003
- }
1004
-
1005
- /**
1006
- * @notice Purchases a token from project `_projectId` and sets
1007
- * the token's owner to `_to`.
1008
- * @param _to Address to be the new token's owner.
1009
- * @param _projectId Project ID to mint a token on.
1010
- * @param _coreContract Core contract address for the given project.
791
+ * @notice Purchases a token from project `projectId` and sets
792
+ * the token's owner to `to`.
793
+ * @param to Address to be the new token's owner.
794
+ * @param projectId Project ID to mint a token on.
795
+ * @param coreContract Core contract address for the given project.
1011
796
  * @return tokenId Token ID of minted token
1012
797
  */
1013
798
  function purchaseTo(
1014
- address _to,
1015
- uint256 _projectId,
1016
- address _coreContract
799
+ address to,
800
+ uint256 projectId,
801
+ address coreContract
1017
802
  ) public payable nonReentrant returns (uint256 tokenId) {
1018
803
  // CHECKS
1019
- SettlementExpLib.SettlementAuctionProjectConfig
1020
- storage _settlementAuctionProjectConfig = _settlementAuctionProjectConfigMapping[
1021
- _coreContract
1022
- ][_projectId];
1023
- MaxInvocationsLib.MaxInvocationsProjectConfig
1024
- storage _maxInvocationsProjectConfig = _maxInvocationsProjectConfigMapping[
1025
- _coreContract
1026
- ][_projectId];
1027
- DAExpLib.DAProjectConfig
1028
- storage _auctionProjectConfig = _auctionProjectConfigMapping[
1029
- _coreContract
1030
- ][_projectId];
1031
-
804
+ // pre-mint MaxInvocationsLib checks
1032
805
  // Note that `maxHasBeenInvoked` is only checked here to reduce gas
1033
806
  // consumption after a project has been fully minted.
1034
- // `_maxInvocationsProjectConfig.maxHasBeenInvoked` is locally cached to reduce
807
+ // `maxInvocationsProjectConfig.maxHasBeenInvoked` is locally cached to reduce
1035
808
  // gas consumption, but if not in sync with the core contract's value,
1036
809
  // the core contract also enforces its own max invocation check during
1037
810
  // minting.
1038
- require(
1039
- !_maxInvocationsProjectConfig.maxHasBeenInvoked,
1040
- "Max invocations reached"
1041
- );
811
+ MaxInvocationsLib.preMintChecks({
812
+ projectId: projectId,
813
+ coreContract: coreContract
814
+ });
1042
815
 
1043
816
  // _getPriceUnsafe reverts if auction has not yet started or auction is
1044
817
  // unconfigured, and auction has not sold out or revenues have not been
@@ -1050,77 +823,64 @@ contract MinterDAExpSettlementV3 is
1050
823
  // call later on in this function, when the core contract's max
1051
824
  // invocation check fails.
1052
825
  uint256 currentPriceInWei = SettlementExpLib.getPriceUnsafe({
1053
- _settlementAuctionProjectConfig: _settlementAuctionProjectConfig,
1054
- _maxInvocationsProjectConfig: _maxInvocationsProjectConfig,
1055
- _DAProjectConfig: _auctionProjectConfig
826
+ projectId: projectId,
827
+ coreContract: coreContract,
828
+ maxHasBeenInvoked: false // always false due to MaxInvocationsLib.preMintChecks
1056
829
  });
1057
830
 
1058
831
  // EFFECTS
1059
- // update the purchaser's receipt and require sufficient net payment
1060
- SettlementExpLib.Receipt storage receipt = _receiptsMapping[msg.sender][
1061
- _coreContract
1062
- ][_projectId];
1063
-
1064
- (uint232 netPosted, uint24 numPurchased) = SettlementExpLib
1065
- .validateReceiptEffects(receipt, currentPriceInWei);
1066
-
1067
- // emit event indicating new receipt state
1068
- emit ReceiptUpdated({
1069
- _purchaser: msg.sender,
1070
- _projectId: _projectId,
1071
- _coreContract: _coreContract,
1072
- _numPurchased: numPurchased,
1073
- _netPosted: netPosted
832
+ // update and validate receipts, latest purchase price, overall project
833
+ // balance, and number of tokens auctioned on this minter
834
+ SettlementExpLib.preMintEffects({
835
+ projectId: projectId,
836
+ coreContract: coreContract,
837
+ currentPriceInWei: currentPriceInWei,
838
+ msgValue: msg.value,
839
+ purchaserAddress: msg.sender
1074
840
  });
1075
841
 
1076
- // update latest purchase price (on this minter) in storage
1077
- // @dev this is used to enforce monotonically decreasing purchase price
1078
- // across multiple auctions
1079
- _settlementAuctionProjectConfig.latestPurchasePrice = currentPriceInWei
1080
- .toUint128();
1081
-
1082
- tokenId = minterFilter.mint_joo({
1083
- _to: _to,
1084
- _projectId: _projectId,
1085
- _coreContract: _coreContract,
1086
- _sender: msg.sender
842
+ // INTERACTIONS
843
+ tokenId = _minterFilter.mint_joo({
844
+ to: to,
845
+ projectId: projectId,
846
+ coreContract: coreContract,
847
+ sender: msg.sender
1087
848
  });
1088
849
 
1089
850
  // verify token invocation is valid given local minter max invocations,
1090
851
  // update local maxHasBeenInvoked
1091
- MaxInvocationsLib.validatePurchaseEffectsInvocations(
1092
- tokenId,
1093
- _maxInvocationsProjectConfig
1094
- );
852
+ MaxInvocationsLib.validatePurchaseEffectsInvocations({
853
+ tokenId: tokenId,
854
+ coreContract: coreContract
855
+ });
1095
856
 
1096
- // INTERACTIONS
1097
- // @dev this logic is intentionally defined here to avoid a dependency
1098
- // in SettlementLib on SplitFundsLib, which would increase complexity
1099
- if (_settlementAuctionProjectConfig.auctionRevenuesCollected) {
1100
- // if revenues have been collected, split funds immediately.
1101
- // @dev note that we are guaranteed to be at auction base price,
1102
- // since we know we didn't sellout prior to this tx.
1103
- // note that we don't refund msg.sender here, since a separate
1104
- // settlement mechanism is provided on this minter, unrelated to
1105
- // msg.value
1106
- // INTERACTIONS
1107
- bool isEngine = SplitFundsLib.isEngine(
1108
- _coreContract,
1109
- _isEngineCaches[_coreContract]
1110
- );
1111
- SplitFundsLib.splitFundsETH({
1112
- _projectId: _projectId,
1113
- _pricePerTokenInWei: currentPriceInWei,
1114
- _coreContract: _coreContract,
1115
- _isEngine: isEngine
1116
- });
1117
- } else {
1118
- // increment the number of settleable invocations that will be
1119
- // claimable by the artist and admin once auction is validated.
1120
- // do not split revenue here since will be claimed at a later time.
1121
- _settlementAuctionProjectConfig.numSettleableInvocations++;
1122
- }
857
+ // distribute payments if revenues have been collected, or increment
858
+ // number of settleable invocations if revenues have not been collected
859
+ SettlementExpLib.postMintInteractions({
860
+ projectId: projectId,
861
+ coreContract: coreContract,
862
+ currentPriceInWei: currentPriceInWei
863
+ });
864
+ }
1123
865
 
1124
- return tokenId;
866
+ /**
867
+ * @notice This function is intentionally not implemented for this version
868
+ * of the minter. Due to potential for unintended consequences, the
869
+ * function `manuallyLimitProjectMaxInvocations` should be used to manually
870
+ * and explicitly limit the maximum invocations for a project to a value
871
+ * other than the core contract's maximum invocations for a project.
872
+ * @param coreContract Core contract address for the given project.
873
+ * @param projectId Project ID to set the maximum invocations for.
874
+ */
875
+ function syncProjectMaxInvocationsToCore(
876
+ uint256 projectId,
877
+ address coreContract
878
+ ) public view {
879
+ AuthLib.onlyArtist({
880
+ projectId: projectId,
881
+ coreContract: coreContract,
882
+ sender: msg.sender
883
+ });
884
+ revert("Not implemented");
1125
885
  }
1126
886
  }