@artblocks/contracts 0.0.1 → 1.0.1

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 (138) hide show
  1. package/README.md +30 -11
  2. package/artifacts/contracts/AdminACLV1.sol/AdminACLV1.json +2 -2
  3. package/artifacts/contracts/BasicPolyptychRandomizerV0.sol/BasicPolyptychRandomizerV0.json +229 -0
  4. package/artifacts/contracts/BasicRandomizerV2.sol/BasicRandomizerV2.json +3 -3
  5. package/artifacts/contracts/GenArt721CoreV3.sol/GenArt721CoreV3.json +2 -2
  6. package/artifacts/contracts/GenArt721CoreV3_Engine.sol/GenArt721CoreV3_Engine.json +2 -2
  7. package/artifacts/contracts/archive/GenArt721CoreV0.sol/Address.json +10 -0
  8. package/artifacts/contracts/archive/GenArt721CoreV0.sol/Counters.json +10 -0
  9. package/artifacts/contracts/archive/GenArt721CoreV0.sol/CustomERC721Metadata.json +425 -0
  10. package/artifacts/contracts/archive/GenArt721CoreV0.sol/ERC165.json +38 -0
  11. package/artifacts/contracts/archive/GenArt721CoreV0.sol/ERC721.json +322 -0
  12. package/artifacts/contracts/archive/GenArt721CoreV0.sol/ERC721Enumerable.json +384 -0
  13. package/artifacts/contracts/archive/GenArt721CoreV0.sol/ERC721ReceiverMock.json +101 -0
  14. package/artifacts/contracts/archive/GenArt721CoreV0.sol/GenArt721.json +1528 -0
  15. package/artifacts/contracts/archive/GenArt721CoreV0.sol/IERC165.json +32 -0
  16. package/artifacts/contracts/archive/GenArt721CoreV0.sol/IERC721.json +316 -0
  17. package/artifacts/contracts/archive/GenArt721CoreV0.sol/IERC721Enumerable.json +378 -0
  18. package/artifacts/contracts/archive/GenArt721CoreV0.sol/IERC721Receiver.json +47 -0
  19. package/artifacts/contracts/archive/GenArt721CoreV0.sol/SafeMath.json +10 -0
  20. package/artifacts/contracts/archive/GenArt721CoreV0.sol/Strings.json +10 -0
  21. package/artifacts/contracts/archive/GenArt721CoreV1.sol/Address.json +10 -0
  22. package/artifacts/contracts/archive/GenArt721CoreV1.sol/Counters.json +10 -0
  23. package/artifacts/contracts/archive/GenArt721CoreV1.sol/CustomERC721Metadata.json +425 -0
  24. package/artifacts/contracts/archive/GenArt721CoreV1.sol/ERC165.json +38 -0
  25. package/artifacts/contracts/archive/GenArt721CoreV1.sol/ERC721.json +322 -0
  26. package/artifacts/contracts/archive/GenArt721CoreV1.sol/ERC721Enumerable.json +384 -0
  27. package/artifacts/contracts/archive/GenArt721CoreV1.sol/GenArt721Core.json +1773 -0
  28. package/artifacts/contracts/archive/GenArt721CoreV1.sol/IERC165.json +32 -0
  29. package/artifacts/contracts/archive/GenArt721CoreV1.sol/IERC721.json +316 -0
  30. package/artifacts/contracts/archive/GenArt721CoreV1.sol/IERC721Enumerable.json +378 -0
  31. package/artifacts/contracts/archive/GenArt721CoreV1.sol/IERC721Receiver.json +47 -0
  32. package/artifacts/contracts/archive/GenArt721CoreV1.sol/Randomizer.json +26 -0
  33. package/artifacts/contracts/archive/GenArt721CoreV1.sol/SafeMath.json +10 -0
  34. package/artifacts/contracts/archive/GenArt721CoreV1.sol/Strings.json +10 -0
  35. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV0.sol/MinterDAExpV0.json +575 -0
  36. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV1.sol/MinterDAExpV1.json +463 -0
  37. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDAExp/MinterDAExpV2.sol/MinterDAExpV2.json +3 -3
  38. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDAExp/MinterDAExpV3.sol/MinterDAExpV3.json +3 -3
  39. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol/MinterDAExpSettlementV0.json +15 -15
  40. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV1.sol/MinterDAExpSettlementV1.json +1066 -0
  41. package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV0.sol/MinterDALinV0.json +551 -0
  42. package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV1.sol/MinterDALinV1.json +439 -0
  43. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDALin/MinterDALinV2.sol/MinterDALinV2.json +3 -3
  44. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDALin/MinterDALinV3.sol/MinterDALinV3.json +3 -3
  45. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV0.sol/MinterHolderV0.json +622 -0
  46. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV1.sol/MinterHolderV1.json +719 -0
  47. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV2.sol/MinterHolderV2.json +794 -0
  48. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterHolder/MinterHolderV3.sol/MinterHolderV3.json +3 -3
  49. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV0.sol/MinterMerkleV0.json +873 -0
  50. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV1.sol/MinterMerkleV1.json +932 -0
  51. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV2.sol/MinterMerkleV2.json +984 -0
  52. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterMerkle/MinterMerkleV3.sol/MinterMerkleV3.json +3 -3
  53. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterMerkle/MinterMerkleV4.sol/MinterMerkleV4.json +3 -3
  54. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV0.sol/MinterSetPriceV0.json +400 -0
  55. package/artifacts/contracts/{minter-suite/Minters/MinterSetPrice/deprecated → archive/minter-suite/Minters/MinterSetPrice}/MinterSetPriceV1.sol/MinterSetPriceV1.json +3 -3
  56. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterSetPrice/MinterSetPriceV2.sol/MinterSetPriceV2.json +3 -3
  57. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterSetPrice/MinterSetPriceV3.sol/MinterSetPriceV3.json +3 -3
  58. package/artifacts/contracts/{minter-suite/Minters/MinterSetPriceERC20/deprecated → archive/minter-suite/Minters/MinterSetPriceERC20}/MinterSetPriceERC20V0.sol/MinterSetPriceERC20V0.json +3 -3
  59. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V1.sol/MinterSetPriceERC20V1.json +349 -0
  60. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol/MinterSetPriceERC20V2.json +3 -3
  61. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol/MinterSetPriceERC20V3.json +3 -3
  62. package/artifacts/contracts/explorations/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +2 -2
  63. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDAExpSettlementV0.sol/IFilteredMinterDAExpSettlementV0.json +12 -12
  64. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDAExpSettlementV1.sol/IFilteredMinterDAExpSettlementV1.json +767 -0
  65. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDAExpSettlement_Mixin.sol/IFilteredMinterDAExpSettlement_Mixin.json +161 -0
  66. package/artifacts/contracts/interfaces/0.8.x/IMinterBaseV0.sol/IMinterBaseV0.json +24 -0
  67. package/artifacts/contracts/interfaces/0.8.x/IMinterFilterV0.sol/IMinterFilterV0.json +6 -0
  68. package/artifacts/contracts/interfaces/0.8.x/IMintingAPICoreV0.sol/IMintingAPICoreV0.json +185 -0
  69. package/artifacts/contracts/interfaces/0.8.x/IMintingAPIMinterV0.sol/IMintingAPIMinterV0.json +88 -0
  70. package/artifacts/contracts/interfaces/0.8.x/IRandomizerPolyptychV0.sol/IRandomizerPolyptychV0.json +87 -0
  71. package/artifacts/contracts/interfaces/0.8.x/IRandomizerV2.sol/IRandomizerV2.json +1 -1
  72. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV0.sol/MinterFilterV0.json +8 -2
  73. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV1.sol/MinterFilterV1.json +34 -2
  74. package/artifacts/contracts/minter-suite/Minters/MinterBase_v0_1_1.sol/MinterBase.json +24 -0
  75. package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV2.sol/MinterDAExpSettlementV2.json +1127 -0
  76. package/artifacts/contracts/minter-suite/Minters/MinterDAExpV4.sol/MinterDAExpV4.json +882 -0
  77. package/artifacts/contracts/minter-suite/Minters/MinterDALinV4.sol/MinterDALinV4.json +858 -0
  78. package/artifacts/contracts/minter-suite/Minters/MinterHolderV4.sol/MinterHolderV4.json +1126 -0
  79. package/artifacts/contracts/minter-suite/Minters/MinterMerkleV5.sol/MinterMerkleV5.json +1065 -0
  80. package/artifacts/contracts/minter-suite/Minters/MinterPolyptychV0.sol/IGenArt721CoreContractV3WithRandomizer.json +662 -0
  81. package/artifacts/contracts/minter-suite/Minters/MinterPolyptychV0.sol/MinterPolyptychV0.json +1268 -0
  82. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20V4.sol/MinterSetPriceERC20V4.json +768 -0
  83. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceV4.sol/MinterSetPriceV4.json +697 -0
  84. package/artifacts/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol/GenArt721CoreV3_Engine_IncorrectCoreType.json +1817 -0
  85. package/artifacts/contracts/mock/RandomizerV2_NoAssignMock.sol/RandomizerV2_NoAssignMock.json +3 -3
  86. package/contracts/BasicPolyptychRandomizerV0.sol +126 -0
  87. package/contracts/BasicRandomizerV2.sol +3 -3
  88. package/contracts/archive/GenArt721CoreV0.sol +1621 -0
  89. package/contracts/archive/GenArt721CoreV1.sol +1577 -0
  90. package/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV0.sol +503 -0
  91. package/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV1.sol +442 -0
  92. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDAExp/MinterDAExpV2.sol +3 -3
  93. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDAExp/MinterDAExpV3.sol +3 -3
  94. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol +3 -3
  95. package/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV1.sol +1026 -0
  96. package/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV0.sol +450 -0
  97. package/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV1.sol +406 -0
  98. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDALin/MinterDALinV2.sol +3 -3
  99. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDALin/MinterDALinV3.sol +3 -3
  100. package/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV0.sol +540 -0
  101. package/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV1.sol +648 -0
  102. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterHolder/MinterHolderV2.sol +6 -6
  103. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterHolder/MinterHolderV3.sol +4 -4
  104. package/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV0.sol +523 -0
  105. package/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV1.sol +602 -0
  106. package/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV2.sol +679 -0
  107. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterMerkle/MinterMerkleV3.sol +4 -4
  108. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterMerkle/MinterMerkleV4.sol +4 -4
  109. package/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV0.sol +333 -0
  110. package/contracts/{minter-suite/Minters/MinterSetPrice/deprecated → archive/minter-suite/Minters/MinterSetPrice}/MinterSetPriceV1.sol +0 -0
  111. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterSetPrice/MinterSetPriceV2.sol +3 -3
  112. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterSetPrice/MinterSetPriceV3.sol +3 -3
  113. package/contracts/{minter-suite/Minters/MinterSetPriceERC20/deprecated → archive/minter-suite/Minters/MinterSetPriceERC20}/MinterSetPriceERC20V0.sol +0 -0
  114. package/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V1.sol +411 -0
  115. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol +3 -3
  116. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol +3 -3
  117. package/contracts/interfaces/0.8.x/IFilteredMinterDAExpSettlementV0.sol +4 -53
  118. package/contracts/interfaces/0.8.x/IFilteredMinterDAExpSettlementV1.sol +21 -0
  119. package/contracts/interfaces/0.8.x/IFilteredMinterDAExpSettlement_Mixin.sol +62 -0
  120. package/contracts/interfaces/0.8.x/IMinterBaseV0.sol +20 -0
  121. package/contracts/interfaces/0.8.x/IMinterFilterV0.sol +6 -0
  122. package/contracts/interfaces/0.8.x/IMintingAPICoreV0.sol +62 -0
  123. package/contracts/interfaces/0.8.x/IMintingAPIMinterV0.sol +31 -0
  124. package/contracts/interfaces/0.8.x/IRandomizerPolyptychV0.sol +31 -0
  125. package/contracts/interfaces/0.8.x/IRandomizerV2.sol +5 -2
  126. package/contracts/minter-suite/MinterFilter/MinterFilterV1.sol +18 -0
  127. package/contracts/minter-suite/Minters/MinterBase_v0_1_1.sol +293 -0
  128. package/contracts/minter-suite/Minters/MinterDAExpSettlementV2.sol +1312 -0
  129. package/contracts/minter-suite/Minters/MinterDAExpV4.sol +600 -0
  130. package/contracts/minter-suite/Minters/MinterDALinV4.sol +552 -0
  131. package/contracts/minter-suite/Minters/MinterHolderV4.sol +781 -0
  132. package/contracts/minter-suite/Minters/MinterMerkleV5.sol +717 -0
  133. package/contracts/minter-suite/Minters/MinterPolyptychV0.sol +998 -0
  134. package/contracts/minter-suite/Minters/MinterSetPriceERC20V4.sol +480 -0
  135. package/contracts/minter-suite/Minters/MinterSetPriceV4.sol +380 -0
  136. package/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol +1979 -0
  137. package/package.json +8 -2
  138. package/artifacts/contracts/minter-suite/Minters/MinterHolder/MinterHolderV2.sol/MinterHolderV2.json +0 -794
