@artblocks/contracts 0.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 (196) hide show
  1. package/.env.example +10 -0
  2. package/LICENSE +165 -0
  3. package/README.md +286 -0
  4. package/artifacts/contracts/AdminACLV0.sol/AdminACLV0.json +164 -0
  5. package/artifacts/contracts/AdminACLV1.sol/AdminACLV1.json +248 -0
  6. package/artifacts/contracts/BasicRandomizer.sol/BasicRandomizer.json +24 -0
  7. package/artifacts/contracts/BasicRandomizerV2.sol/BasicRandomizerV2.json +102 -0
  8. package/artifacts/contracts/DependencyRegistryV0.sol/DependencyRegistryV0.json +1020 -0
  9. package/artifacts/contracts/GenArt721CoreV3.sol/GenArt721CoreV3.json +1928 -0
  10. package/artifacts/contracts/GenArt721CoreV3_Engine.sol/GenArt721CoreV3_Engine.json +1942 -0
  11. package/artifacts/contracts/engine/GenArt721CoreV2_ENGINE_FLEX.sol/GenArt721CoreV2_ENGINE_FLEX.json +1708 -0
  12. package/artifacts/contracts/engine/GenArt721CoreV2_PBAB.sol/GenArt721CoreV2_PBAB.json +1410 -0
  13. package/artifacts/contracts/engine/GenArt721CoreV2_PRTNR.sol/GenArt721CoreV2_PRTNR.json +1436 -0
  14. package/artifacts/contracts/engine/GenArt721MinterBurner_PBAB.sol/GenArt721MinterBurner_PBAB.json +437 -0
  15. package/artifacts/contracts/engine/GenArt721MinterDAExp_PBAB.sol/GenArt721MinterDAExp_PBAB.json +508 -0
  16. package/artifacts/contracts/engine/GenArt721Minter_PBAB.sol/GenArt721Minter_PBAB.json +381 -0
  17. package/artifacts/contracts/engine-registry/EngineRegistryV0.sol/EngineRegistryV0.json +109 -0
  18. package/artifacts/contracts/engine-registry/future/EngineRegistryV1.sol/EngineRegistryV1.json +109 -0
  19. package/artifacts/contracts/explorations/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +1902 -0
  20. package/artifacts/contracts/interfaces/0.5.x/IBonusContract.sol/IBonusContract.json +47 -0
  21. package/artifacts/contracts/interfaces/0.5.x/IGenArt721CoreContractV1.sol/IGenArt721CoreContractV1.json +413 -0
  22. package/artifacts/contracts/interfaces/0.5.x/IGenArt721CoreV2_PBAB.sol/IGenArt721CoreV2_PBAB.json +392 -0
  23. package/artifacts/contracts/interfaces/0.5.x/IRandomizer.sol/IRandomizer.json +26 -0
  24. package/artifacts/contracts/interfaces/0.8.x/IAdminACLV0.sol/IAdminACLV0.json +122 -0
  25. package/artifacts/contracts/interfaces/0.8.x/IArtblocksRoyaltyOverride.sol/IArtblocksRoyaltyOverride.json +59 -0
  26. package/artifacts/contracts/interfaces/0.8.x/IBonusContract.sol/IBonusContract.json +43 -0
  27. package/artifacts/contracts/interfaces/0.8.x/IDelegationRegistry.sol/IDelegationRegistry.json +510 -0
  28. package/artifacts/contracts/interfaces/0.8.x/IDependencyRegistryCompatibleV0.sol/IDependencyRegistryCompatibleV0.json +53 -0
  29. package/artifacts/contracts/interfaces/0.8.x/IDependencyRegistryV0.sol/IDependencyRegistryV0.json +350 -0
  30. package/artifacts/contracts/interfaces/0.8.x/IEngineRegistryV0.sol/IEngineRegistryV0.json +85 -0
  31. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDAExpSettlementV0.sol/IFilteredMinterDAExpSettlementV0.json +730 -0
  32. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDAExpV0.sol/IFilteredMinterDAExpV0.json +311 -0
  33. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDAExpV1.sol/IFilteredMinterDAExpV1.json +617 -0
  34. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDALinV0.sol/IFilteredMinterDALinV0.json +292 -0
  35. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDALinV1.sol/IFilteredMinterDALinV1.json +598 -0
  36. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterHolderV0.sol/IFilteredMinterHolderV0.json +355 -0
  37. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterHolderV1.sol/IFilteredMinterHolderV1.json +368 -0
  38. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterHolderV2.sol/IFilteredMinterHolderV2.json +674 -0
  39. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterMerkleV0.sol/IFilteredMinterMerkleV0.json +551 -0
  40. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterMerkleV1.sol/IFilteredMinterMerkleV1.json +564 -0
  41. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterMerkleV2.sol/IFilteredMinterMerkleV2.json +601 -0
  42. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterV0.sol/IFilteredMinterV0.json +216 -0
  43. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterV1.sol/IFilteredMinterV1.json +485 -0
  44. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterV2.sol/IFilteredMinterV2.json +522 -0
  45. package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreContractV1.sol/IGenArt721CoreContractV1.json +299 -0
  46. package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreContractV3.sol/IGenArt721CoreContractV3.json +609 -0
  47. package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Base.sol/IGenArt721CoreContractV3_Base.json +448 -0
  48. package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Engine.sol/IGenArt721CoreContractV3_Engine.json +649 -0
  49. package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreV2_PBAB.sol/IGenArt721CoreV2_PBAB.json +362 -0
  50. package/artifacts/contracts/interfaces/0.8.x/IManifold.sol/IManifold.json +35 -0
  51. package/artifacts/contracts/interfaces/0.8.x/IMinterFilterV0.sol/IMinterFilterV0.json +192 -0
  52. package/artifacts/contracts/interfaces/0.8.x/IRandomizer.sol/IRandomizer.json +24 -0
  53. package/artifacts/contracts/interfaces/0.8.x/IRandomizerV2.sol/IRandomizerV2.json +37 -0
  54. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/Address.json +10 -0
  55. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/Counters.json +10 -0
  56. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/CustomERC721Metadata.json +425 -0
  57. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/ERC165.json +38 -0
  58. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/ERC721.json +322 -0
  59. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/ERC721Enumerable.json +384 -0
  60. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/GenArt721CoreV1.json +1773 -0
  61. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/IERC165.json +32 -0
  62. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/IERC721.json +316 -0
  63. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/IERC721Enumerable.json +378 -0
  64. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/IERC721Receiver.json +47 -0
  65. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/SafeMath.json +10 -0
  66. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/Strings.json +10 -0
  67. package/artifacts/contracts/legacy/GenArt721LegacyMinter.sol/GenArt721LegacyMinter.json +338 -0
  68. package/artifacts/contracts/libs/0.5.x/CustomERC721Metadata.sol/CustomERC721Metadata.json +425 -0
  69. package/artifacts/contracts/libs/0.5.x/IERC20.sol/IERC20.json +206 -0
  70. package/artifacts/contracts/libs/0.5.x/SafeMath.sol/SafeMath.json +10 -0
  71. package/artifacts/contracts/libs/0.5.x/Strings.sol/Strings.json +10 -0
  72. package/artifacts/contracts/libs/0.8.x/BytecodeStorage.sol/BytecodeStorage.json +10 -0
  73. package/artifacts/contracts/libs/0.8.x/Bytes32Strings.sol/Bytes32Strings.json +10 -0
  74. package/artifacts/contracts/libs/0.8.x/ERC721_PackedHashSeed.sol/ERC721_PackedHashSeed.json +357 -0
  75. package/artifacts/contracts/libs/integration-refs/delegation-registry/DelegationRegistry.sol/DelegationRegistry.json +529 -0
  76. package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeMock.sol/GnosisSafeMock.json +1037 -0
  77. package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeProxyFactoryMock.sol/GnosisSafeProxyFactoryMock.json +172 -0
  78. package/artifacts/contracts/libs/integration-refs/gnosis-safe/MultiSendMock.sol/MultiSendMock.json +24 -0
  79. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV0.sol/MinterFilterV0.json +342 -0
  80. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV1.sol/MinterFilterV1.json +322 -0
  81. package/artifacts/contracts/minter-suite/Minters/MinterDAExp/MinterDAExpV2.sol/MinterDAExpV2.json +550 -0
  82. package/artifacts/contracts/minter-suite/Minters/MinterDAExp/MinterDAExpV3.sol/MinterDAExpV3.json +856 -0
  83. package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol/MinterDAExpSettlementV0.json +1053 -0
  84. package/artifacts/contracts/minter-suite/Minters/MinterDALin/MinterDALinV2.sol/MinterDALinV2.json +526 -0
  85. package/artifacts/contracts/minter-suite/Minters/MinterDALin/MinterDALinV3.sol/MinterDALinV3.json +832 -0
  86. package/artifacts/contracts/minter-suite/Minters/MinterHolder/MinterHolderV2.sol/MinterHolderV2.json +794 -0
  87. package/artifacts/contracts/minter-suite/Minters/MinterHolder/MinterHolderV3.sol/MinterHolderV3.json +1100 -0
  88. package/artifacts/contracts/minter-suite/Minters/MinterMerkle/MinterMerkleV3.sol/MinterMerkleV3.json +1002 -0
  89. package/artifacts/contracts/minter-suite/Minters/MinterMerkle/MinterMerkleV4.sol/MinterMerkleV4.json +1039 -0
  90. package/artifacts/contracts/minter-suite/Minters/MinterSetPrice/MinterSetPriceV2.sol/MinterSetPriceV2.json +365 -0
  91. package/artifacts/contracts/minter-suite/Minters/MinterSetPrice/MinterSetPriceV3.sol/MinterSetPriceV3.json +671 -0
  92. package/artifacts/contracts/minter-suite/Minters/MinterSetPrice/deprecated/MinterSetPriceV1.sol/MinterSetPriceV1.json +288 -0
  93. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol/MinterSetPriceERC20V2.json +436 -0
  94. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol/MinterSetPriceERC20V3.json +742 -0
  95. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20/deprecated/MinterSetPriceERC20V0.sol/MinterSetPriceERC20V0.json +461 -0
  96. package/artifacts/contracts/mock/BytecodeTextCR_DMock.sol/BytecodeTextCR_DMock.json +194 -0
  97. package/artifacts/contracts/mock/DeadReceiverMock.sol/DeadReceiverMock.json +15 -0
  98. package/artifacts/contracts/mock/ERC20Mock.sol/ERC20Mock.json +292 -0
  99. package/artifacts/contracts/mock/MockAdminACLV0.sol/MockAdminACLV0Events.json +165 -0
  100. package/artifacts/contracts/mock/RandomizerV2_NoAssignMock.sol/RandomizerV2_NoAssignMock.json +128 -0
  101. package/artifacts/contracts/mock/ReentrancyHolderMock.sol/ReentrancyHolderMock.json +118 -0
  102. package/artifacts/contracts/mock/ReentrancyMerkleMock.sol/ReentrancyMerkleMock.json +87 -0
  103. package/artifacts/contracts/mock/ReentrancyMock.sol/ReentrancyMock.json +82 -0
  104. package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverride.sol/GenArt721RoyaltyOverride.json +208 -0
  105. package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverride_PBAB.sol/GenArt721RoyaltyOverride_PBAB.json +301 -0
  106. package/contracts/AdminACLV0.sol +103 -0
  107. package/contracts/AdminACLV1.sol +193 -0
  108. package/contracts/BasicRandomizer.sol +23 -0
  109. package/contracts/BasicRandomizerV2.sol +36 -0
  110. package/contracts/DependencyRegistryV0.sol +893 -0
  111. package/contracts/GenArt721CoreV3.sol +2001 -0
  112. package/contracts/GenArt721CoreV3_Engine.sol +2061 -0
  113. package/contracts/engine/GenArt721CoreV2_ENGINE_FLEX.sol +887 -0
  114. package/contracts/engine/GenArt721CoreV2_PBAB.sol +695 -0
  115. package/contracts/engine/GenArt721CoreV2_PRTNR.sol +749 -0
  116. package/contracts/engine/GenArt721MinterBurner_PBAB.sol +467 -0
  117. package/contracts/engine/GenArt721MinterDAExp_PBAB.sol +614 -0
  118. package/contracts/engine/GenArt721Minter_PBAB.sol +420 -0
  119. package/contracts/engine-registry/EngineRegistryV0.sol +72 -0
  120. package/contracts/engine-registry/future/EngineRegistryV1.sol +86 -0
  121. package/contracts/explorations/GenArt721CoreV3_Explorations.sol +1989 -0
  122. package/contracts/interfaces/0.5.x/IBonusContract.sol +10 -0
  123. package/contracts/interfaces/0.5.x/IGenArt721CoreContractV1.sol +91 -0
  124. package/contracts/interfaces/0.5.x/IGenArt721CoreV2_PBAB.sol +92 -0
  125. package/contracts/interfaces/0.5.x/IRandomizer.sol +8 -0
  126. package/contracts/interfaces/0.8.x/IAdminACLV0.sol +51 -0
  127. package/contracts/interfaces/0.8.x/IArtblocksRoyaltyOverride.sol +34 -0
  128. package/contracts/interfaces/0.8.x/IBonusContract.sol +10 -0
  129. package/contracts/interfaces/0.8.x/IDelegationRegistry.sol +221 -0
  130. package/contracts/interfaces/0.8.x/IDependencyRegistryCompatibleV0.sol +31 -0
  131. package/contracts/interfaces/0.8.x/IDependencyRegistryV0.sol +95 -0
  132. package/contracts/interfaces/0.8.x/IEngineRegistryV0.sol +38 -0
  133. package/contracts/interfaces/0.8.x/IFilteredMinterDAExpSettlementV0.sol +70 -0
  134. package/contracts/interfaces/0.8.x/IFilteredMinterDAExpV0.sol +35 -0
  135. package/contracts/interfaces/0.8.x/IFilteredMinterDAExpV1.sol +16 -0
  136. package/contracts/interfaces/0.8.x/IFilteredMinterDALinV0.sol +32 -0
  137. package/contracts/interfaces/0.8.x/IFilteredMinterDALinV1.sol +16 -0
  138. package/contracts/interfaces/0.8.x/IFilteredMinterHolderV0.sol +68 -0
  139. package/contracts/interfaces/0.8.x/IFilteredMinterHolderV1.sol +19 -0
  140. package/contracts/interfaces/0.8.x/IFilteredMinterHolderV2.sol +19 -0
  141. package/contracts/interfaces/0.8.x/IFilteredMinterMerkleV0.sol +37 -0
  142. package/contracts/interfaces/0.8.x/IFilteredMinterMerkleV1.sol +19 -0
  143. package/contracts/interfaces/0.8.x/IFilteredMinterMerkleV2.sol +19 -0
  144. package/contracts/interfaces/0.8.x/IFilteredMinterV0.sol +74 -0
  145. package/contracts/interfaces/0.8.x/IFilteredMinterV1.sol +127 -0
  146. package/contracts/interfaces/0.8.x/IFilteredMinterV2.sol +30 -0
  147. package/contracts/interfaces/0.8.x/IGenArt721CoreContractV1.sol +73 -0
  148. package/contracts/interfaces/0.8.x/IGenArt721CoreContractV3.sol +79 -0
  149. package/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Base.sol +127 -0
  150. package/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Engine.sol +80 -0
  151. package/contracts/interfaces/0.8.x/IGenArt721CoreV2_PBAB.sol +91 -0
  152. package/contracts/interfaces/0.8.x/IManifold.sol +24 -0
  153. package/contracts/interfaces/0.8.x/IMinterFilterV0.sol +47 -0
  154. package/contracts/interfaces/0.8.x/IRandomizer.sol +8 -0
  155. package/contracts/interfaces/0.8.x/IRandomizerV2.sol +15 -0
  156. package/contracts/legacy/GenArt721CoreV1.sol +1593 -0
  157. package/contracts/legacy/GenArt721LegacyMinter.sol +275 -0
  158. package/contracts/libs/0.5.x/CustomERC721Metadata.sol +52 -0
  159. package/contracts/libs/0.5.x/IERC20.sol +96 -0
  160. package/contracts/libs/0.5.x/SafeMath.sol +98 -0
  161. package/contracts/libs/0.5.x/Strings.sol +92 -0
  162. package/contracts/libs/0.8.x/BytecodeStorage.sol +314 -0
  163. package/contracts/libs/0.8.x/Bytes32Strings.sol +66 -0
  164. package/contracts/libs/0.8.x/ERC721_PackedHashSeed.sol +514 -0
  165. package/contracts/libs/integration-refs/delegation-registry/DelegationRegistry.sol +663 -0
  166. package/contracts/libs/integration-refs/gnosis-safe/GnosisSafeMock.sol +6 -0
  167. package/contracts/libs/integration-refs/gnosis-safe/GnosisSafeProxyFactoryMock.sol +6 -0
  168. package/contracts/libs/integration-refs/gnosis-safe/MultiSendMock.sol +6 -0
  169. package/contracts/minter-suite/MinterFilter/MinterFilterV0.sol +291 -0
  170. package/contracts/minter-suite/MinterFilter/MinterFilterV1.sol +320 -0
  171. package/contracts/minter-suite/Minters/MinterDAExp/MinterDAExpV2.sol +571 -0
  172. package/contracts/minter-suite/Minters/MinterDAExp/MinterDAExpV3.sol +622 -0
  173. package/contracts/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol +1066 -0
  174. package/contracts/minter-suite/Minters/MinterDALin/MinterDALinV2.sol +527 -0
  175. package/contracts/minter-suite/Minters/MinterDALin/MinterDALinV3.sol +576 -0
  176. package/contracts/minter-suite/Minters/MinterHolder/MinterHolderV2.sol +749 -0
  177. package/contracts/minter-suite/Minters/MinterHolder/MinterHolderV3.sol +798 -0
  178. package/contracts/minter-suite/Minters/MinterMerkle/MinterMerkleV3.sol +682 -0
  179. package/contracts/minter-suite/Minters/MinterMerkle/MinterMerkleV4.sol +733 -0
  180. package/contracts/minter-suite/Minters/MinterSetPrice/MinterSetPriceV2.sol +350 -0
  181. package/contracts/minter-suite/Minters/MinterSetPrice/MinterSetPriceV3.sol +401 -0
  182. package/contracts/minter-suite/Minters/MinterSetPrice/deprecated/MinterSetPriceV1.sol +274 -0
  183. package/contracts/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol +491 -0
  184. package/contracts/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol +542 -0
  185. package/contracts/minter-suite/Minters/MinterSetPriceERC20/deprecated/MinterSetPriceERC20V0.sol +470 -0
  186. package/contracts/mock/BytecodeTextCR_DMock.sol +184 -0
  187. package/contracts/mock/DeadReceiverMock.sol +13 -0
  188. package/contracts/mock/ERC20Mock.sol +11 -0
  189. package/contracts/mock/MockAdminACLV0.sol +65 -0
  190. package/contracts/mock/RandomizerV2_NoAssignMock.sol +43 -0
  191. package/contracts/mock/ReentrancyHolderMock.sol +50 -0
  192. package/contracts/mock/ReentrancyMerkleMock.sol +64 -0
  193. package/contracts/mock/ReentrancyMock.sol +44 -0
  194. package/contracts/royalty-registry/GenArt721RoyaltyOverride.sol +168 -0
  195. package/contracts/royalty-registry/GenArt721RoyaltyOverride_PBAB.sol +221 -0
  196. package/package.json +83 -0
