@artblocks/contracts 1.0.4 → 1.2.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 (289) hide show
  1. package/README.md +75 -7
  2. package/artifacts/contracts/AdminACLV0.sol/AdminACLV0.json +2 -2
  3. package/artifacts/contracts/AdminACLV1.sol/AdminACLV1.json +2 -2
  4. package/artifacts/contracts/DependencyRegistryV0.sol/DependencyRegistryV0.json +336 -131
  5. package/artifacts/contracts/archive/GenArt721CoreV3.sol/GenArt721CoreV3.json +2047 -0
  6. package/artifacts/contracts/archive/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +2021 -0
  7. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterBase_v0_1_1.sol/MinterBase.json +1 -1
  8. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV2.sol/MinterDAExpV2.json +2 -2
  9. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV3.sol/MinterDAExpV3.json +2 -2
  10. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDAExp}/MinterDAExpV4.sol/MinterDAExpV4.json +3 -3
  11. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol/MinterDAExpSettlementV0.json +2 -2
  12. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV1.sol/MinterDAExpSettlementV1.json +2 -2
  13. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV2.sol/MinterDAExpSettlementV2.json +1109 -0
  14. package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV2.sol/MinterDALinV2.json +2 -2
  15. package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV3.sol/MinterDALinV3.json +2 -2
  16. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDALin}/MinterDALinV4.sol/MinterDALinV4.json +3 -3
  17. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV1.sol/MinterHolderV1.json +2 -2
  18. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV2.sol/MinterHolderV2.json +2 -2
  19. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV3.sol/MinterHolderV3.json +2 -2
  20. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterHolder}/MinterHolderV4.sol/MinterHolderV4.json +3 -3
  21. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV1.sol/MinterMerkleV1.json +2 -2
  22. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV2.sol/MinterMerkleV2.json +2 -2
  23. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV3.sol/MinterMerkleV3.json +2 -2
  24. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV4.sol/MinterMerkleV4.json +2 -2
  25. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterMerkle}/MinterMerkleV5.sol/MinterMerkleV5.json +3 -3
  26. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterPolyptych}/MinterPolyptychV0.sol/IGenArt721CoreContractV3WithRandomizer.json +31 -63
  27. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterPolyptych}/MinterPolyptychV0.sol/MinterPolyptychV0.json +3 -3
  28. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSEA}/MinterSEAV0.sol/MinterSEAV0.json +3 -3
  29. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV2.sol/MinterSetPriceV2.json +2 -2
  30. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV3.sol/MinterSetPriceV3.json +2 -2
  31. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSetPrice}/MinterSetPriceV4.sol/MinterSetPriceV4.json +3 -3
  32. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V0.sol/MinterSetPriceERC20V0.json +65 -2
  33. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V1.sol/MinterSetPriceERC20V1.json +65 -2
  34. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol/MinterSetPriceERC20V2.json +2 -2
  35. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol/MinterSetPriceERC20V3.json +2 -2
  36. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V4.sol/MinterSetPriceERC20V4.json +807 -0
  37. package/artifacts/contracts/engine/V2/GenArt721MinterBurner_PBAB.sol/GenArt721MinterBurner_PBAB.json +65 -2
  38. package/artifacts/contracts/engine/V2/GenArt721Minter_PBAB.sol/GenArt721Minter_PBAB.json +65 -2
  39. package/artifacts/contracts/engine/V3/EngineFactoryV0.sol/EngineFactoryV0.json +606 -0
  40. package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine.sol/GenArt721CoreV3_Engine.json +565 -209
  41. package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol/GenArt721CoreV3_Engine_Flex.json +785 -227
  42. package/artifacts/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol/GenArt721CoreV3_Engine_Flex_PROOF.json +40 -15
  43. package/artifacts/contracts/engine/V3/forks/PROHIBITION/AdminACLV0_PROHIBITION.sol/AdminACLV0_PROHIBITION.json +2 -2
  44. package/artifacts/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol/GenArt721CoreV3_Engine_Flex_PROHIBITION.json +40 -15
  45. package/artifacts/contracts/engine/V3/forks/PROHIBITION/interfaces/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.sol/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.json +36 -68
  46. package/artifacts/contracts/engine-registry/CoreRegistryV1.sol/CoreRegistryV1.json +12 -12
  47. package/artifacts/contracts/interfaces/v0.8.x/IAdminACLV0_Extended.sol/IAdminACLV0_Extended.json +140 -0
  48. package/artifacts/contracts/interfaces/v0.8.x/IBytecodeStorageReaderV2.sol/IBytecodeStorageReaderV2.json +130 -0
  49. package/artifacts/contracts/interfaces/v0.8.x/ICoreRegistryV1.sol/ICoreRegistryV1.json +6 -6
  50. package/artifacts/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol/IDependencyRegistryV0.json +71 -39
  51. package/artifacts/contracts/interfaces/v0.8.x/IEngineFactoryV0.sol/IEngineFactoryV0.json +283 -0
  52. package/artifacts/contracts/interfaces/v0.8.x/IFilteredMinterDAExpSettlementV0.sol/IFilteredMinterDAExpSettlementV0.json +12 -12
  53. package/artifacts/contracts/interfaces/v0.8.x/IFilteredMinterDAExpSettlementV1.sol/IFilteredMinterDAExpSettlementV1.json +12 -12
  54. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3.sol/IGenArt721CoreContractV3.json +30 -62
  55. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Base.sol/IGenArt721CoreContractV3_Base.json +30 -62
  56. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine.sol/IGenArt721CoreContractV3_Engine.json +170 -104
  57. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex.sol/IGenArt721CoreContractV3_Engine_Flex.json +170 -104
  58. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex_PreV3p2.sol/IGenArt721CoreContractV3_Engine_Flex_PreV3p2.json +1028 -0
  59. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_PreV3p2.sol/IGenArt721CoreContractV3_Engine_PreV3p2.json +741 -0
  60. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_ProjectFinance.sol/IGenArt721CoreContractV3_ProjectFinance.json +87 -0
  61. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721Minter_PBAB.sol/IGenArt721Minter_PBAB.json +279 -0
  62. package/artifacts/contracts/interfaces/v0.8.x/IMinterFilterV1.sol/IMinterFilterV1.json +22 -22
  63. package/artifacts/contracts/interfaces/v0.8.x/IPseudorandomAtomic.sol/IPseudorandomAtomic.json +1 -1
  64. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol/ISharedMinterDAExpSettlementV0.json +26 -101
  65. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAExpV0.sol/ISharedMinterDAExpV0.json +1 -57
  66. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDALinV0.sol/ISharedMinterDALinV0.json +1 -57
  67. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAV0.sol/ISharedMinterDAV0.json +2 -21
  68. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterHolderERC20V0.sol/ISharedMinterHolderERC20V0.json +158 -0
  69. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterHolderV0.sol/ISharedMinterHolderV0.json +15 -90
  70. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterMerkleV0.sol/ISharedMinterMerkleV0.json +10 -36
  71. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterRAMV0.sol/ISharedMinterRAMV0.json +62 -0
  72. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterRequired.sol/ISharedMinterRequired.json +37 -0
  73. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterSEAV0.sol/ISharedMinterSEAV0.json +4 -236
  74. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterSimplePurchaseV0.sol/ISharedMinterSimplePurchaseV0.json +5 -5
  75. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterV0.sol/ISharedMinterV0.json +7 -423
  76. package/artifacts/contracts/interfaces/v0.8.x/ISharedRandomizerV0.sol/ISharedRandomizerV0.json +17 -17
  77. package/artifacts/contracts/interfaces/v0.8.x/ISplitAtomicFactoryV0.sol/ISplitAtomicFactoryV0.json +170 -0
  78. package/artifacts/contracts/interfaces/v0.8.x/ISplitAtomicV0.sol/ISplitAtomicV0.json +126 -0
  79. package/artifacts/contracts/interfaces/v0.8.x/ISplitProviderV0.sol/ISplitProviderV0.json +98 -0
  80. package/artifacts/contracts/interfaces/v0.8.x/integration-refs/splits-0x-v2/ISplitFactoryV2.sol/ISplitFactoryV2.json +123 -0
  81. package/artifacts/contracts/libs/integration-refs/delegation-registry/DelegationRegistry.sol/DelegationRegistry.json +2 -2
  82. package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeMock.sol/GnosisSafeMock.json +2 -2
  83. package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeProxyFactoryMock.sol/GnosisSafeProxyFactoryMock.json +2 -2
  84. package/artifacts/contracts/libs/integration-refs/gnosis-safe/MultiSendMock.sol/MultiSendMock.json +2 -2
  85. package/artifacts/contracts/libs/integration-refs/weth9/weth9.sol/WETH9_.json +2 -2
  86. package/artifacts/contracts/libs/v0.8.x/ABHelpers.sol/ABHelpers.json +2 -2
  87. package/artifacts/contracts/libs/v0.8.x/AuthLib.sol/AuthLib.json +2 -2
  88. package/artifacts/contracts/libs/v0.8.x/BitMap.sol/BitMaps256.json +10 -0
  89. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV0.sol/BytecodeStorage.json +2 -2
  90. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV1.sol/BytecodeStorageReader.json +2 -2
  91. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV1.sol/BytecodeStorageWriter.json +2 -2
  92. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV2.sol/BytecodeStorageReader.json +214 -0
  93. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV2.sol/BytecodeStorageWriter.json +10 -0
  94. package/artifacts/contracts/libs/v0.8.x/Bytes32Strings.sol/Bytes32Strings.json +2 -2
  95. package/artifacts/contracts/libs/v0.8.x/DependencyRegistryStorageLib.sol/DependencyRegistryStorageLib.json +10 -0
  96. package/artifacts/contracts/libs/v0.8.x/ERC721_PackedHashSeed.sol/ERC721_PackedHashSeed.json +2 -2
  97. package/artifacts/contracts/libs/v0.8.x/ERC721_PackedHashSeedV1.sol/ERC721_PackedHashSeedV1.json +444 -0
  98. package/artifacts/contracts/libs/v0.8.x/PackedBools.sol/PackedBools.json +10 -0
  99. package/artifacts/contracts/libs/v0.8.x/SSTORE2.sol/SSTORE2.json +2 -2
  100. package/artifacts/contracts/libs/v0.8.x/V3FlexLib.sol/V3FlexLib.json +208 -0
  101. package/artifacts/contracts/libs/v0.8.x/minter-libs/DAExpLib.sol/DAExpLib.json +60 -3
  102. package/artifacts/contracts/libs/v0.8.x/minter-libs/DALib.sol/DALib.json +30 -0
  103. package/artifacts/contracts/libs/v0.8.x/minter-libs/DALinLib.sol/DALinLib.json +60 -3
  104. package/artifacts/contracts/libs/v0.8.x/minter-libs/GenericMinterEventsLib.sol/GenericMinterEventsLib.json +346 -0
  105. package/artifacts/contracts/libs/v0.8.x/minter-libs/MaxInvocationsLib.sol/MaxInvocationsLib.json +29 -3
  106. package/artifacts/contracts/libs/v0.8.x/minter-libs/MerkleLib.sol/MerkleLib.json +30 -3
  107. package/artifacts/contracts/libs/v0.8.x/minter-libs/PolyptychLib.sol/PolyptychLib.json +2 -2
  108. package/artifacts/contracts/libs/v0.8.x/minter-libs/RAMLib.sol/RAMLib.json +398 -0
  109. package/artifacts/contracts/libs/v0.8.x/minter-libs/SEALib.sol/SEALib.json +254 -3
  110. package/artifacts/contracts/libs/v0.8.x/minter-libs/SetPriceLib.sol/SetPriceLib.json +48 -3
  111. package/artifacts/contracts/libs/v0.8.x/minter-libs/SettlementExpLib.sol/SettlementExpLib.json +41 -3
  112. package/artifacts/contracts/libs/v0.8.x/minter-libs/SplitFundsLib.sol/SplitFundsLib.json +35 -3
  113. package/artifacts/contracts/libs/v0.8.x/minter-libs/TokenHolderLib.sol/TokenHolderLib.json +79 -3
  114. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV1.sol/MinterFilterV1.json +2 -2
  115. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV2.sol/MinterFilterV2.json +41 -41
  116. package/artifacts/contracts/minter-suite/Minters/MinterDAExpHolderV5.sol/MinterDAExpHolderV5.json +66 -632
  117. package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV3.sol/MinterDAExpSettlementV3.json +67 -594
  118. package/artifacts/contracts/minter-suite/Minters/MinterDAExpV5.sol/MinterDAExpV5.json +33 -524
  119. package/artifacts/contracts/minter-suite/Minters/MinterDALinHolderV5.sol/MinterDALinHolderV5.json +66 -632
  120. package/artifacts/contracts/minter-suite/Minters/MinterDALinV5.sol/MinterDALinV5.json +33 -524
  121. package/artifacts/contracts/minter-suite/Minters/MinterRAMV0.sol/MinterRAMV0.json +1374 -0
  122. package/artifacts/contracts/minter-suite/Minters/MinterSEAV1.sol/MinterSEAV1.json +56 -722
  123. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20V5.sol/MinterSetPriceERC20V5.json +58 -454
  124. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceHolderV5.sol/MinterSetPriceHolderV5.json +61 -552
  125. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceMerkleV5.sol/MinterSetPriceMerkleV5.json +55 -497
  126. package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychERC20V5.sol/MinterSetPricePolyptychERC20V5.json +110 -571
  127. package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychV5.sol/MinterSetPricePolyptychV5.json +69 -560
  128. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceV5.sol/MinterSetPriceV5.json +28 -444
  129. package/artifacts/contracts/minter-suite/Minters/one-off/MinterSetPriceV5_SingleCore.sol/MinterSetPriceV5_SingleCore.json +417 -0
  130. package/artifacts/contracts/mock/BytecodeV2LibCallsMock.sol/BytecodeV2LibCallsMock.json +154 -0
  131. package/artifacts/contracts/mock/BytecodeV2TextCR_DMock.sol/BytecodeV2TextCR_DMock.json +428 -0
  132. package/artifacts/contracts/mock/DummySharedMinter.sol/DummySharedMinter.json +2 -2
  133. package/artifacts/contracts/mock/ERC20Mock.sol/ERC20Mock.json +2 -2
  134. package/artifacts/contracts/mock/ForceSendMock.sol/ForceSendMock.json +24 -0
  135. package/artifacts/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol/GenArt721CoreV3_Engine_IncorrectCoreType.json +4 -9
  136. package/artifacts/contracts/mock/Mock0xSplitsV2PullFactory.sol/Mock0xSplitsV2PullFactory.json +149 -0
  137. package/artifacts/contracts/mock/Mock0xSplitsV2Splitter.sol/Mock0xSplitsV2Splitter.json +99 -0
  138. package/artifacts/contracts/mock/MockAdminACLV0.sol/MockAdminACLV0Events.json +20 -2
  139. package/artifacts/contracts/mock/MockAdminACLV0_PROHIBITION.sol/MockAdminACLV0Events_PROHIBITION.json +20 -2
  140. package/artifacts/contracts/mock/OriginRegisterMock.sol/OriginRegisterMock.json +2 -2
  141. package/artifacts/contracts/mock/RandomizerV2_NoAssignMock.sol/RandomizerV2_NoAssignMock.json +2 -2
  142. package/artifacts/contracts/mock/ReentrancyGenArt721MinterMock.sol/ReentrancyGenArt721MinterMock.json +100 -0
  143. package/artifacts/contracts/mock/ReentrancyHolderMock.sol/ReentrancyHolderMock.json +2 -2
  144. package/artifacts/contracts/mock/ReentrancyHolderMockShared.sol/ReentrancyHolderMockShared.json +136 -0
  145. package/artifacts/contracts/mock/ReentrancyMerkleMock.sol/ReentrancyMerkleMock.json +2 -2
  146. package/artifacts/contracts/mock/ReentrancyMerkleMockShared.sol/ReentrancyMerkleMockShared.json +105 -0
  147. package/artifacts/contracts/mock/ReentrancyMock.sol/ReentrancyMock.json +2 -2
  148. package/artifacts/contracts/mock/ReentrancyMockShared.sol/ReentrancyMockShared.json +100 -0
  149. package/artifacts/contracts/mock/ReentrancySEAMock.sol/ReentrancySEAAutoBidderMock.json +2 -2
  150. package/artifacts/contracts/mock/ReentrancySEAMockShared.sol/ReentrancySEAAutoBidderMockShared.json +69 -0
  151. package/artifacts/contracts/mock/ReentrancySplitterMocks.sol/ReentrancySplitterDrainETHMock.json +54 -0
  152. package/artifacts/contracts/mock/ReentrancySplitterMocks.sol/ReentrancySplitterSendETHMock.json +54 -0
  153. package/artifacts/contracts/randomizer/deprecated/PolyptychRandomizerV0.sol/BasicPolyptychRandomizerV0.json +2 -2
  154. package/artifacts/contracts/randomizer/deprecated/RandomizerV2.sol/BasicRandomizerV2.json +2 -2
  155. package/artifacts/contracts/randomizer/primitive/PseudorandomAtomicBasic.sol/PseudorandomAtomic.json +2 -2
  156. package/artifacts/contracts/randomizer/shared/SharedRandomizerV0.sol/SharedRandomizerV0.json +19 -19
  157. package/artifacts/contracts/split/SplitAtomicFactoryV0.sol/SplitAtomicFactoryV0.json +203 -0
  158. package/artifacts/contracts/split/SplitAtomicV0.sol/SplitAtomicV0.json +168 -0
  159. package/artifacts/contracts/split/split-provider/SplitProviderV0.sol/SplitProviderV0.json +141 -0
  160. package/contracts/AdminACLV0.sol +6 -2
  161. package/contracts/AdminACLV1.sol +2 -2
  162. package/contracts/DependencyRegistryV0.sol +737 -390
  163. package/contracts/{GenArt721CoreV3.sol → archive/GenArt721CoreV3.sol} +56 -20
  164. package/contracts/{explorations → archive}/GenArt721CoreV3_Explorations.sol +49 -13
  165. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterBase_v0_1_1.sol +4 -4
  166. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDAExp}/MinterDAExpV4.sol +4 -4
  167. package/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol +4 -4
  168. package/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV1.sol +5 -5
  169. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDAExpSettlement}/MinterDAExpSettlementV2.sol +9 -62
  170. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDALin}/MinterDALinV4.sol +4 -4
  171. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterHolder}/MinterHolderV4.sol +5 -5
  172. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterMerkle}/MinterMerkleV5.sol +5 -5
  173. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterPolyptych}/MinterPolyptychV0.sol +7 -7
  174. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSEA}/MinterSEAV0.sol +13 -13
  175. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSetPrice}/MinterSetPriceV4.sol +4 -4
  176. package/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V0.sol +82 -10
  177. package/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V1.sol +82 -10
  178. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSetPriceERC20}/MinterSetPriceERC20V4.sol +88 -21
  179. package/contracts/engine/V2/GenArt721MinterBurner_PBAB.sol +81 -22
  180. package/contracts/engine/V2/GenArt721Minter_PBAB.sol +80 -22
  181. package/contracts/engine/V3/EngineFactoryV0.sol +419 -0
  182. package/contracts/engine/V3/GenArt721CoreV3_Engine.sol +893 -493
  183. package/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol +1053 -655
  184. package/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol +7 -13
  185. package/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol +5 -11
  186. package/contracts/engine/V3/forks/PROHIBITION/interfaces/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.sol +2 -2
  187. package/contracts/engine-registry/CoreRegistryV1.sol +58 -65
  188. package/contracts/interfaces/v0.8.x/IAdminACLV0_Extended.sol +20 -0
  189. package/contracts/interfaces/v0.8.x/IBytecodeStorageReaderV2.sol +23 -0
  190. package/contracts/interfaces/v0.8.x/ICoreRegistryV1.sol +6 -8
  191. package/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol +48 -43
  192. package/contracts/interfaces/v0.8.x/IEngineFactoryV0.sol +124 -0
  193. package/contracts/interfaces/v0.8.x/IFilteredMinterDAExpSettlementV0.sol +1 -3
  194. package/contracts/interfaces/v0.8.x/IFilteredMinterDAExpSettlementV1.sol +1 -3
  195. package/contracts/interfaces/v0.8.x/IFilteredMinterDAExpV1.sol +1 -3
  196. package/contracts/interfaces/v0.8.x/IFilteredMinterDALinV1.sol +1 -3
  197. package/contracts/interfaces/v0.8.x/IFilteredMinterHolderV2.sol +1 -3
  198. package/contracts/interfaces/v0.8.x/IFilteredMinterMerkleV2.sol +1 -3
  199. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Base.sol +115 -11
  200. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine.sol +84 -8
  201. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex.sol +26 -8
  202. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex_PreV3p2.sol +141 -0
  203. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_PreV3p2.sol +78 -0
  204. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_ProjectFinance.sol +47 -0
  205. package/contracts/interfaces/v0.8.x/IGenArt721Minter_PBAB.sol +91 -0
  206. package/contracts/interfaces/v0.8.x/IMinterFilterV1.sol +25 -25
  207. package/contracts/interfaces/v0.8.x/IPseudorandomAtomic.sol +1 -3
  208. package/contracts/interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol +30 -20
  209. package/contracts/interfaces/v0.8.x/ISharedMinterDAExpV0.sol +1 -14
  210. package/contracts/interfaces/v0.8.x/ISharedMinterDALinV0.sol +1 -15
  211. package/contracts/interfaces/v0.8.x/ISharedMinterDAV0.sol +2 -8
  212. package/contracts/interfaces/v0.8.x/ISharedMinterHolderERC20V0.sol +47 -0
  213. package/contracts/interfaces/v0.8.x/ISharedMinterHolderV0.sol +15 -43
  214. package/contracts/interfaces/v0.8.x/ISharedMinterMerkleV0.sol +10 -20
  215. package/contracts/interfaces/v0.8.x/ISharedMinterRAMV0.sol +23 -0
  216. package/contracts/interfaces/v0.8.x/ISharedMinterRequired.sol +20 -0
  217. package/contracts/interfaces/v0.8.x/ISharedMinterSEAV0.sol +1 -67
  218. package/contracts/interfaces/v0.8.x/ISharedMinterSimplePurchaseV0.sol +5 -5
  219. package/contracts/interfaces/v0.8.x/ISharedMinterV0.sol +18 -160
  220. package/contracts/interfaces/v0.8.x/ISharedRandomizerV0.sol +37 -37
  221. package/contracts/interfaces/v0.8.x/ISplitAtomicFactoryV0.sol +81 -0
  222. package/contracts/interfaces/v0.8.x/ISplitAtomicV0.sol +72 -0
  223. package/contracts/interfaces/v0.8.x/ISplitProviderV0.sol +49 -0
  224. package/contracts/interfaces/v0.8.x/integration-refs/splits-0x-v2/ISplitFactoryV2.sol +62 -0
  225. package/contracts/libs/v0.8.x/ABHelpers.sol +31 -17
  226. package/contracts/libs/v0.8.x/AuthLib.sol +101 -102
  227. package/contracts/libs/v0.8.x/BitMap.sol +112 -0
  228. package/contracts/libs/v0.8.x/BytecodeStorageV2.sol +593 -0
  229. package/contracts/libs/v0.8.x/Bytes32Strings.sol +5 -5
  230. package/contracts/libs/v0.8.x/DependencyRegistryStorageLib.sol +90 -0
  231. package/contracts/libs/v0.8.x/ERC721_PackedHashSeedV1.sol +591 -0
  232. package/contracts/libs/v0.8.x/PackedBools.sol +42 -0
  233. package/contracts/libs/v0.8.x/V3FlexLib.sol +591 -0
  234. package/contracts/libs/v0.8.x/minter-libs/DAExpLib.sol +162 -39
  235. package/contracts/libs/v0.8.x/minter-libs/DALib.sol +26 -0
  236. package/contracts/libs/v0.8.x/minter-libs/DALinLib.sol +139 -37
  237. package/contracts/libs/v0.8.x/minter-libs/GenericMinterEventsLib.sol +171 -0
  238. package/contracts/libs/v0.8.x/minter-libs/MaxInvocationsLib.sol +299 -158
  239. package/contracts/libs/v0.8.x/minter-libs/MerkleLib.sol +268 -55
  240. package/contracts/libs/v0.8.x/minter-libs/PolyptychLib.sol +138 -58
  241. package/contracts/libs/v0.8.x/minter-libs/RAMLib.sol +2927 -0
  242. package/contracts/libs/v0.8.x/minter-libs/SEALib.sol +796 -123
  243. package/contracts/libs/v0.8.x/minter-libs/SetPriceLib.sol +131 -13
  244. package/contracts/libs/v0.8.x/minter-libs/SettlementExpLib.sol +607 -224
  245. package/contracts/libs/v0.8.x/minter-libs/SplitFundsLib.sol +494 -330
  246. package/contracts/libs/v0.8.x/minter-libs/TokenHolderLib.sol +217 -78
  247. package/contracts/minter-suite/MinterFilter/MinterFilterV2.sol +358 -309
  248. package/contracts/minter-suite/Minters/MinterDAExpHolderV5.sol +391 -491
  249. package/contracts/minter-suite/Minters/MinterDAExpSettlementV3.sol +396 -632
  250. package/contracts/minter-suite/Minters/MinterDAExpV5.sol +212 -273
  251. package/contracts/minter-suite/Minters/MinterDALinHolderV5.sol +393 -488
  252. package/contracts/minter-suite/Minters/MinterDALinV5.sol +220 -277
  253. package/contracts/minter-suite/Minters/MinterRAMV0.sol +1205 -0
  254. package/contracts/minter-suite/Minters/MinterSEAV1.sol +329 -677
  255. package/contracts/minter-suite/Minters/MinterSetPriceERC20V5.sol +287 -303
  256. package/contracts/minter-suite/Minters/MinterSetPriceHolderV5.sol +355 -446
  257. package/contracts/minter-suite/Minters/MinterSetPriceMerkleV5.sol +328 -416
  258. package/contracts/minter-suite/Minters/MinterSetPricePolyptychERC20V5.sol +552 -622
  259. package/contracts/minter-suite/Minters/MinterSetPricePolyptychV5.sol +429 -553
  260. package/contracts/minter-suite/Minters/MinterSetPriceV5.sol +180 -227
  261. package/contracts/minter-suite/Minters/one-off/MinterSetPriceV5_SingleCore.sol +446 -0
  262. package/contracts/mock/BytecodeV2LibCallsMock.sol +128 -0
  263. package/contracts/mock/BytecodeV2TextCR_DMock.sol +316 -0
  264. package/contracts/mock/ForceSendMock.sol +22 -0
  265. package/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol +3 -10
  266. package/contracts/mock/Mock0xSplitsV2PullFactory.sol +75 -0
  267. package/contracts/mock/Mock0xSplitsV2Splitter.sol +47 -0
  268. package/contracts/mock/MockAdminACLV0.sol +21 -0
  269. package/contracts/mock/MockAdminACLV0_PROHIBITION.sol +21 -0
  270. package/contracts/mock/ReentrancyGenArt721MinterMock.sol +47 -0
  271. package/contracts/mock/ReentrancyHolderMockShared.sol +59 -0
  272. package/contracts/mock/ReentrancyMerkleMockShared.sol +58 -0
  273. package/contracts/mock/ReentrancyMockShared.sol +48 -0
  274. package/contracts/mock/ReentrancySEAMockShared.sol +40 -0
  275. package/contracts/mock/ReentrancySplitterMocks.sol +67 -0
  276. package/contracts/randomizer/primitive/PseudorandomAtomicBasic.sol +1 -1
  277. package/contracts/randomizer/shared/SharedRandomizerV0.sol +79 -71
  278. package/contracts/split/SplitAtomicFactoryV0.sol +121 -0
  279. package/contracts/split/SplitAtomicV0.sol +265 -0
  280. package/contracts/split/split-provider/SplitProviderV0.sol +201 -0
  281. package/package.json +79 -45
  282. package/artifacts/contracts/GenArt721CoreV3.sol/GenArt721CoreV3.json +0 -1965
  283. package/artifacts/contracts/explorations/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +0 -1939
  284. package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV2.sol/MinterDAExpSettlementV2.json +0 -1127
  285. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20V4.sol/MinterSetPriceERC20V4.json +0 -768
  286. package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverride.sol/GenArt721RoyaltyOverride.json +0 -208
  287. package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverride_PBAB.sol/GenArt721RoyaltyOverride_PBAB.json +0 -301
  288. package/contracts/royalty-registry/GenArt721RoyaltyOverride.sol +0 -168
  289. package/contracts/royalty-registry/GenArt721RoyaltyOverride_PBAB.sol +0 -221