@@ -0,0 +1,411 @@
1
+ // SPDX-License-Identifier: LGPL-3.0-only
2
+ // Created By: Art Blocks Inc.
3
+
4
+ import "../../../../interfaces/0.8.x/IGenArt721CoreContractV1.sol";
5
+ import "../../../../interfaces/0.8.x/IMinterFilterV0.sol";
6
+ import "../../../../interfaces/0.8.x/IFilteredMinterV0.sol";
7
+
8
+ import "@openzeppelin-4.5/contracts/token/ERC20/IERC20.sol";
9
+ import "@openzeppelin-4.5/contracts/security/ReentrancyGuard.sol";
10
+
11
+ pragma solidity 0.8.9;
12
+
13
+ /**
14
+ * @title Filtered Minter contract that allows tokens to be minted with ETH
15
+ * or any ERC-20 token.
16
+ * @author Art Blocks Inc.
17
+ */
18
+ contract MinterSetPriceERC20V1 is ReentrancyGuard, IFilteredMinterV0 {
19
+ /// Core contract address this minter interacts with
20
+ address public immutable genArt721CoreAddress;
21
+
22
+ /// This contract handles cores with interface IV1
23
+ IGenArt721CoreContractV1 private immutable genArtCoreContract;
24
+
25
+ /// Minter filter address this minter interacts with
26
+ address public immutable minterFilterAddress;
27
+
28
+ /// Minter filter this minter may interact with.
29
+ IMinterFilterV0 private immutable minterFilter;
30
+
31
+ /// minterType for this minter
32
+ string public constant minterType = "MinterSetPriceERC20V1";
33
+
34
+ uint256 constant ONE_MILLION = 1_000_000;
35
+
36
+ /// projectId => has project reached its maximum number of invocations?
37
+ mapping(uint256 => bool) public projectMaxHasBeenInvoked;
38
+ /// projectId => project's maximum number of invocations
39
+ mapping(uint256 => uint256) public projectMaxInvocations;
40
+ /// projectId => price per token in wei - supersedes any defined core price
41
+ mapping(uint256 => uint256) private projectIdToPricePerTokenInWei;
42
+ /// projectId => price per token has been configured on this minter
43
+ mapping(uint256 => bool) private projectIdToPriceIsConfigured;
44
+ /// projectId => currency symbol - supersedes any defined core value
45
+ mapping(uint256 => string) private projectIdToCurrencySymbol;
46
+ /// projectId => currency address - supersedes any defined core value
47
+ mapping(uint256 => address) private projectIdToCurrencyAddress;
48
+
49
+ modifier onlyCoreWhitelisted() {
50
+ require(
51
+ genArtCoreContract.isWhitelisted(msg.sender),
52
+ "Only Core whitelisted"
53
+ );
54
+ _;
55
+ }
56
+
57
+ modifier onlyArtist(uint256 _projectId) {
58
+ require(
59
+ msg.sender ==
60
+ genArtCoreContract.projectIdToArtistAddress(_projectId),
61
+ "Only Artist"
62
+ );
63
+ _;
64
+ }
65
+
66
+ /**
67
+ * @notice Initializes contract to be a Filtered Minter for
68
+ * `_minterFilter`, integrated with Art Blocks core contract
69
+ * at address `_genArt721Address`.
70
+ * @param _genArt721Address Art Blocks core contract for which this
71
+ * contract will be a minter.
72
+ * @param _minterFilter Minter filter for which
73
+ * this will a filtered minter.
74
+ */
75
+ constructor(
76
+ address _genArt721Address,
77
+ address _minterFilter
78
+ ) ReentrancyGuard() {
79
+ genArt721CoreAddress = _genArt721Address;
80
+ genArtCoreContract = IGenArt721CoreContractV1(_genArt721Address);
81
+ minterFilterAddress = _minterFilter;
82
+ minterFilter = IMinterFilterV0(_minterFilter);
83
+ require(
84
+ minterFilter.genArt721CoreAddress() == _genArt721Address,
85
+ "Illegal contract pairing"
86
+ );
87
+ }
88
+
89
+ /**
90
+ * @notice Gets your balance of the ERC-20 token currently set
91
+ * as the payment currency for project `_projectId`.
92
+ * @param _projectId Project ID to be queried.
93
+ * @return balance Balance of ERC-20
94
+ */
95
+ function getYourBalanceOfProjectERC20(
96
+ uint256 _projectId
97
+ ) external view returns (uint256 balance) {
98
+ balance = IERC20(projectIdToCurrencyAddress[_projectId]).balanceOf(
99
+ msg.sender
100
+ );
101
+ return balance;
102
+ }
103
+
104
+ /**
105
+ * @notice Gets your allowance for this minter of the ERC-20
106
+ * token currently set as the payment currency for project
107
+ * `_projectId`.
108
+ * @param _projectId Project ID to be queried.
109
+ * @return remaining Remaining allowance of ERC-20
110
+ */
111
+ function checkYourAllowanceOfProjectERC20(
112
+ uint256 _projectId
113
+ ) external view returns (uint256 remaining) {
114
+ remaining = IERC20(projectIdToCurrencyAddress[_projectId]).allowance(
115
+ msg.sender,
116
+ address(this)
117
+ );
118
+ return remaining;
119
+ }
120
+
121
+ /**
122
+ * @notice Sets the maximum invocations of project `_projectId` based
123
+ * on the value currently defined in the core contract.
124
+ * @param _projectId Project ID to set the maximum invocations for.
125
+ * @dev also checks and may refresh projectMaxHasBeenInvoked for project
126
+ * @dev this enables gas reduction after maxInvocations have been reached -
127
+ * core contracts shall still enforce a maxInvocation check during mint.
128
+ */
129
+ function setProjectMaxInvocations(
130
+ uint256 _projectId
131
+ ) external onlyCoreWhitelisted {
132
+ uint256 invocations;
133
+ uint256 maxInvocations;
134
+ (, , invocations, maxInvocations, , , , , ) = genArtCoreContract
135
+ .projectTokenInfo(_projectId);
136
+ // update storage with results
137
+ projectMaxInvocations[_projectId] = maxInvocations;
138
+ if (invocations < maxInvocations) {
139
+ projectMaxHasBeenInvoked[_projectId] = false;
140
+ }
141
+ }
142
+
143
+ /**
144
+ * @notice Warning: Disabling purchaseTo is not supported on this minter.
145
+ * This method exists purely for interface-conformance purposes.
146
+ */
147
+ function togglePurchaseToDisabled(
148
+ uint256 _projectId
149
+ ) external view onlyArtist(_projectId) {
150
+ revert("Action not supported");
151
+ }
152
+
153
+ /**
154
+ * @notice Updates this minter's price per token of project `_projectId`
155
+ * to be '_pricePerTokenInWei`, in Wei.
156
+ * This price supersedes any legacy core contract price per token value.
157
+ */
158
+ function updatePricePerTokenInWei(
159
+ uint256 _projectId,
160
+ uint256 _pricePerTokenInWei
161
+ ) external onlyArtist(_projectId) {
162
+ projectIdToPricePerTokenInWei[_projectId] = _pricePerTokenInWei;
163
+ projectIdToPriceIsConfigured[_projectId] = true;
164
+ emit PricePerTokenInWeiUpdated(_projectId, _pricePerTokenInWei);
165
+ }
166
+
167
+ /**
168
+ * @notice Updates payment currency of project `_projectId` to be
169
+ * `_currencySymbol` at address `_currencyAddress`.
170
+ * @param _projectId Project ID to update.
171
+ * @param _currencySymbol Currency symbol.
172
+ * @param _currencyAddress Currency address.
173
+ */
174
+ function updateProjectCurrencyInfo(
175
+ uint256 _projectId,
176
+ string memory _currencySymbol,
177
+ address _currencyAddress
178
+ ) external onlyArtist(_projectId) {
179
+ // require null address if symbol is "ETH"
180
+ require(
181
+ (keccak256(abi.encodePacked(_currencySymbol)) ==
182
+ keccak256(abi.encodePacked("ETH"))) ==
183
+ (_currencyAddress == address(0)),
184
+ "ETH is only null address"
185
+ );
186
+ projectIdToCurrencySymbol[_projectId] = _currencySymbol;
187
+ projectIdToCurrencyAddress[_projectId] = _currencyAddress;
188
+ emit ProjectCurrencyInfoUpdated(
189
+ _projectId,
190
+ _currencyAddress,
191
+ _currencySymbol
192
+ );
193
+ }
194
+
195
+ /**
196
+ * @notice Purchases a token from project `_projectId`.
197
+ * @param _projectId Project ID to mint a token on.
198
+ * @return tokenId Token ID of minted token
199
+ */
200
+ function purchase(
201
+ uint256 _projectId
202
+ ) external payable returns (uint256 tokenId) {
203
+ tokenId = purchaseTo(msg.sender, _projectId);
204
+ return tokenId;
205
+ }
206
+
207
+ /**
208
+ * @notice Purchases a token from project `_projectId` and sets
209
+ * the token's owner to `_to`.
210
+ * @param _to Address to be the new token's owner.
211
+ * @param _projectId Project ID to mint a token on.
212
+ * @return tokenId Token ID of minted token
213
+ */
214
+ function purchaseTo(
215
+ address _to,
216
+ uint256 _projectId
217
+ ) public payable nonReentrant returns (uint256 tokenId) {
218
+ // CHECKS
219
+ require(
220
+ !projectMaxHasBeenInvoked[_projectId],
221
+ "Maximum number of invocations reached"
222
+ );
223
+
224
+ // require artist to have configured price of token on this minter
225
+ require(
226
+ projectIdToPriceIsConfigured[_projectId],
227
+ "Price not configured"
228
+ );
229
+
230
+ // EFFECTS
231
+ tokenId = minterFilter.mint(_to, _projectId, msg.sender);
232
+ // what if projectMaxInvocations[_projectId] is 0 (default value)?
233
+ // that is intended, so that by default the minter allows infinite transactions,
234
+ // allowing the artblocks contract to stop minting
235
+ // uint256 tokenInvocation = tokenId % ONE_MILLION;
236
+ if (
237
+ projectMaxInvocations[_projectId] > 0 &&
238
+ tokenId % ONE_MILLION == projectMaxInvocations[_projectId] - 1
239
+ ) {
240
+ projectMaxHasBeenInvoked[_projectId] = true;
241
+ }
242
+
243
+ // INTERACTIONS
244
+ if (projectIdToCurrencyAddress[_projectId] != address(0)) {
245
+ require(
246
+ msg.value == 0,
247
+ "this project accepts a different currency and cannot accept ETH"
248
+ );
249
+ require(
250
+ IERC20(projectIdToCurrencyAddress[_projectId]).allowance(
251
+ msg.sender,
252
+ address(this)
253
+ ) >= projectIdToPricePerTokenInWei[_projectId],
254
+ "Insufficient Funds Approved for TX"
255
+ );
256
+ require(
257
+ IERC20(projectIdToCurrencyAddress[_projectId]).balanceOf(
258
+ msg.sender
259
+ ) >= projectIdToPricePerTokenInWei[_projectId],
260
+ "Insufficient balance."
261
+ );
262
+ _splitFundsERC20(_projectId);
263
+ } else {
264
+ require(
265
+ msg.value >= projectIdToPricePerTokenInWei[_projectId],
266
+ "Must send minimum value to mint!"
267
+ );
268
+ _splitFundsETH(_projectId);
269
+ }
270
+
271
+ return tokenId;
272
+ }
273
+
274
+ /**
275
+ * @dev splits ETH funds between sender (if refund), foundation,
276
+ * artist, and artist's additional payee for a token purchased on
277
+ * project `_projectId`.
278
+ * @dev utilizes transfer() to send ETH, so access lists may need to be
279
+ * populated when purchasing tokens.
280
+ */
281
+ function _splitFundsETH(uint256 _projectId) internal {
282
+ if (msg.value > 0) {
283
+ uint256 pricePerTokenInWei = projectIdToPricePerTokenInWei[
284
+ _projectId
285
+ ];
286
+ uint256 refund = msg.value - pricePerTokenInWei;
287
+ if (refund > 0) {
288
+ (bool success_, ) = msg.sender.call{value: refund}("");
289
+ require(success_, "Refund failed");
290
+ }
291
+ uint256 foundationAmount = (pricePerTokenInWei *
292
+ genArtCoreContract.artblocksPercentage()) / 100;
293
+ if (foundationAmount > 0) {
294
+ (bool success_, ) = genArtCoreContract.artblocksAddress().call{
295
+ value: foundationAmount
296
+ }("");
297
+ require(success_, "Foundation payment failed");
298
+ }
299
+ uint256 projectFunds = pricePerTokenInWei - foundationAmount;
300
+ uint256 additionalPayeeAmount;
301
+ if (
302
+ genArtCoreContract.projectIdToAdditionalPayeePercentage(
303
+ _projectId
304
+ ) > 0
305
+ ) {
306
+ additionalPayeeAmount =
307
+ (projectFunds *
308
+ genArtCoreContract.projectIdToAdditionalPayeePercentage(
309
+ _projectId
310
+ )) /
311
+ 100;
312
+ if (additionalPayeeAmount > 0) {
313
+ (bool success_, ) = genArtCoreContract
314
+ .projectIdToAdditionalPayee(_projectId)
315
+ .call{value: additionalPayeeAmount}("");
316
+ require(success_, "Additional payment failed");
317
+ }
318
+ }
319
+ uint256 creatorFunds = projectFunds - additionalPayeeAmount;
320
+ if (creatorFunds > 0) {
321
+ (bool success_, ) = genArtCoreContract
322
+ .projectIdToArtistAddress(_projectId)
323
+ .call{value: creatorFunds}("");
324
+ require(success_, "Artist payment failed");
325
+ }
326
+ }
327
+ }
328
+
329
+ /**
330
+ * @dev splits ERC-20 funds between foundation, artist, and artist's
331
+ * additional payee, for a token purchased on project `_projectId`.
332
+ */
333
+ function _splitFundsERC20(uint256 _projectId) internal {
334
+ uint256 pricePerTokenInWei = projectIdToPricePerTokenInWei[_projectId];
335
+ uint256 foundationAmount = (pricePerTokenInWei *
336
+ genArtCoreContract.artblocksPercentage()) / 100;
337
+ if (foundationAmount > 0) {
338
+ IERC20(projectIdToCurrencyAddress[_projectId]).transferFrom(
339
+ msg.sender,
340
+ genArtCoreContract.artblocksAddress(),
341
+ foundationAmount
342
+ );
343
+ }
344
+ uint256 projectFunds = pricePerTokenInWei - foundationAmount;
345
+ uint256 additionalPayeeAmount;
346
+ if (
347
+ genArtCoreContract.projectIdToAdditionalPayeePercentage(
348
+ _projectId
349
+ ) > 0
350
+ ) {
351
+ additionalPayeeAmount =
352
+ (projectFunds *
353
+ genArtCoreContract.projectIdToAdditionalPayeePercentage(
354
+ _projectId
355
+ )) /
356
+ 100;
357
+ if (additionalPayeeAmount > 0) {
358
+ IERC20(projectIdToCurrencyAddress[_projectId]).transferFrom(
359
+ msg.sender,
360
+ genArtCoreContract.projectIdToAdditionalPayee(_projectId),
361
+ additionalPayeeAmount
362
+ );
363
+ }
364
+ }
365
+ uint256 creatorFunds = projectFunds - additionalPayeeAmount;
366
+ if (creatorFunds > 0) {
367
+ IERC20(projectIdToCurrencyAddress[_projectId]).transferFrom(
368
+ msg.sender,
369
+ genArtCoreContract.projectIdToArtistAddress(_projectId),
370
+ creatorFunds
371
+ );
372
+ }
373
+ }
374
+
375
+ /**
376
+ * @notice Gets if price of token is configured, price of minting a
377
+ * token on project `_projectId`, and currency symbol and address to be
378
+ * used as payment. Supersedes any core contract price information.
379
+ * @param _projectId Project ID to get price information for.
380
+ * @return isConfigured true only if token price has been configured on
381
+ * this minter
382
+ * @return tokenPriceInWei current price of token on this minter - invalid
383
+ * if price has not yet been configured
384
+ * @return currencySymbol currency symbol for purchases of project on this
385
+ * minter. "ETH" reserved for ether.
386
+ * @return currencyAddress currency address for purchases of project on
387
+ * this minter. Null address reserved for ether.
388
+ */
389
+ function getPriceInfo(
390
+ uint256 _projectId
391
+ )
392
+ external
393
+ view
394
+ returns (
395
+ bool isConfigured,
396
+ uint256 tokenPriceInWei,
397
+ string memory currencySymbol,
398
+ address currencyAddress
399
+ )
400
+ {
401
+ isConfigured = projectIdToPriceIsConfigured[_projectId];
402
+ tokenPriceInWei = projectIdToPricePerTokenInWei[_projectId];
403
+ currencyAddress = projectIdToCurrencyAddress[_projectId];
404
+ if (currencyAddress == address(0)) {
405
+ // defaults to ETH
406
+ currencySymbol = "ETH";
407
+ } else {
408
+ currencySymbol = projectIdToCurrencySymbol[_projectId];
409
+ }
410
+ }
411
+ }
@@ -1,9 +1,9 @@
1
1
  // SPDX-License-Identifier: LGPL-3.0-only
