@artblocks/contracts 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (326) hide show
  1. package/README.md +86 -34
  2. package/artifacts/contracts/AdminACLV0.sol/AdminACLV0.json +2 -2
  3. package/artifacts/contracts/AdminACLV1.sol/AdminACLV1.json +2 -2
  4. package/artifacts/contracts/BytecodeStorageReaders/BytecodeStorageReaderContractV2.sol/BytecodeStorageReaderContractV2.json +201 -0
  5. package/artifacts/contracts/BytecodeStorageReaders/UniversalBytecodeStorageReader.sol/UniversalBytecodeStorageReader.json +154 -0
  6. package/artifacts/contracts/BytecodeStorageV2Writer.sol/BytecodeStorageV2Writer.json +87 -0
  7. package/artifacts/contracts/DependencyRegistryV0.sol/DependencyRegistryV0.json +403 -155
  8. package/artifacts/contracts/GenArt721CoreV3_Curated.sol/GenArt721CoreV3_Curated.json +2493 -0
  9. package/artifacts/contracts/OwnedCreate2FactoryV0.sol/OwnedCreate2FactoryV0.json +311 -0
  10. package/artifacts/contracts/archive/GenArt721CoreV3.sol/GenArt721CoreV3.json +2060 -0
  11. package/artifacts/contracts/archive/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +2034 -0
  12. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterBase_v0_1_1.sol/MinterBase.json +1 -1
  13. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV2.sol/MinterDAExpV2.json +2 -2
  14. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV3.sol/MinterDAExpV3.json +2 -2
  15. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDAExp}/MinterDAExpV4.sol/MinterDAExpV4.json +3 -3
  16. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol/MinterDAExpSettlementV0.json +2 -2
  17. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV1.sol/MinterDAExpSettlementV1.json +2 -2
  18. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDAExpSettlement}/MinterDAExpSettlementV2.sol/MinterDAExpSettlementV2.json +3 -3
  19. package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV2.sol/MinterDALinV2.json +2 -2
  20. package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV3.sol/MinterDALinV3.json +2 -2
  21. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDALin}/MinterDALinV4.sol/MinterDALinV4.json +3 -3
  22. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV1.sol/MinterHolderV1.json +2 -2
  23. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV2.sol/MinterHolderV2.json +2 -2
  24. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV3.sol/MinterHolderV3.json +2 -2
  25. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterHolder}/MinterHolderV4.sol/MinterHolderV4.json +3 -3
  26. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV1.sol/MinterMerkleV1.json +2 -2
  27. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV2.sol/MinterMerkleV2.json +2 -2
  28. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV3.sol/MinterMerkleV3.json +2 -2
  29. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV4.sol/MinterMerkleV4.json +2 -2
  30. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterMerkle}/MinterMerkleV5.sol/MinterMerkleV5.json +3 -3
  31. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterPolyptych}/MinterPolyptychV0.sol/IGenArt721CoreContractV3WithRandomizer.json +54 -49
  32. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterPolyptych}/MinterPolyptychV0.sol/MinterPolyptychV0.json +3 -3
  33. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSEA}/MinterSEAV0.sol/MinterSEAV0.json +3 -3
  34. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV2.sol/MinterSetPriceV2.json +2 -2
  35. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV3.sol/MinterSetPriceV3.json +2 -2
  36. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSetPrice}/MinterSetPriceV4.sol/MinterSetPriceV4.json +3 -3
  37. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V0.sol/MinterSetPriceERC20V0.json +65 -2
  38. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V1.sol/MinterSetPriceERC20V1.json +65 -2
  39. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol/MinterSetPriceERC20V2.json +2 -2
  40. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol/MinterSetPriceERC20V3.json +2 -2
  41. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V4.sol/MinterSetPriceERC20V4.json +807 -0
  42. package/artifacts/contracts/engine/V2/GenArt721MinterBurner_PBAB.sol/GenArt721MinterBurner_PBAB.json +65 -2
  43. package/artifacts/contracts/engine/V2/GenArt721Minter_PBAB.sol/GenArt721Minter_PBAB.json +65 -2
  44. package/artifacts/contracts/engine/V3/EngineFactoryV0.sol/EngineFactoryV0.json +624 -0
  45. package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine.sol/GenArt721CoreV3_Engine.json +613 -216
  46. package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol/GenArt721CoreV3_Engine_Flex.json +805 -206
  47. package/artifacts/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol/GenArt721CoreV3_Engine_Flex_PROOF.json +51 -8
  48. package/artifacts/contracts/engine/V3/forks/PROHIBITION/AdminACLV0_PROHIBITION.sol/AdminACLV0_PROHIBITION.json +2 -2
  49. package/artifacts/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol/GenArt721CoreV3_Engine_Flex_PROHIBITION.json +51 -8
  50. package/artifacts/contracts/engine/V3/forks/PROHIBITION/interfaces/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.sol/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.json +59 -54
  51. package/artifacts/contracts/engine-registry/CoreRegistryV1.sol/CoreRegistryV1.json +2 -2
  52. package/artifacts/contracts/generator/AddressChunks.sol/AddressChunks.json +10 -0
  53. package/artifacts/contracts/generator/GenArt721GeneratorV0.sol/GenArt721GeneratorV0.json +333 -0
  54. package/artifacts/contracts/generator/GenArt721GeneratorV0.sol/ILegacyGenArt721CoreV2_PBAB_Flex.json +47 -0
  55. package/artifacts/contracts/interfaces/v0.8.x/IAdminACLV0_Extended.sol/IAdminACLV0_Extended.json +140 -0
  56. package/artifacts/contracts/interfaces/v0.8.x/IBytecodeStorageReader.sol/IBytecodeStorageReader.json +7 -7
  57. package/artifacts/contracts/interfaces/v0.8.x/IBytecodeStorageReaderV2.sol/IBytecodeStorageReaderV2.json +130 -0
  58. package/artifacts/contracts/interfaces/v0.8.x/IBytecodeStorageReader_Base.sol/IBytecodeStorageReader_Base.json +30 -0
  59. package/artifacts/contracts/interfaces/v0.8.x/ICoreRegistryV1.sol/ICoreRegistryV1.json +13 -0
  60. package/artifacts/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol/IDependencyRegistryV0.json +228 -45
  61. package/artifacts/contracts/interfaces/v0.8.x/IEngineFactoryV0.sol/IEngineFactoryV0.json +283 -0
  62. package/artifacts/contracts/interfaces/v0.8.x/IFilteredMinterDAExpSettlementV0.sol/IFilteredMinterDAExpSettlementV0.json +12 -12
  63. package/artifacts/contracts/interfaces/v0.8.x/IFilteredMinterDAExpSettlementV1.sol/IFilteredMinterDAExpSettlementV1.json +12 -12
  64. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3.sol/IGenArt721CoreContractV3.json +53 -48
  65. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Base.sol/IGenArt721CoreContractV3_Base.json +53 -48
  66. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine.sol/IGenArt721CoreContractV3_Engine.json +198 -90
  67. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex.sol/IGenArt721CoreContractV3_Engine_Flex.json +198 -90
  68. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex_PreV3p2.sol/IGenArt721CoreContractV3_Engine_Flex_PreV3p2.json +1065 -0
  69. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_PreV3p2.sol/IGenArt721CoreContractV3_Engine_PreV3p2.json +778 -0
  70. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_ProjectFinance.sol/IGenArt721CoreContractV3_ProjectFinance.json +87 -0
  71. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreProjectScriptV0.sol/IGenArt721CoreProjectScriptV0.json +59 -0
  72. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreProjectScriptV1.sol/IGenArt721CoreProjectScriptV1.json +64 -0
  73. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreTokenHashProviderV0.sol/IGenArt721CoreTokenHashProviderV0.json +30 -0
  74. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreTokenHashProviderV1.sol/IGenArt721CoreTokenHashProviderV1.json +30 -0
  75. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721GeneratorV0.sol/IGenArt721GeneratorV0.json +63 -0
  76. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721Minter_PBAB.sol/IGenArt721Minter_PBAB.json +279 -0
  77. package/artifacts/contracts/interfaces/v0.8.x/IOwnedCreate2FactoryV0.sol/IOwnedCreate2FactoryV0.json +74 -0
  78. package/artifacts/contracts/interfaces/v0.8.x/IPseudorandomAtomic.sol/IPseudorandomAtomic.json +1 -1
  79. package/artifacts/contracts/interfaces/v0.8.x/ISeaDropShimForContract.sol/ISeaDropShimForContract.json +37 -0
  80. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol/ISharedMinterDAExpSettlementV0.json +18 -0
  81. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterMinPriceV0.sol/ISharedMinterMinPriceV0.json +37 -0
  82. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterRAMV0.sol/ISharedMinterRAMV0.json +62 -0
  83. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterRequired.sol/ISharedMinterRequired.json +37 -0
  84. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterSEAV0.sol/ISharedMinterSEAV0.json +1 -1
  85. package/artifacts/contracts/interfaces/v0.8.x/ISplitAtomicFactoryV0.sol/ISplitAtomicFactoryV0.json +170 -0
  86. package/artifacts/contracts/interfaces/v0.8.x/ISplitAtomicV0.sol/ISplitAtomicV0.json +126 -0
  87. package/artifacts/contracts/interfaces/v0.8.x/ISplitProviderV0.sol/ISplitProviderV0.json +98 -0
  88. package/artifacts/contracts/interfaces/v0.8.x/IUniversalBytecodeStorageReader.sol/IUniversalBytecodeStorageReader.json +56 -0
  89. package/artifacts/contracts/interfaces/v0.8.x/integration-refs/OpenSea/ERC721SeaDropStructsErrorsAndEvents.sol/ERC721SeaDropStructsErrorsAndEvents.json +43 -0
  90. package/artifacts/contracts/interfaces/v0.8.x/integration-refs/OpenSea/INonFungibleSeaDropToken.sol/INonFungibleSeaDropToken.json +715 -0
  91. package/artifacts/contracts/interfaces/v0.8.x/integration-refs/OpenSea/ISeaDrop.sol/ISeaDrop.json +1571 -0
  92. package/artifacts/contracts/interfaces/v0.8.x/integration-refs/OpenSea/ISeaDropTokenContractMetadata.sol/ISeaDropTokenContractMetadata.json +345 -0
  93. package/artifacts/contracts/interfaces/v0.8.x/integration-refs/OpenSea/SeaDropErrorsAndEvents.sol/SeaDropErrorsAndEvents.json +717 -0
  94. package/artifacts/contracts/interfaces/v0.8.x/integration-refs/splits-0x-v2/ISplitFactoryV2.sol/ISplitFactoryV2.json +123 -0
  95. package/artifacts/contracts/libs/integration-refs/delegation-registry/DelegationRegistry.sol/DelegationRegistry.json +2 -2
  96. package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeMock.sol/GnosisSafeMock.json +2 -2
  97. package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeProxyFactoryMock.sol/GnosisSafeProxyFactoryMock.json +2 -2
  98. package/artifacts/contracts/libs/integration-refs/gnosis-safe/MultiSendMock.sol/MultiSendMock.json +2 -2
  99. package/artifacts/contracts/libs/integration-refs/weth9/weth9.sol/WETH9_.json +2 -2
  100. package/artifacts/contracts/libs/v0.8.x/ABHelpers.sol/ABHelpers.json +2 -2
  101. package/artifacts/contracts/libs/v0.8.x/AuthLib.sol/AuthLib.json +2 -2
  102. package/artifacts/contracts/libs/v0.8.x/BitMap.sol/BitMaps256.json +10 -0
  103. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV0.sol/BytecodeStorage.json +2 -2
  104. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV1.sol/BytecodeStorageReader.json +2 -2
  105. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV1.sol/BytecodeStorageWriter.json +2 -2
  106. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV2.sol/BytecodeStorageReader.json +214 -0
  107. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV2.sol/BytecodeStorageWriter.json +10 -0
  108. package/artifacts/contracts/libs/v0.8.x/Bytes32Strings.sol/Bytes32Strings.json +2 -2
  109. package/artifacts/contracts/libs/v0.8.x/DependencyRegistryStorageLib.sol/DependencyRegistryStorageLib.json +10 -0
  110. package/artifacts/contracts/libs/v0.8.x/ERC721_PackedHashSeed.sol/ERC721_PackedHashSeed.json +2 -2
  111. package/artifacts/contracts/libs/v0.8.x/ERC721_PackedHashSeedV1.sol/ERC721_PackedHashSeedV1.json +444 -0
  112. package/artifacts/contracts/libs/v0.8.x/JsonStatic.sol/JsonStatic.json +10 -0
  113. package/artifacts/contracts/libs/v0.8.x/PackedBools.sol/PackedBools.json +10 -0
  114. package/artifacts/contracts/libs/v0.8.x/SSTORE2.sol/SSTORE2.json +2 -2
  115. package/artifacts/contracts/libs/v0.8.x/V3FlexLib.sol/V3FlexLib.json +195 -0
  116. package/artifacts/contracts/libs/v0.8.x/minter-libs/DAExpLib.sol/DAExpLib.json +2 -2
  117. package/artifacts/contracts/libs/v0.8.x/minter-libs/DALib.sol/DALib.json +2 -2
  118. package/artifacts/contracts/libs/v0.8.x/minter-libs/DALinLib.sol/DALinLib.json +2 -2
  119. package/artifacts/contracts/libs/v0.8.x/minter-libs/GenericMinterEventsLib.sol/GenericMinterEventsLib.json +2 -2
  120. package/artifacts/contracts/libs/v0.8.x/minter-libs/MaxInvocationsLib.sol/MaxInvocationsLib.json +2 -2
  121. package/artifacts/contracts/libs/v0.8.x/minter-libs/MerkleLib.sol/MerkleLib.json +2 -2
  122. package/artifacts/contracts/libs/v0.8.x/minter-libs/MinPriceLib.sol/MinPriceLib.json +24 -0
  123. package/artifacts/contracts/libs/v0.8.x/minter-libs/PolyptychLib.sol/PolyptychLib.json +2 -2
  124. package/artifacts/contracts/libs/v0.8.x/minter-libs/RAMLib.sol/RAMLib.json +398 -0
  125. package/artifacts/contracts/libs/v0.8.x/minter-libs/SEALib.sol/SEALib.json +2 -2
  126. package/artifacts/contracts/libs/v0.8.x/minter-libs/SetPriceLib.sol/SetPriceLib.json +2 -2
  127. package/artifacts/contracts/libs/v0.8.x/minter-libs/SettlementExpLib.sol/SettlementExpLib.json +2 -2
  128. package/artifacts/contracts/libs/v0.8.x/minter-libs/SplitFundsLib.sol/SplitFundsLib.json +2 -2
  129. package/artifacts/contracts/libs/v0.8.x/minter-libs/TokenHolderLib.sol/TokenHolderLib.json +2 -2
  130. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV1.sol/MinterFilterV1.json +2 -2
  131. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV2.sol/MinterFilterV2.json +2 -2
  132. package/artifacts/contracts/minter-suite/Minters/MinterDAExpHolderV5.sol/MinterDAExpHolderV5.json +2 -2
  133. package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV3.sol/MinterDAExpSettlementV3.json +2 -2
  134. package/artifacts/contracts/minter-suite/Minters/MinterDAExpV5.sol/MinterDAExpV5.json +2 -2
  135. package/artifacts/contracts/minter-suite/Minters/MinterDALinHolderV5.sol/MinterDALinHolderV5.json +2 -2
  136. package/artifacts/contracts/minter-suite/Minters/MinterDALinV5.sol/MinterDALinV5.json +2 -2
  137. package/artifacts/contracts/minter-suite/Minters/MinterMinPriceMerkleV0.sol/MinterMinPriceMerkleV0.json +664 -0
  138. package/artifacts/contracts/minter-suite/Minters/MinterMinPriceV0.sol/MinterMinPriceV0.json +387 -0
  139. package/artifacts/contracts/minter-suite/Minters/MinterRAMV0.sol/MinterRAMV0.json +1374 -0
  140. package/artifacts/contracts/minter-suite/Minters/MinterSEAV1.sol/MinterSEAV1.json +7 -7
  141. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20V5.sol/MinterSetPriceERC20V5.json +2 -2
  142. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceHolderV5.sol/MinterSetPriceHolderV5.json +2 -2
  143. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceMerkleV5.sol/MinterSetPriceMerkleV5.json +2 -2
  144. package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychERC20V5.sol/MinterSetPricePolyptychERC20V5.json +2 -2
  145. package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychV5.sol/MinterSetPricePolyptychV5.json +2 -2
  146. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceV5.sol/MinterSetPriceV5.json +2 -2
  147. package/artifacts/contracts/minter-suite/Minters/one-off/MinterSetPriceV5_SingleCore.sol/MinterSetPriceV5_SingleCore.json +417 -0
  148. package/artifacts/contracts/minter-suite/Minters/one-off/SeaDropXArtBlocksShim.sol/SeaDropXArtBlocksShim.json +1206 -0
  149. package/artifacts/contracts/mock/BytecodeV1LibCallsMock.sol/BytecodeV1LibCallsMock.json +2 -2
  150. package/artifacts/contracts/mock/BytecodeV2LibCallsMock.sol/BytecodeV2LibCallsMock.json +154 -0
  151. package/artifacts/contracts/mock/BytecodeV2TextCR_DMock.sol/BytecodeV2TextCR_DMock.json +428 -0
  152. package/artifacts/contracts/mock/DummySharedMinter.sol/DummySharedMinter.json +2 -2
  153. package/artifacts/contracts/mock/ERC20Mock.sol/ERC20Mock.json +2 -2
  154. package/artifacts/contracts/mock/ERC20MockAltDecimals.sol/ERC20MockAltDecimals.json +318 -0
  155. package/artifacts/contracts/mock/ForceSendMock.sol/ForceSendMock.json +24 -0
  156. package/artifacts/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol/GenArt721CoreV3_Engine_IncorrectCoreType.json +2 -2
  157. package/artifacts/contracts/mock/Mock0xSplitsV2PullFactory.sol/Mock0xSplitsV2PullFactory.json +149 -0
  158. package/artifacts/contracts/mock/Mock0xSplitsV2Splitter.sol/Mock0xSplitsV2Splitter.json +99 -0
  159. package/artifacts/contracts/mock/MockAdminACLV0.sol/MockAdminACLV0Events.json +20 -2
  160. package/artifacts/contracts/mock/MockAdminACLV0_PROHIBITION.sol/MockAdminACLV0Events_PROHIBITION.json +20 -2
  161. package/artifacts/contracts/mock/MockFileStore.sol/MockFileStore.json +35 -0
  162. package/artifacts/contracts/mock/OriginRegisterMock.sol/OriginRegisterMock.json +2 -2
  163. package/artifacts/contracts/mock/RandomizerV2_NoAssignMock.sol/RandomizerV2_NoAssignMock.json +2 -2
  164. package/artifacts/contracts/mock/ReentrancyGenArt721MinterMock.sol/ReentrancyGenArt721MinterMock.json +100 -0
  165. package/artifacts/contracts/mock/ReentrancyHolderMock.sol/ReentrancyHolderMock.json +2 -2
  166. package/artifacts/contracts/mock/ReentrancyHolderMockShared.sol/ReentrancyHolderMockShared.json +2 -2
  167. package/artifacts/contracts/mock/ReentrancyMerkleMock.sol/ReentrancyMerkleMock.json +2 -2
  168. package/artifacts/contracts/mock/ReentrancyMerkleMockShared.sol/ReentrancyMerkleMockShared.json +2 -2
  169. package/artifacts/contracts/mock/ReentrancyMock.sol/ReentrancyMock.json +2 -2
  170. package/artifacts/contracts/mock/ReentrancyMockShared.sol/ReentrancyMockShared.json +2 -2
  171. package/artifacts/contracts/mock/ReentrancySEAMock.sol/ReentrancySEAAutoBidderMock.json +2 -2
  172. package/artifacts/contracts/mock/ReentrancySEAMockShared.sol/ReentrancySEAAutoBidderMockShared.json +2 -2
  173. package/artifacts/contracts/mock/ReentrancySplitterMocks.sol/ReentrancySplitterDrainETHMock.json +54 -0
  174. package/artifacts/contracts/mock/ReentrancySplitterMocks.sol/ReentrancySplitterSendETHMock.json +54 -0
  175. package/artifacts/contracts/randomizer/deprecated/PolyptychRandomizerV0.sol/BasicPolyptychRandomizerV0.json +2 -2
  176. package/artifacts/contracts/randomizer/deprecated/RandomizerV2.sol/BasicRandomizerV2.json +2 -2
  177. package/artifacts/contracts/randomizer/primitive/PseudorandomAtomicBasic.sol/PseudorandomAtomic.json +2 -2
  178. package/artifacts/contracts/randomizer/shared/SharedRandomizerV0.sol/SharedRandomizerV0.json +2 -2
  179. package/artifacts/contracts/split/SplitAtomicFactoryV0.sol/SplitAtomicFactoryV0.json +203 -0
  180. package/artifacts/contracts/split/SplitAtomicV0.sol/SplitAtomicV0.json +168 -0
  181. package/artifacts/contracts/split/split-provider/SplitProviderV0.sol/SplitProviderV0.json +141 -0
  182. package/contracts/AdminACLV0.sol +6 -2
  183. package/contracts/AdminACLV1.sol +2 -2
  184. package/contracts/BytecodeStorageReaders/BytecodeStorageReaderContractV2.sol +103 -0
  185. package/contracts/BytecodeStorageReaders/UniversalBytecodeStorageReader.sol +70 -0
  186. package/contracts/BytecodeStorageV2Writer.sol +69 -0
  187. package/contracts/DependencyRegistryV0.sol +878 -430
  188. package/contracts/GenArt721CoreV3_Curated.sol +133 -0
  189. package/contracts/OwnedCreate2FactoryV0.sol +173 -0
  190. package/contracts/{GenArt721CoreV3.sol → archive/GenArt721CoreV3.sol} +56 -20
  191. package/contracts/{explorations → archive}/GenArt721CoreV3_Explorations.sol +49 -13
  192. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterBase_v0_1_1.sol +4 -4
  193. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDAExp}/MinterDAExpV4.sol +4 -4
  194. package/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol +4 -4
  195. package/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV1.sol +5 -5
  196. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDAExpSettlement}/MinterDAExpSettlementV2.sol +8 -8
  197. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDALin}/MinterDALinV4.sol +4 -4
  198. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterHolder}/MinterHolderV4.sol +5 -5
  199. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterMerkle}/MinterMerkleV5.sol +5 -5
  200. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterPolyptych}/MinterPolyptychV0.sol +7 -7
  201. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSEA}/MinterSEAV0.sol +13 -13
  202. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSetPrice}/MinterSetPriceV4.sol +4 -4
  203. package/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V0.sol +82 -10
  204. package/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V1.sol +82 -10
  205. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSetPriceERC20}/MinterSetPriceERC20V4.sol +88 -21
  206. package/contracts/engine/V2/GenArt721MinterBurner_PBAB.sol +81 -22
  207. package/contracts/engine/V2/GenArt721Minter_PBAB.sol +80 -22
  208. package/contracts/engine/V3/EngineFactoryV0.sol +427 -0
  209. package/contracts/engine/V3/GenArt721CoreV3_Engine.sol +977 -502
  210. package/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol +1137 -663
  211. package/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol +3 -3
  212. package/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol +1 -1
  213. package/contracts/engine/V3/forks/PROHIBITION/interfaces/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.sol +2 -2
  214. package/contracts/generator/AddressChunks.sol +106 -0
  215. package/contracts/generator/GenArt721GeneratorV0.sol +1094 -0
  216. package/contracts/generator/scripty-support/Scripty.sol +5 -0
  217. package/contracts/interfaces/v0.8.x/IAdminACLV0_Extended.sol +20 -0
  218. package/contracts/interfaces/v0.8.x/IBytecodeStorageReader.sol +34 -36
  219. package/contracts/interfaces/v0.8.x/IBytecodeStorageReaderV2.sol +25 -0
  220. package/contracts/interfaces/v0.8.x/IBytecodeStorageReader_Base.sol +20 -0
  221. package/contracts/interfaces/v0.8.x/ICoreRegistryV1.sol +5 -0
  222. package/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol +141 -45
  223. package/contracts/interfaces/v0.8.x/IEngineFactoryV0.sol +124 -0
  224. package/contracts/interfaces/v0.8.x/IFilteredMinterDAExpSettlementV0.sol +1 -3
  225. package/contracts/interfaces/v0.8.x/IFilteredMinterDAExpSettlementV1.sol +1 -3
  226. package/contracts/interfaces/v0.8.x/IFilteredMinterDAExpV1.sol +1 -3
  227. package/contracts/interfaces/v0.8.x/IFilteredMinterDALinV1.sol +1 -3
  228. package/contracts/interfaces/v0.8.x/IFilteredMinterHolderV2.sol +1 -3
  229. package/contracts/interfaces/v0.8.x/IFilteredMinterMerkleV2.sol +1 -3
  230. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Base.sol +126 -11
  231. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine.sol +86 -8
  232. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex.sol +26 -8
  233. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex_PreV3p2.sol +141 -0
  234. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_PreV3p2.sol +78 -0
  235. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_ProjectFinance.sol +47 -0
  236. package/contracts/interfaces/v0.8.x/IGenArt721CoreProjectScriptV0.sol +22 -0
  237. package/contracts/interfaces/v0.8.x/IGenArt721CoreProjectScriptV1.sol +23 -0
  238. package/contracts/interfaces/v0.8.x/IGenArt721CoreTokenHashProviderV0.sol +11 -0
  239. package/contracts/interfaces/v0.8.x/IGenArt721CoreTokenHashProviderV1.sol +9 -0
  240. package/contracts/interfaces/v0.8.x/IGenArt721GeneratorV0.sol +14 -0
  241. package/contracts/interfaces/v0.8.x/IGenArt721Minter_PBAB.sol +91 -0
  242. package/contracts/interfaces/v0.8.x/IOwnedCreate2FactoryV0.sol +40 -0
  243. package/contracts/interfaces/v0.8.x/IPseudorandomAtomic.sol +1 -3
  244. package/contracts/interfaces/v0.8.x/ISeaDropShimForContract.sol +19 -0
  245. package/contracts/interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol +19 -0
  246. package/contracts/interfaces/v0.8.x/ISharedMinterMinPriceV0.sol +22 -0
  247. package/contracts/interfaces/v0.8.x/ISharedMinterRAMV0.sol +23 -0
  248. package/contracts/interfaces/v0.8.x/ISharedMinterRequired.sol +26 -0
  249. package/contracts/interfaces/v0.8.x/ISharedMinterSEAV0.sol +1 -4
  250. package/contracts/interfaces/v0.8.x/ISharedMinterV0.sol +12 -6
  251. package/contracts/interfaces/v0.8.x/ISplitAtomicFactoryV0.sol +81 -0
  252. package/contracts/interfaces/v0.8.x/ISplitAtomicV0.sol +72 -0
  253. package/contracts/interfaces/v0.8.x/ISplitProviderV0.sol +49 -0
  254. package/contracts/interfaces/v0.8.x/IUniversalBytecodeStorageReader.sol +28 -0
  255. package/contracts/interfaces/v0.8.x/integration-refs/OpenSea/ERC721SeaDropStructsErrorsAndEvents.sol +58 -0
  256. package/contracts/interfaces/v0.8.x/integration-refs/OpenSea/INonFungibleSeaDropToken.sol +186 -0
  257. package/contracts/interfaces/v0.8.x/integration-refs/OpenSea/ISeaDrop.sol +337 -0
  258. package/contracts/interfaces/v0.8.x/integration-refs/OpenSea/ISeaDropTokenContractMetadata.sol +152 -0
  259. package/contracts/interfaces/v0.8.x/integration-refs/OpenSea/SeaDropErrorsAndEvents.sol +320 -0
  260. package/contracts/interfaces/v0.8.x/integration-refs/OpenSea/SeaDropStructs.sol +146 -0
  261. package/contracts/interfaces/v0.8.x/integration-refs/splits-0x-v2/ISplitFactoryV2.sol +62 -0
  262. package/contracts/libs/v0.8.x/ABHelpers.sol +18 -4
  263. package/contracts/libs/v0.8.x/BitMap.sol +112 -0
  264. package/contracts/libs/v0.8.x/BytecodeStorageV2.sol +593 -0
  265. package/contracts/libs/v0.8.x/Bytes32Strings.sol +20 -0
  266. package/contracts/libs/v0.8.x/DependencyRegistryStorageLib.sol +98 -0
  267. package/contracts/libs/v0.8.x/ERC721_PackedHashSeedV1.sol +591 -0
  268. package/contracts/libs/v0.8.x/JsonStatic.sol +373 -0
  269. package/contracts/libs/v0.8.x/PackedBools.sol +42 -0
  270. package/contracts/libs/v0.8.x/V3FlexLib.sol +597 -0
  271. package/contracts/libs/v0.8.x/minter-libs/DAExpLib.sol +10 -12
  272. package/contracts/libs/v0.8.x/minter-libs/DALinLib.sol +4 -9
  273. package/contracts/libs/v0.8.x/minter-libs/GenericMinterEventsLib.sol +44 -44
  274. package/contracts/libs/v0.8.x/minter-libs/MaxInvocationsLib.sol +64 -63
  275. package/contracts/libs/v0.8.x/minter-libs/MerkleLib.sol +14 -10
  276. package/contracts/libs/v0.8.x/minter-libs/MinPriceLib.sol +64 -0
  277. package/contracts/libs/v0.8.x/minter-libs/RAMLib.sol +2927 -0
  278. package/contracts/libs/v0.8.x/minter-libs/SEALib.sol +60 -62
  279. package/contracts/libs/v0.8.x/minter-libs/SetPriceLib.sol +4 -8
  280. package/contracts/libs/v0.8.x/minter-libs/SettlementExpLib.sol +92 -89
  281. package/contracts/libs/v0.8.x/minter-libs/SplitFundsLib.sol +128 -15
  282. package/contracts/libs/v0.8.x/minter-libs/TokenHolderLib.sol +5 -4
  283. package/contracts/minter-suite/MinterFilter/MinterFilterV2.sol +16 -10
  284. package/contracts/minter-suite/Minters/MinterDAExpHolderV5.sol +2 -2
  285. package/contracts/minter-suite/Minters/MinterDAExpSettlementV3.sol +19 -15
  286. package/contracts/minter-suite/Minters/MinterDAExpV5.sol +2 -2
  287. package/contracts/minter-suite/Minters/MinterDALinHolderV5.sol +2 -2
  288. package/contracts/minter-suite/Minters/MinterDALinV5.sol +2 -2
  289. package/contracts/minter-suite/Minters/MinterMinPriceMerkleV0.sol +765 -0
  290. package/contracts/minter-suite/Minters/MinterMinPriceV0.sol +462 -0
  291. package/contracts/minter-suite/Minters/MinterRAMV0.sol +1205 -0
  292. package/contracts/minter-suite/Minters/MinterSEAV1.sol +21 -32
  293. package/contracts/minter-suite/Minters/MinterSetPriceERC20V5.sol +17 -8
  294. package/contracts/minter-suite/Minters/MinterSetPriceHolderV5.sol +2 -2
  295. package/contracts/minter-suite/Minters/MinterSetPriceMerkleV5.sol +2 -2
  296. package/contracts/minter-suite/Minters/MinterSetPricePolyptychERC20V5.sol +23 -9
  297. package/contracts/minter-suite/Minters/MinterSetPricePolyptychV5.sol +2 -2
  298. package/contracts/minter-suite/Minters/MinterSetPriceV5.sol +2 -2
  299. package/contracts/minter-suite/Minters/one-off/MinterSetPriceV5_SingleCore.sol +446 -0
  300. package/contracts/minter-suite/Minters/one-off/SeaDropXArtBlocksShim.sol +869 -0
  301. package/contracts/mock/BytecodeV2LibCallsMock.sol +128 -0
  302. package/contracts/mock/BytecodeV2TextCR_DMock.sol +316 -0
  303. package/contracts/mock/ERC20MockAltDecimals.sol +31 -0
  304. package/contracts/mock/ForceSendMock.sol +22 -0
  305. package/contracts/mock/Mock0xSplitsV2PullFactory.sol +75 -0
  306. package/contracts/mock/Mock0xSplitsV2Splitter.sol +47 -0
  307. package/contracts/mock/MockAdminACLV0.sol +21 -0
  308. package/contracts/mock/MockAdminACLV0_PROHIBITION.sol +21 -0
  309. package/contracts/mock/MockFileStore.sol +22 -0
  310. package/contracts/mock/ReentrancyGenArt721MinterMock.sol +47 -0
  311. package/contracts/mock/ReentrancySplitterMocks.sol +67 -0
  312. package/contracts/randomizer/primitive/PseudorandomAtomicBasic.sol +1 -1
  313. package/contracts/randomizer/shared/SharedRandomizerV0.sol +1 -1
  314. package/contracts/split/SplitAtomicFactoryV0.sol +121 -0
  315. package/contracts/split/SplitAtomicV0.sol +265 -0
  316. package/contracts/split/split-provider/SplitProviderV0.sol +201 -0
  317. package/package.json +66 -36
  318. package/artifacts/contracts/GenArt721CoreV3.sol/GenArt721CoreV3.json +0 -1965
  319. package/artifacts/contracts/explorations/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +0 -1939
  320. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20V4.sol/MinterSetPriceERC20V4.json +0 -768
  321. package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverride.sol/GenArt721RoyaltyOverride.json +0 -208
  322. package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverride_PBAB.sol/GenArt721RoyaltyOverride_PBAB.json +0 -301
  323. package/contracts/archive/readme.md +0 -16
  324. package/contracts/engine/README.md +0 -21
  325. package/contracts/royalty-registry/GenArt721RoyaltyOverride.sol +0 -168
  326. package/contracts/royalty-registry/GenArt721RoyaltyOverride_PBAB.sol +0 -221
