@artblocks/contracts 0.0.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/README.md +27 -2
  2. package/artifacts/contracts/archive/GenArt721CoreV0.sol/Address.json +10 -0
  3. package/artifacts/contracts/archive/GenArt721CoreV0.sol/Counters.json +10 -0
  4. package/artifacts/contracts/archive/GenArt721CoreV0.sol/CustomERC721Metadata.json +425 -0
  5. package/artifacts/contracts/archive/GenArt721CoreV0.sol/ERC165.json +38 -0
  6. package/artifacts/contracts/archive/GenArt721CoreV0.sol/ERC721.json +322 -0
  7. package/artifacts/contracts/archive/GenArt721CoreV0.sol/ERC721Enumerable.json +384 -0
  8. package/artifacts/contracts/archive/GenArt721CoreV0.sol/ERC721ReceiverMock.json +101 -0
  9. package/artifacts/contracts/archive/GenArt721CoreV0.sol/GenArt721.json +1528 -0
  10. package/artifacts/contracts/archive/GenArt721CoreV0.sol/IERC165.json +32 -0
  11. package/artifacts/contracts/archive/GenArt721CoreV0.sol/IERC721.json +316 -0
  12. package/artifacts/contracts/archive/GenArt721CoreV0.sol/IERC721Enumerable.json +378 -0
  13. package/artifacts/contracts/archive/GenArt721CoreV0.sol/IERC721Receiver.json +47 -0
  14. package/artifacts/contracts/archive/GenArt721CoreV0.sol/SafeMath.json +10 -0
  15. package/artifacts/contracts/archive/GenArt721CoreV0.sol/Strings.json +10 -0
  16. package/artifacts/contracts/archive/GenArt721CoreV1.sol/Address.json +10 -0
  17. package/artifacts/contracts/archive/GenArt721CoreV1.sol/Counters.json +10 -0
  18. package/artifacts/contracts/archive/GenArt721CoreV1.sol/CustomERC721Metadata.json +425 -0
  19. package/artifacts/contracts/archive/GenArt721CoreV1.sol/ERC165.json +38 -0
  20. package/artifacts/contracts/archive/GenArt721CoreV1.sol/ERC721.json +322 -0
  21. package/artifacts/contracts/archive/GenArt721CoreV1.sol/ERC721Enumerable.json +384 -0
  22. package/artifacts/contracts/archive/GenArt721CoreV1.sol/GenArt721Core.json +1773 -0
  23. package/artifacts/contracts/archive/GenArt721CoreV1.sol/IERC165.json +32 -0
  24. package/artifacts/contracts/archive/GenArt721CoreV1.sol/IERC721.json +316 -0
  25. package/artifacts/contracts/archive/GenArt721CoreV1.sol/IERC721Enumerable.json +378 -0
  26. package/artifacts/contracts/archive/GenArt721CoreV1.sol/IERC721Receiver.json +47 -0
  27. package/artifacts/contracts/archive/GenArt721CoreV1.sol/Randomizer.json +26 -0
  28. package/artifacts/contracts/archive/GenArt721CoreV1.sol/SafeMath.json +10 -0
  29. package/artifacts/contracts/archive/GenArt721CoreV1.sol/Strings.json +10 -0
  30. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV0.sol/MinterDAExpV0.json +575 -0
  31. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV1.sol/MinterDAExpV1.json +463 -0
  32. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDAExp/MinterDAExpV2.sol/MinterDAExpV2.json +3 -3
  33. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDAExp/MinterDAExpV3.sol/MinterDAExpV3.json +3 -3
  34. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol/MinterDAExpSettlementV0.json +15 -15
  35. package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV0.sol/MinterDALinV0.json +551 -0
  36. package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV1.sol/MinterDALinV1.json +439 -0
  37. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDALin/MinterDALinV2.sol/MinterDALinV2.json +3 -3
  38. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDALin/MinterDALinV3.sol/MinterDALinV3.json +3 -3
  39. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV0.sol/MinterHolderV0.json +622 -0
  40. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV1.sol/MinterHolderV1.json +719 -0
  41. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV2.sol/MinterHolderV2.json +794 -0
  42. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterHolder/MinterHolderV3.sol/MinterHolderV3.json +3 -3
  43. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV0.sol/MinterMerkleV0.json +873 -0
  44. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV1.sol/MinterMerkleV1.json +932 -0
  45. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV2.sol/MinterMerkleV2.json +984 -0
  46. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterMerkle/MinterMerkleV3.sol/MinterMerkleV3.json +3 -3
  47. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterMerkle/MinterMerkleV4.sol/MinterMerkleV4.json +3 -3
  48. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV0.sol/MinterSetPriceV0.json +400 -0
  49. package/artifacts/contracts/{minter-suite/Minters/MinterSetPrice/deprecated → archive/minter-suite/Minters/MinterSetPrice}/MinterSetPriceV1.sol/MinterSetPriceV1.json +3 -3
  50. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterSetPrice/MinterSetPriceV2.sol/MinterSetPriceV2.json +3 -3
  51. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterSetPrice/MinterSetPriceV3.sol/MinterSetPriceV3.json +3 -3
  52. package/artifacts/contracts/{minter-suite/Minters/MinterSetPriceERC20/deprecated → archive/minter-suite/Minters/MinterSetPriceERC20}/MinterSetPriceERC20V0.sol/MinterSetPriceERC20V0.json +3 -3
  53. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V1.sol/MinterSetPriceERC20V1.json +349 -0
  54. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol/MinterSetPriceERC20V2.json +3 -3
  55. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol/MinterSetPriceERC20V3.json +3 -3
  56. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDAExpSettlementV0.sol/IFilteredMinterDAExpSettlementV0.json +12 -12
  57. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDAExpSettlement_Mixin.sol/IFilteredMinterDAExpSettlement_Mixin.json +161 -0
  58. package/artifacts/contracts/interfaces/0.8.x/IMinterBaseV0.sol/IMinterBaseV0.json +24 -0
  59. package/artifacts/contracts/interfaces/0.8.x/IMintingAPICoreV0.sol/IMintingAPICoreV0.json +185 -0
  60. package/artifacts/contracts/interfaces/0.8.x/IMintingAPIMinterV0.sol/IMintingAPIMinterV0.json +88 -0
  61. package/artifacts/contracts/minter-suite/Minters/MinterBase_v0_1_1.sol/MinterBase.json +24 -0
  62. package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV1.sol/MinterDAExpSettlementV1.json +1066 -0
  63. package/artifacts/contracts/minter-suite/Minters/MinterDAExpV4.sol/MinterDAExpV4.json +869 -0
  64. package/artifacts/contracts/minter-suite/Minters/MinterDALinV4.sol/MinterDALinV4.json +845 -0
  65. package/artifacts/contracts/minter-suite/Minters/MinterHolderV4.sol/MinterHolderV4.json +1113 -0
  66. package/artifacts/contracts/minter-suite/Minters/MinterMerkleV5.sol/MinterMerkleV5.json +1052 -0
  67. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20V4.sol/MinterSetPriceERC20V4.json +755 -0
  68. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceV4.sol/MinterSetPriceV4.json +684 -0
  69. package/artifacts/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol/GenArt721CoreV3_Engine_IncorrectCoreType.json +1817 -0
  70. package/contracts/archive/GenArt721CoreV0.sol +1621 -0
  71. package/contracts/archive/GenArt721CoreV1.sol +1577 -0
  72. package/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV0.sol +503 -0
  73. package/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV1.sol +442 -0
  74. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDAExp/MinterDAExpV2.sol +3 -3
  75. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDAExp/MinterDAExpV3.sol +3 -3
  76. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol +3 -3
  77. package/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV0.sol +450 -0
  78. package/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV1.sol +406 -0
  79. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDALin/MinterDALinV2.sol +3 -3
  80. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterDALin/MinterDALinV3.sol +3 -3
  81. package/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV0.sol +540 -0
  82. package/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV1.sol +648 -0
  83. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterHolder/MinterHolderV2.sol +6 -6
  84. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterHolder/MinterHolderV3.sol +4 -4
  85. package/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV0.sol +523 -0
  86. package/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV1.sol +602 -0
  87. package/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV2.sol +679 -0
  88. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterMerkle/MinterMerkleV3.sol +4 -4
  89. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterMerkle/MinterMerkleV4.sol +4 -4
  90. package/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV0.sol +333 -0
  91. package/contracts/{minter-suite/Minters/MinterSetPrice/deprecated → archive/minter-suite/Minters/MinterSetPrice}/MinterSetPriceV1.sol +0 -0
  92. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterSetPrice/MinterSetPriceV2.sol +3 -3
  93. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterSetPrice/MinterSetPriceV3.sol +3 -3
  94. package/contracts/{minter-suite/Minters/MinterSetPriceERC20/deprecated → archive/minter-suite/Minters/MinterSetPriceERC20}/MinterSetPriceERC20V0.sol +0 -0
  95. package/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V1.sol +411 -0
  96. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol +3 -3
  97. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol +3 -3
  98. package/contracts/interfaces/0.8.x/IFilteredMinterDAExpSettlementV0.sol +4 -53
  99. package/contracts/interfaces/0.8.x/IFilteredMinterDAExpSettlement_Mixin.sol +62 -0
  100. package/contracts/interfaces/0.8.x/IMinterBaseV0.sol +20 -0
  101. package/contracts/interfaces/0.8.x/IMintingAPICoreV0.sol +62 -0
  102. package/contracts/interfaces/0.8.x/IMintingAPIMinterV0.sol +31 -0
  103. package/contracts/minter-suite/Minters/MinterBase_v0_1_1.sol +293 -0
  104. package/contracts/minter-suite/Minters/MinterDAExpSettlementV1.sol +1026 -0
  105. package/contracts/minter-suite/Minters/MinterDAExpV4.sol +572 -0
  106. package/contracts/minter-suite/Minters/MinterDALinV4.sol +525 -0
  107. package/contracts/minter-suite/Minters/MinterHolderV4.sol +752 -0
  108. package/contracts/minter-suite/Minters/MinterMerkleV5.sol +688 -0
  109. package/contracts/minter-suite/Minters/MinterSetPriceERC20V4.sol +451 -0
  110. package/contracts/minter-suite/Minters/MinterSetPriceV4.sol +352 -0
  111. package/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol +1979 -0
  112. package/package.json +1 -1
  113. package/artifacts/contracts/minter-suite/Minters/MinterHolder/MinterHolderV2.sol/MinterHolderV2.json +0 -794