@@ -1,14 +1,14 @@
1
1
  // SPDX-License-Identifier: LGPL-3.0-only
2
2
  // Created By: Art Blocks Inc.
3
3
 
4
- import "../../../interfaces/v0.8.x/IMinterBaseV0.sol";
5
- import "../../../interfaces/v0.8.x/IGenArt721CoreContractV3_Base.sol";
6
- import "../../../interfaces/v0.8.x/IGenArt721CoreContractV3.sol";
7
- import "../../../interfaces/v0.8.x/IGenArt721CoreContractV3_Engine.sol";
4
+ pragma solidity ^0.8.0;
8
5
 
9
- import "@openzeppelin-4.7/contracts/token/ERC20/IERC20.sol";
6
+ import {IMinterBaseV0} from "../../../interfaces/v0.8.x/IMinterBaseV0.sol";
7
+ import {IGenArt721CoreContractV3_Base} from "../../../interfaces/v0.8.x/IGenArt721CoreContractV3_Base.sol";
8
+ import {IGenArt721CoreContractV3} from "../../../interfaces/v0.8.x/IGenArt721CoreContractV3.sol";
9
+ import {IGenArt721CoreContractV3_Engine} from "../../../interfaces/v0.8.x/IGenArt721CoreContractV3_Engine.sol";
10
10
 