@@ -1,19 +1,22 @@
1
1
  // SPDX-License-Identifier: LGPL-3.0-only
2
- pragma solidity 0.8.19;
2
+ pragma solidity 0.8.22;
3
3
 
4
4
  // Created By: Art Blocks Inc.
5
5
 
6
6
  import "../../interfaces/v0.8.x/IRandomizer_V3CoreBase.sol";
7
- import "../../interfaces/v0.8.x/IAdminACLV0.sol";
7
+ import "../../interfaces/v0.8.x/IAdminACLV0_Extended.sol";
8
8
  import "../../interfaces/v0.8.x/IGenArt721CoreContractV3_Engine.sol";
9
+ import {IGenArt721CoreContractV3_ProjectFinance} from "../../interfaces/v0.8.x/IGenArt721CoreContractV3_ProjectFinance.sol";
9
10
  import "../../interfaces/v0.8.x/IGenArt721CoreContractExposesHashSeed.sol";
10
11
  import "../../interfaces/v0.8.x/IDependencyRegistryCompatibleV0.sol";
11
- import "../../interfaces/v0.8.x/IManifold.sol";
12
-
13
- import "@openzeppelin-4.7/contracts/utils/Strings.sol";
14
- import "@openzeppelin-4.7/contracts/access/Ownable.sol";
15
- import "../../libs/v0.8.x/ERC721_PackedHashSeed.sol";
16
- import "../../libs/v0.8.x/BytecodeStorageV1.sol";
12
+ import {ISplitProviderV0} from "../../interfaces/v0.8.x/ISplitProviderV0.sol";
13
+ import {IBytecodeStorageReader_Base} from "../../interfaces/v0.8.x/IBytecodeStorageReader_Base.sol";
14
+
15
+ import "@openzeppelin-5.0/contracts/utils/Strings.sol";
16
+ import "@openzeppelin-5.0/contracts/access/Ownable.sol";
17
+ import {IERC2981} from "@openzeppelin-5.0/contracts/interfaces/IERC2981.sol";
18
+ import "../../libs/v0.8.x/ERC721_PackedHashSeedV1.sol";
19
+ import {BytecodeStorageWriter, BytecodeStorageReader} from "../../libs/v0.8.x/BytecodeStorageV2.sol";
17
20
  import "../../libs/v0.8.x/Bytes32Strings.sol";