2
2
  // Created By: Art Blocks Inc.
3
3
 
4
- import "../../../interfaces/0.8.x/IGenArt721CoreContractV3.sol";
5
- import "../../../interfaces/0.8.x/IMinterFilterV0.sol";
6
- import "../../../interfaces/0.8.x/IFilteredMinterV0.sol";
4
+ import "../../../../interfaces/0.8.x/IGenArt721CoreContractV3.sol";
5
+ import "../../../../interfaces/0.8.x/IMinterFilterV0.sol";
6
+ import "../../../../interfaces/0.8.x/IFilteredMinterV0.sol";
7
7
 
8
8
  import "@openzeppelin-4.5/contracts/token/ERC20/IERC20.sol";
9
9
  import "@openzeppelin-4.5/contracts/security/ReentrancyGuard.sol";
@@ -1,9 +1,9 @@
1
1
  // SPDX-License-Identifier: LGPL-3.0-only
2
2
  // Created By: Art Blocks Inc.
3
3
 
4
- import "../../../interfaces/0.8.x/IGenArt721CoreContractV3.sol";
5
- import "../../../interfaces/0.8.x/IMinterFilterV0.sol";
6
- import "../../../interfaces/0.8.x/IFilteredMinterV2.sol";
4
+ import "../../../../interfaces/0.8.x/IGenArt721CoreContractV3.sol";
5
+ import "../../../../interfaces/0.8.x/IMinterFilterV0.sol";
6
+ import "../../../../interfaces/0.8.x/IFilteredMinterV2.sol";
7
7
 
