@artblocks/contracts 1.0.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/artifacts/contracts/AdminACLV1.sol/AdminACLV1.json +2 -2
- package/artifacts/contracts/DependencyRegistryV0.sol/DependencyRegistryV0.json +97 -10
- package/artifacts/contracts/GenArt721CoreV3.sol/GenArt721CoreV3.json +4 -4
- package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine.sol/GenArt721CoreV3_Engine.json +4 -9
- package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol/GenArt721CoreV3_Engine_Flex.json +4 -9
- package/artifacts/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol/GenArt721CoreV3_Engine_Flex_PROOF.json +4 -9
- package/artifacts/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol/GenArt721CoreV3_Engine_Flex_PROHIBITION.json +4 -9
- package/artifacts/contracts/engine-registry/CoreRegistryV1.sol/CoreRegistryV1.json +12 -12
- package/artifacts/contracts/explorations/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +4 -4
- package/artifacts/contracts/interfaces/v0.8.x/ICoreRegistryV1.sol/ICoreRegistryV1.json +6 -6
- package/artifacts/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol/IDependencyRegistryV0.json +19 -0
- package/artifacts/contracts/interfaces/v0.8.x/IMinterFilterV1.sol/IMinterFilterV1.json +22 -22
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol/ISharedMinterDAExpSettlementV0.json +8 -101
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAExpV0.sol/ISharedMinterDAExpV0.json +1 -57
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDALinV0.sol/ISharedMinterDALinV0.json +1 -57
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAV0.sol/ISharedMinterDAV0.json +2 -21
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterHolderERC20V0.sol/ISharedMinterHolderERC20V0.json +158 -0
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterHolderV0.sol/ISharedMinterHolderV0.json +15 -90
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterMerkleV0.sol/ISharedMinterMerkleV0.json +10 -36
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterSEAV0.sol/ISharedMinterSEAV0.json +4 -236
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterSimplePurchaseV0.sol/ISharedMinterSimplePurchaseV0.json +5 -5
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterV0.sol/ISharedMinterV0.json +7 -423
- package/artifacts/contracts/interfaces/v0.8.x/ISharedRandomizerV0.sol/ISharedRandomizerV0.json +17 -17
- package/artifacts/contracts/libs/v0.8.x/ABHelpers.sol/ABHelpers.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/AuthLib.sol/AuthLib.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/Bytes32Strings.sol/Bytes32Strings.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/minter-libs/DAExpLib.sol/DAExpLib.json +60 -3
- package/artifacts/contracts/libs/v0.8.x/minter-libs/DALib.sol/DALib.json +30 -0
- package/artifacts/contracts/libs/v0.8.x/minter-libs/DALinLib.sol/DALinLib.json +60 -3
- package/artifacts/contracts/libs/v0.8.x/minter-libs/GenericMinterEventsLib.sol/GenericMinterEventsLib.json +346 -0
- package/artifacts/contracts/libs/v0.8.x/minter-libs/MaxInvocationsLib.sol/MaxInvocationsLib.json +29 -3
- package/artifacts/contracts/libs/v0.8.x/minter-libs/MerkleLib.sol/MerkleLib.json +30 -3
- package/artifacts/contracts/libs/v0.8.x/minter-libs/PolyptychLib.sol/PolyptychLib.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/minter-libs/SEALib.sol/SEALib.json +254 -3
- package/artifacts/contracts/libs/v0.8.x/minter-libs/SetPriceLib.sol/SetPriceLib.json +48 -3
- package/artifacts/contracts/libs/v0.8.x/minter-libs/SettlementExpLib.sol/SettlementExpLib.json +41 -3
- package/artifacts/contracts/libs/v0.8.x/minter-libs/SplitFundsLib.sol/SplitFundsLib.json +35 -3
- package/artifacts/contracts/libs/v0.8.x/minter-libs/TokenHolderLib.sol/TokenHolderLib.json +79 -3
- package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV1.sol/MinterFilterV1.json +2 -2
- package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV2.sol/MinterFilterV2.json +41 -41
- package/artifacts/contracts/minter-suite/Minters/MinterDAExpHolderV5.sol/MinterDAExpHolderV5.json +66 -632
- package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV2.sol/MinterDAExpSettlementV2.json +2 -20
- package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV3.sol/MinterDAExpSettlementV3.json +67 -594
- package/artifacts/contracts/minter-suite/Minters/MinterDAExpV5.sol/MinterDAExpV5.json +33 -524
- package/artifacts/contracts/minter-suite/Minters/MinterDALinHolderV5.sol/MinterDALinHolderV5.json +66 -632
- package/artifacts/contracts/minter-suite/Minters/MinterDALinV5.sol/MinterDALinV5.json +33 -524
- package/artifacts/contracts/minter-suite/Minters/MinterSEAV1.sol/MinterSEAV1.json +51 -717
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20V5.sol/MinterSetPriceERC20V5.json +58 -454
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceHolderV5.sol/MinterSetPriceHolderV5.json +61 -552
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceMerkleV5.sol/MinterSetPriceMerkleV5.json +55 -497
- package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychERC20V5.sol/MinterSetPricePolyptychERC20V5.json +110 -571
- package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychV5.sol/MinterSetPricePolyptychV5.json +69 -560
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceV5.sol/MinterSetPriceV5.json +28 -444
- package/artifacts/contracts/mock/DummySharedMinter.sol/DummySharedMinter.json +2 -2
- package/artifacts/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol/GenArt721CoreV3_Engine_IncorrectCoreType.json +4 -9
- package/artifacts/contracts/mock/OriginRegisterMock.sol/OriginRegisterMock.json +2 -2
- package/artifacts/contracts/mock/ReentrancyHolderMockShared.sol/ReentrancyHolderMockShared.json +136 -0
- package/artifacts/contracts/mock/ReentrancyMerkleMockShared.sol/ReentrancyMerkleMockShared.json +105 -0
- package/artifacts/contracts/mock/ReentrancyMockShared.sol/ReentrancyMockShared.json +100 -0
- package/artifacts/contracts/mock/ReentrancySEAMockShared.sol/ReentrancySEAAutoBidderMockShared.json +69 -0
- package/artifacts/contracts/randomizer/shared/SharedRandomizerV0.sol/SharedRandomizerV0.json +19 -19
- package/contracts/DependencyRegistryV0.sol +84 -16
- package/contracts/archive/readme.md +16 -0
- package/contracts/engine/README.md +21 -0
- package/contracts/engine/V3/GenArt721CoreV3_Engine.sol +4 -10
- package/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol +4 -10
- package/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol +4 -10
- package/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol +4 -10
- package/contracts/engine-registry/CoreRegistryV1.sol +58 -65
- package/contracts/interfaces/v0.8.x/ICoreRegistryV1.sol +6 -8
- package/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol +3 -0
- package/contracts/interfaces/v0.8.x/IMinterFilterV1.sol +25 -25
- package/contracts/interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol +11 -20
- package/contracts/interfaces/v0.8.x/ISharedMinterDAExpV0.sol +1 -14
- package/contracts/interfaces/v0.8.x/ISharedMinterDALinV0.sol +1 -15
- package/contracts/interfaces/v0.8.x/ISharedMinterDAV0.sol +2 -8
- package/contracts/interfaces/v0.8.x/ISharedMinterHolderERC20V0.sol +47 -0
- package/contracts/interfaces/v0.8.x/ISharedMinterHolderV0.sol +15 -43
- package/contracts/interfaces/v0.8.x/ISharedMinterMerkleV0.sol +10 -20
- package/contracts/interfaces/v0.8.x/ISharedMinterSEAV0.sol +4 -67
- package/contracts/interfaces/v0.8.x/ISharedMinterSimplePurchaseV0.sol +5 -5
- package/contracts/interfaces/v0.8.x/ISharedMinterV0.sol +7 -155
- package/contracts/interfaces/v0.8.x/ISharedRandomizerV0.sol +37 -37
- package/contracts/libs/v0.8.x/ABHelpers.sol +14 -14
- package/contracts/libs/v0.8.x/AuthLib.sol +101 -102
- package/contracts/libs/v0.8.x/Bytes32Strings.sol +5 -5
- package/contracts/libs/v0.8.x/minter-libs/DAExpLib.sol +163 -38
- package/contracts/libs/v0.8.x/minter-libs/DALib.sol +26 -0
- package/contracts/libs/v0.8.x/minter-libs/DALinLib.sol +144 -37
- package/contracts/libs/v0.8.x/minter-libs/GenericMinterEventsLib.sol +171 -0
- package/contracts/libs/v0.8.x/minter-libs/MaxInvocationsLib.sol +250 -110
- package/contracts/libs/v0.8.x/minter-libs/MerkleLib.sol +257 -48
- package/contracts/libs/v0.8.x/minter-libs/PolyptychLib.sol +138 -58
- package/contracts/libs/v0.8.x/minter-libs/SEALib.sol +778 -103
- package/contracts/libs/v0.8.x/minter-libs/SetPriceLib.sol +135 -13
- package/contracts/libs/v0.8.x/minter-libs/SettlementExpLib.sol +567 -187
- package/contracts/libs/v0.8.x/minter-libs/SplitFundsLib.sol +480 -322
- package/contracts/libs/v0.8.x/minter-libs/TokenHolderLib.sol +214 -76
- package/contracts/minter-suite/MinterFilter/MinterFilterV2.sol +347 -304
- package/contracts/minter-suite/Minters/MinterDAExpHolderV5.sol +391 -491
- package/contracts/minter-suite/Minters/MinterDAExpSettlementV2.sol +1 -54
- package/contracts/minter-suite/Minters/MinterDAExpSettlementV3.sol +388 -628
- package/contracts/minter-suite/Minters/MinterDAExpV5.sol +212 -273
- package/contracts/minter-suite/Minters/MinterDALinHolderV5.sol +393 -488
- package/contracts/minter-suite/Minters/MinterDALinV5.sol +220 -277
- package/contracts/minter-suite/Minters/MinterSEAV1.sol +327 -664
- package/contracts/minter-suite/Minters/MinterSetPriceERC20V5.sol +278 -303
- package/contracts/minter-suite/Minters/MinterSetPriceHolderV5.sol +355 -446
- package/contracts/minter-suite/Minters/MinterSetPriceMerkleV5.sol +328 -416
- package/contracts/minter-suite/Minters/MinterSetPricePolyptychERC20V5.sol +538 -622
- package/contracts/minter-suite/Minters/MinterSetPricePolyptychV5.sol +429 -553
- package/contracts/minter-suite/Minters/MinterSetPriceV5.sol +180 -227
- package/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol +3 -10
- package/contracts/mock/ReentrancyHolderMockShared.sol +59 -0
- package/contracts/mock/ReentrancyMerkleMockShared.sol +58 -0
- package/contracts/mock/ReentrancyMockShared.sol +48 -0
- package/contracts/mock/ReentrancySEAMockShared.sol +40 -0
- package/contracts/randomizer/shared/SharedRandomizerV0.sol +78 -70
- package/package.json +39 -33
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
2
2
|
// Created By: Art Blocks Inc.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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 "../../
|
|
12
|
-
import "../../
|
|
13
|
-
import "../../
|
|
14
|
-
import "../../
|
|
15
|
-
import "../../
|
|
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 "
|
|
18
|
-
import "
|
|
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
|
-
|
|
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
|
|
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
|
-
* `
|
|
157
|
-
* @param
|
|
115
|
+
* `minterFilter` minter filter.
|
|
116
|
+
* @param minterFilter Minter filter for which this will be a
|
|
158
117
|
* filtered minter.
|
|
159
118
|
*/
|
|
160
|
-
constructor(address
|
|
161
|
-
minterFilterAddress =
|
|
162
|
-
|
|
163
|
-
emit AuctionMinHalfLifeSecondsUpdated(
|
|
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 `
|
|
168
|
-
* with the provided `
|
|
169
|
-
* than or equal to the value of project `
|
|
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 `
|
|
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
|
|
175
|
-
* @param
|
|
176
|
-
* @param
|
|
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
|
|
180
|
-
address
|
|
181
|
-
uint24
|
|
140
|
+
uint256 projectId,
|
|
141
|
+
address coreContract,
|
|
142
|
+
uint24 maxInvocations
|
|
182
143
|
) external {
|
|
183
144
|
AuthLib.onlyArtist({
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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 `
|
|
206
|
-
* @param
|
|
207
|
-
* @param
|
|
208
|
-
* @param
|
|
209
|
-
* @param
|
|
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
|
|
212
|
-
* @param
|
|
213
|
-
* @dev Note that
|
|
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
|
|
218
|
-
address
|
|
219
|
-
uint40
|
|
220
|
-
uint40
|
|
221
|
-
uint256
|
|
222
|
-
uint256
|
|
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
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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
|
-
|
|
243
|
-
|
|
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(
|
|
200
|
+
require(basePrice > 0, "Base price must be non-zero");
|
|
249
201
|
// require valid half life for this minter
|
|
250
202
|
require(
|
|
251
|
-
(
|
|
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
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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
|
-
|
|
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
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
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
|
-
* `
|
|
308
|
-
* @param
|
|
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
|
|
242
|
+
uint256 minimumPriceDecayHalfLifeSeconds_
|
|
313
243
|
) external {
|
|
314
244
|
AuthLib.onlyMinterFilterAdminACL({
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
245
|
+
minterFilterAddress: minterFilterAddress,
|
|
246
|
+
sender: msg.sender,
|
|
247
|
+
contract_: address(this),
|
|
248
|
+
selector: this.setMinimumPriceDecayHalfLifeSeconds.selector
|
|
319
249
|
});
|
|
320
250
|
require(
|
|
321
|
-
|
|
251
|
+
minimumPriceDecayHalfLifeSeconds_ > 0,
|
|
322
252
|
"Half life of zero not allowed"
|
|
323
253
|
);
|
|
324
|
-
minimumPriceDecayHalfLifeSeconds =
|
|
254
|
+
minimumPriceDecayHalfLifeSeconds = minimumPriceDecayHalfLifeSeconds_;
|
|
325
255
|
|
|
326
|
-
emit AuctionMinHalfLifeSecondsUpdated(
|
|
327
|
-
|
|
256
|
+
emit DAExpLib.AuctionMinHalfLifeSecondsUpdated(
|
|
257
|
+
minimumPriceDecayHalfLifeSeconds_
|
|
328
258
|
);
|
|
329
259
|
}
|
|
330
260
|
|
|
331
261
|
/**
|
|
332
|
-
* @notice Resets auction details for project `
|
|
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
|
|
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
|
|
339
|
-
address
|
|
269
|
+
uint256 projectId,
|
|
270
|
+
address coreContract
|
|
340
271
|
) external {
|
|
341
272
|
AuthLib.onlyCoreAdminACL({
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
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
|
|
350
|
-
|
|
351
|
-
|
|
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
|
-
!
|
|
288
|
+
!settlementAuctionProjectConfig.auctionRevenuesCollected,
|
|
356
289
|
"Only before revenues collected"
|
|
357
290
|
);
|
|
358
291
|
|
|
359
292
|
// EFFECTS
|
|
360
293
|
// delete auction parameters
|
|
361
|
-
|
|
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
|
|
447
|
-
address
|
|
319
|
+
uint256 projectId,
|
|
320
|
+
address coreContract
|
|
448
321
|
) external nonReentrant {
|
|
449
322
|
AuthLib.onlyCoreAdminACLOrArtist({
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
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
|
|
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
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
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 `
|
|
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
|
|
517
|
-
* @param
|
|
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
|
|
521
|
-
address
|
|
357
|
+
uint256 projectId,
|
|
358
|
+
address coreContract
|
|
522
359
|
) external {
|
|
523
|
-
reclaimProjectExcessSettlementFundsTo(
|
|
524
|
-
payable(msg.sender),
|
|
525
|
-
|
|
526
|
-
|
|
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 `
|
|
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
|
|
379
|
+
* @param projectIds Array of project IDs to reclaim excess settlement
|
|
543
380
|
* funds on.
|
|
544
|
-
* @param
|
|
545
|
-
* projects. Must be in the same order as `
|
|
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
|
|
549
|
-
address[] calldata
|
|
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
|
-
|
|
555
|
-
|
|
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 `
|
|
561
|
-
* @param
|
|
562
|
-
* @param
|
|
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
|
|
567
|
-
address
|
|
403
|
+
uint256 projectId,
|
|
404
|
+
address coreContract
|
|
568
405
|
) external payable returns (uint256 tokenId) {
|
|
569
406
|
tokenId = purchaseTo({
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
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
|
|
582
|
-
* @param
|
|
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
|
|
588
|
-
address
|
|
424
|
+
uint256 projectId,
|
|
425
|
+
address coreContract
|
|
589
426
|
)
|
|
590
427
|
external
|
|
591
428
|
view
|
|
592
429
|
returns (MaxInvocationsLib.MaxInvocationsProjectConfig memory)
|
|
593
430
|
{
|
|
594
|
-
return
|
|
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
|
|
600
|
-
* @param
|
|
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
|
|
609
|
-
address
|
|
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
|
-
|
|
622
|
-
|
|
623
|
-
|
|
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 `
|
|
633
|
-
* @dev This function retrieves the cached value of `
|
|
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 `
|
|
636
|
-
* function from the `SplitFundsLib` library to check if `
|
|
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 `
|
|
480
|
+
* @dev This function will revert if the provided `coreContract` is not
|
|
639
481
|
* a valid Engine or V3 Flagship contract.
|
|
640
|
-
* @param
|
|
641
|
-
* @return bool indicating if `
|
|
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
|
|
644
|
-
SplitFundsLib.IsEngineCache storage isEngineCache =
|
|
645
|
-
|
|
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
|
|
651
|
-
return SplitFundsLib.getV3CoreIsEngineView(
|
|
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
|
|
663
|
-
*
|
|
664
|
-
*
|
|
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
|
|
667
|
-
* @param
|
|
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
|
|
671
|
-
address
|
|
511
|
+
uint256 projectId,
|
|
512
|
+
address coreContract
|
|
672
513
|
) external view returns (bool) {
|
|
673
514
|
return
|
|
674
|
-
MaxInvocationsLib.getMaxHasBeenInvoked(
|
|
675
|
-
|
|
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
|
|
690
|
-
*
|
|
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 `
|
|
696
|
-
* @param
|
|
697
|
-
* @param
|
|
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
|
|
701
|
-
address
|
|
543
|
+
uint256 projectId,
|
|
544
|
+
address coreContract
|
|
702
545
|
) external view returns (uint256) {
|
|
703
546
|
return
|
|
704
|
-
MaxInvocationsLib.getMaxInvocations(
|
|
705
|
-
|
|
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 `
|
|
554
|
+
* @notice Gets the latest purchase price for project `projectId`, or 0 if
|
|
711
555
|
* no purchases have been made.
|
|
712
|
-
* @param
|
|
713
|
-
* @param
|
|
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
|
|
717
|
-
address
|
|
561
|
+
uint256 projectId,
|
|
562
|
+
address coreContract
|
|
718
563
|
) external view returns (uint256 latestPurchasePrice) {
|
|
719
564
|
SettlementExpLib.SettlementAuctionProjectConfig
|
|
720
|
-
storage
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
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 `
|
|
728
|
-
* @param
|
|
729
|
-
* @param
|
|
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
|
|
733
|
-
address
|
|
580
|
+
uint256 projectId,
|
|
581
|
+
address coreContract
|
|
734
582
|
) external view returns (uint256 numSettleableInvocations) {
|
|
735
583
|
SettlementExpLib.SettlementAuctionProjectConfig
|
|
736
|
-
storage
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
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 `
|
|
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
|
|
747
|
-
* @param
|
|
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
|
|
759
|
-
address
|
|
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
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
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
|
-
|
|
801
|
-
|
|
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 `
|
|
813
|
-
* for address `
|
|
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
|
|
819
|
-
* @param
|
|
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
|
|
826
|
-
address
|
|
827
|
-
address
|
|
687
|
+
uint256 projectId,
|
|
688
|
+
address coreContract,
|
|
689
|
+
address walletAddress
|
|
828
690
|
) external view returns (uint256 excessSettlementFundsInWei) {
|
|
829
691
|
// input validation
|
|
830
|
-
require(
|
|
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
|
-
|
|
843
|
-
|
|
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 `
|
|
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 `
|
|
859
|
-
* @param
|
|
860
|
-
* @param
|
|
861
|
-
* @param
|
|
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
|
|
865
|
-
uint256
|
|
866
|
-
address
|
|
718
|
+
address payable to,
|
|
719
|
+
uint256 projectId,
|
|
720
|
+
address coreContract
|
|
867
721
|
) public nonReentrant {
|
|
868
|
-
require(
|
|
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
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
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 `
|
|
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 `
|
|
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
|
|
915
|
-
* @param
|
|
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
|
|
918
|
-
* projects. Must be in the same order as `
|
|
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
|
|
922
|
-
uint256[] calldata
|
|
923
|
-
address[] calldata
|
|
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(
|
|
928
|
-
uint256 projectIdsLength =
|
|
757
|
+
require(to != address(0), "No claiming to the zero address");
|
|
758
|
+
uint256 projectIdsLength = projectIds.length;
|
|
929
759
|
require(
|
|
930
|
-
projectIdsLength ==
|
|
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
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
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_, ) =
|
|
786
|
+
(success_, ) = to.call{value: excessSettlementFunds}("");
|
|
981
787
|
require(success_, "Reclaiming failed");
|
|
982
788
|
}
|
|
983
789
|
|
|
984
790
|
/**
|
|
985
|
-
* @notice
|
|
986
|
-
*
|
|
987
|
-
*
|
|
988
|
-
*
|
|
989
|
-
*
|
|
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
|
|
1015
|
-
uint256
|
|
1016
|
-
address
|
|
799
|
+
address to,
|
|
800
|
+
uint256 projectId,
|
|
801
|
+
address coreContract
|
|
1017
802
|
) public payable nonReentrant returns (uint256 tokenId) {
|
|
1018
803
|
// CHECKS
|
|
1019
|
-
|
|
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
|
-
// `
|
|
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
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
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
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
826
|
+
projectId: projectId,
|
|
827
|
+
coreContract: coreContract,
|
|
828
|
+
maxHasBeenInvoked: false // always false due to MaxInvocationsLib.preMintChecks
|
|
1056
829
|
});
|
|
1057
830
|
|
|
1058
831
|
// EFFECTS
|
|
1059
|
-
// update
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
.
|
|
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
|
-
//
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
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
|
-
|
|
1094
|
-
);
|
|
852
|
+
MaxInvocationsLib.validatePurchaseEffectsInvocations({
|
|
853
|
+
tokenId: tokenId,
|
|
854
|
+
coreContract: coreContract
|
|
855
|
+
});
|
|
1095
856
|
|
|
1096
|
-
//
|
|
1097
|
-
//
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
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
|
-
|
|
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
|
}
|