18
21
 
19
22
  /**
@@ -33,22 +36,28 @@ import "../../libs/v0.8.x/Bytes32Strings.sol";
33
36
  * ----------------------------------------------------------------------------
34
37
  * The following functions are restricted to the Admin ACL contract:
35
38
  * - updateArtblocksDependencyRegistryAddress
39
+ * - updateArtblocksOnChainGeneratorAddress
40
+ * - updateNextCoreContract
36
41
  * - updateProviderSalesAddresses
37
42
  * - updateProviderPrimarySalesPercentages (up to 100%)
38
- * - updateProviderSecondarySalesBPS (up to 100%)
43
+ * - updateProviderDefaultSecondarySalesBPS (up to 100%)
44
+ * - syncProviderSecondaryForProjectToDefaults
39
45
  * - updateMinterContract
40
46
  * - updateRandomizerAddress
41
- * - toggleProjectIsActive
47
+ * - toggleProjectIsActive (note: artist may be configured to activate projects)
42
48
  * - addProject
43
49
  * - forbidNewProjects (forever forbidding new projects)
44
50
  * - updateDefaultBaseURI (used to initialize new project base URIs)
51
+ * - updateSplitProvider
52
+ * - updateBytecodeStorageReaderContract
45
53
  * ----------------------------------------------------------------------------
46
- * The following functions are restricted to either the the Artist address or
54
+ * The following functions are restricted to either the Artist address or
47
55
  * the Admin ACL contract, only when the project is not locked:
48
56
  * - updateProjectName
49
57
  * - updateProjectArtistName
50
58
  * - updateProjectLicense
51
- * - Change project script via addProjectScript, updateProjectScript,
59
+ * - Change project script via addProjectScript, addProjectScriptCompressed,
60
+ * updateProjectScript, updateProjectScriptCompressed,
52
61
  * and removeProjectLastScript
53
62
  * - updateProjectScriptType
54
63
  * - updateProjectAspectRatio
@@ -92,14 +101,16 @@ import "../../libs/v0.8.x/Bytes32Strings.sol";
92
101
  * registries, and other contracts that may interact with this core contract.
93
102
  */
94
103
  contract GenArt721CoreV3_Engine is
95
- ERC721_PackedHashSeed,
104
+ ERC721_PackedHashSeedV1,
96
105
  Ownable,
106
+ IERC2981,
97
107
  IDependencyRegistryCompatibleV0,
98
- IManifold,
99
108
  IGenArt721CoreContractV3_Engine,
109
+ IGenArt721CoreContractV3_ProjectFinance,
100
110
  IGenArt721CoreContractExposesHashSeed