8
8
  import "@openzeppelin-4.5/contracts/token/ERC20/IERC20.sol";
9
9
  import "@openzeppelin-4.5/contracts/security/ReentrancyGuard.sol";
@@ -1,70 +1,21 @@
1
1
  // SPDX-License-Identifier: LGPL-3.0-only
2
2
  // Created By: Art Blocks Inc.
3
3
 
4
+ import "./IFilteredMinterDAExpSettlement_Mixin.sol";
4
5
  import "./IFilteredMinterV1.sol";
5
6
  import "./IFilteredMinterDAExpV0.sol";
6
7
 
7
8
  pragma solidity ^0.8.0;
8
9
 
9
10
  /**
10
- * @title This interface extends the IFilteredMinterV1 interface in order to
11
- * add support for Dutch Auction with Settlement minter updates.
12
- * @dev keys represent strings of finite length encoded in bytes32 to minimize
13
- * gas.
11
+ * @title This interface combines the set of interfaces that add support for
12
+ * a Dutch Auction with Settlement minter.
14
13
  * @author Art Blocks Inc.
15
14
  */
16
15
  interface IFilteredMinterDAExpSettlementV0 is
16
+ IFilteredMinterDAExpSettlement_Mixin,
17
17
  IFilteredMinterV1,
18
18
  IFilteredMinterDAExpV0