@@ -0,0 +1,293 @@
1
+ // SPDX-License-Identifier: LGPL-3.0-only
2
+ // Created By: Art Blocks Inc.
3
+
4
+ import "../../interfaces/0.8.x/IMinterBaseV0.sol";
5
+ import "../../interfaces/0.8.x/IGenArt721CoreContractV3_Base.sol";
6
+ import "../../interfaces/0.8.x/IGenArt721CoreContractV3.sol";
7
+ import "../../interfaces/0.8.x/IGenArt721CoreContractV3_Engine.sol";
8
+
9
+ import "@openzeppelin-4.7/contracts/token/ERC20/IERC20.sol";
10
+
11
+ pragma solidity ^0.8.0;
12
+
13
+ /**
14
+ * @title Art Blocks Minter Base Class
15
+ * @notice A base class for Art Blocks minter contracts that provides common
16
+ * functionality used across minter contracts.
17
+ * This contract is not intended to be deployed directly, but rather to be
18
+ * inherited by other minter contracts.
19
+ * From a design perspective, this contract is intended to remain simple and
20
+ * easy to understand. It is not intended to cause a complex inheritance tree,
21
+ * and instead should keep minter contracts as readable as possible for
22
+ * collectors and developers.
23
+ * @dev Semantic versioning is used in the solidity file name, and is therefore
24
+ * controlled by contracts importing the appropriate filename version.
25
+ * @author Art Blocks Inc.
26
+ */
27
+ abstract contract MinterBase is IMinterBaseV0 {
28
+ /// state variable that tracks whether this contract's associated core
29
+ /// contract is an Engine contract, where Engine contracts have an
30
+ /// additional revenue split for the platform provider
31
+ bool public immutable isEngine;
32
+
33
+ // @dev we do not track an initialization state, as the only state variable
34
+ // is immutable, which the compiler enforces to be assigned during
35
+ // construction.
36
+
37
+ /**
38
+ * @notice Initializes contract to ensure state variable `isEngine` is set
39
+ * appropriately based on the minter's associated core contract address.
40
+ * @param genArt721Address Art Blocks core contract address for
41
+ * which this contract will be a minter.
42
+ */
43
+ constructor(address genArt721Address) {
44
+ // set state variable isEngine
45
+ isEngine = _getV3CoreIsEngine(genArt721Address);
46
+ }
47
+
48
+ /**
49
+ * @notice splits ETH funds between sender (if refund), providers,
50
+ * artist, and artist's additional payee for a token purchased on
51
+ * project `_projectId`.
52
+ * WARNING: This function uses msg.value and msg.sender to determine
53
+ * refund amounts, and therefore may not be applicable to all use cases
54
+ * (e.g. do not use with Dutch Auctions with on-chain settlement).
55
+ * @dev possible DoS during splits is acknowledged, and mitigated by
56
+ * business practices, including end-to-end testing on mainnet, and
57
+ * admin-accepted artist payment addresses.
58
+ * @param projectId Project ID for which funds shall be split.
59
+ * @param pricePerTokenInWei Current price of token, in Wei.
60
+ */
61
+ function splitFundsETH(
62
+ uint256 projectId,
63
+ uint256 pricePerTokenInWei,
64
+ address genArt721CoreAddress
65
+ ) internal {
66
+ if (msg.value > 0) {
67
+ bool success_;
68
+ // send refund to sender
69
+ uint256 refund = msg.value - pricePerTokenInWei;
70
+ if (refund > 0) {
71
+ (success_, ) = msg.sender.call{value: refund}("");
72
+ require(success_, "Refund failed");
73
+ }
74
+ // split revenues
75
+ splitRevenuesETH(
76
+ projectId,
77
+ pricePerTokenInWei,
78
+ genArt721CoreAddress
79
+ );
80
+ }
81
+ }
82
+
83
+ /**
84
+ * @notice splits ETH revenues between providers, artist, and artist's
85
+ * additional payee for revenue generated by project `_projectId`.
86
+ * @dev possible DoS during splits is acknowledged, and mitigated by
87
+ * business practices, including end-to-end testing on mainnet, and
88
+ * admin-accepted artist payment addresses.
89
+ * @param projectId Project ID for which funds shall be split.
90
+ * @param valueInWei Value to be split, in Wei.
91
+ */
92
+ function splitRevenuesETH(
93
+ uint256 projectId,
94
+ uint256 valueInWei,
95
+ address genArtCoreContract
96
+ ) internal {
97
+ if (valueInWei <= 0) {
98
+ return; // return early
99
+ }
100
+ bool success;
101
+ // split funds between platforms, artist, and artist's
102
+ // additional payee
103
+ uint256 renderProviderRevenue_;
104
+ address payable renderProviderAddress_;
105
+ uint256 artistRevenue_;
106
+ address payable artistAddress_;
107
+ uint256 additionalPayeePrimaryRevenue_;
108
+ address payable additionalPayeePrimaryAddress_;
109
+ if (isEngine) {
110
+ // get engine splits
111
+ uint256 platformProviderRevenue_;
112
+ address payable platformProviderAddress_;
113
+ (
114
+ renderProviderRevenue_,
115
+ renderProviderAddress_,
116
+ platformProviderRevenue_,
117
+ platformProviderAddress_,
118
+ artistRevenue_,
119
+ artistAddress_,
120
+ additionalPayeePrimaryRevenue_,
121
+ additionalPayeePrimaryAddress_
122
+ ) = IGenArt721CoreContractV3_Engine(genArtCoreContract)
123
+ .getPrimaryRevenueSplits(projectId, valueInWei);
124
+ // Platform Provider payment (only possible if engine)
125
+ if (platformProviderRevenue_ > 0) {
126
+ (success, ) = platformProviderAddress_.call{
127
+ value: platformProviderRevenue_
128
+ }("");
129
+ require(success, "Platform Provider payment failed");
130
+ }
131
+ } else {
132
+ // get flagship splits
133
+ (
134
+ renderProviderRevenue_, // artblocks revenue
135
+ renderProviderAddress_, // artblocks address
136
+ artistRevenue_,
137
+ artistAddress_,
138
+ additionalPayeePrimaryRevenue_,
139
+ additionalPayeePrimaryAddress_
140
+ ) = IGenArt721CoreContractV3(genArtCoreContract)
141
+ .getPrimaryRevenueSplits(projectId, valueInWei);
142
+ }
143
+ // Render Provider / Art Blocks payment
144
+ if (renderProviderRevenue_ > 0) {
145
+ (success, ) = renderProviderAddress_.call{
146
+ value: renderProviderRevenue_
147
+ }("");
148
+ require(success, "Render Provider payment failed");
149
+ }
150
+ // artist payment
151
+ if (artistRevenue_ > 0) {
152
+ (success, ) = artistAddress_.call{value: artistRevenue_}("");
153
+ require(success, "Artist payment failed");
154
+ }
155
+ // additional payee payment
156
+ if (additionalPayeePrimaryRevenue_ > 0) {
157
+ (success, ) = additionalPayeePrimaryAddress_.call{
158
+ value: additionalPayeePrimaryRevenue_
159
+ }("");
160
+ require(success, "Additional Payee payment failed");
161
+ }
162
+ }
163
+
164
+ /**
165
+ * @notice splits ERC-20 funds between providers, artist, and artist's
166
+ * additional payee, for a token purchased on project `_projectId`.
167
+ * @dev possible DoS during splits is acknowledged, and mitigated by
168
+ * business practices, including end-to-end testing on mainnet, and
169
+ * admin-accepted artist payment addresses.
170
+ */
171
+ function splitFundsERC20(
172
+ uint256 projectId,
173
+ uint256 pricePerTokenInWei,
174
+ address currencyAddress,
175
+ address genArtCoreContract
176
+ ) internal {
177
+ IERC20 _projectCurrency = IERC20(currencyAddress);
178
+ // split remaining funds between foundation, artist, and artist's
179
+ // additional payee
180
+ uint256 renderProviderRevenue_;
181
+ address payable renderProviderAddress_;
182
+ uint256 artistRevenue_;
183
+ address payable artistAddress_;
184
+ uint256 additionalPayeePrimaryRevenue_;
185
+ address payable additionalPayeePrimaryAddress_;
186
+ if (isEngine) {
187
+ // get engine splits
188
+ uint256 platformProviderRevenue_;
189
+ address payable platformProviderAddress_;
190
+ (
191
+ renderProviderRevenue_,
192
+ renderProviderAddress_,
193
+ platformProviderRevenue_,
194
+ platformProviderAddress_,
195
+ artistRevenue_,
196
+ artistAddress_,
197
+ additionalPayeePrimaryRevenue_,
198
+ additionalPayeePrimaryAddress_
199
+ ) = IGenArt721CoreContractV3_Engine(genArtCoreContract)
200
+ .getPrimaryRevenueSplits(projectId, pricePerTokenInWei);
201
+ // Platform Provider payment (only possible if engine)
202
+ if (platformProviderRevenue_ > 0) {
203
+ _projectCurrency.transferFrom(
204
+ msg.sender,
205
+ platformProviderAddress_,
206
+ platformProviderRevenue_
207
+ );
208
+ }
209
+ } else {
210
+ // get flagship splits
211
+ (
212
+ renderProviderRevenue_, // artblocks revenue
213
+ renderProviderAddress_, // artblocks address
214
+ artistRevenue_,
215
+ artistAddress_,
216
+ additionalPayeePrimaryRevenue_,
217
+ additionalPayeePrimaryAddress_
218
+ ) = IGenArt721CoreContractV3(genArtCoreContract)
219
+ .getPrimaryRevenueSplits(projectId, pricePerTokenInWei);
220
+ }
221
+ // Art Blocks payment
222
+ if (renderProviderRevenue_ > 0) {
223
+ _projectCurrency.transferFrom(
224
+ msg.sender,
225
+ renderProviderAddress_,
226
+ renderProviderRevenue_
227
+ );
228
+ }
229
+ // artist payment
230
+ if (artistRevenue_ > 0) {
231
+ _projectCurrency.transferFrom(
232
+ msg.sender,
233
+ artistAddress_,
234
+ artistRevenue_
235
+ );
236
+ }
237
+ // additional payee payment
238
+ if (additionalPayeePrimaryRevenue_ > 0) {
239
+ _projectCurrency.transferFrom(
240
+ msg.sender,
241
+ additionalPayeePrimaryAddress_,
242
+ additionalPayeePrimaryRevenue_
243
+ );
244
+ }
245
+ }
246
+
247
+ /**
248
+ * @notice Returns whether a V3 core contract is an Art Blocks Engine
249
+ * contract or not. Return value of false indicates that the core is a
250
+ * flagship contract.
251
+ * @dev this function reverts if a core contract does not return the
252
+ * expected number of return values from getPrimaryRevenueSplits() for
253
+ * either a flagship or engine core contract.
254
+ * @dev this function uses the length of the return data (in bytes) to
255
+ * determine whether the core is an engine or not.
256
+ * @param genArt721CoreV3 The address of the deployed core contract.
257
+ */
258
+ function _getV3CoreIsEngine(
259
+ address genArt721CoreV3
260
+ ) private returns (bool) {
261
+ // call getPrimaryRevenueSplits() on core contract
262
+ bytes memory payload = abi.encodeWithSignature(
263
+ "getPrimaryRevenueSplits(uint256,uint256)",
264
+ 0,
265
+ 0
266
+ );
267
+ (bool success, bytes memory returnData) = genArt721CoreV3.call(payload);
268
+ require(success, "getPrimaryRevenueSplits() call failed");
269
+ // determine whether core is engine or not, based on return data length
270
+ uint256 returnDataLength = returnData.length;
271
+ if (returnDataLength == 6 * 32) {
272
+ // 6 32-byte words returned if flagship (not engine)
273
+ // @dev 6 32-byte words are expected because the non-engine core
274
+ // contracts return a payout address and uint256 payment value for
275
+ // the artist, and artist's additional payee, and Art Blocks.
276
+ // also note that per Solidity ABI encoding, the address return
277
+ // values are padded to 32 bytes.
278
+ return false;
279
+ } else if (returnDataLength == 8 * 32) {
280
+ // 8 32-byte words returned if engine
281
+ // @dev 8 32-byte words are expected because the engine core
282
+ // contracts return a payout address and uint256 payment value for
283
+ // the artist, artist's additional payee, render provider
284
+ // typically Art Blocks, and platform provider (partner).
285
+ // also note that per Solidity ABI encoding, the address return
286
+ // values are padded to 32 bytes.
287
+ return true;
288
+ } else {
289
+ // unexpected return value length
290
+ revert("Unexpected revenue split bytes");
291
+ }
292
+ }
293
+ }