101
111
  {
102
112
  using BytecodeStorageWriter for string;
113
+ using BytecodeStorageWriter for bytes;
103
114
  using Bytes32Strings for bytes32;
104
115
  using Strings for uint256;
105
116
  using Strings for address;
@@ -113,49 +124,16 @@ contract GenArt721CoreV3_Engine is
113
124
  uint256 constant MAX_PROVIDER_SECONDARY_SALES_BPS = 10000; // 10_000 BPS = 100%
114
125
  uint256 constant ARTIST_MAX_SECONDARY_ROYALTY_PERCENTAGE = 95; // 95%
115
126
 
116
- // This contract emits generic events that contain fields that indicate
117
- // which parameter has been updated. This is sufficient for application
118
- // state management, while also simplifying the contract and indexing code.
119
- // This was done as an alternative to having custom events that emit what
120
- // field-values have changed for each event, given that changed values can
121
- // be introspected by indexers due to the design of this smart contract
122
- // exposing these state changes via publicly viewable fields.
123
- //
124
- // The following fields are used to indicate which contract-level parameter
125
- // has been updated in the `PlatformUpdated` event:
126
- bytes32 constant FIELD_NEXT_PROJECT_ID = "nextProjectId";
127
- bytes32 constant FIELD_NEW_PROJECTS_FORBIDDEN = "newProjectsForbidden";
128
- bytes32 constant FIELD_DEFAULT_BASE_URI = "defaultBaseURI";
129
- bytes32 constant FIELD_RANDOMIZER_ADDRESS = "randomizerAddress";
130
- bytes32 constant FIELD_ARTBLOCKS_DEPENDENCY_REGISTRY_ADDRESS =
131
- "dependencyRegistryAddress";
132
- bytes32 constant FIELD_PROVIDER_SALES_ADDRESSES = "providerSalesAddresses";
133
- bytes32 constant FIELD_PROVIDER_PRIMARY_SALES_PERCENTAGES =
134
- "providerPrimaryPercentages";
135
- bytes32 constant FIELD_PROVIDER_SECONDARY_SALES_BPS =
136
- "providerSecondaryBPS";
137
- // The following fields are used to indicate which project-level parameter
138
- // has been updated in the `ProjectUpdated` event:
139
- bytes32 constant FIELD_PROJECT_COMPLETED = "completed";
140
- bytes32 constant FIELD_PROJECT_ACTIVE = "active";
141
- bytes32 constant FIELD_PROJECT_ARTIST_ADDRESS = "artistAddress";
142
- bytes32 constant FIELD_PROJECT_PAUSED = "paused";
143
- bytes32 constant FIELD_PROJECT_CREATED = "created";
144
- bytes32 constant FIELD_PROJECT_NAME = "name";
145
- bytes32 constant FIELD_PROJECT_ARTIST_NAME = "artistName";
146
- bytes32 constant FIELD_PROJECT_SECONDARY_MARKET_ROYALTY_PERCENTAGE =
147
- "royaltyPercentage";
148
- bytes32 constant FIELD_PROJECT_DESCRIPTION = "description";
149
- bytes32 constant FIELD_PROJECT_WEBSITE = "website";
150
- bytes32 constant FIELD_PROJECT_LICENSE = "license";
151
- bytes32 constant FIELD_PROJECT_MAX_INVOCATIONS = "maxInvocations";
152
- bytes32 constant FIELD_PROJECT_SCRIPT = "script";
153
- bytes32 constant FIELD_PROJECT_SCRIPT_TYPE = "scriptType";
154
- bytes32 constant FIELD_PROJECT_ASPECT_RATIO = "aspectRatio";
155
- bytes32 constant FIELD_PROJECT_BASE_URI = "baseURI";
127
+ /// pointer to next core contract associated with this contract
128
+ address public nextCoreContract;
156
129
 
157
130
  /// Dependency registry managed by Art Blocks
158
131
  address public artblocksDependencyRegistryAddress;
132
+ /// On chain generator managed by Art Blocks
133
+ address public artblocksOnChainGeneratorAddress;
134
+
135
+ /// ensure initialization can only be performed once
136
+ bool private _initialized;
159
137
 
160
138
  /// current randomizer contract
161
139
  IRandomizer_V3CoreBase public randomizerContract;
@@ -189,20 +167,10 @@ contract GenArt721CoreV3_Engine is
189
167
 
190
168
  mapping(uint256 => Project) projects;
191
169
 
192
- /// packed struct containing project financial information
193
- struct ProjectFinance {
194
- address payable additionalPayeePrimarySales;
195
- // packed uint: max of 95, max uint8 = 255
196
- uint8 secondaryMarketRoyaltyPercentage;
197
- address payable additionalPayeeSecondarySales;
198
- // packed uint: max of 100, max uint8 = 255
199
- uint8 additionalPayeeSecondarySalesPercentage;
200
- address payable artistAddress;
201
- // packed uint: max of 100, max uint8 = 255
202
- uint8 additionalPayeePrimarySalesPercentage;
203
- }
204
- // Project financials mapping
205
- mapping(uint256 => ProjectFinance) projectIdToFinancials;
170
+ /// private mapping from project ID to project financial information. See
171
+ /// `projectIdToFinancials` getter for public access.
172
+ mapping(uint256 _projectId => ProjectFinance)
173
+ private _projectIdToFinancials;
206
174
 
207
175
  /// hash of artist's proposed payment updates to be approved by admin
208
176
  mapping(uint256 => bytes32) public proposedArtistAddressesAndSplitsHash;
@@ -213,33 +181,54 @@ contract GenArt721CoreV3_Engine is
213
181
  /// Percentage of primary sales revenue allocated to the render provider
214
182
  /// (packed)
215
183
  // packed uint: max of 100, max uint8 = 255
216
- uint8 private _renderProviderPrimarySalesPercentage = 10;
184
+ uint8 private _renderProviderPrimarySalesPercentage;
217
185
  /// The platform provider payment address for all primary sales revenues
218
186
  /// (packed)
219
187
  address payable public platformProviderPrimarySalesAddress;
220
188
  /// Percentage of primary sales revenue allocated to the platform provider
221
189
  /// (packed)
222
190
  // packed uint: max of 100, max uint8 = 255
223
- uint8 private _platformProviderPrimarySalesPercentage = 10;
224
-
225
- /// The render provider payment address for all secondary sales royalty
226
- /// revenues
227
- address payable public renderProviderSecondarySalesAddress;
228
- /// Basis Points of secondary sales royalties allocated to the
229
- /// render provider
230
- uint256 public renderProviderSecondarySalesBPS = 250;
231
- /// The platform provider payment address for all secondary sales royalty
232
- /// revenues
233
- address payable public platformProviderSecondarySalesAddress;
234
- /// Basis Points of secondary sales royalties allocated to the
235
- /// platform provider
236
- uint256 public platformProviderSecondarySalesBPS = 250;
191
+ uint8 private _platformProviderPrimarySalesPercentage;
192
+
193
+ /// @dev Note on "default" provider secondary values - the only way these can
194
+ /// be different on a per project basis is if admin updates these and then
195
+ /// does not call syncProviderSecondaryForProjectToDefaults for the project.
196
+ /// -----------------------------------------------------------------------
197
+ /// The default render provider payment address for all secondary sales royalty
198
+ /// revenues, for all new projects. Individual project payment info is defined
199
+ /// in each project's ProjectFinance struct.
200
+ /// Projects can be updated to this value by calling the
201
+ /// `syncProviderSecondaryForProjectToDefaults` function for each project.
202
+ address payable public defaultRenderProviderSecondarySalesAddress;
203
+ /// The default basis points allocated to render provider for all secondary
204
+ /// sales royalty revenues, for all new projects. Individual project
205
+ /// payment info is defined in each project's ProjectFinance struct.
206
+ /// Projects can be updated to this value by calling the
207
+ /// `syncProviderSecondaryForProjectToDefaults` function for each project.
208
+ uint256 public defaultRenderProviderSecondarySalesBPS;
209
+ /// The default platform provider payment address for all secondary sales royalty
210
+ /// revenues, for all new projects. Individual project payment info is defined
211
+ /// in each project's ProjectFinance struct.
212
+ /// Projects can be updated to this value by calling the
213
+ /// `syncProviderSecondaryForProjectToDefaults` function for each project.
214
+ address payable public defaultPlatformProviderSecondarySalesAddress;
215
+ /// The default basis points allocated to platform provider for all secondary
216
+ /// sales royalty revenues, for all new projects. Individual project
217
+ /// payment info is defined in each project's ProjectFinance struct.
218
+ /// Projects can be updated to this value by calling the
219
+ /// `syncProviderSecondaryForProjectToDefaults` function for each project.
220
+ uint256 public defaultPlatformProviderSecondarySalesBPS;
221
+ /// -----------------------------------------------------------------------
237
222
 
238
223
  /// single minter allowed for this core contract
239
224
  address public minterContract;
240
225
 
241
- /// starting (initial) project ID on this contract
242
- uint256 public immutable startingProjectId;
226
+ /// starting (initial) project ID on this contract configured
227
+ /// at time of deployment and intended to be immutable after initialization.
228
+ /// Not marked as immutable due to initialization requirements
229
+ /// under the ERC-1167 minimal proxy pattern, which necessitates
230
+ /// setting this value post-deployment.
231
+ uint256 public startingProjectId;
243
232
 
244
233
  /// next project ID to be created
245
234
  uint248 private _nextProjectId;
@@ -248,19 +237,39 @@ contract GenArt721CoreV3_Engine is
248
237
  /// default behavior is to allow new projects
249
238
  bool public newProjectsForbidden;
250
239
 
251
- /// configuration variable (determined at time of deployment)
252
- /// that determines whether or not admin approval^ should be required
253
- /// to accept artist address change proposals, or if these proposals
254
- /// should always auto-approve, as determined by the business process
255
- /// requirements of the Engine partner using this contract.
240
+ /// configuration variable set at time of deployment, intended to be
241
+ /// immutable after initialization, that determines whether or not
242
+ /// admin approval^ should be required to accept artist address change
243
+ /// proposals, or if these proposals should always auto-approve, as
244
+ /// determined by the business process requirements of the Engine
245
+ /// partner using this contract.
256
246
  ///
257
247
  /// ^does not apply in the case where contract-ownership itself is revoked
258
- bool public immutable autoApproveArtistSplitProposals;
248
+ /// Not marked as immutable due to initialization requirements
249
+ /// under the ERC-1167 minimal proxy pattern, which necessitates
250
+ /// setting this value post-deployment.
251
+ bool public autoApproveArtistSplitProposals;
252
+
253
+ /// configuration variable set at time of deployment, intended to be
254
+ /// immutable after initialization, that determines if platform provider
255
+ /// fees and addresses are always required to be set to zero.
256
+ /// Not marked as immutable due to initialization requirements
257
+ /// under the ERC-1167 minimal proxy pattern, which necessitates
258
+ /// setting this value post-deployment.
259
+ bool public nullPlatformProvider;
260
+
261
+ /// configuration variable set at time of deployment, intended to be
262
+ /// immutable after initialization, that determines if artists are allowed
263
+ /// to activate their own projects.
264
+ /// Not marked as immutable due to initialization requirements
265
+ /// under the ERC-1167 minimal proxy pattern, which necessitates
266
+ /// setting this value post-deployment.
267
+ bool public allowArtistProjectActivation;
259
268
 
260
269
  /// version & type of this core contract
261
- bytes32 constant CORE_VERSION = "v3.1.4";
270
+ bytes32 constant CORE_VERSION = "v3.2.4";
262
271
 
263
- function coreVersion() external pure returns (string memory) {
272
+ function coreVersion() external pure virtual returns (string memory) {
264
273
  return CORE_VERSION.toString();
265
274
  }
266
275
 
@@ -273,54 +282,87 @@ contract GenArt721CoreV3_Engine is
273
282
  /// default base URI to initialize all new project projectBaseURI values to
274
283
  string public defaultBaseURI;
275
284
 
285
+ // ERC2981 royalty support and default royalty values
286
+ bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a;
287
+ uint8 private constant _DEFAULT_ARTIST_SECONDARY_ROYALTY_PERCENTAGE = 5;
288
+
289
+ // royalty split provider
290
+ ISplitProviderV0 public splitProvider;
291
+
292
+ // bytecode storage reader contract; may be universal or specific version reader contract
293
+ IBytecodeStorageReader_Base public bytecodeStorageReaderContract;
294
+
295
+ /**
296
+ * @dev This constructor sets the owner to a non-functional address as a formality.
297
+ * It is only ever ran on the implementation contract. The `Ownable` constructor is
298
+ * called to satisfy the contract's inheritance requirements. This owner has no
299
+ * operational significance and should not be considered secure or meaningful.
300
+ * The true ownership will be set in the `initialize` function post-deployment to
301
+ * ensure correct owner management in the proxy architecture.
302
+ * Explicitly setting the owner to '0xdead' to indicate non-operational use.
303
+ */
304
+ constructor() Ownable(0x000000000000000000000000000000000000dEaD) {}
305
+
276
306
  function _onlyNonZeroAddress(address _address) internal pure {
277
- require(_address != address(0), "Must input non-zero address");
307
+ if (_address == address(0)) {
308
+ revert GenArt721Error(ErrorCodes.OnlyNonZeroAddress);
309
+ }
278
310
  }
279
311
 
280
312
  function _onlyNonEmptyString(string memory _string) internal pure {
281
- require(bytes(_string).length != 0, "Must input non-empty string");
313
+ if (bytes(_string).length == 0) {
314
+ revert GenArt721Error(ErrorCodes.OnlyNonEmptyString);
315
+ }
316
+ }
317
+
318
+ function _onlyNonEmptyBytes(bytes memory _bytes) internal pure {
319
+ if (_bytes.length == 0) {
320
+ revert GenArt721Error(ErrorCodes.OnlyNonEmptyBytes);
321
+ }
282
322
  }
283
323
 
284
324
  function _onlyValidTokenId(uint256 _tokenId) internal view {
285
- require(_exists(_tokenId), "Token ID does not exist");
325
+ if (_ownerOf(_tokenId) == address(0)) {
326
+ revert GenArt721Error(ErrorCodes.TokenDoesNotExist);
327
+ }
286
328
  }
287
329
 
288
330
  function _onlyValidProjectId(uint256 _projectId) internal view {
289
- require(
290
- (_projectId >= startingProjectId) && (_projectId < _nextProjectId),
291
- "Project ID does not exist"
292
- );
331
+ if (_projectId < startingProjectId || _projectId >= _nextProjectId) {
332
+ revert GenArt721Error(ErrorCodes.ProjectDoesNotExist);
333
+ }
293
334
  }
294
335
 
295
336
  function _onlyUnlocked(uint256 _projectId) internal view {
296
337
  // Note: calling `_projectUnlocked` enforces that the `_projectId`
297
338
  // passed in is valid.`
298
- require(_projectUnlocked(_projectId), "Only if unlocked");
339
+ if (!_projectUnlocked(_projectId)) {
340
+ revert GenArt721Error(ErrorCodes.OnlyUnlockedProjects);
341
+ }
299
342
  }
300
343
 
301
344
  function _onlyAdminACL(bytes4 _selector) internal {
302
- require(
303
- adminACLAllowed(msg.sender, address(this), _selector),
304
- "Only Admin ACL allowed"
305
- );
345
+ if (!adminACLAllowed(msg.sender, address(this), _selector)) {
346
+ revert GenArt721Error(ErrorCodes.OnlyAdminACL);
347
+ }
306
348
  }
307
349
 
308
350
  function _onlyArtist(uint256 _projectId) internal view {
309
- require(
310
- msg.sender == projectIdToFinancials[_projectId].artistAddress,
311
- "Only artist"
312
- );
351
+ if (msg.sender != _projectIdToFinancials[_projectId].artistAddress) {
352
+ revert GenArt721Error(ErrorCodes.OnlyArtist);
353
+ }
313
354
  }
314
355
 
315
356
  function _onlyArtistOrAdminACL(
316
357
  uint256 _projectId,
317
358
  bytes4 _selector
318
359
  ) internal {
319
- require(
320
- msg.sender == projectIdToFinancials[_projectId].artistAddress ||
321
- adminACLAllowed(msg.sender, address(this), _selector),
322
- "Only artist or Admin ACL allowed"
323
- );
360
+ if (
361
+ !(msg.sender == _projectIdToFinancials[_projectId].artistAddress ||
362
+ adminACLAllowed(msg.sender, address(this), _selector))
363
+ ) {
364
+ revert GenArt721Error(ErrorCodes.OnlyArtistOrAdminACL);
365
+ }
324
366
  }
325
367
 
326
368
  /**
@@ -333,71 +375,50 @@ contract GenArt721CoreV3_Engine is
333
375
  uint256 _projectId,
334
376
  bytes4 _selector
335
377
  ) internal {
336
- require(
337
- adminACLAllowed(msg.sender, address(this), _selector) ||
338
- (owner() == address(0) &&
339
- msg.sender ==
340
- projectIdToFinancials[_projectId].artistAddress),
341
- "Only Admin ACL allowed, or artist if owner has renounced"
342
- );
378
+ // check if Admin ACL is allowed to call this function
379
+ if (adminACLAllowed(msg.sender, address(this), _selector)) {
380
+ return;
381
+ }
382
+ // check if the owner has renounced ownership and the caller is the
383
+ // artist of the project
384
+ if (
385
+ owner() == address(0) &&
386
+ msg.sender == _projectIdToFinancials[_projectId].artistAddress
387
+ ) {
388
+ return;
389
+ }
390
+ // neither of the above conditions were met, revert
391
+ revert GenArt721Error(ErrorCodes.OnlyAdminACLOrRenouncedArtist);
343
392
  }
344
393
 
345
394
  /**
346
- * @notice Initializes contract.
347
- * @param _tokenName Name of token.
348
- * @param _tokenSymbol Token symbol.
349
- * @param _randomizerContract Randomizer contract.
350
- * @param _adminACLContract Address of admin access control contract, to be
395
+ * @notice Initializes the contract with the provided `engineConfiguration`.
396
+ * This function should be called atomically, immediately after deployment.
397
+ * Only callable once. Validation on `engineConfiguration` is performed by caller.
398
+ * @dev This function is intentionally unpermissioned to allow for the
399
+ * initialization of the contract post-deployment. It is expected that this
400
+ * function will be called atomically by the factory contract that deploys this
401
+ * contract, after which it will be initialized and uncallable.
402
+ * @param engineConfiguration EngineConfiguration to configure the contract with.
403
+ * note: parameter `engineConfiguration.newSuperAdminAddress` is not used or operated on in this contract.
404
+ * @param adminACLContract_ Address of admin access control contract, to be
351
405
  * set as contract owner.
352
- * @param _startingProjectId The initial next project ID.
353
- * @param _autoApproveArtistSplitProposals Whether or not to always
354
- * auto-approve proposed artist split updates.
355
- * @dev _startingProjectId should be set to a value much, much less than
356
- * max(uint248), but an explicit input type of `uint248` is used as it is
357
- * safer to cast up to `uint256` than it is to cast down for the purposes
358
- * of setting `_nextProjectId`.
359
- */
360
- constructor(
361
- string memory _tokenName,
362
- string memory _tokenSymbol,
363
- address _renderProviderAddress,
364
- address _platformProviderAddress,
365
- address _randomizerContract,
366
- address _adminACLContract,
367
- uint248 _startingProjectId,
368
- bool _autoApproveArtistSplitProposals
369
- ) ERC721_PackedHashSeed(_tokenName, _tokenSymbol) {
370
- _onlyNonZeroAddress(_renderProviderAddress);
371
- _onlyNonZeroAddress(_platformProviderAddress);
372
- _onlyNonZeroAddress(_randomizerContract);
373
- _onlyNonZeroAddress(_adminACLContract);
374
- // setup immutable `autoApproveArtistSplitProposals` config
375
- autoApproveArtistSplitProposals = _autoApproveArtistSplitProposals;
376
- // record contracts starting project ID
377
- // casting-up is safe
378
- startingProjectId = uint256(_startingProjectId);
379
- _updateProviderSalesAddresses(
380
- _renderProviderAddress,
381
- _renderProviderAddress,
382
- _platformProviderAddress,
383
- _platformProviderAddress
384
- );
385
- _updateRandomizerAddress(_randomizerContract);
386
- // set AdminACL management contract as owner
387
- _transferOwnership(_adminACLContract);
388
- // initialize default base URI
389
- _updateDefaultBaseURI(
390
- string.concat(
391
- "https://token.artblocks.io/",
392
- address(this).toHexString(),
393
- "/"
394
- )
395
- );
396
- // initialize next project ID
397
- _nextProjectId = _startingProjectId;
398
- emit PlatformUpdated(FIELD_NEXT_PROJECT_ID);
399
- // @dev follow-on action: This contract does not self-register. A core
400
- // registry owner must register contract in a subsequent call.
406
+ * @param defaultBaseURIHost Base URI prefix to initialize default base URI with.
407
+ * @param bytecodeStorageReaderContract_ Address of the bytecode storage reader contract.
408
+ */
409
+ function initialize(
410
+ EngineConfiguration memory engineConfiguration,
411
+ address adminACLContract_,
412
+ string memory defaultBaseURIHost,
413
+ address bytecodeStorageReaderContract_
414
+ ) external virtual {
415
+ // @dev internal function call so derived contracts have access to initialization logic
416
+ _initialize({
417
+ engineConfiguration: engineConfiguration,
418
+ adminACLContract_: adminACLContract_,
419
+ defaultBaseURIHost: defaultBaseURIHost,
420
+ bytecodeStorageReaderContract_: bytecodeStorageReaderContract_
421
+ });
401
422
  }
402
423
 
403
424
  /**
@@ -417,7 +438,9 @@ contract GenArt721CoreV3_Engine is
417
438
  address _by
418
439
  ) external returns (uint256 _tokenId) {
419
440
  // CHECKS
420
- require(msg.sender == minterContract, "Must mint from minter contract");
441
+ if (msg.sender != minterContract) {
442
+ revert GenArt721Error(ErrorCodes.OnlyMinterContract);
443
+ }
421
444
  Project storage project = projects[_projectId];
422
445
  // load invocations into memory
423
446
  uint24 invocationsBefore = project.invocations;
@@ -428,21 +451,21 @@ contract GenArt721CoreV3_Engine is
428
451
  invocationsAfter = invocationsBefore + 1;
429
452
  }
430
453
  uint24 maxInvocations = project.maxInvocations;
431
-
432
- require(
433
- invocationsBefore < maxInvocations,
434
- "Must not exceed max invocations"
435
- );
436
- require(
437
- project.active ||
438
- _by == projectIdToFinancials[_projectId].artistAddress,
439
- "Project must exist and be active"
440
- );
441
- require(
442
- !project.paused ||
443
- _by == projectIdToFinancials[_projectId].artistAddress,
444
- "Purchases are paused."
445
- );
454
+ if (invocationsBefore >= maxInvocations) {
455
+ revert GenArt721Error(ErrorCodes.MaxInvocationsReached);
456
+ }
457
+ if (
458
+ !(project.active ||
459
+ _by == _projectIdToFinancials[_projectId].artistAddress)
460
+ ) {
461
+ revert GenArt721Error(ErrorCodes.ProjectMustExistAndBeActive);
462
+ }
463
+ if (
464
+ project.paused &&
465
+ _by != _projectIdToFinancials[_projectId].artistAddress
466
+ ) {
467
+ revert GenArt721Error(ErrorCodes.PurchasesPaused);
468
+ }
446
469
 
447
470
  // EFFECTS
448
471
  // increment project's invocations
@@ -494,15 +517,15 @@ contract GenArt721CoreV3_Engine is
494
517
  OwnerAndHashSeed storage ownerAndHashSeed = _ownersAndHashSeeds[
495
518
  _tokenId
496
519
  ];
497
- require(
498
- msg.sender == address(randomizerContract),
499
- "Only randomizer may set"
500
- );
501
- require(
502
- ownerAndHashSeed.hashSeed == bytes12(0),
503
- "Token hash already set"
504
- );
505
- require(_hashSeed != bytes12(0), "No zero hash seed");
520
+ if (msg.sender != address(randomizerContract)) {
521
+ revert GenArt721Error(ErrorCodes.OnlyRandomizer);
522
+ }
523
+ if (ownerAndHashSeed.hashSeed != bytes12(0)) {
524
+ revert GenArt721Error(ErrorCodes.TokenHashAlreadySet);
525
+ }
526
+ if (_hashSeed == bytes12(0)) {
527
+ revert GenArt721Error(ErrorCodes.NoZeroHashSeed);
528
+ }
506
529
  ownerAndHashSeed.hashSeed = bytes12(_hashSeed);
507
530
  }
508
531
 
@@ -533,6 +556,18 @@ contract GenArt721CoreV3_Engine is
533
556
  Ownable.renounceOwnership();
534
557
  }
535
558
 
559
+ /**
560
+ * @notice Updates reference to next core contract, associated with this contract.
561
+ * @param _nextCoreContract Address of the next core contract
562
+ */
563
+ function updateNextCoreContract(address _nextCoreContract) external {
564
+ _onlyAdminACL(this.updateNextCoreContract.selector);
565
+ nextCoreContract = _nextCoreContract;
566
+ emit PlatformUpdated(
567
+ bytes32(uint256(PlatformUpdatedFields.FIELD_NEXT_CORE_CONTRACT))
568
+ );
569
+ }
570
+
536
571
  /**
537
572
  * @notice Updates reference to Art Blocks Dependency Registry contract.
538
573
  * @param _artblocksDependencyRegistryAddress Address of new Dependency
@@ -544,43 +579,74 @@ contract GenArt721CoreV3_Engine is
544
579
  _onlyAdminACL(this.updateArtblocksDependencyRegistryAddress.selector);
545
580
  _onlyNonZeroAddress(_artblocksDependencyRegistryAddress);
546
581
  artblocksDependencyRegistryAddress = _artblocksDependencyRegistryAddress;
547
- emit PlatformUpdated(FIELD_ARTBLOCKS_DEPENDENCY_REGISTRY_ADDRESS);
582
+ emit PlatformUpdated(
583
+ bytes32(
584
+ uint256(
585
+ PlatformUpdatedFields
586
+ .FIELD_ARTBLOCKS_DEPENDENCY_REGISTRY_ADDRESS
587
+ )
588
+ )
589
+ );
590
+ }
591
+
592
+ /**
593
+ * @notice Updates reference to Art Blocks On Chain Generator contract.
594
+ * @param _artblocksOnChainGeneratorAddress Address of new on chain generator.
595
+ */
596
+ function updateArtblocksOnChainGeneratorAddress(
597
+ address _artblocksOnChainGeneratorAddress
598
+ ) external {
599
+ _onlyAdminACL(this.updateArtblocksOnChainGeneratorAddress.selector);
600
+ _onlyNonZeroAddress(_artblocksOnChainGeneratorAddress);
601
+ artblocksOnChainGeneratorAddress = _artblocksOnChainGeneratorAddress;
602
+ emit PlatformUpdated(
603
+ bytes32(
604
+ uint256(
605
+ PlatformUpdatedFields
606
+ .FIELD_ARTBLOCKS_ON_CHAIN_GENERATOR_ADDRESS
607
+ )
608
+ )
609
+ );
548
610
  }
549
611
 
550
612
  /**
551
613
  * @notice Updates sales addresses for the platform and render providers to
552
614
  * the input parameters.
615
+ * note: This does not update splitter contracts for all projects on
616
+ * this core contract. If updated splitter contracts are desired, they must be
617
+ * updated after this update via the `syncProviderSecondaryForProjectToDefaults` function.
553
618
  * @param _renderProviderPrimarySalesAddress Address of new primary sales
554
619
  * payment address.
555
- * @param _renderProviderSecondarySalesAddress Address of new secondary sales
620
+ * @param _defaultRenderProviderSecondarySalesAddress Default address of new secondary sales
556
621
  * payment address.
557
622
  * @param _platformProviderPrimarySalesAddress Address of new primary sales
558
623
  * payment address.
559
- * @param _platformProviderSecondarySalesAddress Address of new secondary sales
624
+ * @param _defaultPlatformProviderSecondarySalesAddress Default address of new secondary sales
560
625
  * payment address.
561
626
  */
562
627
  function updateProviderSalesAddresses(
563
628
  address payable _renderProviderPrimarySalesAddress,
564
- address payable _renderProviderSecondarySalesAddress,
629
+ address payable _defaultRenderProviderSecondarySalesAddress,
565
630
  address payable _platformProviderPrimarySalesAddress,
566
- address payable _platformProviderSecondarySalesAddress
631
+ address payable _defaultPlatformProviderSecondarySalesAddress
567
632
  ) external {
568
633
  _onlyAdminACL(this.updateProviderSalesAddresses.selector);
569
634
  _onlyNonZeroAddress(_renderProviderPrimarySalesAddress);
570
- _onlyNonZeroAddress(_renderProviderSecondarySalesAddress);
571
- _onlyNonZeroAddress(_platformProviderPrimarySalesAddress);
572
- _onlyNonZeroAddress(_platformProviderSecondarySalesAddress);
635
+ _onlyNonZeroAddress(_defaultRenderProviderSecondarySalesAddress);
636
+ // @dev checks on platform provider addresses performed in _updateProviderSalesAddresses
573
637
  _updateProviderSalesAddresses(
574
638
  _renderProviderPrimarySalesAddress,
575
- _renderProviderSecondarySalesAddress,
639
+ _defaultRenderProviderSecondarySalesAddress,
576
640
  _platformProviderPrimarySalesAddress,
577
- _platformProviderSecondarySalesAddress
641
+ _defaultPlatformProviderSecondarySalesAddress
578
642
  );
579
643
  }
580
644
 
581
645
  /**
582
646
  * @notice Updates the render and platform provider primary sales revenue percentage to
583
647
  * the provided inputs.
648
+ * If contract is configured to have a null platform provider, the platform provider
649
+ * primary sales percentage must be set to zero.
584
650
  * @param renderProviderPrimarySalesPercentage_ New primary sales revenue % for the render provider
585
651
  * @param platformProviderPrimarySalesPercentage_ New primary sales revenue % for the platform provider
586
652
  * percentage.
@@ -590,13 +656,20 @@ contract GenArt721CoreV3_Engine is
590
656
  uint256 platformProviderPrimarySalesPercentage_
591
657
  ) external {
592
658
  _onlyAdminACL(this.updateProviderPrimarySalesPercentages.selector);
659
+ // require no platform provider payment if null platform provider
660
+ if (
661
+ nullPlatformProvider && platformProviderPrimarySalesPercentage_ != 0
662
+ ) {
663
+ revert GenArt721Error(ErrorCodes.OnlyNullPlatformProvider);
664
+ }
593
665
 
594
666
  // Validate that the sum of the proposed %s, does not exceed 100%.
595
- require(
667
+ if (
596
668
  (renderProviderPrimarySalesPercentage_ +
597
- platformProviderPrimarySalesPercentage_) <= ONE_HUNDRED,
598
- "Max sum of ONE_HUNDRED %"
599
- );
669
+ platformProviderPrimarySalesPercentage_) > ONE_HUNDRED
670
+ ) {
671
+ revert GenArt721Error(ErrorCodes.OverMaxSumOfPercentages);
672
+ }
600
673
  // Casting to `uint8` here is safe due check above, which does not allow
601
674
  // overflow as of solidity version ^0.8.0.
602
675
  _renderProviderPrimarySalesPercentage = uint8(
@@ -605,15 +678,27 @@ contract GenArt721CoreV3_Engine is
605
678
  _platformProviderPrimarySalesPercentage = uint8(
606
679
  platformProviderPrimarySalesPercentage_
607
680
  );
608
- emit PlatformUpdated(FIELD_PROVIDER_PRIMARY_SALES_PERCENTAGES);
681
+ emit PlatformUpdated(
682
+ bytes32(
683
+ uint256(
684
+ PlatformUpdatedFields
685
+ .FIELD_PROVIDER_PRIMARY_SALES_PERCENTAGES
686
+ )
687
+ )
688
+ );
609
689
  }
610
690
 
611
691
  /**
612
- * @notice Updates render and platform provider secondary sales royalty Basis Points to
613
- * the provided inputs.
614
- * @param _renderProviderSecondarySalesBPS New secondary sales royalty Basis
692
+ * @notice Updates default render and platform provider secondary sales royalty
693
+ * Basis Points to the provided inputs.
694
+ * If contract is configured to have a null platform provider, the platform provider
695
+ * secondary sales BPS must be set to zero.
696
+ * note: This does not update splitter contracts for all projects on
697
+ * this core contract. If updated splitter contracts are desired, they must be
698
+ * updated after this update via the `syncProviderSecondaryForProjectToDefaults` function.
699
+ * @param _defaultRenderProviderSecondarySalesBPS New default secondary sales royalty Basis
615
700
  * points.
616
- * @param _platformProviderSecondarySalesBPS New secondary sales royalty Basis
701
+ * @param _defaultPlatformProviderSecondarySalesBPS New default secondary sales royalty Basis
617
702
  * points.
618
703
  * @dev Due to secondary royalties being ultimately enforced via social
619
704
  * consensus, no hard upper limit is imposed on the BPS value, other than
@@ -621,21 +706,35 @@ contract GenArt721CoreV3_Engine is
621
706
  * changing this value is expected to either never occur, or be a rare
622
707
  * occurrence.
623
708
  */
624
- function updateProviderSecondarySalesBPS(
625
- uint256 _renderProviderSecondarySalesBPS,
626
- uint256 _platformProviderSecondarySalesBPS
709
+ function updateProviderDefaultSecondarySalesBPS(
710
+ uint256 _defaultRenderProviderSecondarySalesBPS,
711
+ uint256 _defaultPlatformProviderSecondarySalesBPS
627
712
  ) external {
628
- _onlyAdminACL(this.updateProviderSecondarySalesBPS.selector);
713
+ _onlyAdminACL(this.updateProviderDefaultSecondarySalesBPS.selector);
714
+ // require no platform provider payment if null platform provider
715
+ if (
716
+ nullPlatformProvider &&
717
+ _defaultPlatformProviderSecondarySalesBPS != 0
718
+ ) {
719
+ revert GenArt721Error(ErrorCodes.OnlyNullPlatformProvider);
720
+ }
629
721
  // Validate that the sum of the proposed provider BPS, does not exceed 10_000 BPS.
630
- require(
631
- (_renderProviderSecondarySalesBPS +
632
- _platformProviderSecondarySalesBPS) <=
633
- MAX_PROVIDER_SECONDARY_SALES_BPS,
634
- "Over max sum of BPS"
722
+ if (
723
+ _defaultRenderProviderSecondarySalesBPS +
724
+ _defaultPlatformProviderSecondarySalesBPS >
725
+ MAX_PROVIDER_SECONDARY_SALES_BPS
726
+ ) {
727
+ revert GenArt721Error(ErrorCodes.OverMaxSumOfBPS);
728
+ }
729
+ defaultRenderProviderSecondarySalesBPS = _defaultRenderProviderSecondarySalesBPS;
730
+ defaultPlatformProviderSecondarySalesBPS = _defaultPlatformProviderSecondarySalesBPS;
731
+ emit PlatformUpdated(
732
+ bytes32(
733
+ uint256(
734
+ PlatformUpdatedFields.FIELD_PROVIDER_SECONDARY_SALES_BPS
735
+ )
736
+ )
635
737
  );
636
- renderProviderSecondarySalesBPS = _renderProviderSecondarySalesBPS;
637
- platformProviderSecondarySalesBPS = _platformProviderSecondarySalesBPS;
638
- emit PlatformUpdated(FIELD_PROVIDER_SECONDARY_SALES_BPS);
639
738
  }
640
739
 
641
740
  /**
@@ -645,8 +744,7 @@ contract GenArt721CoreV3_Engine is
645
744
  function updateMinterContract(address _address) external {
646
745
  _onlyAdminACL(this.updateMinterContract.selector);
647
746
  _onlyNonZeroAddress(_address);
648
- minterContract = _address;
649
- emit MinterUpdated(_address);
747
+ _updateMinterContract(_address);
650
748
  }
651
749
 
652
750
  /**
@@ -659,15 +757,51 @@ contract GenArt721CoreV3_Engine is
659
757
  _updateRandomizerAddress(_randomizerAddress);
660
758
  }
661
759
 
760
+ /**
761
+ * @notice Updates split provider address to `_splitProviderAddress`.
762
+ * Reverts if `_splitProviderAddress` is zero address.
763
+ * @param _splitProviderAddress New split provider address.
764
+ */
765
+ function updateSplitProvider(address _splitProviderAddress) external {
766
+ _onlyAdminACL(this.updateSplitProvider.selector);
767
+ _updateSplitProvider(_splitProviderAddress);
768
+ }
769
+
770
+ /**
771
+ * @notice Updates bytecode storage reader contract to `_bytecodeStorageReaderContract`.
772
+ * Reverts if `_bytecodeStorageReaderContract` is zero address.
773
+ * Updating the active Bytecode Storage Reader contract may affect the ability to read
774
+ * data related to existing projects. Care should be taken to ensure that the new
775
+ * contract is compatible with the existing project data.
776
+ * @param _bytecodeStorageReaderContract New bytecode storage reader contract address.
777
+ */
778
+ function updateBytecodeStorageReaderContract(
779
+ address _bytecodeStorageReaderContract
780
+ ) external {
781
+ _onlyAdminACL(this.updateBytecodeStorageReaderContract.selector);
782
+ _onlyNonZeroAddress(_bytecodeStorageReaderContract);
783
+ _updateBytecodeStorageReaderContract(_bytecodeStorageReaderContract);
784
+ }
785
+
662
786
  /**
663
787
  * @notice Toggles project `_projectId` as active/inactive.
664
788
  * @param _projectId Project ID to be toggled.
665
789
  */
666
790
  function toggleProjectIsActive(uint256 _projectId) external {
667
- _onlyAdminACL(this.toggleProjectIsActive.selector);
791
+ if (allowArtistProjectActivation) {
792
+ _onlyArtistOrAdminACL(
793
+ _projectId,
794
+ this.toggleProjectIsActive.selector
795
+ );
796
+ } else {
797
+ _onlyAdminACL(this.toggleProjectIsActive.selector);
798
+ }
668
799
  _onlyValidProjectId(_projectId);
669
800
  projects[_projectId].active = !projects[_projectId].active;
670
- emit ProjectUpdated(_projectId, FIELD_PROJECT_ACTIVE);
801
+ emit ProjectUpdated(
802
+ _projectId,
803
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_ACTIVE))
804
+ );
671
805
  }
672
806
 
673
807
  /**
@@ -712,25 +846,28 @@ contract GenArt721CoreV3_Engine is
712
846
  _onlyValidProjectId(_projectId);
713
847
  _onlyArtist(_projectId);
714
848
  _onlyNonZeroAddress(_artistAddress);
715
- ProjectFinance storage projectFinance = projectIdToFinancials[
849
+ ProjectFinance storage projectFinance = _projectIdToFinancials[
716
850
  _projectId
717
851
  ];
718
852
  // checks
719
- require(
720
- _additionalPayeePrimarySalesPercentage <= ONE_HUNDRED &&
721
- _additionalPayeeSecondarySalesPercentage <= ONE_HUNDRED,
722
- "Max of 100%"
723
- );
724
- require(
725
- _additionalPayeePrimarySalesPercentage == 0 ||
726
- _additionalPayeePrimarySales != address(0),
727
- "Primary payee is zero address"
728
- );
729
- require(
730
- _additionalPayeeSecondarySalesPercentage == 0 ||
731
- _additionalPayeeSecondarySales != address(0),
732
- "Secondary payee is zero address"
733
- );
853
+ if (
854
+ _additionalPayeePrimarySalesPercentage > ONE_HUNDRED ||
855
+ _additionalPayeeSecondarySalesPercentage > ONE_HUNDRED
856
+ ) {
857
+ revert GenArt721Error(ErrorCodes.MaxOf100Percent);
858
+ }
859
+ if (
860
+ _additionalPayeePrimarySalesPercentage > 0 &&
861
+ _additionalPayeePrimarySales == address(0)
862
+ ) {
863
+ revert GenArt721Error(ErrorCodes.PrimaryPayeeIsZeroAddress);
864
+ }
865
+ if (
866
+ _additionalPayeeSecondarySalesPercentage > 0 &&
867
+ _additionalPayeeSecondarySales == address(0)
868
+ ) {
869
+ revert GenArt721Error(ErrorCodes.SecondaryPayeeIsZeroAddress);
870
+ }
734
871
  // effects
735
872
  // emit event for off-chain indexing
736
873
  // note: always emit a proposal event, even in the pathway of
@@ -766,6 +903,7 @@ contract GenArt721CoreV3_Engine is
766
903
  if (automaticAccept) {
767
904
  // clear any previously proposed values
768
905
  proposedArtistAddressesAndSplitsHash[_projectId] = bytes32(0);
906
+
769
907
  // update storage
770
908
  // artist address can change during automatic accept if
771
909
  // autoApproveArtistSplitProposals is true
@@ -782,6 +920,11 @@ contract GenArt721CoreV3_Engine is
782
920
  projectFinance.additionalPayeeSecondarySalesPercentage = uint8(
783
921
  _additionalPayeeSecondarySalesPercentage
784
922
  );
923
+
924
+ // assign project's splitter
925
+ // @dev only call after all previous storage updates
926
+ _assignSplitter(_projectId);
927
+
785
928
  // emit event for off-chain indexing
786
929
  emit AcceptedArtistAddressesAndSplits(_projectId);
787
930
  } else {
@@ -837,21 +980,22 @@ contract GenArt721CoreV3_Engine is
837
980
  );
838
981
  _onlyNonZeroAddress(_artistAddress);
839
982
  // checks
840
- require(
841
- proposedArtistAddressesAndSplitsHash[_projectId] ==
842
- keccak256(
843
- abi.encode(
844
- _artistAddress,
845
- _additionalPayeePrimarySales,
846
- _additionalPayeePrimarySalesPercentage,
847
- _additionalPayeeSecondarySales,
848
- _additionalPayeeSecondarySalesPercentage
849
- )
850
- ),
851
- "Must match artist proposal"
852
- );
983
+ if (
984
+ proposedArtistAddressesAndSplitsHash[_projectId] !=
985
+ keccak256(
986
+ abi.encode(
987
+ _artistAddress,
988
+ _additionalPayeePrimarySales,
989
+ _additionalPayeePrimarySalesPercentage,
990
+ _additionalPayeeSecondarySales,
991
+ _additionalPayeeSecondarySalesPercentage
992
+ )
993
+ )
994
+ ) {
995
+ revert GenArt721Error(ErrorCodes.MustMatchArtistProposal);
996
+ }
853
997
  // effects
854
- ProjectFinance storage projectFinance = projectIdToFinancials[
998
+ ProjectFinance storage projectFinance = _projectIdToFinancials[
855
999
  _projectId
856
1000
  ];
857
1001
  projectFinance.artistAddress = _artistAddress;
@@ -867,6 +1011,11 @@ contract GenArt721CoreV3_Engine is
867
1011
  );
868
1012
  // clear proposed values
869
1013
  proposedArtistAddressesAndSplitsHash[_projectId] = bytes32(0);
1014
+
1015
+ // assign project's splitter
1016
+ // @dev only call after all previous storage updates
1017
+ _assignSplitter(_projectId);
1018
+
870
1019
  // emit event for off-chain indexing
871
1020
  emit AcceptedArtistAddressesAndSplits(_projectId);
872
1021
  }
@@ -888,8 +1037,17 @@ contract GenArt721CoreV3_Engine is
888
1037
  this.updateProjectArtistAddress.selector
889
1038
  );
890
1039
  _onlyNonZeroAddress(_artistAddress);
891
- projectIdToFinancials[_projectId].artistAddress = _artistAddress;
892
- emit ProjectUpdated(_projectId, FIELD_PROJECT_ARTIST_ADDRESS);
1040
+
1041
+ _projectIdToFinancials[_projectId].artistAddress = _artistAddress;
1042
+
1043
+ // assign project's splitter
1044
+ // @dev only call after all previous storage updates
1045
+ _assignSplitter(_projectId);
1046
+
1047
+ emit ProjectUpdated(
1048
+ _projectId,
1049
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_ARTIST_ADDRESS))
1050
+ );
893
1051
  }
894
1052
 
895
1053
  /**
@@ -899,7 +1057,10 @@ contract GenArt721CoreV3_Engine is
899
1057
  function toggleProjectIsPaused(uint256 _projectId) external {
900
1058
  _onlyArtist(_projectId);
901
1059
  projects[_projectId].paused = !projects[_projectId].paused;
902
- emit ProjectUpdated(_projectId, FIELD_PROJECT_PAUSED);
1060
+ emit ProjectUpdated(
1061
+ _projectId,
1062
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_PAUSED))
1063
+ );
903
1064
  }
904
1065
 
905
1066
  /**
@@ -915,16 +1076,44 @@ contract GenArt721CoreV3_Engine is
915
1076
  _onlyAdminACL(this.addProject.selector);
916
1077
  _onlyNonEmptyString(_projectName);
917
1078
  _onlyNonZeroAddress(_artistAddress);
918
- require(!newProjectsForbidden, "New projects forbidden");
1079
+ if (newProjectsForbidden) {
1080
+ revert GenArt721Error(ErrorCodes.NewProjectsForbidden);
1081
+ }
919
1082
  uint256 projectId = _nextProjectId;
920
- projectIdToFinancials[projectId].artistAddress = _artistAddress;
1083
+ ProjectFinance storage projectFinance = _projectIdToFinancials[
1084
+ projectId
1085
+ ];
1086
+ projectFinance.artistAddress = _artistAddress;
921
1087
  projects[projectId].name = _projectName;
922
1088
  projects[projectId].paused = true;
923
1089
  projects[projectId].maxInvocations = ONE_MILLION_UINT24;
924
1090
  projects[projectId].projectBaseURI = defaultBaseURI;
1091
+ // assign default artist royalty to artist
1092
+ projectFinance
1093
+ .secondaryMarketRoyaltyPercentage = _DEFAULT_ARTIST_SECONDARY_ROYALTY_PERCENTAGE;
1094
+ // copy default platform and render provider royalties to ProjectFinance
1095
+ projectFinance
1096
+ .platformProviderSecondarySalesAddress = defaultPlatformProviderSecondarySalesAddress;
1097
+ projectFinance.platformProviderSecondarySalesBPS = uint16(
1098
+ defaultPlatformProviderSecondarySalesBPS
1099
+ );
1100
+ projectFinance
1101
+ .renderProviderSecondarySalesAddress = defaultRenderProviderSecondarySalesAddress;
1102
+ projectFinance.renderProviderSecondarySalesBPS = uint16(
1103
+ defaultRenderProviderSecondarySalesBPS
1104
+ );
925
1105
 
926
1106
  _nextProjectId = uint248(projectId) + 1;
927
- emit ProjectUpdated(projectId, FIELD_PROJECT_CREATED);
1107
+
1108
+ // @dev emit initial project created event before splitter event
1109
+ emit ProjectUpdated(
1110
+ projectId,
1111
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_CREATED))
1112
+ );
1113
+
1114
+ // assign project's splitter
1115
+ // @dev only call after all previous storage updates
1116
+ _assignSplitter(projectId);
928
1117
  }
929
1118
 
930
1119
  /**
@@ -932,7 +1121,9 @@ contract GenArt721CoreV3_Engine is
932
1121
  */
933
1122
  function forbidNewProjects() external {
934
1123
  _onlyAdminACL(this.forbidNewProjects.selector);
935
- require(!newProjectsForbidden, "Already forbidden");
1124
+ if (newProjectsForbidden) {
1125
+ revert GenArt721Error(ErrorCodes.NewProjectsAlreadyForbidden);
1126
+ }
936
1127
  _forbidNewProjects();
937
1128
  }
938
1129
 
@@ -949,12 +1140,17 @@ contract GenArt721CoreV3_Engine is
949
1140
  _onlyArtistOrAdminACL(_projectId, this.updateProjectName.selector);
950
1141
  _onlyNonEmptyString(_projectName);
951
1142
  projects[_projectId].name = _projectName;
952
- emit ProjectUpdated(_projectId, FIELD_PROJECT_NAME);
1143
+ emit ProjectUpdated(
1144
+ _projectId,
1145
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_NAME))
1146
+ );
953
1147
  }