19
19
  {
20
- /// Auction details cleared for project `projectId`.
21
- /// At time of reset, the project has had `numPurchases` purchases on this
22
- /// minter, with a most recent purchase price of `latestPurchasePrice`. If
23
- /// the number of purchases is 0, the latest purchase price will have a
24
- /// dummy value of 0.
25
- event ResetAuctionDetails(
26
- uint256 indexed projectId,
27
- uint256 numPurchases,
28
- uint256 latestPurchasePrice
29
- );
30
20
 
31
- /// sellout price updated for project `projectId`.
32
- /// @dev does not use generic event because likely will trigger additional
33
- /// actions in indexing layer
34
- event SelloutPriceUpdated(
35
- uint256 indexed _projectId,
36
- uint256 _selloutPrice
37
- );
38
-
39
- /// artist and admin have withdrawn revenues from settleable purchases for
40
- /// project `projectId`.
41
- /// @dev does not use generic event because likely will trigger additional
42
- /// actions in indexing layer
43
- event ArtistAndAdminRevenuesWithdrawn(uint256 indexed _projectId);
44
-
45
- /// receipt has an updated state
46
- event ReceiptUpdated(
47
- address indexed _purchaser,
48
- uint256 indexed _projectId,
49
- uint256 _numPurchased,
50
- uint256 _netPosted
51
- );
52
-
53
- /// returns latest purchase price for project `_projectId`, or 0 if no
54
- /// purchases have been made.
55
- function getProjectLatestPurchasePrice(
56
- uint256 _projectId
57
- ) external view returns (uint256 latestPurchasePrice);
58
-
59
- /// returns the number of settleable invocations for project `_projectId`.
60
- function getNumSettleableInvocations(
61
- uint256 _projectId
62
- ) external view returns (uint256 numSettleableInvocations);
63
-
64
- /// Returns the current excess settlement funds on project `_projectId`
65
- /// for address `_walletAddress`.
66
- function getProjectExcessSettlementFunds(
67
- uint256 _projectId,
68
- address _walletAddress
69
- ) external view returns (uint256 excessSettlementFundsInWei);
70
21
  }