11
- pragma solidity ^0.8.0;
11
+ import {IERC20} from "@openzeppelin-4.7/contracts/token/ERC20/IERC20.sol";
12
12
 
13
13
  /**
14
14
  * @title Art Blocks Split Funds Library
@@ -20,6 +20,26 @@ pragma solidity ^0.8.0;
20
20
  */
21
21
 
22
22
  library SplitFundsLib {
23
+ /**
24
+ * @notice Currency updated for project `projectId` to symbol
25
+ * `currencySymbol` and address `currencyAddress`.
26
+ * @param projectId Project ID currency was updated for
27
+ * @param coreContract Core contract address currency was updated for
28
+ * @param currencyAddress Currency address
29
+ * @param currencySymbol Currency symbol
30
+ */
31
+ event ProjectCurrencyInfoUpdated(
32
+ uint256 indexed projectId,
33
+ address indexed coreContract,
34
+ address indexed currencyAddress,
35
+ string currencySymbol
36
+ );
37
+
38
+ // position of Split Funds Lib storage, using a diamond storage pattern
39
+ // for this library
40
+ bytes32 constant SPLIT_FUNDS_LIB_STORAGE_POSITION =
41
+ keccak256("splitfundslib.storage");
42
+
23
43
  // contract-level variables
24
44
  struct IsEngineCache {
25
45
  bool isEngine;
@@ -32,10 +52,16 @@ library SplitFundsLib {
32
52
  string currencySymbol; // Assumed to be ETH if null
33
53
  }
34
54
 
55
+ // Diamond storage pattern is used in this library
56
+ struct SplitFundsLibStorage {
57
+ mapping(address coreContract => mapping(uint256 projectId => SplitFundsProjectConfig)) splitFundsProjectConfigs;
58
+ mapping(address coreContract => IsEngineCache) isEngineCacheConfigs;
59
+ }
60
+
35
61
  /**
36
62
  * @notice splits ETH funds between sender (if refund), providers,
37
63
  * artist, and artist's additional payee for a token purchased on
38
- * project `_projectId`.
64
+ * project `projectId`.
39
65
  * WARNING: This function uses msg.value and msg.sender to determine
40
66
  * refund amounts, and therefore may not be applicable to all use cases
41
67
  * (e.g. do not use with Dutch Auctions with on-chain settlement).
@@ -44,269 +70,281 @@ library SplitFundsLib {
44
70
  * @dev possible DoS during splits is acknowledged, and mitigated by
45
71
  * business practices, including end-to-end testing on mainnet, and
46
72
  * admin-accepted artist payment addresses.
47
- * @param _projectId Project ID for which funds shall be split.
48
- * @param _pricePerTokenInWei Current price of token, in Wei.
49
- * @param _coreContract Address of the GenArt721CoreContract associated
73
+ * @param projectId Project ID for which funds shall be split.
74
+ * @param pricePerTokenInWei Current price of token, in Wei.
75
+ * @param coreContract Address of the GenArt721CoreContract associated
50
76
  * with the project.
51
- * @param _isEngine Whether the core contract is an engine contract.
52
77
  */
53
- function splitFundsETH(
54
- uint256 _projectId,
55
- uint256 _pricePerTokenInWei,
56
- address _coreContract,
57
- bool _isEngine
78
+ function splitFundsETHRefundSender(
79
+ uint256 projectId,
80
+ uint256 pricePerTokenInWei,
81
+ address coreContract
58
82
  ) internal {
59
83
  if (msg.value > 0) {
60
- bool success_;
61
84
  // send refund to sender
62
- uint256 refund = msg.value - _pricePerTokenInWei;
85
+ uint256 refund = msg.value - pricePerTokenInWei;
63
86
  if (refund > 0) {
64
- (success_, ) = msg.sender.call{value: refund}("");
87
+ (bool success_, ) = msg.sender.call{value: refund}("");
65
88
  require(success_, "Refund failed");
66
89
  }
67
90
  // split revenues
68
- splitRevenuesETH(
69
- _projectId,
70
- _pricePerTokenInWei,
71
- _coreContract,
72
- _isEngine
73
- );
91
+ splitRevenuesETHNoRefund({
92
+ projectId: projectId,
93
+ valueInWei: pricePerTokenInWei,
94
+ coreContract: coreContract
95
+ });
74
96
  }
75
97
  }
76
98
 
77
99
  /**
78
100
  * @notice Splits ETH revenues between providers, artist, and artist's
79
- * additional payee for revenue generated by project `_projectId`.
101
+ * additional payee for revenue generated by project `projectId`.
102
+ * This function does NOT refund msg.sender, and does NOT use msg.value
103
+ * when determining the value to be split.
80
104
  * @dev possible DoS during splits is acknowledged, and mitigated by
81
105
  * business practices, including end-to-end testing on mainnet, and
82
106
  * admin-accepted artist payment addresses.
83
- * @param _projectId Project ID for which funds shall be split.
84
- * @param _valueInWei Value to be split, in Wei.
85
- * @param _coreContract Address of the GenArt721CoreContract
107
+ * @param projectId Project ID for which funds shall be split.
108
+ * @param valueInWei Value to be split, in Wei.
109
+ * @param coreContract Address of the GenArt721CoreContract
86
110
  * associated with the project.
87
- * @param _isEngine Whether the core contract is an engine contract.
88
111
  */
89
- function splitRevenuesETH(
90
- uint256 _projectId,
91
- uint256 _valueInWei,
92
- address _coreContract,
93
- bool _isEngine
112
+ function splitRevenuesETHNoRefund(
113
+ uint256 projectId,
114
+ uint256 valueInWei,
115
+ address coreContract
94
116
  ) internal {
95
- if (_valueInWei == 0) {
117
+ if (valueInWei == 0) {
96
118
  return; // return early
97
119
  }
98
- bool success;
99
120
  // split funds between platforms, artist, and artist's
100
121
  // additional payee
101
- uint256 renderProviderRevenue_;
102
- address payable renderProviderAddress_;
103
- uint256 artistRevenue_;
104
- address payable artistAddress_;
105
- uint256 additionalPayeePrimaryRevenue_;
106
- address payable additionalPayeePrimaryAddress_;
107
-
108
- if (_isEngine) {
122
+ bool isEngine_ = isEngine(coreContract);
123
+ uint256 renderProviderRevenue;
124
+ address payable renderProviderAddress;
125
+ uint256 platformProviderRevenue;
126
+ address payable platformProviderAddress;
127
+ uint256 artistRevenue;
128
+ address payable artistAddress;
129
+ uint256 additionalPayeePrimaryRevenue;
130
+ address payable additionalPayeePrimaryAddress;
131
+ if (isEngine_) {
109
132
  // get engine splits
110
- uint256 platformProviderRevenue_;
111
- address payable platformProviderAddress_;
112
133
  (
113
- renderProviderRevenue_,
114
- renderProviderAddress_,
115
- platformProviderRevenue_,
116
- platformProviderAddress_,
117
- artistRevenue_,
118
- artistAddress_,
119
- additionalPayeePrimaryRevenue_,
120
- additionalPayeePrimaryAddress_
121
- ) = IGenArt721CoreContractV3_Engine(_coreContract)
122
- .getPrimaryRevenueSplits(_projectId, _valueInWei);
123
- // Platform Provider payment (only possible if engine)
124
- if (platformProviderRevenue_ > 0) {
125
- (success, ) = platformProviderAddress_.call{
126
- value: platformProviderRevenue_
127
- }("");
128
- require(success, "Platform Provider payment failed");
129
- }
134
+ renderProviderRevenue,
135
+ renderProviderAddress,
136
+ platformProviderRevenue,
137
+ platformProviderAddress,
138
+ artistRevenue,
139
+ artistAddress,
140
+ additionalPayeePrimaryRevenue,
141
+ additionalPayeePrimaryAddress
142
+ ) = IGenArt721CoreContractV3_Engine(coreContract)
143
+ .getPrimaryRevenueSplits({
144
+ _projectId: projectId,
145
+ _price: valueInWei
146
+ });
130
147
  } else {
131
148
  // get flagship splits
149
+ // @dev note that platformProviderAddress and
150
+ // platformProviderRevenue remain 0 for flagship
132
151
  (
133
- renderProviderRevenue_, // artblocks revenue
134
- renderProviderAddress_, // artblocks address
135
- artistRevenue_,
136
- artistAddress_,
137
- additionalPayeePrimaryRevenue_,
138
- additionalPayeePrimaryAddress_
139
- ) = IGenArt721CoreContractV3(_coreContract).getPrimaryRevenueSplits(
140
- _projectId,
141
- _valueInWei
142
- );
143
- }
144
- // Render Provider / Art Blocks payment
145
- if (renderProviderRevenue_ > 0) {
146
- (success, ) = renderProviderAddress_.call{
147
- value: renderProviderRevenue_
148
- }("");
149
- require(success, "Render Provider payment failed");
150
- }
151
- // artist payment
152
- if (artistRevenue_ > 0) {
153
- (success, ) = artistAddress_.call{value: artistRevenue_}("");
154
- require(success, "Artist payment failed");
155
- }
156
- // additional payee payment
157
- if (additionalPayeePrimaryRevenue_ > 0) {
158
- (success, ) = additionalPayeePrimaryAddress_.call{
159
- value: additionalPayeePrimaryRevenue_
160
- }("");
161
- require(success, "Additional Payee payment failed");
152
+ renderProviderRevenue, // artblocks revenue
153
+ renderProviderAddress, // artblocks address
154
+ artistRevenue,
155
+ artistAddress,
156
+ additionalPayeePrimaryRevenue,
157
+ additionalPayeePrimaryAddress
158
+ ) = IGenArt721CoreContractV3(coreContract).getPrimaryRevenueSplits({
159
+ _projectId: projectId,
160
+ _price: valueInWei
161
+ });
162
162
  }
163
+ // require total revenue split is 100%
164
+ // @dev note that platformProviderRevenue remains 0 for flagship
165
+ require(
166
+ renderProviderRevenue +
167
+ platformProviderRevenue +
168
+ artistRevenue +
169
+ additionalPayeePrimaryRevenue ==
170
+ valueInWei,
171
+ "Invalid revenue split totals"
172
+ );
173
+ // distribute revenues
174
+ // @dev note that platformProviderAddress and platformProviderRevenue
175
+ // remain 0 for flagship
176
+ _sendPaymentsETH({
177
+ platformProviderRevenue: platformProviderRevenue,
178
+ platformProviderAddress: platformProviderAddress,
179
+ renderProviderRevenue: renderProviderRevenue,
180
+ renderProviderAddress: renderProviderAddress,
181
+ artistRevenue: artistRevenue,
182
+ artistAddress: artistAddress,
183
+ additionalPayeePrimaryRevenue: additionalPayeePrimaryRevenue,
184
+ additionalPayeePrimaryAddress: additionalPayeePrimaryAddress
185
+ });
163
186
  }
164
187
 
165
188
  /**
166
189
  * @notice Splits ERC20 funds between providers, artist, and artist's
167
- * additional payee, for a token purchased on project `_projectId`.
190
+ * additional payee, for a token purchased on project `projectId`.
168
191
  * The function performs checks to ensure that the ERC20 token is
169
192
  * approved for transfer, and that a non-zero ERC20 token address is
170
193
  * configured.
171
- * @dev This function relies on msg.sender and msg.value, so it must be
194
+ * @dev This function relies on msg.sender, so it must be
172
195
  * called directly from the contract that is receiving the payment.
173
196
  * @dev possible DoS during splits is acknowledged, and mitigated by
174
197
  * business practices, including end-to-end testing on mainnet, and
175
198
  * admin-accepted artist payment addresses.
176
- * @param _splitFundsProjectConfig SplitFundsProjectConfig of the project.
177
- * @param _projectId Project ID for which funds shall be split.
178
- * @param _pricePerTokenInWei Current price of token, in Wei.
179
- * @param _coreContract Core contract address.
180
- * @param _isEngine Whether the core contract is an engine contract.
199
+ * @param projectId Project ID for which funds shall be split.
200
+ * @param pricePerToken Current price of token, in base units. For example,
201
+ * if the ERC20 token has 6 decimals, an input value of `1_000_000` would
202
+ * represent a price of `1.000000` tokens.
203
+ * @param coreContract Core contract address.
181
204
  */
182
205
  function splitFundsERC20(
183
- SplitFundsProjectConfig storage _splitFundsProjectConfig,
184
- uint256 _projectId,
185
- uint256 _pricePerTokenInWei,
186
- address _coreContract,
187
- bool _isEngine
206
+ uint256 projectId,
207
+ uint256 pricePerToken,
208
+ address coreContract
188
209
  ) internal {
189
- if (_pricePerTokenInWei == 0) {
210
+ if (pricePerToken == 0) {
190
211
  return; // nothing to split, return early
191
212
  }
192
- address currencyAddress = _splitFundsProjectConfig.currencyAddress;
193
- require(currencyAddress != address(0), "ERC20: payment not configured");
194
- require(msg.value == 0, "ERC20: No ETH when using ERC20");
195
- // ERC20 token is used for payment
196
- validateERC20Approvals({
197
- _msgSender: msg.sender,
198
- _currencyAddress: currencyAddress,
199
- _pricePerTokenInWei: _pricePerTokenInWei
200
- });
201
- IERC20 _projectCurrency = IERC20(currencyAddress);
202
- // split remaining funds between foundation, artist, and artist's
203
- // additional payee
204
- uint256 renderProviderRevenue_;
205
- address payable renderProviderAddress_;
206
- uint256 artistRevenue_;
207
- address payable artistAddress_;
208
- uint256 additionalPayeePrimaryRevenue_;
209
- address payable additionalPayeePrimaryAddress_;
210
-
211
- if (_isEngine) {
213
+ IERC20 projectCurrency;
214
+ // block scope to avoid stack too deep error
215
+ {
216
+ SplitFundsProjectConfig
217
+ storage splitFundsProjectConfig = getSplitFundsProjectConfig({
218
+ projectId: projectId,
219
+ coreContract: coreContract
220
+ });
221
+ address currencyAddress = splitFundsProjectConfig.currencyAddress;
222
+ require(
223
+ currencyAddress != address(0),
224
+ "ERC20: payment not configured"
225
+ );
226
+ // ERC20 token is used for payment
227
+ validateERC20Approvals({
228
+ msgSender: msg.sender,
229
+ currencyAddress: currencyAddress,
230
+ pricePerToken: pricePerToken
231
+ });
232
+ projectCurrency = IERC20(currencyAddress);
233
+ }
234
+ // split remaining funds between foundation, artist, and artist's additional payee
235
+ bool isEngine_ = isEngine(coreContract);
236
+ uint256 renderProviderRevenue;
237
+ address payable renderProviderAddress;
238
+ uint256 platformProviderRevenue;
239
+ address payable platformProviderAddress;
240
+ uint256 artistRevenue;
241
+ address payable artistAddress;
242
+ uint256 additionalPayeePrimaryRevenue;
243
+ address payable additionalPayeePrimaryAddress;
244
+ if (isEngine_) {
212
245
  // get engine splits
213
- uint256 platformProviderRevenue_;
214
- address payable platformProviderAddress_;
215
246
  (
216
- renderProviderRevenue_,
217
- renderProviderAddress_,
218
- platformProviderRevenue_,
219
- platformProviderAddress_,
220
- artistRevenue_,
221
- artistAddress_,
222
- additionalPayeePrimaryRevenue_,
223
- additionalPayeePrimaryAddress_
224
- ) = IGenArt721CoreContractV3_Engine(_coreContract)
225
- .getPrimaryRevenueSplits(_projectId, _pricePerTokenInWei);
226
- // Platform Provider payment (only possible if engine)
227
- if (platformProviderRevenue_ > 0) {
228
- require(
229
- _projectCurrency.transferFrom(
230
- msg.sender,
231
- platformProviderAddress_,
232
- platformProviderRevenue_
233
- ),
234
- "Platform Provider payment failed"
235
- );
236
- }
247
+ renderProviderRevenue,
248
+ renderProviderAddress,
249
+ platformProviderRevenue,
250
+ platformProviderAddress,
251
+ artistRevenue,
252
+ artistAddress,
253
+ additionalPayeePrimaryRevenue,
254
+ additionalPayeePrimaryAddress
255
+ ) = IGenArt721CoreContractV3_Engine(coreContract)
256
+ .getPrimaryRevenueSplits({
257
+ _projectId: projectId,
258
+ _price: pricePerToken
259
+ });
237
260
  } else {
238
261
  // get flagship splits
262
+ // @dev note that platformProviderAddress and
263
+ // platformProviderRevenue remain 0 for flagship
239
264
  (
240
- renderProviderRevenue_, // artblocks revenue
241
- renderProviderAddress_, // artblocks address
242
- artistRevenue_,
243
- artistAddress_,
244
- additionalPayeePrimaryRevenue_,
245
- additionalPayeePrimaryAddress_
246
- ) = IGenArt721CoreContractV3(_coreContract).getPrimaryRevenueSplits(
247
- _projectId,
248
- _pricePerTokenInWei
249
- );
250
- }
251
- // Art Blocks payment
252
- if (renderProviderRevenue_ > 0) {
253
- require(
254
- _projectCurrency.transferFrom(
255
- msg.sender,
256
- renderProviderAddress_,
257
- renderProviderRevenue_
258
- ),
259
- "Render Provider payment failed"
260
- );
261
- }
262
- // artist payment
263
- if (artistRevenue_ > 0) {
264
- require(
265
- _projectCurrency.transferFrom(
266
- msg.sender,
267
- artistAddress_,
268
- artistRevenue_
269
- ),
270
- "Artist payment failed"
271
- );
272
- }
273
- // additional payee payment
274
- if (additionalPayeePrimaryRevenue_ > 0) {
275
- // @dev some ERC20 may not revert on transfer failure, so we
276
- // check the return value
277
- require(
278
- _projectCurrency.transferFrom(
279
- msg.sender,
280
- additionalPayeePrimaryAddress_,
281
- additionalPayeePrimaryRevenue_
282
- ),
283
- "Additional Payee payment failed"
284
- );
265
+ renderProviderRevenue, // artblocks revenue
266
+ renderProviderAddress, // artblocks address
267
+ artistRevenue,
268
+ artistAddress,
269
+ additionalPayeePrimaryRevenue,
270
+ additionalPayeePrimaryAddress
271
+ ) = IGenArt721CoreContractV3(coreContract).getPrimaryRevenueSplits({
272
+ _projectId: projectId,
273
+ _price: pricePerToken
274
+ });
285
275
  }
276
+ // require total revenue split is 100%
277
+ // @dev note that platformProviderRevenue remains 0 for flagship
278
+ require(
279
+ renderProviderRevenue +
280
+ platformProviderRevenue +
281
+ artistRevenue +
282
+ additionalPayeePrimaryRevenue ==
283
+ pricePerToken,
284
+ "Invalid revenue split totals"
285
+ );
286
+ // distribute revenues
287
+ // @dev note that platformProviderAddress and platformProviderRevenue
288
+ // remain 0 for flagship
289
+ _sendPaymentsERC20({
290
+ projectCurrency: projectCurrency,
291
+ platformProviderRevenue: platformProviderRevenue,
292
+ platformProviderAddress: platformProviderAddress,
293
+ renderProviderRevenue: renderProviderRevenue,
294
+ renderProviderAddress: renderProviderAddress,
295
+ artistRevenue: artistRevenue,
296
+ artistAddress: artistAddress,
297
+ additionalPayeePrimaryRevenue: additionalPayeePrimaryRevenue,
298
+ additionalPayeePrimaryAddress: additionalPayeePrimaryAddress
299
+ });
286
300
  }
287
301
 
288
302
  /**
289
303
  * @notice Updates payment currency of the referenced
290
- * SplitFundsProjectConfig to be `_currencySymbol` at address
291
- * `_currencyAddress`.
304
+ * SplitFundsProjectConfig to be `currencySymbol` at address
305
+ * `currencyAddress`.
292
306
  * Only supports setting currency info of ERC20 tokens.
307
+ * Returns bool that is true if the price should be reset after this
308
+ * update. Price is recommended to be reset if the currency address was
309
+ * previously configured, but is now being updated to a different currency
310
+ * address. This is to protect accidental price reductions when changing
311
+ * currency if an artist is changing currencies in an unpaused state.
293
312
  * @dev artist-defined currency symbol is used instead of any on-chain
294
313
  * currency symbol.
295
- * @param _splitFundsProjectConfig SplitFundsProjectConfig to update.
296
- * @param _currencySymbol Currency symbol.
297
- * @param _currencyAddress Currency address.
314
+ * @param projectId Project ID to update.
315
+ * @param coreContract Core contract address.
316
+ * @param currencySymbol Currency symbol.
317
+ * @param currencyAddress Currency address.
318
+ * @return recommendPriceReset True if the price should be reset after this
319
+ * update.
298
320
  */
299
321
  function updateProjectCurrencyInfoERC20(
300
- SplitFundsProjectConfig storage _splitFundsProjectConfig,
301
- string memory _currencySymbol,
302
- address _currencyAddress
303
- ) internal {
322
+ uint256 projectId,
323
+ address coreContract,
324
+ string memory currencySymbol,
325
+ address currencyAddress
326
+ ) internal returns (bool recommendPriceReset) {
304
327
  // CHECKS
305
- require(_currencyAddress != address(0), "null address, only ERC20");
306
- require(bytes(_currencySymbol).length > 0, "only non-null symbol");
328
+ require(currencyAddress != address(0), "null address, only ERC20");
329
+ require(bytes(currencySymbol).length > 0, "only non-null symbol");
307
330
  // EFFECTS
308
- _splitFundsProjectConfig.currencySymbol = _currencySymbol;
309
- _splitFundsProjectConfig.currencyAddress = _currencyAddress;
331
+ SplitFundsProjectConfig
332
+ storage splitFundsProjectConfig = getSplitFundsProjectConfig({
333
+ projectId: projectId,
334
+ coreContract: coreContract
335
+ });
336
+ // recommend price reset if currency address was previously configured
337
+ recommendPriceReset = (splitFundsProjectConfig.currencyAddress !=
338
+ address(0));
339
+ splitFundsProjectConfig.currencySymbol = currencySymbol;
340
+ splitFundsProjectConfig.currencyAddress = currencyAddress;
341
+
342
+ emit ProjectCurrencyInfoUpdated({
343
+ projectId: projectId,
344
+ coreContract: coreContract,
345
+ currencyAddress: currencyAddress,
346
+ currencySymbol: currencySymbol
347
+ });
310
348
  }
311
349
 
312
350
  /**
@@ -316,8 +354,10 @@ library SplitFundsLib {
316
354
  * creating a temporary contract which uses `SELFDESTRUCT` to force send
317
355
  * the ETH.
318
356
  * Reverts if the current contract has insufficient balance.
319
- * @param _to The address to send ETH to.
320
- * @param _amount The amount of ETH to send.
357
+ * @param to The address to send ETH to.
358
+ * @param amount The amount of ETH to send.
359
+ * @param minterRefundGasLimit The gas limit to use when sending ETH, prior
360
+ * to fallback.
321
361
  * @dev This function is adapted from the `forceSafeTransferETH` function
322
362
  * in the `https://github.com/Vectorized/solady` repository, with
323
363
  * modifications to not check if the current contract has sufficient
@@ -326,9 +366,9 @@ library SplitFundsLib {
326
366
  * applicable.
327
367
  */
328
368
  function forceSafeTransferETH(
329
- address _to,
330
- uint256 _amount,
331
- uint256 _minterRefundGasLimit
369
+ address to,
370
+ uint256 amount,
371
+ uint256 minterRefundGasLimit
332
372
  ) internal {
333
373
  // Manually inlined because the compiler doesn't inline functions with
334
374
  // branches.
@@ -338,7 +378,7 @@ library SplitFundsLib {
338
378
  // balance, because that is not intended to be a valid state.
339
379
 
340
380
  // Transfer the ETH and check if it succeeded or not.
341
- if iszero(call(_minterRefundGasLimit, _to, _amount, 0, 0, 0, 0)) {
381
+ if iszero(call(minterRefundGasLimit, to, amount, 0, 0, 0, 0)) {
342
382
  // if the transfer failed, we create a temporary contract with
343
383
  // initialization code that uses `SELFDESTRUCT` to force send
344
384
  // the ETH.
@@ -356,14 +396,14 @@ library SplitFundsLib {
356
396
  //---------------------------------------------------------------------------------------------------------------//
357
397
  // Store the address in scratch space, starting at 0x00, which begins the 20-byte address at 32-20=12 in memory
358
398
  // @dev use scratch space because we have enough space for simple creation code (less than 0x40 bytes)
359
- mstore(0x00, _to)
399
+ mstore(0x00, to)
360
400
  // store opcode PUSH20 immediately before the address, starting at 0x0b (11) in memory
361
401
  mstore8(0x0b, 0x73)
362
402
  // store opcode SELFDESTRUCT immediately after the address, starting at 0x20 (32) in memory
363
403
  mstore8(0x20, 0xff)
364
404
  // this will always succeed because the contract creation code is
365
405
  // valid, and the address is valid because it is a 20-byte value
366
- if iszero(create(_amount, 0x0b, 0x16)) {
406
+ if iszero(create(amount, 0x0b, 0x16)) {
367
407
  // @dev For better gas estimation.
368
408
  if iszero(gt(gas(), 1000000)) {
369
409
  revert(0, 0)
@@ -374,22 +414,23 @@ library SplitFundsLib {
374
414
  }
375
415
 
376
416
  /**
377
- * @notice Returns whether or not the provided address `_coreContract`
417
+ * @notice Returns whether or not the provided address `coreContract`
378
418
  * is an Art Blocks Engine core contract. Caches the result for future access.
379
- * @param _coreContract Address of the core contract to check.
380
- * @param _isEngineCache The storage pointer to the project's
381
- * SplitFundsProjectConfig struct.
419
+ * @param coreContract Address of the core contract to check.
382
420
  */
383
- function isEngine(
384
- address _coreContract,
385
- IsEngineCache storage _isEngineCache
386
- ) internal returns (bool) {
387
- if (_isEngineCache.isCached) {
388
- return _isEngineCache.isEngine;
389
- } else {
390
- bool _isEngine = getV3CoreIsEngine(_coreContract, _isEngineCache);
391
- return _isEngine;
421
+ function isEngine(address coreContract) internal returns (bool) {
422
+ IsEngineCache storage isEngineCache = getIsEngineCacheConfig(
423
+ coreContract
424
+ );
425
+ // check cache, return early if cached
426
+ if (isEngineCache.isCached) {
427
+ return isEngineCache.isEngine;
392
428
  }
429
+ // populate cache and return result
430
+ bool isEngine_ = getV3CoreIsEngineView(coreContract);
431
+ isEngineCache.isCached = true;
432
+ isEngineCache.isEngine = isEngine_;
433
+ return isEngine_;
393
434
  }
394
435
 
395
436
  /**
@@ -402,10 +443,10 @@ library SplitFundsLib {
402
443
  * either a flagship or engine core contract.
403
444
  * @dev this function uses the length of the return data (in bytes) to
404
445
  * determine whether the core is an engine or not.
405
- * @param _coreContract The address of the deployed core contract.
446
+ * @param coreContract The address of the deployed core contract.
406
447
  */
407
448
  function getV3CoreIsEngineView(
408
- address _coreContract
449
+ address coreContract
409
450
  ) internal view returns (bool) {
410
451
  // call getPrimaryRevenueSplits() on core contract
411
452
  bytes memory payload = abi.encodeWithSignature(
@@ -413,7 +454,7 @@ library SplitFundsLib {
413
454
  0,
414
455
  0
415
456
  );
416
- (bool success, bytes memory returnData) = _coreContract.staticcall(
457
+ (bool success, bytes memory returnData) = coreContract.staticcall(
417
458
  payload
418
459
  );
419
460
  require(success, "getPrimaryRevenueSplits() call failed");
@@ -437,147 +478,270 @@ library SplitFundsLib {
437
478
  // also note that per Solidity ABI encoding, the address return
438
479
  // values are padded to 32 bytes.
439
480
  return true;
440
- } else {
441
- // unexpected return value length
442
- revert("Unexpected revenue split bytes");
443
481
  }
482
+ // unexpected return value length
483
+ revert("Unexpected revenue split bytes");
444
484
  }
445
485
 
446
486
  /**
447
- * Gets the currency address and symbol for the referenced
487
+ * @notice Gets the currency address and symbol for the referenced
448
488
  * SplitFundsProjectConfig.
449
489
  * Only supports ERC20 tokens - returns currencySymbol of `UNCONFIG` if
450
490
  * `currencyAddress` is zero.
451
- * @param _splitFundsProjectConfig SplitFundsProjectConfig to read
452
- * @return currencyAddress
453
- * @return currencySymbol
491
+ * @param projectId Project ID to get config for
492
+ * @param coreContract Core contract address to get config for
493
+ * @return currencyAddress currency address for the referenced SplitFundsProjectConfig.
494
+ * @return currencySymbol currency symbol for the referenced SplitFundsProjectConfig.
454
495
  */
455
496
  function getCurrencyInfoERC20(
456
- SplitFundsProjectConfig storage _splitFundsProjectConfig
497
+ uint256 projectId,
498
+ address coreContract
457
499
  )
458
500
  internal
459
501
  view
460
502
  returns (address currencyAddress, string memory currencySymbol)
461
503
  {
462
- currencyAddress = _splitFundsProjectConfig.currencyAddress;
504
+ SplitFundsProjectConfig
505
+ storage splitFundsProjectConfig = getSplitFundsProjectConfig({
506
+ projectId: projectId,
507
+ coreContract: coreContract
508
+ });
509
+ currencyAddress = splitFundsProjectConfig.currencyAddress;
463
510
  // default to "UNCONFIG" if project currency address is initial value
464
511
  currencySymbol = currencyAddress == address(0)
465
512
  ? "UNCONFIG"
466
- : _splitFundsProjectConfig.currencySymbol;
513
+ : splitFundsProjectConfig.currencySymbol;
467
514
  }
468
515
 
469
516
  /**
470
- * Get the balance of `_currencyAddress` ERC20 tokens for `_walletAddress`.
471
- * @param _currencyAddress ERC20 token address.
472
- * @param _walletAddress wallet address.
473
- * @return balance
517
+ * @notice Gets the balance of `currencyAddress` ERC20 tokens for `walletAddress`.
518
+ * @param currencyAddress ERC20 token address.
519
+ * @param walletAddress wallet address.
520
+ * @return balance Balance of ERC-20
474
521
  */
475
522
  function getERC20Balance(
476
- address _currencyAddress,
477
- address _walletAddress
523
+ address currencyAddress,
524
+ address walletAddress
478
525
  ) internal view returns (uint256) {
479
- return IERC20(_currencyAddress).balanceOf(_walletAddress);
526
+ return IERC20(currencyAddress).balanceOf(walletAddress);
480
527
  }
481
528
 
482
529
  /**
483
- * Gets the allowance of `_spenderAddress` to spend `_walletAddress`'s
484
- * `_currencyAddress` ERC20 tokens.
485
- * @param _currencyAddress ERC20 token address.
486
- * @param _walletAddress wallet address.
487
- * @param _spenderAddress spender address.
488
- * @return allowance
530
+ * @notice Gets the allowance of `spenderAddress` to spend `walletAddress`'s
531
+ * `currencyAddress` ERC20 tokens.
532
+ * @param currencyAddress ERC20 token address.
533
+ * @param walletAddress wallet address.
534
+ * @param spenderAddress spender address.
535
+ * @return allowance Allowance of ERC-20
489
536
  */
490
537
  function getERC20Allowance(
491
- address _currencyAddress,
492
- address _walletAddress,
493
- address _spenderAddress
538
+ address currencyAddress,
539
+ address walletAddress,
540
+ address spenderAddress
494
541
  ) internal view returns (uint256 allowance) {
495
- allowance = IERC20(_currencyAddress).allowance(
496
- _walletAddress,
497
- _spenderAddress
498
- );
542
+ allowance = IERC20(currencyAddress).allowance({
543
+ owner: walletAddress,
544
+ spender: spenderAddress
545
+ });
499
546
  return allowance;
500
547
  }
501
548
 
502
549
  /**
503
- * @notice Returns whether a V3 core contract is an Art Blocks Engine
504
- * contract or not. Return value of false indicates that the core is a
505
- * flagship contract. If this function resolves without reverting, it also
506
- * updates the cache state for the given V3 core contract.
507
- * @dev this function reverts if a core contract does not return the
508
- * expected number of return values from getPrimaryRevenueSplits() for
509
- * either a flagship or engine core contract.
510
- * @dev this function uses the length of the return data (in bytes) to
511
- * determine whether the core is an engine or not.
512
- * @param _coreContract The address of the deployed core contract.
513
- * @param _isEngineCache The storage pointer to the project's
514
- * IsEngineCache struct.
515
- */
516
- function getV3CoreIsEngine(
517
- address _coreContract,
518
- IsEngineCache storage _isEngineCache
519
- ) private returns (bool) {
520
- // call getPrimaryRevenueSplits() on core contract
521
- bytes memory payload = abi.encodeWithSignature(
522
- "getPrimaryRevenueSplits(uint256,uint256)",
523
- 0,
524
- 0
525
- );
526
- (bool success, bytes memory returnData) = _coreContract.call(payload);
527
- require(success, "getPrimaryRevenueSplits() call failed");
528
- // determine whether core is engine or not, based on return data length
529
- uint256 returnDataLength = returnData.length;
530
- if (returnDataLength == 6 * 32) {
531
- // 6 32-byte words returned if flagship (not engine)
532
- // @dev 6 32-byte words are expected because the non-engine core
533
- // contracts return a payout address and uint256 payment value for
534
- // the artist, and artist's additional payee, and Art Blocks.
535
- // also note that per Solidity ABI encoding, the address return
536
- // values are padded to 32 bytes.
537
- _isEngineCache.isCached = true;
538
- _isEngineCache.isEngine = false;
539
- return false;
540
- } else if (returnDataLength == 8 * 32) {
541
- // 8 32-byte words returned if engine
542
- // @dev 8 32-byte words are expected because the engine core
543
- // contracts return a payout address and uint256 payment value for
544
- // the artist, artist's additional payee, render provider
545
- // typically Art Blocks, and platform provider (partner).
546
- // also note that per Solidity ABI encoding, the address return
547
- // values are padded to 32 bytes.
548
- _isEngineCache.isCached = true;
549
- _isEngineCache.isEngine = true;
550
- return true;
551
- } else {
552
- // unexpected return value length
553
- revert("Unexpected revenue split bytes");
554
- }
555
- }
556
-
557
- /**
558
- * Validate that `_msgSender` has approved the contract to spend at least
559
- * `_pricePerTokenInWei` of `_currencyAddress` ERC20 tokens, and that
560
- * `_msgSender` has a balance of at least `_pricePerTokenInWei` of
561
- * `_currencyAddress` ERC20 tokens.
550
+ * @notice Function validates that `msgSender` has approved the contract to spend at least
551
+ * `pricePerToken` of `currencyAddress` ERC20 tokens, and that
552
+ * `msgSender` has a balance of at least `pricePerToken` of
553
+ * `currencyAddress` ERC20 tokens.
562
554
  * Reverts if insufficient allowance or balance.
563
- * @param _msgSender Address of the message sender to validate.
564
- * @param _currencyAddress Address of the ERC20 token to validate.
565
- * @param _pricePerTokenInWei Price per token in wei to validate.
555
+ * @param msgSender Address of the message sender to validate.
556
+ * @param currencyAddress Address of the ERC20 token to validate.
557
+ * @param pricePerToken Price of token, in base units. For example,
558
+ * if the ERC20 token has 6 decimals, an input value of `1_000_000` would
559
+ * represent a price of `1.000000` tokens.
566
560
  */
567
561
  function validateERC20Approvals(
568
- address _msgSender,
569
- address _currencyAddress,
570
- uint256 _pricePerTokenInWei
562
+ address msgSender,
563
+ address currencyAddress,
564
+ uint256 pricePerToken
571
565
  ) private view {
572
566
  require(
573
- IERC20(_currencyAddress).allowance(_msgSender, address(this)) >=
574
- _pricePerTokenInWei,
567
+ IERC20(currencyAddress).allowance({
568
+ owner: msgSender,
569
+ spender: address(this)
570
+ }) >= pricePerToken,
575
571
  "Insufficient ERC20 allowance"
576
572
  );
577
573
  require(
578
- IERC20(_currencyAddress).balanceOf(_msgSender) >=
579
- _pricePerTokenInWei,
574
+ IERC20(currencyAddress).balanceOf(msgSender) >= pricePerToken,
580
575
  "Insufficient ERC20 balance"
581
576
  );
582
577
  }
578
+
579
+ /**
580
+ * @notice Sends ETH revenues between providers, artist, and artist's
581
+ * additional payee. Reverts if any payment fails.
582
+ * @dev This function pays priviliged addresses. DoS is acknowledged, and
583
+ * mitigated by business practices, including end-to-end testing on
584
+ * mainnet, and admin-accepted artist payment addresses.
585
+ * @param platformProviderRevenue Platform Provider revenue.
586
+ * @param platformProviderAddress Platform Provider address.
587
+ * @param renderProviderRevenue Render Provider revenue.
588
+ * @param renderProviderAddress Render Provider address.
589
+ * @param artistRevenue Artist revenue.
590
+ * @param artistAddress Artist address.
591
+ * @param additionalPayeePrimaryRevenue Additional Payee revenue.
592
+ * @param additionalPayeePrimaryAddress Additional Payee address.
593
+ */
594
+ function _sendPaymentsETH(
595
+ uint256 platformProviderRevenue,
596
+ address payable platformProviderAddress,
597
+ uint256 renderProviderRevenue,
598
+ address payable renderProviderAddress,
599
+ uint256 artistRevenue,
600
+ address payable artistAddress,
601
+ uint256 additionalPayeePrimaryRevenue,
602
+ address payable additionalPayeePrimaryAddress
603
+ ) private {
604
+ // Platform Provider payment (only possible if engine)
605
+ if (platformProviderRevenue > 0) {
606
+ (bool success, ) = platformProviderAddress.call{
607
+ value: platformProviderRevenue
608
+ }("");
609
+ require(success, "Platform Provider payment failed");
610
+ }
611
+ // Render Provider / Art Blocks payment
612
+ if (renderProviderRevenue > 0) {
613
+ (bool success, ) = renderProviderAddress.call{
614
+ value: renderProviderRevenue
615
+ }("");
616
+ require(success, "Render Provider payment failed");
617
+ }
618
+ // artist payment
619
+ if (artistRevenue > 0) {
620
+ (bool success, ) = artistAddress.call{value: artistRevenue}("");
621
+ require(success, "Artist payment failed");
622
+ }
623
+ // additional payee payment
624
+ if (additionalPayeePrimaryRevenue > 0) {
625
+ (bool success, ) = additionalPayeePrimaryAddress.call{
626
+ value: additionalPayeePrimaryRevenue
627
+ }("");
628
+ require(success, "Additional Payee payment failed");
629
+ }
630
+ }
631
+
632
+ /**
633
+ * @notice Sends ERC20 revenues between providers, artist, and artist's
634
+ * additional payee. Reverts if any payment fails. All revenue values
635
+ * should use base units. For example, if the ERC20 token has 6 decimals,
636
+ * an input value of `1_000_000` would represent an amount of `1.000000`
637
+ * tokens.
638
+ * @dev This function relies on msg.sender, so it must be called from
639
+ * the contract that is receiving the payment.
640
+ * @param projectCurrency IERC20 payment token.
641
+ * @param platformProviderRevenue Platform Provider revenue.
642
+ * @param platformProviderAddress Platform Provider address.
643
+ * @param renderProviderRevenue Render Provider revenue.
644
+ * @param renderProviderAddress Render Provider address.
645
+ * @param artistRevenue Artist revenue.
646
+ * @param artistAddress Artist address.
647
+ * @param additionalPayeePrimaryRevenue Additional Payee revenue.
648
+ * @param additionalPayeePrimaryAddress Additional Payee address.
649
+ */
650
+ function _sendPaymentsERC20(
651
+ IERC20 projectCurrency,
652
+ uint256 platformProviderRevenue,
653
+ address payable platformProviderAddress,
654
+ uint256 renderProviderRevenue,
655
+ address payable renderProviderAddress,
656
+ uint256 artistRevenue,
657
+ address payable artistAddress,
658
+ uint256 additionalPayeePrimaryRevenue,
659
+ address payable additionalPayeePrimaryAddress
660
+ ) private {
661
+ // Platform Provider payment (only possible if engine)
662
+ if (platformProviderRevenue > 0) {
663
+ require(
664
+ projectCurrency.transferFrom({
665
+ from: msg.sender,
666
+ to: platformProviderAddress,
667
+ amount: platformProviderRevenue
668
+ }),
669
+ "Platform Provider payment failed"
670
+ );
671
+ }
672
+ // Art Blocks payment
673
+ if (renderProviderRevenue > 0) {
674
+ require(
675
+ projectCurrency.transferFrom({
676
+ from: msg.sender,
677
+ to: renderProviderAddress,
678
+ amount: renderProviderRevenue
679
+ }),
680
+ "Render Provider payment failed"
681
+ );
682
+ }
683
+ // artist payment
684
+ if (artistRevenue > 0) {
685
+ require(
686
+ projectCurrency.transferFrom({
687
+ from: msg.sender,
688
+ to: artistAddress,
689
+ amount: artistRevenue
690
+ }),
691
+ "Artist payment failed"
692
+ );
693
+ }
694
+ // additional payee payment
695
+ if (additionalPayeePrimaryRevenue > 0) {
696
+ // @dev some ERC20 may not revert on transfer failure, so we
697
+ // check the return value
698
+ require(
699
+ projectCurrency.transferFrom({
700
+ from: msg.sender,
701
+ to: additionalPayeePrimaryAddress,
702
+ amount: additionalPayeePrimaryRevenue
703
+ }),
704
+ "Additional Payee payment failed"
705
+ );
706
+ }
707
+ }
708
+
709
+ /**
710
+ * @notice Loads the SplitFundsProjectConfig for a given project and core
711
+ * contract.
712
+ * @param projectId Project Id to get config for
713
+ * @param coreContract Core contract address to get config for
714
+ */
715
+ function getSplitFundsProjectConfig(
716
+ uint256 projectId,
717
+ address coreContract
718
+ ) internal view returns (SplitFundsProjectConfig storage) {
719
+ return s().splitFundsProjectConfigs[coreContract][projectId];
720
+ }
721
+
722
+ /**
723
+ * @notice Loads the IsEngineCache for a given core contract.
724
+ * @param coreContract Core contract address to get config for
725
+ */
726
+ function getIsEngineCacheConfig(
727
+ address coreContract
728
+ ) internal view returns (IsEngineCache storage) {
729
+ return s().isEngineCacheConfigs[coreContract];
730
+ }
731
+
732
+ /**
733
+ * @notice Return the storage struct for reading and writing. This library
734
+ * uses a diamond storage pattern when managing storage.
735
+ * @return storageStruct The SetPriceLibStorage struct.
736
+ */
737
+ function s()
738
+ internal
739
+ pure
740
+ returns (SplitFundsLibStorage storage storageStruct)
741
+ {
742
+ bytes32 position = SPLIT_FUNDS_LIB_STORAGE_POSITION;
743
+ assembly ("memory-safe") {
744
+ storageStruct.slot := position
745
+ }
746
+ }
583
747
  }