954
1148
 
955
1149
  /**
956
1150
  * @notice Updates artist name for project `_projectId` to be
957
1151
  * `_projectArtistName`.
1152
+ * @dev allows admin to update after project is locked, due to our
1153
+ * experiences of artist name changes being requested post-lock.
958
1154
  * @param _projectId Project ID.
959
1155
  * @param _projectArtistName New artist name.
960
1156
  */
@@ -962,42 +1158,111 @@ contract GenArt721CoreV3_Engine is
962
1158
  uint256 _projectId,
963
1159
  string memory _projectArtistName
964
1160
  ) external {
965
- _onlyUnlocked(_projectId);
966
- _onlyArtistOrAdminACL(
967
- _projectId,
968
- this.updateProjectArtistName.selector
969
- );
1161
+ // if unlocked, only artist may update, if locked, only admin may update
1162
+ // @dev valid project checked in _projectUnlocked function
1163
+ if (_projectUnlocked(_projectId)) {
1164
+ if (
1165
+ msg.sender != _projectIdToFinancials[_projectId].artistAddress
1166
+ ) {
1167
+ revert GenArt721Error(ErrorCodes.OnlyArtistOrAdminIfLocked);
1168
+ }
1169
+ } else {
1170
+ if (
1171
+ !adminACLAllowed(
1172
+ msg.sender,
1173
+ address(this),
1174
+ this.updateProjectArtistName.selector
1175
+ )
1176
+ ) {
1177
+ revert GenArt721Error(ErrorCodes.OnlyArtistOrAdminIfLocked);
1178
+ }
1179
+ }
970
1180
  _onlyNonEmptyString(_projectArtistName);
971
1181
  projects[_projectId].artist = _projectArtistName;
972
- emit ProjectUpdated(_projectId, FIELD_PROJECT_ARTIST_NAME);
1182
+ emit ProjectUpdated(
1183
+ _projectId,
1184
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_ARTIST_NAME))
1185
+ );
973
1186
  }