@@ -0,0 +1,401 @@
1
+ // SPDX-License-Identifier: LGPL-3.0-only
2
+ // Created By: Art Blocks Inc.
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";
7
+
8
+ import "@openzeppelin-4.5/contracts/security/ReentrancyGuard.sol";
9
+
10
+ pragma solidity 0.8.17;
11
+
12
+ /**
13
+ * @title Filtered Minter contract that allows tokens to be minted with ETH.
14
+ * This is designed to be used with IGenArt721CoreContractV3 contracts.
15
+ * @author Art Blocks Inc.
16
+ * @notice Privileged Roles and Ownership:
17
+ * This contract is designed to be managed, with limited powers.
18
+ * Privileged roles and abilities are controlled by the project's artist, which
19
+ * can be modified by the core contract's Admin ACL contract. Both of these
20
+ * roles hold extensive power and can modify minter details.
21
+ * Care must be taken to ensure that the admin ACL contract and artist
22
+ * addresses are secure behind a multi-sig or other access control mechanism.
23
+ * ----------------------------------------------------------------------------
24
+ * The following functions are restricted to a project's artist:
25
+ * - updatePricePerTokenInWei
26
+ * - setProjectMaxInvocations
27
+ * - manuallyLimitProjectMaxInvocations
28
+ * ----------------------------------------------------------------------------
29
+ * Additional admin and artist privileged roles may be described on other
30
+ * contracts that this minter integrates with.
31
+ */
32
+ contract MinterSetPriceV3 is ReentrancyGuard, IFilteredMinterV2 {
33
+ /// Core contract address this minter interacts with
34
+ address public immutable genArt721CoreAddress;
35
+
36
+ /// This contract handles cores with interface IV3
37
+ IGenArt721CoreContractV3 private immutable genArtCoreContract;
38
+
39
+ /// Minter filter address this minter interacts with
40
+ address public immutable minterFilterAddress;
41
+
42
+ /// Minter filter this minter may interact with.
43
+ IMinterFilterV0 private immutable minterFilter;
44
+
45
+ /// minterType for this minter
46
+ string public constant minterType = "MinterSetPriceV3";
47
+
48
+ uint256 constant ONE_MILLION = 1_000_000;
49
+
50
+ struct ProjectConfig {
51
+ bool maxHasBeenInvoked;
52
+ bool priceIsConfigured;
53
+ uint24 maxInvocations;
54
+ uint256 pricePerTokenInWei;
55
+ }
56
+
57
+ mapping(uint256 => ProjectConfig) public projectConfig;
58
+
59
+ modifier onlyArtist(uint256 _projectId) {
60
+ require(
61
+ msg.sender ==
62
+ genArtCoreContract.projectIdToArtistAddress(_projectId),
63
+ "Only Artist"
64
+ );
65
+ _;
66
+ }
67
+
68
+ /**
69
+ * @notice Initializes contract to be a Filtered Minter for
70
+ * `_minterFilter`, integrated with Art Blocks core contract
71
+ * at address `_genArt721Address`.
72
+ * @param _genArt721Address Art Blocks core contract address for
73
+ * which this contract will be a minter.
74
+ * @param _minterFilter Minter filter for which this will be a
75
+ * filtered minter.
76
+ */
77
+ constructor(
78
+ address _genArt721Address,
79
+ address _minterFilter
80
+ ) ReentrancyGuard() {
81
+ genArt721CoreAddress = _genArt721Address;
82
+ genArtCoreContract = IGenArt721CoreContractV3(_genArt721Address);
83
+ minterFilterAddress = _minterFilter;
84
+ minterFilter = IMinterFilterV0(_minterFilter);
85
+ require(
86
+ minterFilter.genArt721CoreAddress() == _genArt721Address,
87
+ "Illegal contract pairing"
88
+ );
89
+ }
90
+
91
+ /**
92
+ * @notice Syncs local maximum invocations of project `_projectId` based on
93
+ * the value currently defined in the core contract.
94
+ * @param _projectId Project ID to set the maximum invocations for.
95
+ * @dev this enables gas reduction after maxInvocations have been reached -
96
+ * core contracts shall still enforce a maxInvocation check during mint.
97
+ */
98
+ function setProjectMaxInvocations(
99
+ uint256 _projectId
100
+ ) external onlyArtist(_projectId) {
101
+ uint256 maxInvocations;
102
+ uint256 invocations;
103
+ (invocations, maxInvocations, , , , ) = genArtCoreContract
104
+ .projectStateData(_projectId);
105
+ // update storage with results
106
+ projectConfig[_projectId].maxInvocations = uint24(maxInvocations);
107
+
108
+ // We need to ensure maxHasBeenInvoked is correctly set after manually syncing the
109
+ // local maxInvocations value with the core contract's maxInvocations value.
110
+ // This synced value of maxInvocations from the core contract will always be greater
111
+ // than or equal to the previous value of maxInvocations stored locally.
112
+ projectConfig[_projectId].maxHasBeenInvoked =
113
+ invocations == maxInvocations;
114
+
115
+ emit ProjectMaxInvocationsLimitUpdated(_projectId, maxInvocations);
116
+ }
117
+
118
+ /**
119
+ * @notice Manually sets the local maximum invocations of project `_projectId`
120
+ * with the provided `_maxInvocations`, checking that `_maxInvocations` is less
121
+ * than or equal to the value of project `_project_id`'s maximum invocations that is
122
+ * set on the core contract.
123
+ * @dev Note that a `_maxInvocations` of 0 can only be set if the current `invocations`
124
+ * value is also 0 and this would also set `maxHasBeenInvoked` to true, correctly short-circuiting
125
+ * this minter's purchase function, avoiding extra gas costs from the core contract's maxInvocations check.
126
+ * @param _projectId Project ID to set the maximum invocations for.
127
+ * @param _maxInvocations Maximum invocations to set for the project.
128
+ */
129
+ function manuallyLimitProjectMaxInvocations(
130
+ uint256 _projectId,
131
+ uint256 _maxInvocations
132
+ ) external onlyArtist(_projectId) {
133
+ // CHECKS
134
+ // ensure that the manually set maxInvocations is not greater than what is set on the core contract
135
+ uint256 maxInvocations;
136
+ uint256 invocations;
137
+ (invocations, maxInvocations, , , , ) = genArtCoreContract
138
+ .projectStateData(_projectId);
139
+ require(
140
+ _maxInvocations <= maxInvocations,
141
+ "Cannot increase project max invocations above core contract set project max invocations"
142
+ );
143
+ require(
144
+ _maxInvocations >= invocations,
145
+ "Cannot set project max invocations to less than current invocations"
146
+ );
147
+
148
+ // EFFECTS
149
+ // update storage with results
150
+ projectConfig[_projectId].maxInvocations = uint24(_maxInvocations);
151
+ // We need to ensure maxHasBeenInvoked is correctly set after manually setting the
152
+ // local maxInvocations value.
153
+ projectConfig[_projectId].maxHasBeenInvoked =
154
+ invocations == _maxInvocations;
155
+
156
+ emit ProjectMaxInvocationsLimitUpdated(_projectId, _maxInvocations);
157
+ }
158
+
159
+ /**
160
+ * @notice Warning: Disabling purchaseTo is not supported on this minter.
161
+ * This method exists purely for interface-conformance purposes.
162
+ */
163
+ function togglePurchaseToDisabled(
164
+ uint256 _projectId
165
+ ) external view onlyArtist(_projectId) {
166
+ revert("Action not supported");
167
+ }
168
+
169
+ /**
170
+ * @notice projectId => has project reached its maximum number of
171
+ * invocations? Note that this returns a local cache of the core contract's
172
+ * state, and may be out of sync with the core contract. This is
173
+ * intentional, as it only enables gas optimization of mints after a
174
+ * project's maximum invocations has been reached. A false negative will
175
+ * only result in a gas cost increase, since the core contract will still
176
+ * enforce a maxInvocation check during minting. A false positive is not
177
+ * possible because the V3 core contract only allows maximum invocations
178
+ * to be reduced, not increased. Based on this rationale, we intentionally
179
+ * do not do input validation in this method as to whether or not the input
180
+ * `_projectId` is an existing project ID.
181
+ */
182
+ function projectMaxHasBeenInvoked(
183
+ uint256 _projectId
184
+ ) external view returns (bool) {
185
+ return projectConfig[_projectId].maxHasBeenInvoked;
186
+ }
187
+
188
+ /**
189
+ * @notice projectId => project's maximum number of invocations.
190
+ * Optionally synced with core contract value, for gas optimization.
191
+ * Note that this returns a local cache of the core contract's
192
+ * state, and may be out of sync with the core contract. This is
193
+ * intentional, as it only enables gas optimization of mints after a
194
+ * project's maximum invocations has been reached.
195
+ * @dev A number greater than the core contract's project max invocations
196
+ * will only result in a gas cost increase, since the core contract will
197
+ * still enforce a maxInvocation check during minting. A number less than
198
+ * the core contract's project max invocations is only possible when the
199
+ * project's max invocations have not been synced on this minter, since the
200
+ * V3 core contract only allows maximum invocations to be reduced, not
201
+ * increased. When this happens, the minter will enable minting, allowing
202
+ * the core contract to enforce the max invocations check. Based on this
203
+ * rationale, we intentionally do not do input validation in this method as
204
+ * to whether or not the input `_projectId` is an existing project ID.
205
+ */
206
+ function projectMaxInvocations(
207
+ uint256 _projectId
208
+ ) external view returns (uint256) {
209
+ return uint256(projectConfig[_projectId].maxInvocations);
210
+ }
211
+
212
+ /**
213
+ * @notice Updates this minter's price per token of project `_projectId`
214
+ * to be '_pricePerTokenInWei`, in Wei.
215
+ * This price supersedes any legacy core contract price per token value.
216
+ * @dev Note that it is intentionally supported here that the configured
217
+ * price may be explicitly set to `0`.
218
+ */
219
+ function updatePricePerTokenInWei(
220
+ uint256 _projectId,
221
+ uint256 _pricePerTokenInWei
222
+ ) external onlyArtist(_projectId) {
223
+ ProjectConfig storage _projectConfig = projectConfig[_projectId];
224
+ _projectConfig.pricePerTokenInWei = _pricePerTokenInWei;
225
+ _projectConfig.priceIsConfigured = true;
226
+ emit PricePerTokenInWeiUpdated(_projectId, _pricePerTokenInWei);
227
+ }
228
+
229
+ /**
230
+ * @notice Purchases a token from project `_projectId`.
231
+ * @param _projectId Project ID to mint a token on.
232
+ * @return tokenId Token ID of minted token
233
+ */
234
+ function purchase(
235
+ uint256 _projectId
236
+ ) external payable returns (uint256 tokenId) {
237
+ tokenId = purchaseTo_do6(msg.sender, _projectId);
238
+ return tokenId;
239
+ }
240
+
241
+ /**
242
+ * @notice gas-optimized version of purchase(uint256).
243
+ */
244
+ function purchase_H4M(
245
+ uint256 _projectId
246
+ ) external payable returns (uint256 tokenId) {
247
+ tokenId = purchaseTo_do6(msg.sender, _projectId);
248
+ return tokenId;
249
+ }
250
+
251
+ /**
252
+ * @notice Purchases a token from project `_projectId` and sets
253
+ * the token's owner to `_to`.
254
+ * @param _to Address to be the new token's owner.
255
+ * @param _projectId Project ID to mint a token on.
256
+ * @return tokenId Token ID of minted token
257
+ */
258
+ function purchaseTo(
259
+ address _to,
260
+ uint256 _projectId
261
+ ) external payable returns (uint256 tokenId) {
262
+ return purchaseTo_do6(_to, _projectId);
263
+ }
264
+
265
+ /**
266
+ * @notice gas-optimized version of purchaseTo(address, uint256).
267
+ */
268
+ function purchaseTo_do6(
269
+ address _to,
270
+ uint256 _projectId
271
+ ) public payable nonReentrant returns (uint256 tokenId) {
272
+ // CHECKS
273
+ ProjectConfig storage _projectConfig = projectConfig[_projectId];
274
+
275
+ // Note that `maxHasBeenInvoked` is only checked here to reduce gas
276
+ // consumption after a project has been fully minted.
277
+ // `_projectConfig.maxHasBeenInvoked` is locally cached to reduce
278
+ // gas consumption, but if not in sync with the core contract's value,
279
+ // the core contract also enforces its own max invocation check during
280
+ // minting.
281
+ require(
282
+ !_projectConfig.maxHasBeenInvoked,
283
+ "Maximum number of invocations reached"
284
+ );
285
+
286
+ // require artist to have configured price of token on this minter
287
+ require(_projectConfig.priceIsConfigured, "Price not configured");
288
+
289
+ // load price of token into memory
290
+ uint256 _pricePerTokenInWei = _projectConfig.pricePerTokenInWei;
291
+
292
+ require(
293
+ msg.value >= _pricePerTokenInWei,
294
+ "Must send minimum value to mint!"
295
+ );
296
+
297
+ // EFFECTS
298
+ tokenId = minterFilter.mint(_to, _projectId, msg.sender);
299
+
300
+ // okay if this underflows because if statement will always eval false.
301
+ // this is only for gas optimization (core enforces maxInvocations).
302
+ unchecked {
303
+ if (tokenId % ONE_MILLION == _projectConfig.maxInvocations - 1) {
304
+ _projectConfig.maxHasBeenInvoked = true;
305
+ }
306
+ }
307
+
308
+ // INTERACTIONS
309
+ _splitFundsETH(_projectId, _pricePerTokenInWei);
310
+
311
+ return tokenId;
312
+ }
313
+
314
+ /**
315
+ * @dev splits ETH funds between sender (if refund), foundation,
316
+ * artist, and artist's additional payee for a token purchased on
317
+ * project `_projectId`.
318
+ * @dev possible DoS during splits is acknowledged, and mitigated by
319
+ * business practices, including end-to-end testing on mainnet, and
320
+ * admin-accepted artist payment addresses.
321
+ */
322
+ function _splitFundsETH(
323
+ uint256 _projectId,
324
+ uint256 _pricePerTokenInWei
325
+ ) internal {
326
+ if (msg.value > 0) {
327
+ bool success_;
328
+ // send refund to sender
329
+ uint256 refund = msg.value - _pricePerTokenInWei;
330
+ if (refund > 0) {
331
+ (success_, ) = msg.sender.call{value: refund}("");
332
+ require(success_, "Refund failed");
333
+ }
334
+ // split remaining funds between foundation, artist, and artist's
335
+ // additional payee
336
+ (
337
+ uint256 artblocksRevenue_,
338
+ address payable artblocksAddress_,
339
+ uint256 artistRevenue_,
340
+ address payable artistAddress_,
341
+ uint256 additionalPayeePrimaryRevenue_,
342
+ address payable additionalPayeePrimaryAddress_
343
+ ) = genArtCoreContract.getPrimaryRevenueSplits(
344
+ _projectId,
345
+ _pricePerTokenInWei
346
+ );
347
+ // Art Blocks payment
348
+ if (artblocksRevenue_ > 0) {
349
+ (success_, ) = artblocksAddress_.call{value: artblocksRevenue_}(
350
+ ""
351
+ );
352
+ require(success_, "Art Blocks payment failed");
353
+ }
354
+ // artist payment
355
+ if (artistRevenue_ > 0) {
356
+ (success_, ) = artistAddress_.call{value: artistRevenue_}("");
357
+ require(success_, "Artist payment failed");
358
+ }
359
+ // additional payee payment
360
+ if (additionalPayeePrimaryRevenue_ > 0) {
361
+ (success_, ) = additionalPayeePrimaryAddress_.call{
362
+ value: additionalPayeePrimaryRevenue_
363
+ }("");
364
+ require(success_, "Additional Payee payment failed");
365
+ }
366
+ }
367
+ }
368
+
369
+ /**
370
+ * @notice Gets if price of token is configured, price of minting a
371
+ * token on project `_projectId`, and currency symbol and address to be
372
+ * used as payment. Supersedes any core contract price information.
373
+ * @param _projectId Project ID to get price information for.
374
+ * @return isConfigured true only if token price has been configured on
375
+ * this minter
376
+ * @return tokenPriceInWei current price of token on this minter - invalid
377
+ * if price has not yet been configured
378
+ * @return currencySymbol currency symbol for purchases of project on this
379
+ * minter. This minter always returns "ETH"
380
+ * @return currencyAddress currency address for purchases of project on
381
+ * this minter. This minter always returns null address, reserved for ether
382
+ */
383
+ function getPriceInfo(
384
+ uint256 _projectId
385
+ )
386
+ external
387
+ view
388
+ returns (
389
+ bool isConfigured,
390
+ uint256 tokenPriceInWei,
391
+ string memory currencySymbol,
392
+ address currencyAddress
393
+ )
394
+ {
395
+ ProjectConfig storage _projectConfig = projectConfig[_projectId];
396
+ isConfigured = _projectConfig.priceIsConfigured;
397
+ tokenPriceInWei = _projectConfig.pricePerTokenInWei;
398
+ currencySymbol = "ETH";
399
+ currencyAddress = address(0);
400
+ }
401
+ }
@@ -0,0 +1,274 @@
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/security/ReentrancyGuard.sol";
9
+
10
+ pragma solidity 0.8.9;
11
+
12
+ /**
13
+ * @title Filtered Minter contract that allows tokens to be minted with ETH.
14
+ * @author Art Blocks Inc.
15
+ */
16
+ contract MinterSetPriceV1 is ReentrancyGuard, IFilteredMinterV0 {
17
+ /// Core contract address this minter interacts with
18
+ address public immutable genArt721CoreAddress;
19
+
20
+ /// This contract handles cores with interface IV1
21
+ IGenArt721CoreContractV1 private immutable genArtCoreContract;
22
+
23
+ /// Minter filter address this minter interacts with
24
+ address public immutable minterFilterAddress;
25
+
26
+ /// Minter filter this minter may interact with.
27
+ IMinterFilterV0 private immutable minterFilter;
28
+
29
+ /// minterType for this minter
30
+ string public constant minterType = "MinterSetPriceV1";
31
+
32
+ uint256 constant ONE_MILLION = 1_000_000;
33
+
34
+ /// projectId => has project reached its maximum number of invocations?
35
+ mapping(uint256 => bool) public projectMaxHasBeenInvoked;
36
+ /// projectId => project's maximum number of invocations
37
+ mapping(uint256 => uint256) public projectMaxInvocations;
38
+ /// projectId => price per token in wei - supersedes any defined core price
39
+ mapping(uint256 => uint256) private projectIdToPricePerTokenInWei;
40
+ /// projectId => price per token has been configured on this minter
41
+ mapping(uint256 => bool) private projectIdToPriceIsConfigured;
42
+
43
+ modifier onlyCoreWhitelisted() {
44
+ require(
45
+ genArtCoreContract.isWhitelisted(msg.sender),
46
+ "Only Core whitelisted"
47
+ );
48
+ _;
49
+ }
50
+
51
+ modifier onlyArtist(uint256 _projectId) {
52
+ require(
53
+ msg.sender ==
54
+ genArtCoreContract.projectIdToArtistAddress(_projectId),
55
+ "Only Artist"
56
+ );
57
+ _;
58
+ }
59
+
60
+ /**
61
+ * @notice Initializes contract to be a Filtered Minter for
62
+ * `_minterFilter`, integrated with Art Blocks core contract
63
+ * at address `_genArt721Address`.
64
+ * @param _genArt721Address Art Blocks core contract address for
65
+ * which this contract will be a minter.
66
+ * @param _minterFilter Minter filter for whichccthis will a
67
+ * filtered minter.
68
+ */
69
+ constructor(
70
+ address _genArt721Address,
71
+ address _minterFilter
72
+ ) ReentrancyGuard() {
73
+ genArt721CoreAddress = _genArt721Address;
74
+ genArtCoreContract = IGenArt721CoreContractV1(_genArt721Address);
75
+ minterFilterAddress = _minterFilter;
76
+ minterFilter = IMinterFilterV0(_minterFilter);
77
+ require(
78
+ minterFilter.genArt721CoreAddress() == _genArt721Address,
79
+ "Illegal contract pairing"
80
+ );
81
+ }
82
+
83
+ /**
84
+ * @notice Sets the maximum invocations of project `_projectId` based
85
+ * on the value currently defined in the core contract.
86
+ * @param _projectId Project ID to set the maximum invocations for.
87
+ * @dev also checks and may refresh projectMaxHasBeenInvoked for project
88
+ * @dev this enables gas reduction after maxInvocations have been reached -
89
+ * core contracts shall still enforce a maxInvocation check during mint.
90
+ */
91
+ function setProjectMaxInvocations(
92
+ uint256 _projectId
93
+ ) external onlyCoreWhitelisted {
94
+ uint256 invocations;
95
+ uint256 maxInvocations;
96
+ (, , invocations, maxInvocations, , , , , ) = genArtCoreContract
97
+ .projectTokenInfo(_projectId);
98
+ // update storage with results
99
+ projectMaxInvocations[_projectId] = maxInvocations;
100
+ if (invocations < maxInvocations) {
101
+ projectMaxHasBeenInvoked[_projectId] = false;
102
+ }
103
+ }
104
+
105
+ /**
106
+ * @notice Warning: Disabling purchaseTo is not supported on this minter.
107
+ * This method exists purely for interface-conformance purposes.
108
+ */
109
+ function togglePurchaseToDisabled(
110
+ uint256 _projectId
111
+ ) external view onlyArtist(_projectId) {
112
+ revert("Action not supported");
113
+ }
114
+
115
+ /**
116
+ * @notice Updates this minter's price per token of project `_projectId`
117
+ * to be '_pricePerTokenInWei`, in Wei.
118
+ * This price supersedes any legacy core contract price per token value.
119
+ */
120
+ function updatePricePerTokenInWei(
121
+ uint256 _projectId,
122
+ uint256 _pricePerTokenInWei
123
+ ) external onlyArtist(_projectId) {
124
+ projectIdToPricePerTokenInWei[_projectId] = _pricePerTokenInWei;
125
+ projectIdToPriceIsConfigured[_projectId] = true;
126
+ emit PricePerTokenInWeiUpdated(_projectId, _pricePerTokenInWei);
127
+ }
128
+
129
+ /**
130
+ * @notice Purchases a token from project `_projectId`.
131
+ * @param _projectId Project ID to mint a token on.
132
+ * @return tokenId Token ID of minted token
133
+ */
134
+ function purchase(
135
+ uint256 _projectId
136
+ ) external payable returns (uint256 tokenId) {
137
+ tokenId = purchaseTo(msg.sender, _projectId);
138
+ return tokenId;
139
+ }
140
+
141
+ /**
142
+ * @notice Purchases a token from project `_projectId` and sets
143
+ * the token's owner to `_to`.
144
+ * @param _to Address to be the new token's owner.
145
+ * @param _projectId Project ID to mint a token on.
146
+ * @return tokenId Token ID of minted token
147
+ */
148
+ function purchaseTo(
149
+ address _to,
150
+ uint256 _projectId
151
+ ) public payable nonReentrant returns (uint256 tokenId) {
152
+ // CHECKS
153
+ require(
154
+ !projectMaxHasBeenInvoked[_projectId],
155
+ "Maximum number of invocations reached"
156
+ );
157
+
158
+ // require artist to have configured price of token on this minter
159
+ require(
160
+ projectIdToPriceIsConfigured[_projectId],
161
+ "Price not configured"
162
+ );
163
+
164
+ require(
165
+ msg.value >= projectIdToPricePerTokenInWei[_projectId],
166
+ "Must send minimum value to mint!"
167
+ );
168
+
169
+ // EFFECTS
170
+ tokenId = minterFilter.mint(_to, _projectId, msg.sender);
171
+ // what if projectMaxInvocations[_projectId] is 0 (default value)?
172
+ // that is intended, so that by default the minter allows infinite transactions,
173
+ // allowing the artblocks contract to stop minting
174
+ // uint256 tokenInvocation = tokenId % ONE_MILLION;
175
+ if (
176
+ projectMaxInvocations[_projectId] > 0 &&
177
+ tokenId % ONE_MILLION == projectMaxInvocations[_projectId] - 1
178
+ ) {
179
+ projectMaxHasBeenInvoked[_projectId] = true;
180
+ }
181
+
182
+ // INTERACTIONS
183
+ _splitFundsETH(_projectId);
184
+
185
+ return tokenId;
186
+ }
187
+
188
+ /**
189
+ * @dev splits ETH funds between sender (if refund), foundation,
190
+ * artist, and artist's additional payee for a token purchased on
191
+ * project `_projectId`.
192
+ * @dev utilizes transfer() to send ETH, so access lists may need to be
193
+ * populated when purchasing tokens.
194
+ */
195
+ function _splitFundsETH(uint256 _projectId) internal {
196
+ if (msg.value > 0) {
197
+ uint256 pricePerTokenInWei = projectIdToPricePerTokenInWei[
198
+ _projectId
199
+ ];
200
+ uint256 refund = msg.value - pricePerTokenInWei;
201
+ if (refund > 0) {
202
+ (bool success_, ) = msg.sender.call{value: refund}("");
203
+ require(success_, "Refund failed");
204
+ }
205
+ uint256 foundationAmount = (pricePerTokenInWei *
206
+ genArtCoreContract.artblocksPercentage()) / 100;
207
+ if (foundationAmount > 0) {
208
+ (bool success_, ) = genArtCoreContract.artblocksAddress().call{
209
+ value: foundationAmount
210
+ }("");
211
+ require(success_, "Foundation payment failed");
212
+ }
213
+ uint256 projectFunds = pricePerTokenInWei - foundationAmount;
214
+ uint256 additionalPayeeAmount;
215
+ if (
216
+ genArtCoreContract.projectIdToAdditionalPayeePercentage(
217
+ _projectId
218
+ ) > 0
219
+ ) {
220
+ additionalPayeeAmount =
221
+ (projectFunds *
222
+ genArtCoreContract.projectIdToAdditionalPayeePercentage(
223
+ _projectId
224
+ )) /
225
+ 100;
226
+ if (additionalPayeeAmount > 0) {
227
+ (bool success_, ) = genArtCoreContract
228
+ .projectIdToAdditionalPayee(_projectId)
229
+ .call{value: additionalPayeeAmount}("");
230
+ require(success_, "Additional payment failed");
231
+ }
232
+ }
233
+ uint256 creatorFunds = projectFunds - additionalPayeeAmount;
234
+ if (creatorFunds > 0) {
235
+ (bool success_, ) = genArtCoreContract
236
+ .projectIdToArtistAddress(_projectId)
237
+ .call{value: creatorFunds}("");
238
+ require(success_, "Artist payment failed");
239
+ }
240
+ }
241
+ }
242
+
243
+ /**
244
+ * @notice Gets if price of token is configured, price of minting a
245
+ * token on project `_projectId`, and currency symbol and address to be
246
+ * used as payment. Supersedes any core contract price information.
247
+ * @param _projectId Project ID to get price information for.
248
+ * @return isConfigured true only if token price has been configured on
249
+ * this minter
250
+ * @return tokenPriceInWei current price of token on this minter - invalid
251
+ * if price has not yet been configured
252
+ * @return currencySymbol currency symbol for purchases of project on this
253
+ * minter. This minter always returns "ETH"
254
+ * @return currencyAddress currency address for purchases of project on
255
+ * this minter. This minter always returns null address, reserved for ether
256
+ */
257
+ function getPriceInfo(
258
+ uint256 _projectId
259
+ )
260
+ external
261
+ view
262
+ returns (
263
+ bool isConfigured,
264
+ uint256 tokenPriceInWei,
265
+ string memory currencySymbol,
266
+ address currencyAddress
267
+ )
268
+ {
269
+ isConfigured = projectIdToPriceIsConfigured[_projectId];
270
+ tokenPriceInWei = projectIdToPricePerTokenInWei[_projectId];
271
+ currencySymbol = "ETH";
272
+ currencyAddress = address(0);
273
+ }
274
+ }