@@ -0,0 +1,21 @@
1
+ // SPDX-License-Identifier: LGPL-3.0-only
2
+ // Created By: Art Blocks Inc.
3
+
4
+ import "./IFilteredMinterDAExpSettlement_Mixin.sol";
5
+ import "./IFilteredMinterV2.sol";
6
+ import "./IFilteredMinterDAExpV0.sol";
7
+
8
+ pragma solidity ^0.8.0;
9
+
10
+ /**
11
+ * @title This interface combines the set of interfaces that add support for
12
+ * a Dutch Auction with Settlement minter.
13
+ * @author Art Blocks Inc.
14
+ */
15
+ interface IFilteredMinterDAExpSettlementV1 is
16
+ IFilteredMinterDAExpSettlement_Mixin,
17
+ IFilteredMinterV2,
18
+ IFilteredMinterDAExpV0
19
+ {
20
+
21
+ }
@@ -0,0 +1,62 @@
1
+ // SPDX-License-Identifier: LGPL-3.0-only
2
+ // Created By: Art Blocks Inc.
3
+
4
+ pragma solidity ^0.8.0;
5
+
6
+ /**
7
+ * @title This interface is a mixin for IFilteredMinterExpSettlementV<version>
8
+ * interfaces to use when defining settlement minter interfaces.
9
+ * @author Art Blocks Inc.
10
+ */
11
+ interface IFilteredMinterDAExpSettlement_Mixin {
12
+ /// Auction details cleared for project `projectId`.
13
+ /// At time of reset, the project has had `numPurchases` purchases on this
14
+ /// minter, with a most recent purchase price of `latestPurchasePrice`. If
15
+ /// the number of purchases is 0, the latest purchase price will have a
16
+ /// dummy value of 0.
17
+ event ResetAuctionDetails(
18
+ uint256 indexed projectId,
19
+ uint256 numPurchases,
20
+ uint256 latestPurchasePrice
21
+ );
22
+
23
+ /// sellout price updated for project `projectId`.
24
+ /// @dev does not use generic event because likely will trigger additional
25
+ /// actions in indexing layer
26
+ event SelloutPriceUpdated(
27
+ uint256 indexed _projectId,
28
+ uint256 _selloutPrice
29
+ );
30
+
31
+ /// artist and admin have withdrawn revenues from settleable purchases for
32
+ /// project `projectId`.
33
+ /// @dev does not use generic event because likely will trigger additional
34
+ /// actions in indexing layer
35
+ event ArtistAndAdminRevenuesWithdrawn(uint256 indexed _projectId);
36
+
37
+ /// receipt has an updated state
38
+ event ReceiptUpdated(
39
+ address indexed _purchaser,
40
+ uint256 indexed _projectId,
41
+ uint256 _numPurchased,
42
+ uint256 _netPosted
43
+ );
44
+
45
+ /// returns latest purchase price for project `_projectId`, or 0 if no
46
+ /// purchases have been made.
47
+ function getProjectLatestPurchasePrice(
48
+ uint256 _projectId
49
+ ) external view returns (uint256 latestPurchasePrice);
50
+
51
+ /// returns the number of settleable invocations for project `_projectId`.
52
+ function getNumSettleableInvocations(
53
+ uint256 _projectId
54
+ ) external view returns (uint256 numSettleableInvocations);
55
+
56
+ /// Returns the current excess settlement funds on project `_projectId`
57
+ /// for address `_walletAddress`.
58
+ function getProjectExcessSettlementFunds(
59
+ uint256 _projectId,
60
+ address _walletAddress
61
+ ) external view returns (uint256 excessSettlementFundsInWei);
62
+ }
@@ -0,0 +1,20 @@
1
+ // SPDX-License-Identifier: LGPL-3.0-only
2
+ // Created By: Art Blocks Inc.
3
+
4
+ import "./IFilteredMinterV2.sol";
5
+
6
+ pragma solidity ^0.8.0;
7
+
8
+ /**
9
+ * @title This interface defines any events or functions required for a minter
10
+ * to conform to the MinterBase contract.
11
+ * @dev The MinterBase contract was not implemented from the beginning of the
12
+ * MinterSuite contract suite, therefore early versions of some minters may not
13
+ * conform to this interface.
14
+ * @author Art Blocks Inc.
15
+ */
16
+ interface IMinterBaseV0 {
17
+ // Function that returns if a minter is configured to integrate with a V3 flagship or V3 engine contract.
18
+ // Returns true only if the minter is configured to integrate with an engine contract.
19
+ function isEngine() external returns (bool isEngine);
20
+ }
@@ -4,6 +4,12 @@
4
4
  pragma solidity ^0.8.0;
5
5
 
6
6
  interface IMinterFilterV0 {
7
+ /**
8
+ * @notice Emitted when contract is deployed to notify indexing services
9
+ * of the new contract deployment.
10
+ */
11
+ event Deployed();
12
+
7
13
  /**
8
14
  * @notice Approved minter `_minterAddress`.
9
15
  */