974
1187
 
975
1188
  /**
976
1189
  * @notice Updates artist secondary market royalties for project
977
- * `_projectId` to be `_secondMarketRoyalty` percent.
1190
+ * `_projectId` to be `_secondaryMarketRoyalty` percent.
1191
+ * This deploys a new splitter contract if needed.
978
1192
  * This DOES NOT include the secondary market royalty percentages collected
979
1193
  * by the issuing platform; it is only the total percentage of royalties
980
1194
  * that will be split to artist and additionalSecondaryPayee.
981
1195
  * @param _projectId Project ID.
982
- * @param _secondMarketRoyalty Percent of secondary sales revenue that will
1196
+ * @param _secondaryMarketRoyalty Percent of secondary sales revenue that will
983
1197
  * be split to artist and additionalSecondaryPayee. This must be less than
984
1198
  * or equal to ARTIST_MAX_SECONDARY_ROYALTY_PERCENTAGE percent.
985
1199
  */
986
1200
  function updateProjectSecondaryMarketRoyaltyPercentage(
987
1201
  uint256 _projectId,
988
- uint256 _secondMarketRoyalty
1202
+ uint256 _secondaryMarketRoyalty
989
1203
  ) external {
990
1204
  _onlyArtist(_projectId);
991
- require(
992
- _secondMarketRoyalty <= ARTIST_MAX_SECONDARY_ROYALTY_PERCENTAGE,
993
- "Over max percent"
1205
+ if (_secondaryMarketRoyalty > ARTIST_MAX_SECONDARY_ROYALTY_PERCENTAGE) {
1206
+ revert GenArt721Error(ErrorCodes.OverMaxSecondaryRoyaltyPercentage);
1207
+ }
1208
+ _projectIdToFinancials[_projectId]
1209
+ .secondaryMarketRoyaltyPercentage = uint8(_secondaryMarketRoyalty);
1210
+
1211
+ // assign project's splitter
1212
+ // @dev only call after all previous storage updates
1213
+ _assignSplitter(_projectId);
1214
+
1215
+ emit ProjectUpdated(
1216
+ _projectId,
1217
+ bytes32(
1218
+ uint256(
1219
+ ProjectUpdatedFields
1220
+ .FIELD_PROJECT_SECONDARY_MARKET_ROYALTY_PERCENTAGE
1221
+ )
1222
+ )
1223
+ );
1224
+ }
1225
+
1226
+ /**
1227
+ * @notice Updates platform and render provider secondary market royalty addresses
1228
+ * and BPS to the contract-level default values for project `_projectId`.
1229
+ * This updates the splitter parameters on the existing splitter for the project.
1230
+ * Reverts if called by a non-admin address.
1231
+ * @param _projectId Project ID.
1232
+ */
1233
+ function syncProviderSecondaryForProjectToDefaults(
1234
+ uint256 _projectId
1235
+ ) external {
1236
+ _onlyAdminACL(this.syncProviderSecondaryForProjectToDefaults.selector);
1237
+ _onlyValidProjectId(_projectId);
1238
+ ProjectFinance storage projectFinance = _projectIdToFinancials[
1239
+ _projectId
1240
+ ];
1241
+ // update project finance for project in storage
1242
+ projectFinance
1243
+ .platformProviderSecondarySalesAddress = defaultPlatformProviderSecondarySalesAddress;
1244
+ projectFinance.platformProviderSecondarySalesBPS = uint16(
1245
+ defaultPlatformProviderSecondarySalesBPS
994
1246
  );
995
- projectIdToFinancials[_projectId]
996
- .secondaryMarketRoyaltyPercentage = uint8(_secondMarketRoyalty);
1247
+ projectFinance
1248
+ .renderProviderSecondarySalesAddress = defaultRenderProviderSecondarySalesAddress;
1249
+ projectFinance.renderProviderSecondarySalesBPS = uint16(
1250
+ defaultRenderProviderSecondarySalesBPS
1251
+ );
1252
+
997
1253
  emit ProjectUpdated(
998
1254
  _projectId,
999
- FIELD_PROJECT_SECONDARY_MARKET_ROYALTY_PERCENTAGE
1255
+ bytes32(
1256
+ uint256(
1257
+ ProjectUpdatedFields
1258
+ .FIELD_PROJECT_PROVIDER_SECONDARY_FINANCIALS
1259
+ )
1260
+ )
1000
1261
  );
1262
+
1263
+ // assign project's splitter
1264
+ // @dev only call after all previous storage updates
1265
+ _assignSplitter(_projectId);
1001
1266
  }
1002
1267
 
1003
1268
  /**
@@ -1018,22 +1283,33 @@ contract GenArt721CoreV3_Engine is
1018
1283
  string memory _projectDescription
1019
1284
  ) external {
1020
1285
  // checks
1021
- require(
1022
- _projectUnlocked(_projectId)
1023
- ? msg.sender == projectIdToFinancials[_projectId].artistAddress
1024
- : adminACLAllowed(
1286
+ // if unlocked, only artist may update, if locked, only admin may update
1287
+ if (_projectUnlocked(_projectId)) {
1288
+ if (
1289
+ msg.sender != _projectIdToFinancials[_projectId].artistAddress
1290
+ ) {
1291
+ revert GenArt721Error(ErrorCodes.OnlyArtistOrAdminIfLocked);
1292
+ }
1293
+ } else {
1294
+ if (
1295
+ !adminACLAllowed(
1025
1296
  msg.sender,
1026
1297
  address(this),
1027
1298
  this.updateProjectDescription.selector
1028
- ),
1029
- "Only artist when unlocked, owner when locked"
1030
- );
1299
+ )
1300
+ ) {
1301
+ revert GenArt721Error(ErrorCodes.OnlyArtistOrAdminIfLocked);
1302
+ }
1303
+ }
1031
1304
  // effects
1032
1305
  // store description in contract bytecode, replacing reference address from
1033
1306
  // the old storage description with the newly created one
1034
1307
  projects[_projectId].descriptionAddress = _projectDescription
1035
1308
  .writeToBytecode();
1036
- emit ProjectUpdated(_projectId, FIELD_PROJECT_DESCRIPTION);
1309
+ emit ProjectUpdated(
1310
+ _projectId,
1311
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_DESCRIPTION))
1312
+ );
1037
1313
  }
1038
1314
 
1039
1315
  /**
@@ -1048,7 +1324,10 @@ contract GenArt721CoreV3_Engine is
1048
1324
  ) external {
1049
1325
  _onlyArtist(_projectId);
1050
1326
  projects[_projectId].website = _projectWebsite;
1051
- emit ProjectUpdated(_projectId, FIELD_PROJECT_WEBSITE);
1327
+ emit ProjectUpdated(
1328
+ _projectId,
1329
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_WEBSITE))
1330
+ );
1052
1331
  }
1053
1332
 
1054
1333
  /**
@@ -1064,7 +1343,10 @@ contract GenArt721CoreV3_Engine is
1064
1343
  _onlyArtistOrAdminACL(_projectId, this.updateProjectLicense.selector);
1065
1344
  _onlyNonEmptyString(_projectLicense);
1066
1345
  projects[_projectId].license = _projectLicense;
1067
- emit ProjectUpdated(_projectId, FIELD_PROJECT_LICENSE);
1346
+ emit ProjectUpdated(
1347
+ _projectId,
1348
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_LICENSE))
1349
+ );
1068
1350
  }
1069
1351
 
1070
1352
  /**
@@ -1084,14 +1366,18 @@ contract GenArt721CoreV3_Engine is
1084
1366
  // CHECKS
1085
1367
  Project storage project = projects[_projectId];
1086
1368
  uint256 _invocations = project.invocations;
1087
- require(
1088
- (_maxInvocations < project.maxInvocations),
1089
- "Only maxInvocations decrease"
1090
- );
1091
- require(_maxInvocations >= _invocations, "Only gte invocations");
1369
+ if (_maxInvocations >= project.maxInvocations) {
1370
+ revert GenArt721Error(ErrorCodes.OnlyMaxInvocationsDecrease);
1371
+ }
1372
+ if (_maxInvocations < _invocations) {
1373
+ revert GenArt721Error(ErrorCodes.OnlyGteInvocations);
1374
+ }
1092
1375
  // EFFECTS
1093
1376
  project.maxInvocations = _maxInvocations;
1094
- emit ProjectUpdated(_projectId, FIELD_PROJECT_MAX_INVOCATIONS);
1377
+ emit ProjectUpdated(
1378
+ _projectId,
1379
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_MAX_INVOCATIONS))
1380
+ );
1095
1381
 
1096
1382
  // register completed timestamp if action completed the project
1097
1383
  if (_maxInvocations == _invocations) {
@@ -1117,7 +1403,41 @@ contract GenArt721CoreV3_Engine is
1117
1403
  project.scriptBytecodeAddresses[project.scriptCount] = _script
1118
1404
  .writeToBytecode();
1119
1405
  project.scriptCount = project.scriptCount + 1;
1120
- emit ProjectUpdated(_projectId, FIELD_PROJECT_SCRIPT);
1406
+ emit ProjectUpdated(
1407
+ _projectId,
1408
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_SCRIPT))
1409
+ );
1410
+ }
1411
+
1412
+ /**
1413
+ * @notice Adds a pre-compressed script to project `_projectId`. The script
1414
+ * should be compressed using `getCompressed`. This function stores the script
1415
+ * in a compressed format on-chain. For reads, the compressed script is
1416
+ * decompressed on-chain, ensuring the original text is reconstructed without
1417
+ * external dependencies.
1418
+ * @param _projectId Project to be updated.
1419
+ * @param _compressedScript Pre-compressed script to be added.
1420
+ * Required to be non-empty, but no further validation is performed.
1421
+ */
1422
+ function addProjectScriptCompressed(
1423
+ uint256 _projectId,
1424
+ bytes memory _compressedScript
1425
+ ) external {
1426
+ _onlyUnlocked(_projectId);
1427
+ _onlyArtistOrAdminACL(
1428
+ _projectId,
1429
+ this.addProjectScriptCompressed.selector
1430
+ );
1431
+ _onlyNonEmptyBytes(_compressedScript);
1432
+ Project storage project = projects[_projectId];
1433
+ // store compressed script in contract bytecode
1434
+ project.scriptBytecodeAddresses[project.scriptCount] = _compressedScript
1435
+ .writeToBytecodeCompressed();
1436
+ project.scriptCount = project.scriptCount + 1;
1437
+ emit ProjectUpdated(
1438
+ _projectId,
1439
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_SCRIPT))
1440
+ );
1121
1441
  }
1122
1442
 
1123
1443
  /**
@@ -1136,11 +1456,52 @@ contract GenArt721CoreV3_Engine is
1136
1456
  _onlyArtistOrAdminACL(_projectId, this.updateProjectScript.selector);
1137
1457
  _onlyNonEmptyString(_script);
1138
1458
  Project storage project = projects[_projectId];
1139
- require(_scriptId < project.scriptCount, "scriptId out of range");
1459
+ if (_scriptId >= project.scriptCount) {
1460
+ revert GenArt721Error(ErrorCodes.ScriptIdOutOfRange);
1461
+ }
1140
1462
  // store script in contract bytecode, replacing reference address from
1141
1463
  // the old storage contract with the newly created one
1142
1464
  project.scriptBytecodeAddresses[_scriptId] = _script.writeToBytecode();
1143
- emit ProjectUpdated(_projectId, FIELD_PROJECT_SCRIPT);
1465
+ emit ProjectUpdated(
1466
+ _projectId,
1467
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_SCRIPT))
1468
+ );
1469
+ }
1470
+
1471
+ /**
1472
+ * @notice Updates script for project `_projectId` at script ID `_scriptId`
1473
+ * with a pre-compressed script. The script should be compressed using
1474
+ * `getCompressed`. This function stores the script in a compressed format
1475
+ * on-chain. For reads, the compressed script is decompressed on-chain, ensuring
1476
+ * the original text is reconstructed without external dependencies.
1477
+ * @param _projectId Project to be updated.
1478
+ * @param _scriptId Script ID to be updated.
1479
+ * @param _compressedScript The updated pre-compressed script value.
1480
+ * Required to be non-empty, but no further validation is performed.
1481
+ */
1482
+ function updateProjectScriptCompressed(
1483
+ uint256 _projectId,
1484
+ uint256 _scriptId,
1485
+ bytes memory _compressedScript
1486
+ ) external {
1487
+ _onlyUnlocked(_projectId);
1488
+ _onlyArtistOrAdminACL(
1489
+ _projectId,
1490
+ this.updateProjectScriptCompressed.selector
1491
+ );
1492
+ _onlyNonEmptyBytes(_compressedScript);
1493
+ Project storage project = projects[_projectId];
1494
+ if (_scriptId >= project.scriptCount) {
1495
+ revert GenArt721Error(ErrorCodes.ScriptIdOutOfRange);
1496
+ }
1497
+ // store script in contract bytecode, replacing reference address from
1498
+ // the old storage contract with the newly created one
1499
+ project.scriptBytecodeAddresses[_scriptId] = _compressedScript
1500
+ .writeToBytecodeCompressed();
1501
+ emit ProjectUpdated(
1502
+ _projectId,
1503
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_SCRIPT))
1504
+ );
1144
1505
  }
1145
1506
 
1146
1507
  /**
@@ -1154,13 +1515,18 @@ contract GenArt721CoreV3_Engine is
1154
1515
  this.removeProjectLastScript.selector
1155
1516
  );
1156
1517
  Project storage project = projects[_projectId];
1157
- require(project.scriptCount > 0, "No scripts to remove");
1518
+ if (project.scriptCount == 0) {
1519
+ revert GenArt721Error(ErrorCodes.NoScriptsToRemove);
1520
+ }
1158
1521
  // delete reference to old storage contract address
1159
1522
  delete project.scriptBytecodeAddresses[project.scriptCount - 1];
1160
1523
  unchecked {
1161
1524
  project.scriptCount = project.scriptCount - 1;
1162
1525
  }
1163
- emit ProjectUpdated(_projectId, FIELD_PROJECT_SCRIPT);
1526
+ emit ProjectUpdated(
1527
+ _projectId,
1528
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_SCRIPT))
1529
+ );
1164
1530
  }
1165
1531
 
1166
1532
  /**
@@ -1180,15 +1546,19 @@ contract GenArt721CoreV3_Engine is
1180
1546
  );
1181
1547
  Project storage project = projects[_projectId];
1182
1548
  // require exactly one @ symbol in _scriptTypeAndVersion
1183
- require(
1184
- _scriptTypeAndVersion.containsExactCharacterQty(
1549
+ if (
1550
+ !_scriptTypeAndVersion.containsExactCharacterQty(
1185
1551
  AT_CHARACTER_CODE,
1186
1552
  uint8(1)
1187
- ),
1188
- "must contain exactly one @"
1189
- );
1553
+ )
1554
+ ) {
1555
+ revert GenArt721Error(ErrorCodes.ScriptTypeAndVersionFormat);
1556
+ }
1190
1557
  project.scriptTypeAndVersion = _scriptTypeAndVersion;
1191
- emit ProjectUpdated(_projectId, FIELD_PROJECT_SCRIPT_TYPE);
1558
+ emit ProjectUpdated(
1559
+ _projectId,
1560
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_SCRIPT_TYPE))
1561
+ );
1192
1562
  }
1193
1563
 
1194
1564
  /**
@@ -1211,7 +1581,9 @@ contract GenArt721CoreV3_Engine is
1211
1581
  // Perform more detailed input validation for aspect ratio.
1212
1582
  bytes memory aspectRatioBytes = bytes(_aspectRatio);
1213
1583
  uint256 bytesLength = aspectRatioBytes.length;
1214
- require(bytesLength <= 11, "Aspect ratio format too long");
1584
+ if (bytesLength > 11) {
1585
+ revert GenArt721Error(ErrorCodes.AspectRatioTooLong);
1586
+ }
1215
1587
  bool hasSeenDecimalSeparator = false;
1216
1588
  bool hasSeenNumber = false;
1217
1589
  for (uint256 i; i < bytesLength; i++) {
@@ -1231,12 +1603,17 @@ contract GenArt721CoreV3_Engine is
1231
1603
  continue;
1232
1604
  }
1233
1605
  }
1234
- revert("Improperly formatted aspect ratio");
1606
+ revert GenArt721Error(ErrorCodes.AspectRatioImproperFormat);
1607
+ }
1608
+ if (!hasSeenNumber) {
1609
+ revert GenArt721Error(ErrorCodes.AspectRatioNoNumbers);
1235
1610
  }
1236
- require(hasSeenNumber, "Aspect ratio has no numbers");
1237
1611
 
1238
1612
  projects[_projectId].aspectRatio = _aspectRatio;
1239
- emit ProjectUpdated(_projectId, FIELD_PROJECT_ASPECT_RATIO);
1613
+ emit ProjectUpdated(
1614
+ _projectId,
1615
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_ASPECT_RATIO))
1616
+ );
1240
1617
  }
1241
1618
 
1242
1619
  /**
@@ -1254,7 +1631,10 @@ contract GenArt721CoreV3_Engine is
1254
1631
  _onlyArtist(_projectId);
1255
1632
  _onlyNonEmptyString(_newBaseURI);
1256
1633
  projects[_projectId].projectBaseURI = _newBaseURI;
1257
- emit ProjectUpdated(_projectId, FIELD_PROJECT_BASE_URI);
1634
+ emit ProjectUpdated(
1635
+ _projectId,
1636
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_BASE_URI))
1637
+ );
1258
1638
  }
1259
1639
 
1260
1640
  /**
@@ -1343,7 +1723,7 @@ contract GenArt721CoreV3_Engine is
1343
1723
  function projectIdToArtistAddress(
1344
1724
  uint256 _projectId
1345
1725
  ) external view returns (address payable) {
1346
- return projectIdToFinancials[_projectId].artistAddress;
1726
+ return _projectIdToFinancials[_projectId].artistAddress;
1347
1727
  }
1348
1728
 
1349
1729
  /**
@@ -1358,60 +1738,19 @@ contract GenArt721CoreV3_Engine is
1358
1738
  uint256 _projectId
1359
1739
  ) external view returns (uint256) {
1360
1740
  return
1361
- projectIdToFinancials[_projectId].secondaryMarketRoyaltyPercentage;
1362
- }
1363
-
1364
- /**
1365
- * @notice View function returning Artist's additional payee address for
1366
- * primary sales, for project `_projectId`.
1367
- * @param _projectId Project ID to be queried.
1368
- * @return address Artist's additional payee address for primary sales.
1369
- */
1370
- function projectIdToAdditionalPayeePrimarySales(
1371
- uint256 _projectId
1372
- ) external view returns (address payable) {
1373
- return projectIdToFinancials[_projectId].additionalPayeePrimarySales;
1374
- }
1375
-
1376
- /**
1377
- * @notice View function returning Artist's additional payee primary sales
1378
- * percentage, for project `_projectId`.
1379
- * @param _projectId Project ID to be queried.
1380
- * @return uint256 Artist's additional payee primary sales percentage.
1381
- */
1382
- function projectIdToAdditionalPayeePrimarySalesPercentage(
1383
- uint256 _projectId
1384
- ) external view returns (uint256) {
1385
- return
1386
- projectIdToFinancials[_projectId]
1387
- .additionalPayeePrimarySalesPercentage;
1388
- }
1389
-
1390
- /**
1391
- * @notice View function returning Artist's additional payee address for
1392
- * secondary sales, for project `_projectId`.
1393
- * @param _projectId Project ID to be queried.
1394
- * @return address payable Artist's additional payee address for secondary
1395
- * sales.
1396
- */
1397
- function projectIdToAdditionalPayeeSecondarySales(
1398
- uint256 _projectId
1399
- ) external view returns (address payable) {
1400
- return projectIdToFinancials[_projectId].additionalPayeeSecondarySales;
1741
+ _projectIdToFinancials[_projectId].secondaryMarketRoyaltyPercentage;
1401
1742
  }
1402
1743
 
1403
1744
  /**
1404
- * @notice View function returning Artist's additional payee secondary
1405
- * sales percentage, for project `_projectId`.
1745
+ * @notice View function returning project financial details for project
1746
+ * `_projectId`.
1406
1747
  * @param _projectId Project ID to be queried.
1407
- * @return uint256 Artist's additional payee secondary sales percentage.
1748
+ * @return ProjectFinance Project financial details.
1408
1749
  */
1409
- function projectIdToAdditionalPayeeSecondarySalesPercentage(
1750
+ function projectIdToFinancials(
1410
1751
  uint256 _projectId
1411
- ) external view returns (uint256) {
1412
- return
1413
- projectIdToFinancials[_projectId]
1414
- .additionalPayeeSecondarySalesPercentage;
1752
+ ) external view returns (ProjectFinance memory) {
1753
+ return _projectIdToFinancials[_projectId];
1415
1754
  }
1416
1755
 
1417
1756
  /**
@@ -1485,54 +1824,6 @@ contract GenArt721CoreV3_Engine is
1485
1824
  locked = !_projectUnlocked(_projectId);
1486
1825
  }
1487
1826
 
1488
- /**
1489
- * @notice Returns artist payment information for project `_projectId`.
1490
- * @param _projectId Project to be queried
1491
- * @return artistAddress Project Artist's address
1492
- * @return additionalPayeePrimarySales Additional payee address for primary
1493
- * sales
1494
- * @return additionalPayeePrimarySalesPercentage Percentage of artist revenue
1495
- * to be sent to the additional payee address for primary sales
1496
- * @return additionalPayeeSecondarySales Additional payee address for secondary
1497
- * sales royalties
1498
- * @return additionalPayeeSecondarySalesPercentage Percentage of artist revenue
1499
- * to be sent to the additional payee address for secondary sales royalties
1500
- * @return secondaryMarketRoyaltyPercentage Royalty percentage to be sent to
1501
- * combination of artist and additional payee. This does not include the
1502
- * platform's percentage of secondary sales royalties, which is defined as
1503
- * the sum of `renderProviderSecondarySalesBPS`
1504
- * and `platformProviderSecondarySalesBPS`.
1505
- */
1506
- function projectArtistPaymentInfo(
1507
- uint256 _projectId
1508
- )
1509
- external
1510
- view
1511
- returns (
1512
- address artistAddress,
1513
- address additionalPayeePrimarySales,
1514
- uint256 additionalPayeePrimarySalesPercentage,
1515
- address additionalPayeeSecondarySales,
1516
- uint256 additionalPayeeSecondarySalesPercentage,
1517
- uint256 secondaryMarketRoyaltyPercentage
1518
- )
1519
- {
1520
- ProjectFinance storage projectFinance = projectIdToFinancials[
1521
- _projectId
1522
- ];
1523
- artistAddress = projectFinance.artistAddress;
1524
- additionalPayeePrimarySales = projectFinance
1525
- .additionalPayeePrimarySales;
1526
- additionalPayeePrimarySalesPercentage = projectFinance
1527
- .additionalPayeePrimarySalesPercentage;
1528
- additionalPayeeSecondarySales = projectFinance
1529
- .additionalPayeeSecondarySales;
1530
- additionalPayeeSecondarySalesPercentage = projectFinance
1531
- .additionalPayeeSecondarySalesPercentage;
1532
- secondaryMarketRoyaltyPercentage = projectFinance
1533
- .secondaryMarketRoyaltyPercentage;
1534
- }
1535
-
1536
1827
  /**
1537
1828
  * @notice Returns script information for project `_projectId`.
1538
1829
  * @param _projectId Project to be queried.
@@ -1571,6 +1862,19 @@ contract GenArt721CoreV3_Engine is
1571
1862
  return projects[_projectId].scriptBytecodeAddresses[_index];
1572
1863
  }
1573
1864
 
1865
+ /**
1866
+ * @notice Returns the compressed form of a string in bytes using solady LibZip's flz compress algorithm. The bytes output from this function are intended to be used as input to `addProjectScriptCompressed` and `updateProjectScriptCompressed`.
1867
+ * @param _script Script to be compressed. Required to be a non-empty string, but no further validaton is performed.
1868
+ * @return bytes compressed bytes
1869
+ */
1870
+ function getCompressed(
1871
+ string memory _script
1872
+ ) external pure returns (bytes memory) {
1873
+ _onlyNonEmptyString(_script);
1874
+ // @dev want a potentially version-specific compression algorithm, so use version-specific library here
1875
+ return BytecodeStorageReader.getCompressed(_script);
1876
+ }
1877
+
1574
1878
  /**
1575
1879
  * @notice Returns script for project `_projectId` at script index `_index`.
1576
1880
  * @param _projectId Project to be queried.
@@ -1630,82 +1934,50 @@ contract GenArt721CoreV3_Engine is
1630
1934
  function getHistoricalRandomizerAt(
1631
1935
  uint256 _index
1632
1936
  ) external view returns (address) {
1633
- require(
1634
- _index < _historicalRandomizerAddresses.length,
1635
- "Index out of bounds"
1636
- );
1937
+ if (_index >= _historicalRandomizerAddresses.length) {
1938
+ revert GenArt721Error(ErrorCodes.IndexOutOfBounds);
1939
+ }
1637
1940
  return _historicalRandomizerAddresses[_index];
1638
1941
  }
1639
1942
 
1640
1943
  /**
1641
- * @notice Gets royalty Basis Points (BPS) for token ID `_tokenId`.
1642
- * This conforms to the IManifold interface designated in the Royalty
1643
- * Registry's RoyaltyEngineV1.sol contract.
1644
- * ref: https://github.com/manifoldxyz/royalty-registry-solidity
1645
- * @param _tokenId Token ID to be queried.
1646
- * @return recipients Array of royalty payment recipients
1647
- * @return bps Array of Basis Points (BPS) allocated to each recipient,
1648
- * aligned by index.
1944
+ * @notice Gets ERC-2981 royalty information for token with ID `_tokenId`
1945
+ * and sale price `_salePrice`.
1946
+ * @param _tokenId Token ID to be queried for royalty information
1947
+ * @param _salePrice the sale price of the NFT asset specified by _tokenId
1948
+ * @return receiver address that should be sent the royalty payment
1949
+ * @return royaltyAmount the royalty payment amount for `_salePrice
1649
1950
  * @dev reverts if invalid _tokenId
1650
- * @dev only returns recipients that have a non-zero BPS allocation
1651
1951
  */
1652
- function getRoyalties(
1653
- uint256 _tokenId
1654
- )
1655
- external
1656
- view
1657
- returns (address payable[] memory recipients, uint256[] memory bps)
1658
- {
1952
+ function royaltyInfo(
1953
+ uint256 _tokenId,
1954
+ uint256 _salePrice
1955
+ ) external view returns (address receiver, uint256 royaltyAmount) {
1659
1956
  _onlyValidTokenId(_tokenId);
1660
- // initialize arrays with maximum potential length
1661
- recipients = new address payable[](4);
1662
- bps = new uint256[](4);
1663
1957
 
1958
+ // populate receiver with project's royalty splitter
1959
+ // @dev royalty splitter created upon project creation, so will always exist
1960
+ // for valid token ID
1664
1961
  uint256 projectId = tokenIdToProjectId(_tokenId);
1665
- ProjectFinance storage projectFinance = projectIdToFinancials[
1962
+ ProjectFinance storage projectFinance = _projectIdToFinancials[
1666
1963
  projectId
1667
1964
  ];
1668
- // load values into memory
1669
- uint256 royaltyPercentageForArtistAndAdditional = projectFinance
1670
- .secondaryMarketRoyaltyPercentage;
1671
- uint256 additionalPayeePercentage = projectFinance
1672
- .additionalPayeeSecondarySalesPercentage;
1673
- // calculate BPS = percentage * 100
1674
- uint256 artistBPS = (ONE_HUNDRED - additionalPayeePercentage) *
1675
- royaltyPercentageForArtistAndAdditional;
1676
-
1677
- uint256 additionalBPS = additionalPayeePercentage *
1678
- royaltyPercentageForArtistAndAdditional;
1679
- uint256 renderProviderBPS = renderProviderSecondarySalesBPS;
1680
- uint256 platformProviderBPS = platformProviderSecondarySalesBPS;
1681
- // populate arrays
1682
- uint256 payeeCount;
1683
- if (artistBPS > 0) {
1684
- recipients[payeeCount] = projectFinance.artistAddress;
1685
- bps[payeeCount++] = artistBPS;
1686
- }
1687
- if (additionalBPS > 0) {
1688
- recipients[payeeCount] = projectFinance
1689
- .additionalPayeeSecondarySales;
1690
- bps[payeeCount++] = additionalBPS;
1691
- }
1692
- if (renderProviderBPS > 0) {
1693
- recipients[payeeCount] = renderProviderSecondarySalesAddress;
1694
- bps[payeeCount++] = renderProviderBPS;
1695
- }
1696
- if (platformProviderBPS > 0) {
1697
- recipients[payeeCount] = platformProviderSecondarySalesAddress;
1698
- bps[payeeCount++] = platformProviderBPS;
1965
+ receiver = projectFinance.royaltySplitter;
1966
+
1967
+ // populate royaltyAmount with calculated royalty amount
1968
+ // @dev important to cast to uint256 before multiplying to avoid overflow
1969
+ uint256 totalRoyaltyBPS = (100 *
1970
+ uint256(projectFinance.secondaryMarketRoyaltyPercentage)) +
1971
+ projectFinance.platformProviderSecondarySalesBPS +
1972
+ projectFinance.renderProviderSecondarySalesBPS;
1973
+ // @dev totalRoyaltyBPS guaranteed to be <= 10,000,
1974
+ if (totalRoyaltyBPS > 10_000) {
1975
+ revert GenArt721Error(ErrorCodes.OverMaxSumOfBPS);
1699
1976
  }
1700
- // trim arrays if necessary
1701
- if (4 > payeeCount) {
1702
- assembly {
1703
- let decrease := sub(4, payeeCount)
1704
- mstore(recipients, sub(mload(recipients), decrease))
1705
- mstore(bps, sub(mload(bps), decrease))
1706
- }
1707
- }
1708
- return (recipients, bps);
1977
+ // @dev overflow automatically checked in solidity 0.8
1978
+ // @dev totalRoyaltyBPS guaranteed to be <= 10_000,
1979
+ // so overflow only possible with unreasonably high _salePrice values near uint256 max
1980
+ royaltyAmount = (_salePrice * totalRoyaltyBPS) / 10_000;
1709
1981
  }
1710
1982
 
1711
1983
  /**
@@ -1758,7 +2030,7 @@ contract GenArt721CoreV3_Engine is
1758
2030
  address payable additionalPayeePrimaryAddress_
1759
2031
  )
1760
2032
  {
1761
- ProjectFinance storage projectFinance = projectIdToFinancials[
2033
+ ProjectFinance storage projectFinance = _projectIdToFinancials[
1762
2034
  _projectId
1763
2035
  ];
1764
2036
  // calculate revenues – this is a three-way split between the
@@ -1880,9 +2152,15 @@ contract GenArt721CoreV3_Engine is
1880
2152
  */
1881
2153
  function supportsInterface(
1882
2154
  bytes4 interfaceId
1883
- ) public view virtual override returns (bool) {
2155
+ )
2156
+ public
2157
+ view
2158
+ virtual
2159
+ override(ERC721_PackedHashSeedV1, IERC165)
2160
+ returns (bool)
2161
+ {
1884
2162
  return
1885
- interfaceId == type(IManifold).interfaceId ||
2163
+ interfaceId == _INTERFACE_ID_ERC2981 ||
1886
2164
  super.supportsInterface(interfaceId);
1887
2165
  }
1888
2166
 
@@ -1894,7 +2172,11 @@ contract GenArt721CoreV3_Engine is
1894
2172
  function _forbidNewProjects() internal {
1895
2173
  if (!newProjectsForbidden) {
1896
2174
  newProjectsForbidden = true;
1897
- emit PlatformUpdated(FIELD_NEW_PROJECTS_FORBIDDEN);
2175
+ emit PlatformUpdated(
2176
+ bytes32(
2177
+ uint256(PlatformUpdatedFields.FIELD_NEW_PROJECTS_FORBIDDEN)
2178
+ )
2179
+ );
1898
2180
  }
1899
2181
  }
1900
2182
 
@@ -1914,37 +2196,65 @@ contract GenArt721CoreV3_Engine is
1914
2196
  /**
1915
2197
  * @notice Updates sales addresses for the platform and render providers to
1916
2198
  * the input parameters.
2199
+ * Reverts if invalid platform provider addresses are provided given the
2200
+ * contract's immutably configured nullPlatformProvider state.
2201
+ * Does not check render provider addresses in any way.
1917
2202
  * @param _renderProviderPrimarySalesAddress Address of new primary sales
1918
2203
  * payment address.
1919
- * @param _renderProviderSecondarySalesAddress Address of new secondary sales
2204
+ * @param _defaultRenderProviderSecondarySalesAddress Address of new secondary sales
1920
2205
  * payment address.
1921
2206
  * @param _platformProviderPrimarySalesAddress Address of new primary sales
1922
2207
  * payment address.
1923
- * @param _platformProviderSecondarySalesAddress Address of new secondary sales
2208
+ * @param _defaultPlatformProviderSecondarySalesAddress Address of new secondary sales
1924
2209
  * payment address.
1925
- * @dev Note that this method does not check that the input address is
1926
- * not `address(0)`, as it is expected that callers of this method should
1927
- * perform input validation where applicable.
1928
2210
  */
1929
2211
  function _updateProviderSalesAddresses(
1930
2212
  address _renderProviderPrimarySalesAddress,
1931
- address _renderProviderSecondarySalesAddress,
2213
+ address _defaultRenderProviderSecondarySalesAddress,
1932
2214
  address _platformProviderPrimarySalesAddress,
1933
- address _platformProviderSecondarySalesAddress
2215
+ address _defaultPlatformProviderSecondarySalesAddress
1934
2216
  ) internal {
2217
+ if (nullPlatformProvider) {
2218
+ // require null platform provider address
2219
+ if (
2220
+ _platformProviderPrimarySalesAddress != address(0) ||
2221
+ _defaultPlatformProviderSecondarySalesAddress != address(0)
2222
+ ) {
2223
+ revert GenArt721Error(ErrorCodes.OnlyNullPlatformProvider);
2224
+ }
2225
+ } else {
2226
+ _onlyNonZeroAddress(_platformProviderPrimarySalesAddress);
2227
+ _onlyNonZeroAddress(_defaultPlatformProviderSecondarySalesAddress);
2228
+ }
1935
2229
  platformProviderPrimarySalesAddress = payable(
1936
2230
  _platformProviderPrimarySalesAddress
1937
2231
  );
1938
- platformProviderSecondarySalesAddress = payable(
1939
- _platformProviderSecondarySalesAddress
2232
+ defaultPlatformProviderSecondarySalesAddress = payable(
2233
+ _defaultPlatformProviderSecondarySalesAddress
1940
2234
  );
1941
2235
  renderProviderPrimarySalesAddress = payable(
1942
2236
  _renderProviderPrimarySalesAddress
1943
2237
  );
1944
- renderProviderSecondarySalesAddress = payable(
1945
- _renderProviderSecondarySalesAddress
2238
+ defaultRenderProviderSecondarySalesAddress = payable(
2239
+ _defaultRenderProviderSecondarySalesAddress
2240
+ );
2241
+ emit PlatformUpdated(
2242
+ bytes32(
2243
+ uint256(PlatformUpdatedFields.FIELD_PROVIDER_SALES_ADDRESSES)
2244
+ )
1946
2245
  );
1947
- emit PlatformUpdated(FIELD_PROVIDER_SALES_ADDRESSES);
2246
+ }
2247
+
2248
+ /**
2249
+ * @notice Updates minter address to `_minterAddress`.
2250
+ * @param _minterAddress New minter address.
2251
+ * @dev Note that this method does not check that the input address is
2252
+ * not `address(0)`, as it is expected that callers of this method should
2253
+ * perform input validation where applicable.
2254
+ */
2255
+ function _updateMinterContract(address _minterAddress) internal {
2256
+ minterContract = _minterAddress;
2257
+ emit MinterUpdated(_minterAddress);
1948
2258
  }
1949
2259
 
1950
2260
  /**
@@ -1958,7 +2268,85 @@ contract GenArt721CoreV3_Engine is
1958
2268
  randomizerContract = IRandomizer_V3CoreBase(_randomizerAddress);
1959
2269
  // populate historical randomizer array
1960
2270
  _historicalRandomizerAddresses.push(_randomizerAddress);
1961
- emit PlatformUpdated(FIELD_RANDOMIZER_ADDRESS);
2271
+ emit PlatformUpdated(
2272
+ bytes32(uint256(PlatformUpdatedFields.FIELD_RANDOMIZER_ADDRESS))
2273
+ );
2274
+ }
2275
+
2276
+ /**
2277
+ * @notice Updates split provider address to `_splitProviderAddress`.
2278
+ * Reverts if `_splitProviderAddress` is the zero address.
2279
+ * @param _splitProviderAddress New split provider address.
2280
+ * @dev Note that this method does not check that the input address is
2281
+ * not `address(0)`, as it is expected that callers of this method should
2282
+ * perform input validation where applicable.
2283
+ */
2284
+ function _updateSplitProvider(address _splitProviderAddress) internal {
2285
+ // require non-zero split provider address
2286
+ _onlyNonZeroAddress(_splitProviderAddress);
2287
+ splitProvider = ISplitProviderV0(_splitProviderAddress);
2288
+ emit PlatformUpdated(
2289
+ bytes32(uint256(PlatformUpdatedFields.FIELD_SPLIT_PROVIDER))
2290
+ );
2291
+ }
2292
+
2293
+ /**
2294
+ * @notice Update the bytecode storage reader contract address, and emit corresponding event.
2295
+ * @param _bytecodeStorageReaderContract New bytecode storage reader contract address.
2296
+ */
2297
+ function _updateBytecodeStorageReaderContract(
2298
+ address _bytecodeStorageReaderContract
2299
+ ) internal {
2300
+ bytecodeStorageReaderContract = IBytecodeStorageReader_Base(
2301
+ _bytecodeStorageReaderContract
2302
+ );
2303
+ emit PlatformUpdated(
2304
+ bytes32(
2305
+ uint256(PlatformUpdatedFields.FIELD_BYTECODE_STORAGE_READER)
2306
+ )
2307
+ );
2308
+ }
2309
+
2310
+ /**
2311
+ * @notice internal function to update a splitter contract for a project,
2312
+ * based on the project's financials in this contract's storage.
2313
+ * @dev Warning: this function uses storage reads to get the project's
2314
+ * financials, so ensure storage has been updated before calling this
2315
+ * @dev This function includes a trusted interaction that is entrusted to
2316
+ * not reenter this contract.
2317
+ * @param projectId Project ID to be updated.
2318
+ */
2319
+ function _assignSplitter(uint256 projectId) internal {
2320
+ ProjectFinance storage projectFinance = _projectIdToFinancials[
2321
+ projectId
2322
+ ];
2323
+ // assign project's royalty splitter
2324
+ // @dev loads values from storage, so need to ensure storage has been updated
2325
+ address royaltySplitter = splitProvider.getOrCreateSplitter(
2326
+ ISplitProviderV0.SplitInputs({
2327
+ platformProviderSecondarySalesAddress: projectFinance
2328
+ .platformProviderSecondarySalesAddress,
2329
+ platformProviderSecondarySalesBPS: projectFinance
2330
+ .platformProviderSecondarySalesBPS,
2331
+ renderProviderSecondarySalesAddress: projectFinance
2332
+ .renderProviderSecondarySalesAddress,
2333
+ renderProviderSecondarySalesBPS: projectFinance
2334
+ .renderProviderSecondarySalesBPS,
2335
+ artistTotalRoyaltyPercentage: projectFinance
2336
+ .secondaryMarketRoyaltyPercentage,
2337
+ artist: projectFinance.artistAddress,
2338
+ additionalPayee: projectFinance.additionalPayeeSecondarySales,
2339
+ additionalPayeePercentage: projectFinance
2340
+ .additionalPayeeSecondarySalesPercentage
2341
+ })
2342
+ );
2343
+
2344
+ projectFinance.royaltySplitter = royaltySplitter;
2345
+
2346
+ emit ProjectRoyaltySplitterUpdated({
2347
+ projectId: projectId,
2348
+ royaltySplitter: royaltySplitter
2349
+ });
1962
2350
  }
1963
2351
 
1964
2352
  /**
@@ -1972,7 +2360,9 @@ contract GenArt721CoreV3_Engine is
1972
2360
  */
1973
2361
  function _updateDefaultBaseURI(string memory _defaultBaseURI) internal {
1974
2362
  defaultBaseURI = _defaultBaseURI;
1975
- emit PlatformUpdated(FIELD_DEFAULT_BASE_URI);
2363
+ emit PlatformUpdated(
2364
+ bytes32(uint256(PlatformUpdatedFields.FIELD_DEFAULT_BASE_URI))
2365
+ );
1976
2366
  }
1977
2367
 
1978
2368
  /**
@@ -1981,7 +2371,92 @@ contract GenArt721CoreV3_Engine is
1981
2371
  */
1982
2372
  function _completeProject(uint256 _projectId) internal {
1983
2373
  projects[_projectId].completedTimestamp = uint64(block.timestamp);
1984
- emit ProjectUpdated(_projectId, FIELD_PROJECT_COMPLETED);
2374
+ emit ProjectUpdated(
2375
+ _projectId,
2376
+ bytes32(uint256(ProjectUpdatedFields.FIELD_PROJECT_COMPLETED))
2377
+ );
2378
+ }
2379
+
2380
+ /**
2381
+ * @notice Initializes the contract with the provided `engineConfiguration`.
2382
+ * This function should be called atomically, immediately after deployment.
2383
+ * Only callable once. Validation on `engineConfiguration` is performed by caller.
2384
+ * @param engineConfiguration EngineConfiguration to configure the contract with.
2385
+ * note: parameter `engineConfiguration.newSuperAdminAddress` is not used or operated on in this contract.
2386
+ * @param adminACLContract_ Address of admin access control contract, to be
2387
+ * set as contract owner.
2388
+ * @param defaultBaseURIHost Base URI prefix to initialize default base URI with.
2389
+ * @param bytecodeStorageReaderContract_ Address of bytecode storage reader contract.
2390
+ */
2391
+ function _initialize(
2392
+ EngineConfiguration memory engineConfiguration,
2393
+ address adminACLContract_,
2394
+ string memory defaultBaseURIHost,
2395
+ address bytecodeStorageReaderContract_
2396
+ ) internal {
2397
+ // can only be initialized once
2398
+ if (_initialized) {
2399
+ revert GenArt721Error(ErrorCodes.ContractInitialized);
2400
+ }
2401
+ // immediately mark as initialized
2402
+ _initialized = true;
2403
+ // @dev assume renderProviderAddress, randomizer, and AdminACL non-zero
2404
+ // checks on platform provider addresses performed in _updateProviderSalesAddresses
2405
+ // initialize default sales revenue percentages and basis points
2406
+ _renderProviderPrimarySalesPercentage = 10;
2407
+ defaultRenderProviderSecondarySalesBPS = 250;
2408
+ _platformProviderPrimarySalesPercentage = engineConfiguration
2409
+ .nullPlatformProvider
2410
+ ? 0
2411
+ : 10;
2412
+ defaultPlatformProviderSecondarySalesBPS = engineConfiguration
2413
+ .nullPlatformProvider
2414
+ ? 0
2415
+ : 250;
2416
+
2417
+ // set token name and token symbol
2418
+ ERC721_PackedHashSeedV1.initialize(
2419
+ engineConfiguration.tokenName,
2420
+ engineConfiguration.tokenSymbol
2421
+ );
2422
+ // update minter if populated
2423
+ if (engineConfiguration.minterFilterAddress != address(0)) {
2424
+ _updateMinterContract(engineConfiguration.minterFilterAddress);
2425
+ }
2426
+ _updateSplitProvider(engineConfiguration.splitProviderAddress);
2427
+ _updateBytecodeStorageReaderContract(bytecodeStorageReaderContract_);
2428
+ // setup immutable `autoApproveArtistSplitProposals` config
2429
+ autoApproveArtistSplitProposals = engineConfiguration
2430
+ .autoApproveArtistSplitProposals;
2431
+ // setup immutable `nullPlatformProvider` config
2432
+ nullPlatformProvider = engineConfiguration.nullPlatformProvider;
2433
+ // setup immutable `allowArtistProjectActivation` config
2434
+ allowArtistProjectActivation = engineConfiguration
2435
+ .allowArtistProjectActivation;
2436
+ // record contracts starting project ID
2437
+ // casting-up is safe
2438
+ startingProjectId = uint256(engineConfiguration.startingProjectId);
2439
+ // @dev nullPlatformProvider must be set before calling _updateProviderSalesAddresses
2440
+ _updateProviderSalesAddresses(
2441
+ engineConfiguration.renderProviderAddress,
2442
+ engineConfiguration.renderProviderAddress,
2443
+ engineConfiguration.platformProviderAddress,
2444
+ engineConfiguration.platformProviderAddress
2445
+ );
2446
+ _updateRandomizerAddress(engineConfiguration.randomizerContract);
2447
+ // set AdminACL management contract as owner
2448
+ _transferOwnership(adminACLContract_);
2449
+ // initialize default base URI
2450
+ _updateDefaultBaseURI(
2451
+ string.concat(defaultBaseURIHost, address(this).toHexString(), "/")
2452
+ );
2453
+ // initialize next project ID
2454
+ _nextProjectId = engineConfiguration.startingProjectId;
2455
+ emit PlatformUpdated(
2456
+ bytes32(uint256(PlatformUpdatedFields.FIELD_NEXT_PROJECT_ID))
2457
+ );
2458
+ // @dev This contract is registered on the core registry in a
2459
+ // subsequent call by the factory.
1985
2460
  }
1986
2461
 
1987
2462
  /**
@@ -2006,12 +2481,12 @@ contract GenArt721CoreV3_Engine is
2006
2481
  }
2007
2482
 
2008
2483
  /**
2009
- * Helper for calling `BytecodeStorageReader` external library reader method,
2484
+ * @notice Helper for calling bytecodeStorageReaderContract reader method;
2010
2485
  * added for bytecode size reduction purposes.
2011
2486
  */
2012
2487
  function _readFromBytecode(
2013
2488
  address _address
2014
2489
  ) internal view returns (string memory) {
2015
- return BytecodeStorageReader.readFromBytecode(_address);
2490
+ return bytecodeStorageReaderContract.readFromBytecode(_address);
2016
2491
  }
2017
2492
  }