@artblocks/contracts 1.0.2 → 1.0.4

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 (387) hide show
  1. package/README.md +56 -21
  2. package/artifacts/contracts/AdminACLV0.sol/AdminACLV0.json +2 -2
  3. package/artifacts/contracts/AdminACLV1.sol/AdminACLV1.json +2 -2
  4. package/artifacts/contracts/DependencyRegistryV0.sol/DependencyRegistryV0.json +141 -15
  5. package/artifacts/contracts/GenArt721CoreV3.sol/GenArt721CoreV3.json +42 -5
  6. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV0.sol/MinterDAExpV0.json +2 -2
  7. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV1.sol/MinterDAExpV1.json +2 -2
  8. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV2.sol/MinterDAExpV2.json +2 -2
  9. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV3.sol/MinterDAExpV3.json +2 -2
  10. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol/MinterDAExpSettlementV0.json +2 -2
  11. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV1.sol/MinterDAExpSettlementV1.json +2 -2
  12. package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV0.sol/MinterDALinV0.json +2 -2
  13. package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV1.sol/MinterDALinV1.json +2 -2
  14. package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV2.sol/MinterDALinV2.json +2 -2
  15. package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV3.sol/MinterDALinV3.json +2 -2
  16. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV0.sol/MinterHolderV0.json +2 -2
  17. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV1.sol/MinterHolderV1.json +2 -2
  18. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV2.sol/MinterHolderV2.json +2 -2
  19. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV3.sol/MinterHolderV3.json +2 -2
  20. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV0.sol/MinterMerkleV0.json +2 -2
  21. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV1.sol/MinterMerkleV1.json +2 -2
  22. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV2.sol/MinterMerkleV2.json +2 -2
  23. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV3.sol/MinterMerkleV3.json +2 -2
  24. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV4.sol/MinterMerkleV4.json +2 -2
  25. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV0.sol/MinterSetPriceV0.json +2 -2
  26. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV1.sol/MinterSetPriceV1.json +2 -2
  27. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV2.sol/MinterSetPriceV2.json +2 -2
  28. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV3.sol/MinterSetPriceV3.json +2 -2
  29. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V0.sol/MinterSetPriceERC20V0.json +2 -2
  30. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V1.sol/MinterSetPriceERC20V1.json +2 -2
  31. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol/MinterSetPriceERC20V2.json +2 -2
  32. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol/MinterSetPriceERC20V3.json +2 -2
  33. package/artifacts/contracts/engine/{GenArt721CoreV2_ENGINE_FLEX.sol → V2/GenArt721CoreV2_ENGINE_FLEX.sol}/GenArt721CoreV2_ENGINE_FLEX.json +3 -3
  34. package/artifacts/contracts/engine/{GenArt721CoreV2_PBAB.sol → V2/GenArt721CoreV2_PBAB.sol}/GenArt721CoreV2_PBAB.json +3 -3
  35. package/artifacts/contracts/engine/{GenArt721CoreV2_PRTNR.sol → V2/GenArt721CoreV2_PRTNR.sol}/GenArt721CoreV2_PRTNR.json +3 -3
  36. package/artifacts/contracts/engine/{GenArt721MinterBurner_PBAB.sol → V2/GenArt721MinterBurner_PBAB.sol}/GenArt721MinterBurner_PBAB.json +3 -3
  37. package/artifacts/contracts/engine/{GenArt721MinterDAExp_PBAB.sol → V2/GenArt721MinterDAExp_PBAB.sol}/GenArt721MinterDAExp_PBAB.json +3 -3
  38. package/artifacts/contracts/engine/{GenArt721Minter_PBAB.sol → V2/GenArt721Minter_PBAB.sol}/GenArt721Minter_PBAB.json +3 -3
  39. package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine.sol/GenArt721CoreV3_Engine.json +1960 -0
  40. package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol/GenArt721CoreV3_Engine_Flex.json +2247 -0
  41. package/artifacts/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol/GenArt721CoreV3_Engine_Flex_PROOF.json +2247 -0
  42. package/artifacts/contracts/engine/V3/forks/PROHIBITION/AdminACLV0_PROHIBITION.sol/AdminACLV0_PROHIBITION.json +401 -0
  43. package/artifacts/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol/GenArt721CoreV3_Engine_Flex_PROHIBITION.json +2281 -0
  44. package/artifacts/contracts/engine/V3/forks/PROHIBITION/interfaces/IAdminACLV0_PROHIBITION.sol/IAdminACLV0_PROHIBITION.json +359 -0
  45. package/artifacts/contracts/engine/V3/forks/PROHIBITION/interfaces/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.sol/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.json +1094 -0
  46. package/artifacts/contracts/engine-registry/CoreRegistryV1.sol/CoreRegistryV1.json +242 -0
  47. package/artifacts/contracts/engine-registry/EngineRegistryV0.sol/EngineRegistryV0.json +2 -2
  48. package/artifacts/contracts/explorations/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +41 -4
  49. package/artifacts/contracts/interfaces/{0.5.x → v0.5.x}/IBonusContract.sol/IBonusContract.json +1 -1
  50. package/artifacts/contracts/interfaces/{0.5.x → v0.5.x}/IGenArt721CoreContractV1.sol/IGenArt721CoreContractV1.json +1 -1
  51. package/artifacts/contracts/interfaces/{0.5.x → v0.5.x}/IGenArt721CoreV2_PBAB.sol/IGenArt721CoreV2_PBAB.json +1 -1
  52. package/artifacts/contracts/interfaces/{0.5.x → v0.5.x}/IRandomizer.sol/IRandomizer.json +1 -1
  53. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IAdminACLV0.sol/IAdminACLV0.json +1 -1
  54. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IArtblocksRoyaltyOverride.sol/IArtblocksRoyaltyOverride.json +1 -1
  55. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IBonusContract.sol/IBonusContract.json +1 -1
  56. package/artifacts/contracts/interfaces/v0.8.x/IBytecodeStorageReader.sol/IBytecodeStorageReader.json +111 -0
  57. package/artifacts/contracts/interfaces/v0.8.x/ICoreRegistryV1.sol/ICoreRegistryV1.json +172 -0
  58. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IDelegationRegistry.sol/IDelegationRegistry.json +1 -1
  59. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IDependencyRegistryCompatibleV0.sol/IDependencyRegistryCompatibleV0.json +1 -1
  60. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IDependencyRegistryV0.sol/IDependencyRegistryV0.json +3 -3
  61. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IEngineRegistryV0.sol/IEngineRegistryV0.json +1 -1
  62. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterDAExpSettlementV0.sol/IFilteredMinterDAExpSettlementV0.json +1 -1
  63. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterDAExpSettlementV1.sol/IFilteredMinterDAExpSettlementV1.json +1 -1
  64. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterDAExpSettlement_Mixin.sol/IFilteredMinterDAExpSettlement_Mixin.json +1 -1
  65. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterDAExpV0.sol/IFilteredMinterDAExpV0.json +1 -1
  66. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterDAExpV1.sol/IFilteredMinterDAExpV1.json +1 -1
  67. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterDALinV0.sol/IFilteredMinterDALinV0.json +1 -1
  68. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterDALinV1.sol/IFilteredMinterDALinV1.json +1 -1
  69. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterHolderV0.sol/IFilteredMinterHolderV0.json +1 -1
  70. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterHolderV1.sol/IFilteredMinterHolderV1.json +1 -1
  71. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterHolderV2.sol/IFilteredMinterHolderV2.json +1 -1
  72. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterMerkleV0.sol/IFilteredMinterMerkleV0.json +1 -1
  73. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterMerkleV1.sol/IFilteredMinterMerkleV1.json +1 -1
  74. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterMerkleV2.sol/IFilteredMinterMerkleV2.json +1 -1
  75. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterSEAV0.sol/IFilteredMinterSEAV0.json +56 -54
  76. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterV0.sol/IFilteredMinterV0.json +1 -1
  77. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterV1.sol/IFilteredMinterV1.json +1 -1
  78. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterV2.sol/IFilteredMinterV2.json +1 -1
  79. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractExposesHashSeed.sol/IGenArt721CoreContractExposesHashSeed.json +30 -0
  80. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IGenArt721CoreContractV1.sol/IGenArt721CoreContractV1.json +1 -1
  81. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IGenArt721CoreContractV3.sol/IGenArt721CoreContractV3.json +14 -1
  82. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3WithSharedRandomizer.sol/IGenArt721CoreContractV3WithSharedRandomizer.json +24 -0
  83. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IGenArt721CoreContractV3_Base.sol/IGenArt721CoreContractV3_Base.json +14 -1
  84. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IGenArt721CoreContractV3_Engine.sol/IGenArt721CoreContractV3_Engine.json +8 -14
  85. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IGenArt721CoreContractV3_Engine_Flex.sol/IGenArt721CoreContractV3_Engine_Flex.json +8 -14
  86. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IGenArt721CoreV2_PBAB.sol/IGenArt721CoreV2_PBAB.json +1 -1
  87. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IManifold.sol/IManifold.json +1 -1
  88. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IMinterBaseV0.sol/IMinterBaseV0.json +1 -1
  89. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IMinterFilterV0.sol/IMinterFilterV0.json +1 -1
  90. package/artifacts/contracts/interfaces/v0.8.x/IMinterFilterV1.sol/IMinterFilterV1.json +514 -0
  91. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IMintingAPICoreV0.sol/IMintingAPICoreV0.json +1 -1
  92. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IMintingAPIMinterV0.sol/IMintingAPIMinterV0.json +1 -1
  93. package/artifacts/contracts/interfaces/v0.8.x/IPseudorandomAtomic.sol/IPseudorandomAtomic.json +30 -0
  94. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IRandomizer.sol/IRandomizer.json +1 -1
  95. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IRandomizerPolyptychV0.sol/IRandomizerPolyptychV0.json +1 -1
  96. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IRandomizerV2.sol/IRandomizerV2.json +1 -1
  97. package/artifacts/contracts/interfaces/v0.8.x/IRandomizer_V3CoreBase.sol/IRandomizer_V3CoreBase.json +24 -0
  98. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol/ISharedMinterDAExpSettlementV0.json +207 -0
  99. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAExpV0.sol/ISharedMinterDAExpV0.json +93 -0
  100. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDALinV0.sol/ISharedMinterDALinV0.json +93 -0
  101. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAV0.sol/ISharedMinterDAV0.json +69 -0
  102. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterHolderV0.sol/ISharedMinterHolderV0.json +203 -0
  103. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterMerkleV0.sol/ISharedMinterMerkleV0.json +123 -0
  104. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterSEAV0.sol/ISharedMinterSEAV0.json +261 -0
  105. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterSimplePurchaseV0.sol/ISharedMinterSimplePurchaseV0.json +64 -0
  106. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterV0.sol/ISharedMinterV0.json +533 -0
  107. package/artifacts/contracts/interfaces/v0.8.x/ISharedRandomizerV0.sol/ISharedRandomizerV0.json +223 -0
  108. package/artifacts/contracts/interfaces/{0.8.x → v0.8.x}/IWETH.sol/IWETH.json +1 -1
  109. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/Address.json +2 -2
  110. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/Counters.json +2 -2
  111. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/CustomERC721Metadata.json +2 -2
  112. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/ERC721.json +2 -2
  113. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/ERC721Enumerable.json +2 -2
  114. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/GenArt721CoreV1.json +2 -2
  115. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/SafeMath.json +2 -2
  116. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/Strings.json +2 -2
  117. package/artifacts/contracts/legacy/GenArt721LegacyMinter.sol/GenArt721LegacyMinter.json +2 -2
  118. package/artifacts/contracts/libs/integration-refs/delegation-registry/DelegationRegistry.sol/DelegationRegistry.json +2 -2
  119. package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeMock.sol/GnosisSafeMock.json +2 -2
  120. package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeProxyFactoryMock.sol/GnosisSafeProxyFactoryMock.json +2 -2
  121. package/artifacts/contracts/libs/integration-refs/gnosis-safe/MultiSendMock.sol/MultiSendMock.json +2 -2
  122. package/artifacts/contracts/libs/integration-refs/weth9/weth9.sol/WETH9_.json +2 -2
  123. package/artifacts/contracts/libs/{0.5.x → v0.5.x}/CustomERC721Metadata.sol/CustomERC721Metadata.json +3 -3
  124. package/artifacts/contracts/libs/{0.5.x → v0.5.x}/IERC20.sol/IERC20.json +1 -1
  125. package/artifacts/contracts/libs/{0.5.x → v0.5.x}/SafeMath.sol/SafeMath.json +3 -3
  126. package/artifacts/contracts/libs/{0.5.x → v0.5.x}/Strings.sol/Strings.json +3 -3
  127. package/artifacts/contracts/libs/v0.8.x/ABHelpers.sol/ABHelpers.json +10 -0
  128. package/artifacts/contracts/libs/v0.8.x/AuthLib.sol/AuthLib.json +10 -0
  129. package/artifacts/contracts/libs/{0.8.x/BytecodeStorage.sol → v0.8.x/BytecodeStorageV0.sol}/BytecodeStorage.json +3 -3
  130. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV1.sol/BytecodeStorageReader.json +163 -0
  131. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV1.sol/BytecodeStorageWriter.json +10 -0
  132. package/artifacts/contracts/libs/{0.8.x → v0.8.x}/Bytes32Strings.sol/Bytes32Strings.json +3 -3
  133. package/artifacts/contracts/libs/{0.8.x → v0.8.x}/ERC721_PackedHashSeed.sol/ERC721_PackedHashSeed.json +3 -3
  134. package/artifacts/contracts/libs/v0.8.x/SSTORE2.sol/SSTORE2.json +10 -0
  135. package/artifacts/contracts/libs/v0.8.x/minter-libs/DAExpLib.sol/DAExpLib.json +10 -0
  136. package/artifacts/contracts/libs/v0.8.x/minter-libs/DALinLib.sol/DALinLib.json +10 -0
  137. package/artifacts/contracts/libs/v0.8.x/minter-libs/MaxInvocationsLib.sol/MaxInvocationsLib.json +10 -0
  138. package/artifacts/contracts/libs/v0.8.x/minter-libs/MerkleLib.sol/MerkleLib.json +10 -0
  139. package/artifacts/contracts/libs/v0.8.x/minter-libs/PolyptychLib.sol/PolyptychLib.json +10 -0
  140. package/artifacts/contracts/libs/v0.8.x/minter-libs/SEALib.sol/SEALib.json +10 -0
  141. package/artifacts/contracts/libs/v0.8.x/minter-libs/SetPriceLib.sol/SetPriceLib.json +10 -0
  142. package/artifacts/contracts/libs/v0.8.x/minter-libs/SettlementExpLib.sol/SettlementExpLib.json +10 -0
  143. package/artifacts/contracts/libs/v0.8.x/minter-libs/SplitFundsLib.sol/SplitFundsLib.json +10 -0
  144. package/artifacts/contracts/libs/v0.8.x/minter-libs/TokenHolderLib.sol/TokenHolderLib.json +10 -0
  145. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV0.sol/MinterFilterV0.json +2 -2
  146. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV1.sol/MinterFilterV1.json +2 -2
  147. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV2.sol/MinterFilterV2.json +748 -0
  148. package/artifacts/contracts/minter-suite/Minters/MinterDAExpHolderV5.sol/MinterDAExpHolderV5.json +1228 -0
  149. package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV2.sol/MinterDAExpSettlementV2.json +2 -2
  150. package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV3.sol/MinterDAExpSettlementV3.json +1146 -0
  151. package/artifacts/contracts/minter-suite/Minters/MinterDAExpV4.sol/MinterDAExpV4.json +2 -2
  152. package/artifacts/contracts/minter-suite/Minters/MinterDAExpV5.sol/MinterDAExpV5.json +909 -0
  153. package/artifacts/contracts/minter-suite/Minters/MinterDALinHolderV5.sol/MinterDALinHolderV5.json +1228 -0
  154. package/artifacts/contracts/minter-suite/Minters/MinterDALinV4.sol/MinterDALinV4.json +2 -2
  155. package/artifacts/contracts/minter-suite/Minters/MinterDALinV5.sol/MinterDALinV5.json +909 -0
  156. package/artifacts/contracts/minter-suite/Minters/MinterHolderV4.sol/MinterHolderV4.json +2 -2
  157. package/artifacts/contracts/minter-suite/Minters/MinterMerkleV5.sol/MinterMerkleV5.json +2 -2
  158. package/artifacts/contracts/minter-suite/Minters/MinterPolyptychV0.sol/IGenArt721CoreContractV3WithRandomizer.json +10 -160
  159. package/artifacts/contracts/minter-suite/Minters/MinterPolyptychV0.sol/MinterPolyptychV0.json +2 -2
  160. package/artifacts/contracts/minter-suite/Minters/MinterSEAV0.sol/MinterSEAV0.json +59 -80
  161. package/artifacts/contracts/minter-suite/Minters/MinterSEAV1.sol/MinterSEAV1.json +1325 -0
  162. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20V4.sol/MinterSetPriceERC20V4.json +2 -2
  163. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20V5.sol/MinterSetPriceERC20V5.json +848 -0
  164. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceHolderV5.sol/MinterSetPriceHolderV5.json +1091 -0
  165. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceMerkleV5.sol/MinterSetPriceMerkleV5.json +1075 -0
  166. package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychERC20V5.sol/MinterSetPricePolyptychERC20V5.json +1243 -0
  167. package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychV5.sol/MinterSetPricePolyptychV5.json +1167 -0
  168. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceV4.sol/MinterSetPriceV4.json +2 -2
  169. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceV5.sol/MinterSetPriceV5.json +772 -0
  170. package/artifacts/contracts/mock/{BytecodeTextCR_DMock.sol/BytecodeTextCR_DMock.json → BytecodeV0TextCR_DMock.sol/BytecodeV0TextCR_DMock.json} +4 -4
  171. package/artifacts/contracts/mock/BytecodeV1LibCallsMock.sol/BytecodeV1LibCallsMock.json +135 -0
  172. package/artifacts/contracts/mock/BytecodeV1TextCR_DMock.sol/BytecodeV1TextCR_DMock.json +301 -0
  173. package/artifacts/contracts/mock/DeadReceiverBidderMock.sol/DeadReceiverBidderMock.json +25 -2
  174. package/artifacts/contracts/mock/DeadReceiverMock.sol/DeadReceiverMock.json +2 -2
  175. package/artifacts/contracts/mock/DummySharedMinter.sol/DummySharedMinter.json +114 -0
  176. package/artifacts/contracts/mock/ERC20Mock.sol/ERC20Mock.json +28 -2
  177. package/artifacts/contracts/mock/GasLimitReceiverBidderMock.sol/GasLimitReceiverBidderMock.json +2 -2
  178. package/artifacts/contracts/mock/GasLimitReceiverMock.sol/GasLimitReceiverMock.json +2 -2
  179. package/artifacts/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol/GenArt721CoreV3_Engine_IncorrectCoreType.json +22 -4
  180. package/artifacts/contracts/mock/MockAdminACLV0.sol/MockAdminACLV0Events.json +2 -2
  181. package/artifacts/contracts/mock/MockAdminACLV0_PROHIBITION.sol/MockAdminACLV0Events_PROHIBITION.json +440 -0
  182. package/artifacts/contracts/mock/OriginRegisterMock.sol/OriginRegisterMock.json +39 -0
  183. package/artifacts/contracts/mock/RandomizerV2_NoAssignMock.sol/RandomizerV2_NoAssignMock.json +2 -2
  184. package/artifacts/contracts/mock/ReentrancyHolderMock.sol/ReentrancyHolderMock.json +2 -2
  185. package/artifacts/contracts/mock/ReentrancyMerkleMock.sol/ReentrancyMerkleMock.json +2 -2
  186. package/artifacts/contracts/mock/ReentrancyMock.sol/ReentrancyMock.json +2 -2
  187. package/artifacts/contracts/mock/ReentrancySEAMock.sol/ReentrancySEAAutoBidderMock.json +2 -2
  188. package/artifacts/contracts/mock/SSTORE2Mock.sol/SSTORE2Mock.json +118 -0
  189. package/artifacts/contracts/randomizer/{BasicRandomizer.sol → deprecated/BasicRandomizer.sol}/BasicRandomizer.json +3 -3
  190. package/artifacts/contracts/randomizer/{BasicRandomizerBase_v0_0_0.sol → deprecated/BasicRandomizerBase_v0_0_0.sol}/RandomizerBase.json +1 -1
  191. package/artifacts/contracts/randomizer/{PolyptychRandomizerV0.sol → deprecated/PolyptychRandomizerV0.sol}/BasicPolyptychRandomizerV0.json +3 -3
  192. package/artifacts/contracts/randomizer/{RandomizerV2.sol → deprecated/RandomizerV2.sol}/BasicRandomizerV2.json +3 -3
  193. package/artifacts/contracts/randomizer/primitive/PseudorandomAtomicBasic.sol/PseudorandomAtomic.json +30 -0
  194. package/artifacts/contracts/randomizer/shared/SharedRandomizerV0.sol/SharedRandomizerV0.json +247 -0
  195. package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverride.sol/GenArt721RoyaltyOverride.json +2 -2
  196. package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverride_PBAB.sol/GenArt721RoyaltyOverride_PBAB.json +2 -2
  197. package/contracts/AdminACLV0.sol +2 -2
  198. package/contracts/AdminACLV1.sol +2 -2
  199. package/contracts/DependencyRegistryV0.sol +219 -123
  200. package/contracts/GenArt721CoreV3.sol +60 -42
  201. package/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV0.sol +3 -3
  202. package/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV1.sol +3 -3
  203. package/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV2.sol +4 -4
  204. package/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV3.sol +4 -4
  205. package/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol +4 -4
  206. package/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV1.sol +4 -4
  207. package/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV0.sol +3 -3
  208. package/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV1.sol +3 -3
  209. package/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV2.sol +4 -4
  210. package/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV3.sol +4 -4
  211. package/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV0.sol +3 -3
  212. package/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV1.sol +4 -4
  213. package/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV2.sol +5 -5
  214. package/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV3.sol +5 -5
  215. package/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV0.sol +3 -3
  216. package/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV1.sol +4 -4
  217. package/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV2.sol +5 -5
  218. package/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV3.sol +5 -5
  219. package/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV4.sol +5 -5
  220. package/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV0.sol +3 -3
  221. package/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV1.sol +3 -3
  222. package/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV2.sol +4 -4
  223. package/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV3.sol +4 -4
  224. package/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V0.sol +3 -3
  225. package/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V1.sol +3 -3
  226. package/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol +4 -4
  227. package/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol +4 -4
  228. package/contracts/engine/{GenArt721CoreV2_ENGINE_FLEX.sol → V2/GenArt721CoreV2_ENGINE_FLEX.sol} +2 -2
  229. package/contracts/engine/{GenArt721CoreV2_PBAB.sol → V2/GenArt721CoreV2_PBAB.sol} +2 -2
  230. package/contracts/engine/{GenArt721CoreV2_PRTNR.sol → V2/GenArt721CoreV2_PRTNR.sol} +3 -3
  231. package/contracts/engine/{GenArt721MinterBurner_PBAB.sol → V2/GenArt721MinterBurner_PBAB.sol} +2 -2
  232. package/contracts/engine/{GenArt721MinterDAExp_PBAB.sol → V2/GenArt721MinterDAExp_PBAB.sol} +2 -2
  233. package/contracts/engine/{GenArt721Minter_PBAB.sol → V2/GenArt721Minter_PBAB.sol} +2 -2
  234. package/contracts/{GenArt721CoreV3_Engine.sol → engine/V3/GenArt721CoreV3_Engine.sol} +48 -24
  235. package/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol +2298 -0
  236. package/contracts/{GenArt721CoreV3_Engine_Flex.sol → engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol} +50 -31
  237. package/contracts/engine/V3/forks/PROHIBITION/AdminACLV0_PROHIBITION.sol +281 -0
  238. package/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol +2359 -0
  239. package/contracts/engine/V3/forks/PROHIBITION/interfaces/IAdminACLV0_PROHIBITION.sol +123 -0
  240. package/contracts/engine/V3/forks/PROHIBITION/interfaces/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.sol +29 -0
  241. package/contracts/engine-registry/CoreRegistryV1.sol +254 -0
  242. package/contracts/engine-registry/EngineRegistryV0.sol +2 -2
  243. package/contracts/explorations/GenArt721CoreV3_Explorations.sol +58 -40
  244. package/contracts/interfaces/v0.8.x/IBytecodeStorageReader.sol +62 -0
  245. package/contracts/interfaces/v0.8.x/ICoreRegistryV1.sol +27 -0
  246. package/contracts/interfaces/{0.8.x → v0.8.x}/IDelegationRegistry.sol +1 -1
  247. package/contracts/interfaces/{0.8.x → v0.8.x}/IDependencyRegistryCompatibleV0.sol +1 -1
  248. package/contracts/interfaces/{0.8.x → v0.8.x}/IDependencyRegistryV0.sol +3 -3
  249. package/contracts/interfaces/{0.8.x → v0.8.x}/IEngineRegistryV0.sol +1 -1
  250. package/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterSEAV0.sol +34 -15
  251. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractExposesHashSeed.sol +11 -0
  252. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3WithSharedRandomizer.sol +23 -0
  253. package/contracts/interfaces/{0.8.x → v0.8.x}/IGenArt721CoreContractV3_Base.sol +3 -0
  254. package/contracts/interfaces/{0.8.x → v0.8.x}/IGenArt721CoreContractV3_Engine.sol +0 -5
  255. package/contracts/interfaces/v0.8.x/IMinterFilterV1.sol +184 -0
  256. package/contracts/interfaces/v0.8.x/IPseudorandomAtomic.sol +16 -0
  257. package/contracts/interfaces/{0.8.x → v0.8.x}/IRandomizerPolyptychV0.sol +1 -1
  258. package/contracts/interfaces/{0.8.x → v0.8.x}/IRandomizerV2.sol +2 -5
  259. package/contracts/interfaces/v0.8.x/IRandomizer_V3CoreBase.sol +23 -0
  260. package/contracts/interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol +37 -0
  261. package/contracts/interfaces/v0.8.x/ISharedMinterDAExpV0.sol +25 -0
  262. package/contracts/interfaces/v0.8.x/ISharedMinterDALinV0.sol +26 -0
  263. package/contracts/interfaces/v0.8.x/ISharedMinterDAV0.sol +19 -0
  264. package/contracts/interfaces/v0.8.x/ISharedMinterHolderV0.sol +69 -0
  265. package/contracts/interfaces/v0.8.x/ISharedMinterMerkleV0.sol +44 -0
  266. package/contracts/interfaces/v0.8.x/ISharedMinterSEAV0.sol +78 -0
  267. package/contracts/interfaces/v0.8.x/ISharedMinterSimplePurchaseV0.sol +28 -0
  268. package/contracts/interfaces/v0.8.x/ISharedMinterV0.sol +191 -0
  269. package/contracts/interfaces/v0.8.x/ISharedRandomizerV0.sol +123 -0
  270. package/contracts/legacy/GenArt721CoreV1.sol +2 -2
  271. package/contracts/legacy/GenArt721LegacyMinter.sol +5 -5
  272. package/contracts/libs/integration-refs/delegation-registry/DelegationRegistry.sol +2 -2
  273. package/contracts/libs/integration-refs/weth9/weth9.sol +2 -0
  274. package/contracts/libs/v0.8.x/ABHelpers.sol +55 -0
  275. package/contracts/libs/v0.8.x/AuthLib.sol +197 -0
  276. package/contracts/libs/v0.8.x/BytecodeStorageV1.sol +399 -0
  277. package/contracts/libs/v0.8.x/SSTORE2.sol +109 -0
  278. package/contracts/libs/v0.8.x/minter-libs/DAExpLib.sol +125 -0
  279. package/contracts/libs/v0.8.x/minter-libs/DALinLib.sol +109 -0
  280. package/contracts/libs/v0.8.x/minter-libs/MaxInvocationsLib.sol +348 -0
  281. package/contracts/libs/v0.8.x/minter-libs/MerkleLib.sol +175 -0
  282. package/contracts/libs/v0.8.x/minter-libs/PolyptychLib.sol +160 -0
  283. package/contracts/libs/v0.8.x/minter-libs/SEALib.sol +320 -0
  284. package/contracts/libs/v0.8.x/minter-libs/SetPriceLib.sol +44 -0
  285. package/contracts/libs/v0.8.x/minter-libs/SettlementExpLib.sol +390 -0
  286. package/contracts/libs/v0.8.x/minter-libs/SplitFundsLib.sol +583 -0
  287. package/contracts/libs/v0.8.x/minter-libs/TokenHolderLib.sol +153 -0
  288. package/contracts/minter-suite/MinterFilter/MinterFilterV0.sol +3 -3
  289. package/contracts/minter-suite/MinterFilter/MinterFilterV1.sol +6 -6
  290. package/contracts/minter-suite/MinterFilter/MinterFilterV2.sol +830 -0
  291. package/contracts/minter-suite/Minters/MinterBase_v0_1_1.sol +4 -4
  292. package/contracts/minter-suite/Minters/MinterDAExpHolderV5.sol +966 -0
  293. package/contracts/minter-suite/Minters/MinterDAExpSettlementV2.sol +4 -4
  294. package/contracts/minter-suite/Minters/MinterDAExpSettlementV3.sol +1126 -0
  295. package/contracts/minter-suite/Minters/MinterDAExpV4.sol +4 -4
  296. package/contracts/minter-suite/Minters/MinterDAExpV5.sol +606 -0
  297. package/contracts/minter-suite/Minters/MinterDALinHolderV5.sol +952 -0
  298. package/contracts/minter-suite/Minters/MinterDALinV4.sol +4 -4
  299. package/contracts/minter-suite/Minters/MinterDALinV5.sol +591 -0
  300. package/contracts/minter-suite/Minters/MinterHolderV4.sol +5 -5
  301. package/contracts/minter-suite/Minters/MinterMerkleV5.sol +5 -5
  302. package/contracts/minter-suite/Minters/MinterPolyptychV0.sol +18 -17
  303. package/contracts/minter-suite/Minters/MinterSEAV0.sol +235 -186
  304. package/contracts/minter-suite/Minters/MinterSEAV1.sol +1190 -0
  305. package/contracts/minter-suite/Minters/MinterSetPriceERC20V4.sol +6 -6
  306. package/contracts/minter-suite/Minters/MinterSetPriceERC20V5.sol +570 -0
  307. package/contracts/minter-suite/Minters/MinterSetPriceHolderV5.sol +821 -0
  308. package/contracts/minter-suite/Minters/MinterSetPriceMerkleV5.sol +802 -0
  309. package/contracts/minter-suite/Minters/MinterSetPricePolyptychERC20V5.sol +1096 -0
  310. package/contracts/minter-suite/Minters/MinterSetPricePolyptychV5.sol +992 -0
  311. package/contracts/minter-suite/Minters/MinterSetPriceV4.sol +4 -4
  312. package/contracts/minter-suite/Minters/MinterSetPriceV5.sol +461 -0
  313. package/contracts/mock/{BytecodeTextCR_DMock.sol → BytecodeV0TextCR_DMock.sol} +5 -5
  314. package/contracts/mock/BytecodeV1LibCallsMock.sol +114 -0
  315. package/contracts/mock/BytecodeV1TextCR_DMock.sol +233 -0
  316. package/contracts/mock/DeadReceiverBidderMock.sol +16 -1
  317. package/contracts/mock/DeadReceiverMock.sol +1 -1
  318. package/contracts/mock/DummySharedMinter.sol +75 -0
  319. package/contracts/mock/ERC20Mock.sol +16 -0
  320. package/contracts/mock/GasLimitReceiverBidderMock.sol +1 -1
  321. package/contracts/mock/GasLimitReceiverMock.sol +1 -1
  322. package/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol +22 -35
  323. package/contracts/mock/MockAdminACLV0.sol +2 -2
  324. package/contracts/mock/MockAdminACLV0_PROHIBITION.sol +207 -0
  325. package/contracts/mock/OriginRegisterMock.sol +27 -0
  326. package/contracts/mock/RandomizerV2_NoAssignMock.sol +2 -2
  327. package/contracts/mock/ReentrancyHolderMock.sol +1 -1
  328. package/contracts/mock/ReentrancyMerkleMock.sol +1 -1
  329. package/contracts/mock/ReentrancyMock.sol +1 -1
  330. package/contracts/mock/ReentrancySEAMock.sol +1 -1
  331. package/contracts/mock/SSTORE2Mock.sol +93 -0
  332. package/contracts/randomizer/{BasicRandomizer.sol → deprecated/BasicRandomizer.sol} +1 -1
  333. package/contracts/randomizer/{BasicRandomizerBase_v0_0_0.sol → deprecated/BasicRandomizerBase_v0_0_0.sol} +1 -1
  334. package/contracts/randomizer/{PolyptychRandomizerV0.sol → deprecated/PolyptychRandomizerV0.sol} +3 -3
  335. package/contracts/randomizer/{RandomizerV2.sol → deprecated/RandomizerV2.sol} +3 -3
  336. package/contracts/randomizer/primitive/PseudorandomAtomicBasic.sol +30 -0
  337. package/contracts/randomizer/shared/SharedRandomizerV0.sol +260 -0
  338. package/contracts/royalty-registry/GenArt721RoyaltyOverride.sol +2 -2
  339. package/contracts/royalty-registry/GenArt721RoyaltyOverride_PBAB.sol +2 -2
  340. package/package.json +51 -43
  341. package/.env.example +0 -17
  342. package/LICENSE +0 -165
  343. package/artifacts/contracts/GenArt721CoreV3_Engine.sol/GenArt721CoreV3_Engine.json +0 -1942
  344. package/artifacts/contracts/GenArt721CoreV3_Engine_Flex.sol/GenArt721CoreV3_Engine_Flex.json +0 -2229
  345. package/artifacts/contracts/engine-registry/future/EngineRegistryV1.sol/EngineRegistryV1.json +0 -109
  346. package/contracts/engine-registry/future/EngineRegistryV1.sol +0 -86
  347. /package/contracts/interfaces/{0.5.x → v0.5.x}/IBonusContract.sol +0 -0
  348. /package/contracts/interfaces/{0.5.x → v0.5.x}/IGenArt721CoreContractV1.sol +0 -0
  349. /package/contracts/interfaces/{0.5.x → v0.5.x}/IGenArt721CoreV2_PBAB.sol +0 -0
  350. /package/contracts/interfaces/{0.5.x → v0.5.x}/IRandomizer.sol +0 -0
  351. /package/contracts/interfaces/{0.8.x → v0.8.x}/IAdminACLV0.sol +0 -0
  352. /package/contracts/interfaces/{0.8.x → v0.8.x}/IArtblocksRoyaltyOverride.sol +0 -0
  353. /package/contracts/interfaces/{0.8.x → v0.8.x}/IBonusContract.sol +0 -0
  354. /package/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterDAExpSettlementV0.sol +0 -0
  355. /package/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterDAExpSettlementV1.sol +0 -0
  356. /package/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterDAExpSettlement_Mixin.sol +0 -0
  357. /package/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterDAExpV0.sol +0 -0
  358. /package/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterDAExpV1.sol +0 -0
  359. /package/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterDALinV0.sol +0 -0
  360. /package/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterDALinV1.sol +0 -0
  361. /package/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterHolderV0.sol +0 -0
  362. /package/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterHolderV1.sol +0 -0
  363. /package/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterHolderV2.sol +0 -0
  364. /package/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterMerkleV0.sol +0 -0
  365. /package/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterMerkleV1.sol +0 -0
  366. /package/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterMerkleV2.sol +0 -0
  367. /package/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterV0.sol +0 -0
  368. /package/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterV1.sol +0 -0
  369. /package/contracts/interfaces/{0.8.x → v0.8.x}/IFilteredMinterV2.sol +0 -0
  370. /package/contracts/interfaces/{0.8.x → v0.8.x}/IGenArt721CoreContractV1.sol +0 -0
  371. /package/contracts/interfaces/{0.8.x → v0.8.x}/IGenArt721CoreContractV3.sol +0 -0
  372. /package/contracts/interfaces/{0.8.x → v0.8.x}/IGenArt721CoreContractV3_Engine_Flex.sol +0 -0
  373. /package/contracts/interfaces/{0.8.x → v0.8.x}/IGenArt721CoreV2_PBAB.sol +0 -0
  374. /package/contracts/interfaces/{0.8.x → v0.8.x}/IManifold.sol +0 -0
  375. /package/contracts/interfaces/{0.8.x → v0.8.x}/IMinterBaseV0.sol +0 -0
  376. /package/contracts/interfaces/{0.8.x → v0.8.x}/IMinterFilterV0.sol +0 -0
  377. /package/contracts/interfaces/{0.8.x → v0.8.x}/IMintingAPICoreV0.sol +0 -0
  378. /package/contracts/interfaces/{0.8.x → v0.8.x}/IMintingAPIMinterV0.sol +0 -0
  379. /package/contracts/interfaces/{0.8.x → v0.8.x}/IRandomizer.sol +0 -0
  380. /package/contracts/interfaces/{0.8.x → v0.8.x}/IWETH.sol +0 -0
  381. /package/contracts/libs/{0.5.x → v0.5.x}/CustomERC721Metadata.sol +0 -0
  382. /package/contracts/libs/{0.5.x → v0.5.x}/IERC20.sol +0 -0
  383. /package/contracts/libs/{0.5.x → v0.5.x}/SafeMath.sol +0 -0
  384. /package/contracts/libs/{0.5.x → v0.5.x}/Strings.sol +0 -0
  385. /package/contracts/libs/{0.8.x/BytecodeStorage.sol → v0.8.x/BytecodeStorageV0.sol} +0 -0
  386. /package/contracts/libs/{0.8.x → v0.8.x}/Bytes32Strings.sol +0 -0
  387. /package/contracts/libs/{0.8.x → v0.8.x}/ERC721_PackedHashSeed.sol +0 -0
@@ -0,0 +1,2298 @@
1
+ // SPDX-License-Identifier: LGPL-3.0-only
2
+ pragma solidity 0.8.19;
3
+
4
+ // Created By: Art Blocks Inc.
5
+
6
+ import "../../interfaces/v0.8.x/IRandomizer_V3CoreBase.sol";
7
+ import "../../interfaces/v0.8.x/IAdminACLV0.sol";
8
+ import "../../interfaces/v0.8.x/IEngineRegistryV0.sol";
9
+ import "../../interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex.sol";
10
+ import "../../interfaces/v0.8.x/IGenArt721CoreContractExposesHashSeed.sol";
11
+ import "../../interfaces/v0.8.x/IDependencyRegistryCompatibleV0.sol";
12
+ import "../../interfaces/v0.8.x/IManifold.sol";
13
+
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";
17
+ import "../../libs/v0.8.x/Bytes32Strings.sol";
18
+
19
+ /**
20
+ * @title Art Blocks Engine Flex ERC-721 core contract, V3.
21
+ * @author Art Blocks Inc.
22
+ * @notice Privileged Roles and Ownership:
23
+ * This contract is designed to be managed, with progressively limited powers
24
+ * as a project progresses from active to locked.
25
+ * Privileged roles and abilities are controlled by the admin ACL contract and
26
+ * artists. Both of these roles hold extensive power and can arbitrarily
27
+ * control and modify portions of projects, dependent upon project state. After
28
+ * a project is locked, important project metadata fields are locked including
29
+ * the project name, artist name, and script and display details. Edition size
30
+ * can never be increased.
31
+ * Care must be taken to ensure that the admin ACL contract and artist
32
+ * addresses are secure behind a multi-sig or other access control mechanism.
33
+ * ----------------------------------------------------------------------------
34
+ * The following functions are restricted to the Admin ACL contract:
35
+ * - updateArtblocksDependencyRegistryAddress
36
+ * - updateProviderSalesAddresses
37
+ * - updateProviderPrimarySalesPercentages (up to 100%)
38
+ * - updateProviderSecondarySalesBPS (up to 100%)
39
+ * - updateMinterContract
40
+ * - updateRandomizerAddress
41
+ * - toggleProjectIsActive
42
+ * - addProject
43
+ * - forbidNewProjects (forever forbidding new projects)
44
+ * - updateDefaultBaseURI (used to initialize new project base URIs)
45
+ * - updateIPFSGateway
46
+ * - updateArweaveGateway
47
+ * ----------------------------------------------------------------------------
48
+ * The following functions are restricted to either the the Artist address or
49
+ * the Admin ACL contract, only when the project is not locked:
50
+ * - updateProjectName
51
+ * - updateProjectArtistName
52
+ * - updateProjectLicense
53
+ * - Change project script via addProjectScript, updateProjectScript,
54
+ * and removeProjectLastScript
55
+ * - updateProjectScriptType
56
+ * - updateProjectAspectRatio
57
+ * ----------------------------------------------------------------------------
58
+ * The following functions are restricted to only the Artist address:
59
+ * - proposeArtistPaymentAddressesAndSplits (Note that this has to be accepted
60
+ * by adminAcceptArtistAddressesAndSplits to take effect, which is restricted
61
+ * to the Admin ACL contract, or the artist if the core contract owner has
62
+ * renounced ownership. Also note that a proposal will be automatically
63
+ * accepted if the artist only proposes changed payee percentages without
64
+ * modifying any payee addresses, or is only removing payee addresses, or
65
+ * if the global config `autoApproveArtistSplitProposals` is set to `true`.)
66
+ * - toggleProjectIsPaused (note the artist can still mint while paused)
67
+ * - updateProjectSecondaryMarketRoyaltyPercentage (up to
68
+ ARTIST_MAX_SECONDARY_ROYALTY_PERCENTAGE percent)
69
+ * - updateProjectWebsite
70
+ * - updateProjectMaxInvocations (to a number greater than or equal to the
71
+ * current number of invocations, and less than current project maximum
72
+ * invocations)
73
+ * - updateProjectBaseURI (controlling the base URI for tokens in the project)
74
+ * ----------------------------------------------------------------------------
75
+ * The following function is restricted to either the Admin ACL contract, or
76
+ * the Artist address if the core contract owner has renounced ownership:
77
+ * - adminAcceptArtistAddressesAndSplits
78
+ * - updateProjectArtistAddress (owner ultimately controlling the project and
79
+ * its and-on revenue, unless owner has renounced ownership)
80
+ * ----------------------------------------------------------------------------
81
+ * The following function is restricted to the artist when a project is
82
+ * unlocked, and only callable by Admin ACL contract when a project is locked:
83
+ * - updateProjectDescription
84
+ * ----------------------------------------------------------------------------
85
+ * The following functions for managing external asset dependencies are restricted
86
+ * to projects with external asset dependencies that are unlocked:
87
+ * - lockProjectExternalAssetDependencies
88
+ * - updateProjectExternalAssetDependency
89
+ * - removeProjectExternalAssetDependency
90
+ * - addProjectExternalAssetDependency
91
+ * ----------------------------------------------------------------------------
92
+ * The following function is restricted to owner calling directly:
93
+ * - transferOwnership
94
+ * - renounceOwnership
95
+ * ----------------------------------------------------------------------------
96
+ * The following configuration variables are set at time of contract deployment,
97
+ * and not modifiable thereafter (immutable after the point of deployment):
98
+ * - (bool) autoApproveArtistSplitProposals
99
+ * ----------------------------------------------------------------------------
100
+ * Additional admin and artist privileged roles may be described on minters,
101
+ * registries, and other contracts that may interact with this core contract.
102
+ */
103
+ contract GenArt721CoreV3_Engine_Flex is
104
+ ERC721_PackedHashSeed,
105
+ Ownable,
106
+ IDependencyRegistryCompatibleV0,
107
+ IManifold,
108
+ IGenArt721CoreContractV3_Engine_Flex,
109
+ IGenArt721CoreContractExposesHashSeed
110
+ {
111
+ using BytecodeStorageWriter for string;
112
+ using Bytes32Strings for bytes32;
113
+ uint256 constant ONE_HUNDRED = 100;
114
+ uint256 constant ONE_MILLION = 1_000_000;
115
+ uint24 constant ONE_MILLION_UINT24 = 1_000_000;
116
+ uint256 constant FOUR_WEEKS_IN_SECONDS = 2_419_200;
117
+ uint8 constant AT_CHARACTER_CODE = uint8(bytes1("@")); // 0x40
118
+
119
+ // numeric constants
120
+ uint256 constant MAX_PROVIDER_SECONDARY_SALES_BPS = 10000; // 10_000 BPS = 100%
121
+ uint256 constant ARTIST_MAX_SECONDARY_ROYALTY_PERCENTAGE = 95; // 95%
122
+
123
+ // This contract emits generic events that contain fields that indicate
124
+ // which parameter has been updated. This is sufficient for application
125
+ // state management, while also simplifying the contract and indexing code.
126
+ // This was done as an alternative to having custom events that emit what
127
+ // field-values have changed for each event, given that changed values can
128
+ // be introspected by indexers due to the design of this smart contract
129
+ // exposing these state changes via publicly viewable fields.
130
+ //
131
+ // The following fields are used to indicate which contract-level parameter
132
+ // has been updated in the `PlatformUpdated` event:
133
+ bytes32 constant FIELD_NEXT_PROJECT_ID = "nextProjectId";
134
+ bytes32 constant FIELD_NEW_PROJECTS_FORBIDDEN = "newProjectsForbidden";
135
+ bytes32 constant FIELD_DEFAULT_BASE_URI = "defaultBaseURI";
136
+ bytes32 constant FIELD_RANDOMIZER_ADDRESS = "randomizerAddress";
137
+ bytes32 constant FIELD_ARTBLOCKS_DEPENDENCY_REGISTRY_ADDRESS =
138
+ "dependencyRegistryAddress";
139
+ bytes32 constant FIELD_PROVIDER_SALES_ADDRESSES = "providerSalesAddresses";
140
+ bytes32 constant FIELD_PROVIDER_PRIMARY_SALES_PERCENTAGES =
141
+ "providerPrimaryPercentages";
142
+ bytes32 constant FIELD_PROVIDER_SECONDARY_SALES_BPS =
143
+ "providerSecondaryBPS";
144
+ // The following fields are used to indicate which project-level parameter
145
+ // has been updated in the `ProjectUpdated` event:
146
+ bytes32 constant FIELD_PROJECT_COMPLETED = "completed";
147
+ bytes32 constant FIELD_PROJECT_ACTIVE = "active";
148
+ bytes32 constant FIELD_PROJECT_ARTIST_ADDRESS = "artistAddress";
149
+ bytes32 constant FIELD_PROJECT_PAUSED = "paused";
150
+ bytes32 constant FIELD_PROJECT_CREATED = "created";
151
+ bytes32 constant FIELD_PROJECT_NAME = "name";
152
+ bytes32 constant FIELD_PROJECT_ARTIST_NAME = "artistName";
153
+ bytes32 constant FIELD_PROJECT_SECONDARY_MARKET_ROYALTY_PERCENTAGE =
154
+ "royaltyPercentage";
155
+ bytes32 constant FIELD_PROJECT_DESCRIPTION = "description";
156
+ bytes32 constant FIELD_PROJECT_WEBSITE = "website";
157
+ bytes32 constant FIELD_PROJECT_LICENSE = "license";
158
+ bytes32 constant FIELD_PROJECT_MAX_INVOCATIONS = "maxInvocations";
159
+ bytes32 constant FIELD_PROJECT_SCRIPT = "script";
160
+ bytes32 constant FIELD_PROJECT_SCRIPT_TYPE = "scriptType";
161
+ bytes32 constant FIELD_PROJECT_ASPECT_RATIO = "aspectRatio";
162
+ bytes32 constant FIELD_PROJECT_BASE_URI = "baseURI";
163
+
164
+ /// Dependency registry managed by Art Blocks
165
+ address public artblocksDependencyRegistryAddress;
166
+
167
+ /// current randomizer contract
168
+ IRandomizer_V3CoreBase public randomizerContract;
169
+
170
+ /// append-only array of all randomizer contract addresses ever used by
171
+ /// this contract
172
+ address[] private _historicalRandomizerAddresses;
173
+
174
+ /// admin ACL contract
175
+ IAdminACLV0 public adminACLContract;
176
+
177
+ struct Project {
178
+ uint24 invocations;
179
+ uint24 maxInvocations;
180
+ uint24 scriptCount;
181
+ // max uint64 ~= 1.8e19 sec ~= 570 billion years
182
+ uint64 completedTimestamp;
183
+ bool active;
184
+ bool paused;
185
+ string name;
186
+ string artist;
187
+ address descriptionAddress;
188
+ string website;
189
+ string license;
190
+ string projectBaseURI;
191
+ bytes32 scriptTypeAndVersion;
192
+ string aspectRatio;
193
+ // mapping from script index to address storing script in bytecode
194
+ mapping(uint256 => address) scriptBytecodeAddresses;
195
+ bool externalAssetDependenciesLocked;
196
+ uint24 externalAssetDependencyCount;
197
+ mapping(uint256 => ExternalAssetDependency) externalAssetDependencies;
198
+ }
199
+
200
+ mapping(uint256 => Project) projects;
201
+
202
+ string public preferredIPFSGateway;
203
+ string public preferredArweaveGateway;
204
+
205
+ /// packed struct containing project financial information
206
+ struct ProjectFinance {
207
+ address payable additionalPayeePrimarySales;
208
+ // packed uint: max of 95, max uint8 = 255
209
+ uint8 secondaryMarketRoyaltyPercentage;
210
+ address payable additionalPayeeSecondarySales;
211
+ // packed uint: max of 100, max uint8 = 255
212
+ uint8 additionalPayeeSecondarySalesPercentage;
213
+ address payable artistAddress;
214
+ // packed uint: max of 100, max uint8 = 255
215
+ uint8 additionalPayeePrimarySalesPercentage;
216
+ }
217
+ // Project financials mapping
218
+ mapping(uint256 => ProjectFinance) projectIdToFinancials;
219
+
220
+ /// hash of artist's proposed payment updates to be approved by admin
221
+ mapping(uint256 => bytes32) public proposedArtistAddressesAndSplitsHash;
222
+
223
+ /// The render provider payment address for all primary sales revenues
224
+ /// (packed)
225
+ address payable public renderProviderPrimarySalesAddress;
226
+ /// Percentage of primary sales revenue allocated to the render provider
227
+ /// (packed)
228
+ // packed uint: max of 100, max uint8 = 255
229
+ uint8 private _renderProviderPrimarySalesPercentage = 10;
230
+ /// The platform provider payment address for all primary sales revenues
231
+ /// (packed)
232
+ address payable public platformProviderPrimarySalesAddress;
233
+ /// Percentage of primary sales revenue allocated to the platform provider
234
+ /// (packed)
235
+ // packed uint: max of 100, max uint8 = 255
236
+ uint8 private _platformProviderPrimarySalesPercentage = 10;
237
+
238
+ /// The render provider payment address for all secondary sales royalty
239
+ /// revenues
240
+ address payable public renderProviderSecondarySalesAddress;
241
+ /// Basis Points of secondary sales royalties allocated to the
242
+ /// render provider
243
+ uint256 public renderProviderSecondarySalesBPS = 250;
244
+ /// The platform provider payment address for all secondary sales royalty
245
+ /// revenues
246
+ address payable public platformProviderSecondarySalesAddress;
247
+ /// Basis Points of secondary sales royalties allocated to the
248
+ /// platform provider
249
+ uint256 public platformProviderSecondarySalesBPS = 250;
250
+
251
+ /// single minter allowed for this core contract
252
+ address public minterContract;
253
+
254
+ /// starting (initial) project ID on this contract
255
+ uint256 public immutable startingProjectId;
256
+
257
+ /// next project ID to be created
258
+ uint248 private _nextProjectId;
259
+
260
+ /// bool indicating if adding new projects is forbidden;
261
+ /// default behavior is to allow new projects
262
+ bool public newProjectsForbidden;
263
+
264
+ /// configuration variable (determined at time of deployment)
265
+ /// that determines whether or not admin approval^ should be required
266
+ /// to accept artist address change proposals, or if these proposals
267
+ /// should always auto-approve, as determined by the business process
268
+ /// requirements of the Engine partner using this contract.
269
+ ///
270
+ /// ^does not apply in the case where contract-ownership itself is revoked
271
+ bool public immutable autoApproveArtistSplitProposals;
272
+
273
+ /// version & type of this core contract
274
+ bytes32 constant CORE_VERSION = "v3.1.3";
275
+
276
+ function coreVersion() external pure returns (string memory) {
277
+ return CORE_VERSION.toString();
278
+ }
279
+
280
+ bytes32 constant CORE_TYPE = "GenArt721CoreV3_Engine_Flex";
281
+
282
+ function coreType() external pure returns (string memory) {
283
+ return CORE_TYPE.toString();
284
+ }
285
+
286
+ /// default base URI to initialize all new project projectBaseURI values to
287
+ string public defaultBaseURI;
288
+
289
+ function _onlyUnlockedProjectExternalAssetDependencies(
290
+ uint256 _projectId
291
+ ) internal view {
292
+ require(
293
+ !projects[_projectId].externalAssetDependenciesLocked,
294
+ "External dependencies locked"
295
+ );
296
+ }
297
+
298
+ function _onlyNonZeroAddress(address _address) internal pure {
299
+ require(_address != address(0), "Must input non-zero address");
300
+ }
301
+
302
+ function _onlyNonEmptyString(string memory _string) internal pure {
303
+ require(bytes(_string).length != 0, "Must input non-empty string");
304
+ }
305
+
306
+ function _onlyValidTokenId(uint256 _tokenId) internal view {
307
+ require(_exists(_tokenId), "Token ID does not exist");
308
+ }
309
+
310
+ function _onlyValidProjectId(uint256 _projectId) internal view {
311
+ require(
312
+ (_projectId >= startingProjectId) && (_projectId < _nextProjectId),
313
+ "Project ID does not exist"
314
+ );
315
+ }
316
+
317
+ function _onlyUnlocked(uint256 _projectId) internal view {
318
+ // Note: calling `_projectUnlocked` enforces that the `_projectId`
319
+ // passed in is valid.`
320
+ require(_projectUnlocked(_projectId), "Only if unlocked");
321
+ }
322
+
323
+ function _onlyAdminACL(bytes4 _selector) internal {
324
+ require(
325
+ adminACLAllowed(msg.sender, address(this), _selector),
326
+ "Only Admin ACL allowed"
327
+ );
328
+ }
329
+
330
+ function _onlyArtist(uint256 _projectId) internal view {
331
+ require(
332
+ msg.sender == projectIdToFinancials[_projectId].artistAddress,
333
+ "Only artist"
334
+ );
335
+ }
336
+
337
+ function _onlyArtistOrAdminACL(
338
+ uint256 _projectId,
339
+ bytes4 _selector
340
+ ) internal {
341
+ require(
342
+ msg.sender == projectIdToFinancials[_projectId].artistAddress ||
343
+ adminACLAllowed(msg.sender, address(this), _selector),
344
+ "Only artist or Admin ACL allowed"
345
+ );
346
+ }
347
+
348
+ /**
349
+ * This modifier allows the artist of a project to call a function if the
350
+ * owner of the contract has renounced ownership. This is to allow the
351
+ * contract to continue to function if the owner decides to renounce
352
+ * ownership.
353
+ */
354
+ function _onlyAdminACLOrRenouncedArtist(
355
+ uint256 _projectId,
356
+ bytes4 _selector
357
+ ) internal {
358
+ require(
359
+ adminACLAllowed(msg.sender, address(this), _selector) ||
360
+ (owner() == address(0) &&
361
+ msg.sender ==
362
+ projectIdToFinancials[_projectId].artistAddress),
363
+ "Only Admin ACL allowed, or artist if owner has renounced"
364
+ );
365
+ }
366
+
367
+ /**
368
+ * @notice Initializes contract.
369
+ * @param _tokenName Name of token.
370
+ * @param _tokenSymbol Token symbol.
371
+ * @param _randomizerContract Randomizer contract.
372
+ * @param _adminACLContract Address of admin access control contract, to be
373
+ * set as contract owner.
374
+ * @param _startingProjectId The initial next project ID.
375
+ * @param _autoApproveArtistSplitProposals Whether or not to always
376
+ * auto-approve proposed artist split updates.
377
+ * @dev _startingProjectId should be set to a value much, much less than
378
+ * max(uint248), but an explicit input type of `uint248` is used as it is
379
+ * safer to cast up to `uint256` than it is to cast down for the purposes
380
+ * of setting `_nextProjectId`.
381
+ */
382
+ constructor(
383
+ string memory _tokenName,
384
+ string memory _tokenSymbol,
385
+ address _renderProviderAddress,
386
+ address _platformProviderAddress,
387
+ address _randomizerContract,
388
+ address _adminACLContract,
389
+ uint248 _startingProjectId,
390
+ bool _autoApproveArtistSplitProposals,
391
+ address _engineRegistryContract
392
+ ) ERC721_PackedHashSeed(_tokenName, _tokenSymbol) {
393
+ _onlyNonZeroAddress(_renderProviderAddress);
394
+ _onlyNonZeroAddress(_platformProviderAddress);
395
+ _onlyNonZeroAddress(_randomizerContract);
396
+ _onlyNonZeroAddress(_adminACLContract);
397
+ // setup immutable `autoApproveArtistSplitProposals` config
398
+ autoApproveArtistSplitProposals = _autoApproveArtistSplitProposals;
399
+ // record contracts starting project ID
400
+ // casting-up is safe
401
+ startingProjectId = uint256(_startingProjectId);
402
+ _updateProviderSalesAddresses(
403
+ _renderProviderAddress,
404
+ _renderProviderAddress,
405
+ _platformProviderAddress,
406
+ _platformProviderAddress
407
+ );
408
+ _updateRandomizerAddress(_randomizerContract);
409
+ // set AdminACL management contract as owner
410
+ _transferOwnership(_adminACLContract);
411
+ // initialize default base URI
412
+ _updateDefaultBaseURI(
413
+ string.concat(
414
+ "https://token.artblocks.io/",
415
+ toHexString(address(this)),
416
+ "/"
417
+ )
418
+ );
419
+ // initialize next project ID
420
+ _nextProjectId = _startingProjectId;
421
+ emit PlatformUpdated(FIELD_NEXT_PROJECT_ID);
422
+ // register contract as an Engine contract
423
+ IEngineRegistryV0(_engineRegistryContract).registerContract(
424
+ address(this),
425
+ CORE_VERSION,
426
+ CORE_TYPE
427
+ );
428
+ }
429
+
430
+ /**
431
+ * @notice Updates preferredIPFSGateway to `_gateway`.
432
+ */
433
+ function updateIPFSGateway(string calldata _gateway) public {
434
+ _onlyAdminACL(this.updateIPFSGateway.selector);
435
+ preferredIPFSGateway = _gateway;
436
+ emit GatewayUpdated(ExternalAssetDependencyType.IPFS, _gateway);
437
+ }
438
+
439
+ /**
440
+ * @notice Updates preferredArweaveGateway to `_gateway`.
441
+ */
442
+ function updateArweaveGateway(string calldata _gateway) public {
443
+ _onlyAdminACL(this.updateArweaveGateway.selector);
444
+ preferredArweaveGateway = _gateway;
445
+ emit GatewayUpdated(ExternalAssetDependencyType.ARWEAVE, _gateway);
446
+ }
447
+
448
+ /**
449
+ * @notice Locks external asset dependencies for project `_projectId`.
450
+ */
451
+ function lockProjectExternalAssetDependencies(uint256 _projectId) external {
452
+ _onlyUnlockedProjectExternalAssetDependencies(_projectId);
453
+ _onlyArtistOrAdminACL(
454
+ _projectId,
455
+ this.lockProjectExternalAssetDependencies.selector
456
+ );
457
+ projects[_projectId].externalAssetDependenciesLocked = true;
458
+ emit ProjectExternalAssetDependenciesLocked(_projectId);
459
+ }
460
+
461
+ /**
462
+ * @notice Updates external asset dependency for project `_projectId`.
463
+ * @param _projectId Project to be updated.
464
+ * @param _index Asset index.
465
+ * @param _cidOrData Asset cid (Content identifier) or data string to be translated into bytecode.
466
+ * @param _dependencyType Asset dependency type.
467
+ * 0 - IPFS
468
+ * 1 - ARWEAVE
469
+ * 2 - ONCHAIN
470
+ */
471
+ function updateProjectExternalAssetDependency(
472
+ uint256 _projectId,
473
+ uint256 _index,
474
+ string memory _cidOrData,
475
+ ExternalAssetDependencyType _dependencyType
476
+ ) external {
477
+ _onlyUnlockedProjectExternalAssetDependencies(_projectId);
478
+ _onlyArtistOrAdminACL(
479
+ _projectId,
480
+ this.updateProjectExternalAssetDependency.selector
481
+ );
482
+ uint24 assetCount = projects[_projectId].externalAssetDependencyCount;
483
+ require(_index < assetCount, "Asset index out of range");
484
+ ExternalAssetDependency storage _oldDependency = projects[_projectId]
485
+ .externalAssetDependencies[_index];
486
+ ExternalAssetDependencyType _oldDependencyType = _oldDependency
487
+ .dependencyType;
488
+ projects[_projectId]
489
+ .externalAssetDependencies[_index]
490
+ .dependencyType = _dependencyType;
491
+ // if the incoming dependency type is onchain, we need to write the data to bytecode
492
+ if (_dependencyType == ExternalAssetDependencyType.ONCHAIN) {
493
+ if (_oldDependencyType != ExternalAssetDependencyType.ONCHAIN) {
494
+ // we only need to set the cid to an empty string if we are replacing an offchain asset
495
+ // an onchain asset will already have an empty cid
496
+ projects[_projectId].externalAssetDependencies[_index].cid = "";
497
+ }
498
+
499
+ projects[_projectId]
500
+ .externalAssetDependencies[_index]
501
+ .bytecodeAddress = _cidOrData.writeToBytecode();
502
+ // we don't want to emit data, so we emit the cid as an empty string
503
+ _cidOrData = "";
504
+ } else {
505
+ projects[_projectId]
506
+ .externalAssetDependencies[_index]
507
+ .cid = _cidOrData;
508
+ }
509
+ emit ExternalAssetDependencyUpdated(
510
+ _projectId,
511
+ _index,
512
+ _cidOrData,
513
+ _dependencyType,
514
+ assetCount
515
+ );
516
+ }
517
+
518
+ /**
519
+ * @notice Removes external asset dependency for project `_projectId` at index `_index`.
520
+ * Removal is done by swapping the element to be removed with the last element in the array, then deleting this last element.
521
+ * Assets with indices higher than `_index` can have their indices adjusted as a result of this operation.
522
+ * @param _projectId Project to be updated.
523
+ * @param _index Asset index
524
+ */
525
+ function removeProjectExternalAssetDependency(
526
+ uint256 _projectId,
527
+ uint256 _index
528
+ ) external {
529
+ _onlyUnlockedProjectExternalAssetDependencies(_projectId);
530
+ _onlyArtistOrAdminACL(
531
+ _projectId,
532
+ this.removeProjectExternalAssetDependency.selector
533
+ );
534
+ uint24 assetCount = projects[_projectId].externalAssetDependencyCount;
535
+ require(_index < assetCount, "Asset index out of range");
536
+
537
+ uint24 lastElementIndex = assetCount - 1;
538
+
539
+ // copy last element to index of element to be removed
540
+ projects[_projectId].externalAssetDependencies[_index] = projects[
541
+ _projectId
542
+ ].externalAssetDependencies[lastElementIndex];
543
+
544
+ delete projects[_projectId].externalAssetDependencies[lastElementIndex];
545
+
546
+ projects[_projectId].externalAssetDependencyCount = lastElementIndex;
547
+
548
+ emit ExternalAssetDependencyRemoved(_projectId, _index);
549
+ }
550
+
551
+ /**
552
+ * @notice Adds external asset dependency for project `_projectId`.
553
+ * @param _projectId Project to be updated.
554
+ * @param _cidOrData Asset cid (Content identifier) or data string to be translated into bytecode.
555
+ * @param _dependencyType Asset dependency type.
556
+ * 0 - IPFS
557
+ * 1 - ARWEAVE
558
+ * 2 - ONCHAIN
559
+ */
560
+ function addProjectExternalAssetDependency(
561
+ uint256 _projectId,
562
+ string memory _cidOrData,
563
+ ExternalAssetDependencyType _dependencyType
564
+ ) external {
565
+ _onlyUnlockedProjectExternalAssetDependencies(_projectId);
566
+ _onlyArtistOrAdminACL(
567
+ _projectId,
568
+ this.addProjectExternalAssetDependency.selector
569
+ );
570
+ uint24 assetCount = projects[_projectId].externalAssetDependencyCount;
571
+ address _bytecodeAddress = address(0);
572
+ // if the incoming dependency type is onchain, we need to write the data to bytecode
573
+ if (_dependencyType == ExternalAssetDependencyType.ONCHAIN) {
574
+ _bytecodeAddress = _cidOrData.writeToBytecode();
575
+ // we don't want to emit data, so we emit the cid as an empty string
576
+ _cidOrData = "";
577
+ }
578
+ ExternalAssetDependency memory asset = ExternalAssetDependency({
579
+ cid: _cidOrData,
580
+ dependencyType: _dependencyType,
581
+ bytecodeAddress: _bytecodeAddress
582
+ });
583
+ projects[_projectId].externalAssetDependencies[assetCount] = asset;
584
+ projects[_projectId].externalAssetDependencyCount = assetCount + 1;
585
+
586
+ emit ExternalAssetDependencyUpdated(
587
+ _projectId,
588
+ assetCount,
589
+ _cidOrData,
590
+ _dependencyType,
591
+ assetCount + 1
592
+ );
593
+ }
594
+
595
+ /**
596
+ * @notice Mints a token from project `_projectId` and sets the
597
+ * token's owner to `_to`. Hash may or may not be assigned to the token
598
+ * during the mint transaction, depending on the randomizer contract.
599
+ * @param _to Address to be the minted token's owner.
600
+ * @param _projectId Project ID to mint a token on.
601
+ * @param _by Purchaser of minted token.
602
+ * @return _tokenId The ID of the minted token.
603
+ * @dev sender must be the allowed minterContract
604
+ * @dev name of function is optimized for gas usage
605
+ */
606
+ function mint_Ecf(
607
+ address _to,
608
+ uint256 _projectId,
609
+ address _by
610
+ ) external returns (uint256 _tokenId) {
611
+ // CHECKS
612
+ require(msg.sender == minterContract, "Must mint from minter contract");
613
+ Project storage project = projects[_projectId];
614
+ // load invocations into memory
615
+ uint24 invocationsBefore = project.invocations;
616
+ uint24 invocationsAfter;
617
+ unchecked {
618
+ // invocationsBefore guaranteed <= maxInvocations <= 1_000_000,
619
+ // 1_000_000 << max uint24, so no possible overflow
620
+ invocationsAfter = invocationsBefore + 1;
621
+ }
622
+ uint24 maxInvocations = project.maxInvocations;
623
+
624
+ require(
625
+ invocationsBefore < maxInvocations,
626
+ "Must not exceed max invocations"
627
+ );
628
+ require(
629
+ project.active ||
630
+ _by == projectIdToFinancials[_projectId].artistAddress,
631
+ "Project must exist and be active"
632
+ );
633
+ require(
634
+ !project.paused ||
635
+ _by == projectIdToFinancials[_projectId].artistAddress,
636
+ "Purchases are paused."
637
+ );
638
+
639
+ // EFFECTS
640
+ // increment project's invocations
641
+ project.invocations = invocationsAfter;
642
+ uint256 thisTokenId;
643
+ unchecked {
644
+ // invocationsBefore is uint24 << max uint256. In production use,
645
+ // _projectId * ONE_MILLION must be << max uint256, otherwise
646
+ // tokenIdToProjectId function become invalid.
647
+ // Therefore, no risk of overflow
648
+ thisTokenId = (_projectId * ONE_MILLION) + invocationsBefore;
649
+ }
650
+
651
+ // mark project as completed if hit max invocations
652
+ if (invocationsAfter == maxInvocations) {
653
+ _completeProject(_projectId);
654
+ }
655
+
656
+ // INTERACTIONS
657
+ _mint(_to, thisTokenId);
658
+
659
+ // token hash is updated by the randomizer contract on V3
660
+ randomizerContract.assignTokenHash(thisTokenId);
661
+
662
+ // Do not need to also log `projectId` in event, as the `projectId` for
663
+ // a given token can be derived from the `tokenId` with:
664
+ // projectId = tokenId / 1_000_000
665
+ emit Mint(_to, thisTokenId);
666
+
667
+ return thisTokenId;
668
+ }
669
+
670
+ /**
671
+ * @notice Sets the hash seed for a given token ID `_tokenId`.
672
+ * May only be called by the current randomizer contract.
673
+ * May only be called for tokens that have not already been assigned a
674
+ * non-zero hash.
675
+ * @param _tokenId Token ID to set the hash for.
676
+ * @param _hashSeed Hash seed to set for the token ID. Only last 12 bytes
677
+ * will be used.
678
+ * @dev gas-optimized function name because called during mint sequence
679
+ * @dev if a separate event is required when the token hash is set, e.g.
680
+ * for indexing purposes, it must be emitted by the randomizer. This is to
681
+ * minimize gas when minting.
682
+ */
683
+ function setTokenHash_8PT(uint256 _tokenId, bytes32 _hashSeed) external {
684
+ _onlyValidTokenId(_tokenId);
685
+
686
+ OwnerAndHashSeed storage ownerAndHashSeed = _ownersAndHashSeeds[
687
+ _tokenId
688
+ ];
689
+ require(
690
+ msg.sender == address(randomizerContract),
691
+ "Only randomizer may set"
692
+ );
693
+ require(
694
+ ownerAndHashSeed.hashSeed == bytes12(0),
695
+ "Token hash already set"
696
+ );
697
+ require(_hashSeed != bytes12(0), "No zero hash seed");
698
+ ownerAndHashSeed.hashSeed = bytes12(_hashSeed);
699
+ }
700
+
701
+ /**
702
+ * @notice Allows owner (AdminACL) to revoke ownership of the contract.
703
+ * Note that the contract is intended to continue to function after the
704
+ * owner renounces ownership, but no new projects will be able to be added.
705
+ * Renouncing ownership will leave the contract without an owner,
706
+ * thereby removing any functionality that is only available to the
707
+ * owner/AdminACL contract. The same is true for any dependent contracts
708
+ * that also integrate with the owner/AdminACL contract (e.g. potentially
709
+ * minter suite contracts, registry contracts, etc.).
710
+ * After renouncing ownership, artists will be in control of updates to
711
+ * their payment addresses and splits (see modifier
712
+ * onlyAdminACLOrRenouncedArtist`).
713
+ * While there is no currently intended reason to call this method based on
714
+ * typical Engine partner business practices, this method exists to allow
715
+ * artists to continue to maintain the limited set of contract
716
+ * functionality that exists post-project-lock in an environment in which
717
+ * there is no longer an admin maintaining this smart contract.
718
+ * @dev This function is intended to be called directly by the AdminACL,
719
+ * not by an address allowed by the AdminACL contract.
720
+ */
721
+ function renounceOwnership() public override onlyOwner {
722
+ // broadcast that new projects are no longer allowed (if not already)
723
+ _forbidNewProjects();
724
+ // renounce ownership viw Ownable
725
+ Ownable.renounceOwnership();
726
+ }
727
+
728
+ /**
729
+ * @notice Updates reference to Art Blocks Dependency Registry contract.
730
+ * @param _artblocksDependencyRegistryAddress Address of new Dependency
731
+ * Registry.
732
+ */
733
+ function updateArtblocksDependencyRegistryAddress(
734
+ address _artblocksDependencyRegistryAddress
735
+ ) external {
736
+ _onlyAdminACL(this.updateArtblocksDependencyRegistryAddress.selector);
737
+ _onlyNonZeroAddress(_artblocksDependencyRegistryAddress);
738
+ artblocksDependencyRegistryAddress = _artblocksDependencyRegistryAddress;
739
+ emit PlatformUpdated(FIELD_ARTBLOCKS_DEPENDENCY_REGISTRY_ADDRESS);
740
+ }
741
+
742
+ /**
743
+ * @notice Updates sales addresses for the platform and render providers to
744
+ * the input parameters.
745
+ * @param _renderProviderPrimarySalesAddress Address of new primary sales
746
+ * payment address.
747
+ * @param _renderProviderSecondarySalesAddress Address of new secondary sales
748
+ * payment address.
749
+ * @param _platformProviderPrimarySalesAddress Address of new primary sales
750
+ * payment address.
751
+ * @param _platformProviderSecondarySalesAddress Address of new secondary sales
752
+ * payment address.
753
+ */
754
+ function updateProviderSalesAddresses(
755
+ address payable _renderProviderPrimarySalesAddress,
756
+ address payable _renderProviderSecondarySalesAddress,
757
+ address payable _platformProviderPrimarySalesAddress,
758
+ address payable _platformProviderSecondarySalesAddress
759
+ ) external {
760
+ _onlyAdminACL(this.updateProviderSalesAddresses.selector);
761
+ _onlyNonZeroAddress(_renderProviderPrimarySalesAddress);
762
+ _onlyNonZeroAddress(_renderProviderSecondarySalesAddress);
763
+ _onlyNonZeroAddress(_platformProviderPrimarySalesAddress);
764
+ _onlyNonZeroAddress(_platformProviderSecondarySalesAddress);
765
+ _updateProviderSalesAddresses(
766
+ _renderProviderPrimarySalesAddress,
767
+ _renderProviderSecondarySalesAddress,
768
+ _platformProviderPrimarySalesAddress,
769
+ _platformProviderSecondarySalesAddress
770
+ );
771
+ }
772
+
773
+ /**
774
+ * @notice Updates the render and platform provider primary sales revenue percentage to
775
+ * the provided inputs.
776
+ * @param renderProviderPrimarySalesPercentage_ New primary sales revenue % for the render provider
777
+ * @param platformProviderPrimarySalesPercentage_ New primary sales revenue % for the platform provider
778
+ * percentage.
779
+ */
780
+ function updateProviderPrimarySalesPercentages(
781
+ uint256 renderProviderPrimarySalesPercentage_,
782
+ uint256 platformProviderPrimarySalesPercentage_
783
+ ) external {
784
+ _onlyAdminACL(this.updateProviderPrimarySalesPercentages.selector);
785
+
786
+ // Validate that the sum of the proposed %s, does not exceed 100%.
787
+ require(
788
+ (renderProviderPrimarySalesPercentage_ +
789
+ platformProviderPrimarySalesPercentage_) <= ONE_HUNDRED,
790
+ "Max sum of ONE_HUNDRED %"
791
+ );
792
+ // Casting to `uint8` here is safe due check above, which does not allow
793
+ // overflow as of solidity version ^0.8.0.
794
+ _renderProviderPrimarySalesPercentage = uint8(
795
+ renderProviderPrimarySalesPercentage_
796
+ );
797
+ _platformProviderPrimarySalesPercentage = uint8(
798
+ platformProviderPrimarySalesPercentage_
799
+ );
800
+ emit PlatformUpdated(FIELD_PROVIDER_PRIMARY_SALES_PERCENTAGES);
801
+ }
802
+
803
+ /**
804
+ * @notice Updates render and platform provider secondary sales royalty Basis Points to
805
+ * the provided inputs.
806
+ * @param _renderProviderSecondarySalesBPS New secondary sales royalty Basis
807
+ * points.
808
+ * @param _platformProviderSecondarySalesBPS New secondary sales royalty Basis
809
+ * points.
810
+ * @dev Due to secondary royalties being ultimately enforced via social
811
+ * consensus, no hard upper limit is imposed on the BPS value, other than
812
+ * <= 100% royalty, which would not make mathematical sense. Realistically,
813
+ * changing this value is expected to either never occur, or be a rare
814
+ * occurrence.
815
+ */
816
+ function updateProviderSecondarySalesBPS(
817
+ uint256 _renderProviderSecondarySalesBPS,
818
+ uint256 _platformProviderSecondarySalesBPS
819
+ ) external {
820
+ _onlyAdminACL(this.updateProviderSecondarySalesBPS.selector);
821
+ // Validate that the sum of the proposed provider BPS, does not exceed 10_000 BPS.
822
+ require(
823
+ (_renderProviderSecondarySalesBPS +
824
+ _platformProviderSecondarySalesBPS) <=
825
+ MAX_PROVIDER_SECONDARY_SALES_BPS,
826
+ "Over max sum of BPS"
827
+ );
828
+ renderProviderSecondarySalesBPS = _renderProviderSecondarySalesBPS;
829
+ platformProviderSecondarySalesBPS = _platformProviderSecondarySalesBPS;
830
+ emit PlatformUpdated(FIELD_PROVIDER_SECONDARY_SALES_BPS);
831
+ }
832
+
833
+ /**
834
+ * @notice Updates minter to `_address`.
835
+ * @param _address Address of new minter.
836
+ */
837
+ function updateMinterContract(address _address) external {
838
+ _onlyAdminACL(this.updateMinterContract.selector);
839
+ _onlyNonZeroAddress(_address);
840
+ minterContract = _address;
841
+ emit MinterUpdated(_address);
842
+ }
843
+
844
+ /**
845
+ * @notice Updates randomizer to `_randomizerAddress`.
846
+ * @param _randomizerAddress Address of new randomizer.
847
+ */
848
+ function updateRandomizerAddress(address _randomizerAddress) external {
849
+ _onlyAdminACL(this.updateRandomizerAddress.selector);
850
+ _onlyNonZeroAddress(_randomizerAddress);
851
+ _updateRandomizerAddress(_randomizerAddress);
852
+ }
853
+
854
+ /**
855
+ * @notice Toggles project `_projectId` as active/inactive.
856
+ * @param _projectId Project ID to be toggled.
857
+ */
858
+ function toggleProjectIsActive(uint256 _projectId) external {
859
+ _onlyAdminACL(this.toggleProjectIsActive.selector);
860
+ _onlyValidProjectId(_projectId);
861
+ projects[_projectId].active = !projects[_projectId].active;
862
+ emit ProjectUpdated(_projectId, FIELD_PROJECT_ACTIVE);
863
+ }
864
+
865
+ /**
866
+ * @notice Artist proposes updated set of artist address, additional payee
867
+ * addresses, and percentage splits for project `_projectId`. Addresses and
868
+ * percentages do not have to all be changed, but they must all be defined
869
+ * as a complete set.
870
+ * Note that if the artist is only proposing a change to the payee percentage
871
+ * splits, without modifying the payee addresses, the proposal will be
872
+ * automatically approved and the new splits will become active immediately.
873
+ * Automatic approval will also be granted if the artist is only removing
874
+ * additional payee addresses, without adding any new ones.
875
+ * Also note that if `autoApproveArtistSplitProposals` is true, proposals
876
+ * will always be auto-approved, regardless of what is being changed.
877
+ * Also note that if the artist is proposing sending funds to the zero
878
+ * address, this function will revert and the proposal will not be created.
879
+ * @param _projectId Project ID.
880
+ * @param _artistAddress Artist address that controls the project, and may
881
+ * receive payments.
882
+ * @param _additionalPayeePrimarySales Address that may receive a
883
+ * percentage split of the artist's primary sales revenue.
884
+ * @param _additionalPayeePrimarySalesPercentage Percent of artist's
885
+ * portion of primary sale revenue that will be split to address
886
+ * `_additionalPayeePrimarySales`.
887
+ * @param _additionalPayeeSecondarySales Address that may receive a percentage
888
+ * split of the secondary sales royalties.
889
+ * @param _additionalPayeeSecondarySalesPercentage Percent of artist's portion
890
+ * of secondary sale royalties that will be split to address
891
+ * `_additionalPayeeSecondarySales`.
892
+ * @dev `_artistAddress` must be a valid address (non-zero-address), but it
893
+ * is intentionally allowable for `_additionalPayee{Primary,Secondaary}Sales`
894
+ * and their associated percentages to be zero'd out by the controlling artist.
895
+ */
896
+ function proposeArtistPaymentAddressesAndSplits(
897
+ uint256 _projectId,
898
+ address payable _artistAddress,
899
+ address payable _additionalPayeePrimarySales,
900
+ uint256 _additionalPayeePrimarySalesPercentage,
901
+ address payable _additionalPayeeSecondarySales,
902
+ uint256 _additionalPayeeSecondarySalesPercentage
903
+ ) external {
904
+ _onlyValidProjectId(_projectId);
905
+ _onlyArtist(_projectId);
906
+ _onlyNonZeroAddress(_artistAddress);
907
+ ProjectFinance storage projectFinance = projectIdToFinancials[
908
+ _projectId
909
+ ];
910
+ // checks
911
+ require(
912
+ _additionalPayeePrimarySalesPercentage <= ONE_HUNDRED &&
913
+ _additionalPayeeSecondarySalesPercentage <= ONE_HUNDRED,
914
+ "Max of 100%"
915
+ );
916
+ require(
917
+ _additionalPayeePrimarySalesPercentage == 0 ||
918
+ _additionalPayeePrimarySales != address(0),
919
+ "Primary payee is zero address"
920
+ );
921
+ require(
922
+ _additionalPayeeSecondarySalesPercentage == 0 ||
923
+ _additionalPayeeSecondarySales != address(0),
924
+ "Secondary payee is zero address"
925
+ );
926
+ // effects
927
+ // emit event for off-chain indexing
928
+ // note: always emit a proposal event, even in the pathway of
929
+ // automatic approval, to simplify indexing expectations
930
+ emit ProposedArtistAddressesAndSplits(
931
+ _projectId,
932
+ _artistAddress,
933
+ _additionalPayeePrimarySales,
934
+ _additionalPayeePrimarySalesPercentage,
935
+ _additionalPayeeSecondarySales,
936
+ _additionalPayeeSecondarySalesPercentage
937
+ );
938
+ // automatically accept if no proposed addresses modifications, or if
939
+ // the proposal only removes payee addresses, or if contract is set to
940
+ // always auto-approve.
941
+ // store proposal hash on-chain, only if not automatic accept
942
+ bool automaticAccept = autoApproveArtistSplitProposals;
943
+ if (!automaticAccept) {
944
+ // block scope to avoid stack too deep error
945
+ bool artistUnchanged = _artistAddress ==
946
+ projectFinance.artistAddress;
947
+ bool additionalPrimaryUnchangedOrRemoved = (_additionalPayeePrimarySales ==
948
+ projectFinance.additionalPayeePrimarySales) ||
949
+ (_additionalPayeePrimarySales == address(0));
950
+ bool additionalSecondaryUnchangedOrRemoved = (_additionalPayeeSecondarySales ==
951
+ projectFinance.additionalPayeeSecondarySales) ||
952
+ (_additionalPayeeSecondarySales == address(0));
953
+ automaticAccept =
954
+ artistUnchanged &&
955
+ additionalPrimaryUnchangedOrRemoved &&
956
+ additionalSecondaryUnchangedOrRemoved;
957
+ }
958
+ if (automaticAccept) {
959
+ // clear any previously proposed values
960
+ proposedArtistAddressesAndSplitsHash[_projectId] = bytes32(0);
961
+ // update storage
962
+ // artist address can change during automatic accept if
963
+ // autoApproveArtistSplitProposals is true
964
+ projectFinance.artistAddress = _artistAddress;
965
+ projectFinance
966
+ .additionalPayeePrimarySales = _additionalPayeePrimarySales;
967
+ // safe to cast as uint8 as max is 100%, max uint8 is 255
968
+ projectFinance.additionalPayeePrimarySalesPercentage = uint8(
969
+ _additionalPayeePrimarySalesPercentage
970
+ );
971
+ projectFinance
972
+ .additionalPayeeSecondarySales = _additionalPayeeSecondarySales;
973
+ // safe to cast as uint8 as max is 100%, max uint8 is 255
974
+ projectFinance.additionalPayeeSecondarySalesPercentage = uint8(
975
+ _additionalPayeeSecondarySalesPercentage
976
+ );
977
+ // emit event for off-chain indexing
978
+ emit AcceptedArtistAddressesAndSplits(_projectId);
979
+ } else {
980
+ proposedArtistAddressesAndSplitsHash[_projectId] = keccak256(
981
+ abi.encode(
982
+ _artistAddress,
983
+ _additionalPayeePrimarySales,
984
+ _additionalPayeePrimarySalesPercentage,
985
+ _additionalPayeeSecondarySales,
986
+ _additionalPayeeSecondarySalesPercentage
987
+ )
988
+ );
989
+ }
990
+ }
991
+
992
+ /**
993
+ * @notice Admin accepts a proposed set of updated artist address,
994
+ * additional payee addresses, and percentage splits for project
995
+ * `_projectId`. Addresses and percentages do not have to all be changed,
996
+ * but they must all be defined as a complete set.
997
+ * @param _projectId Project ID.
998
+ * @param _artistAddress Artist address that controls the project, and may
999
+ * receive payments.
1000
+ * @param _additionalPayeePrimarySales Address that may receive a
1001
+ * percentage split of the artist's primary sales revenue.
1002
+ * @param _additionalPayeePrimarySalesPercentage Percent of artist's
1003
+ * portion of primary sale revenue that will be split to address
1004
+ * `_additionalPayeePrimarySales`.
1005
+ * @param _additionalPayeeSecondarySales Address that may receive a percentage
1006
+ * split of the secondary sales royalties.
1007
+ * @param _additionalPayeeSecondarySalesPercentage Percent of artist's portion
1008
+ * of secondary sale royalties that will be split to address
1009
+ * `_additionalPayeeSecondarySales`.
1010
+ * @dev this must be called by the Admin ACL contract, and must only accept
1011
+ * the most recent proposed values for a given project (validated on-chain
1012
+ * by comparing the hash of the proposed and accepted values).
1013
+ * @dev `_artistAddress` must be a valid address (non-zero-address), but it
1014
+ * is intentionally allowable for `_additionalPayee{Primary,Secondaary}Sales`
1015
+ * and their associated percentages to be zero'd out by the controlling artist.
1016
+ */
1017
+ function adminAcceptArtistAddressesAndSplits(
1018
+ uint256 _projectId,
1019
+ address payable _artistAddress,
1020
+ address payable _additionalPayeePrimarySales,
1021
+ uint256 _additionalPayeePrimarySalesPercentage,
1022
+ address payable _additionalPayeeSecondarySales,
1023
+ uint256 _additionalPayeeSecondarySalesPercentage
1024
+ ) external {
1025
+ _onlyValidProjectId(_projectId);
1026
+ _onlyAdminACLOrRenouncedArtist(
1027
+ _projectId,
1028
+ this.adminAcceptArtistAddressesAndSplits.selector
1029
+ );
1030
+ _onlyNonZeroAddress(_artistAddress);
1031
+ // checks
1032
+ require(
1033
+ proposedArtistAddressesAndSplitsHash[_projectId] ==
1034
+ keccak256(
1035
+ abi.encode(
1036
+ _artistAddress,
1037
+ _additionalPayeePrimarySales,
1038
+ _additionalPayeePrimarySalesPercentage,
1039
+ _additionalPayeeSecondarySales,
1040
+ _additionalPayeeSecondarySalesPercentage
1041
+ )
1042
+ ),
1043
+ "Must match artist proposal"
1044
+ );
1045
+ // effects
1046
+ ProjectFinance storage projectFinance = projectIdToFinancials[
1047
+ _projectId
1048
+ ];
1049
+ projectFinance.artistAddress = _artistAddress;
1050
+ projectFinance
1051
+ .additionalPayeePrimarySales = _additionalPayeePrimarySales;
1052
+ projectFinance.additionalPayeePrimarySalesPercentage = uint8(
1053
+ _additionalPayeePrimarySalesPercentage
1054
+ );
1055
+ projectFinance
1056
+ .additionalPayeeSecondarySales = _additionalPayeeSecondarySales;
1057
+ projectFinance.additionalPayeeSecondarySalesPercentage = uint8(
1058
+ _additionalPayeeSecondarySalesPercentage
1059
+ );
1060
+ // clear proposed values
1061
+ proposedArtistAddressesAndSplitsHash[_projectId] = bytes32(0);
1062
+ // emit event for off-chain indexing
1063
+ emit AcceptedArtistAddressesAndSplits(_projectId);
1064
+ }
1065
+
1066
+ /**
1067
+ * @notice Updates artist of project `_projectId` to `_artistAddress`.
1068
+ * This is to only be used in the event that the artist address is
1069
+ * compromised or sanctioned.
1070
+ * @param _projectId Project ID.
1071
+ * @param _artistAddress New artist address.
1072
+ */
1073
+ function updateProjectArtistAddress(
1074
+ uint256 _projectId,
1075
+ address payable _artistAddress
1076
+ ) external {
1077
+ _onlyValidProjectId(_projectId);
1078
+ _onlyAdminACLOrRenouncedArtist(
1079
+ _projectId,
1080
+ this.updateProjectArtistAddress.selector
1081
+ );
1082
+ _onlyNonZeroAddress(_artistAddress);
1083
+ projectIdToFinancials[_projectId].artistAddress = _artistAddress;
1084
+ emit ProjectUpdated(_projectId, FIELD_PROJECT_ARTIST_ADDRESS);
1085
+ }
1086
+
1087
+ /**
1088
+ * @notice Toggles paused state of project `_projectId`.
1089
+ * @param _projectId Project ID to be toggled.
1090
+ */
1091
+ function toggleProjectIsPaused(uint256 _projectId) external {
1092
+ _onlyArtist(_projectId);
1093
+ projects[_projectId].paused = !projects[_projectId].paused;
1094
+ emit ProjectUpdated(_projectId, FIELD_PROJECT_PAUSED);
1095
+ }
1096
+
1097
+ /**
1098
+ * @notice Adds new project `_projectName` by `_artistAddress`.
1099
+ * @param _projectName Project name.
1100
+ * @param _artistAddress Artist's address.
1101
+ * @dev token price now stored on minter
1102
+ */
1103
+ function addProject(
1104
+ string memory _projectName,
1105
+ address payable _artistAddress
1106
+ ) external {
1107
+ _onlyAdminACL(this.addProject.selector);
1108
+ _onlyNonEmptyString(_projectName);
1109
+ _onlyNonZeroAddress(_artistAddress);
1110
+ require(!newProjectsForbidden, "New projects forbidden");
1111
+ uint256 projectId = _nextProjectId;
1112
+ projectIdToFinancials[projectId].artistAddress = _artistAddress;
1113
+ projects[projectId].name = _projectName;
1114
+ projects[projectId].paused = true;
1115
+ projects[projectId].maxInvocations = ONE_MILLION_UINT24;
1116
+ projects[projectId].projectBaseURI = defaultBaseURI;
1117
+
1118
+ _nextProjectId = uint248(projectId) + 1;
1119
+ emit ProjectUpdated(projectId, FIELD_PROJECT_CREATED);
1120
+ }
1121
+
1122
+ /**
1123
+ * @notice Forever forbids new projects from being added to this contract.
1124
+ */
1125
+ function forbidNewProjects() external {
1126
+ _onlyAdminACL(this.forbidNewProjects.selector);
1127
+ require(!newProjectsForbidden, "Already forbidden");
1128
+ _forbidNewProjects();
1129
+ }
1130
+
1131
+ /**
1132
+ * @notice Updates name of project `_projectId` to be `_projectName`.
1133
+ * @param _projectId Project ID.
1134
+ * @param _projectName New project name.
1135
+ */
1136
+ function updateProjectName(
1137
+ uint256 _projectId,
1138
+ string memory _projectName
1139
+ ) external {
1140
+ _onlyUnlocked(_projectId);
1141
+ _onlyArtistOrAdminACL(_projectId, this.updateProjectName.selector);
1142
+ _onlyNonEmptyString(_projectName);
1143
+ projects[_projectId].name = _projectName;
1144
+ emit ProjectUpdated(_projectId, FIELD_PROJECT_NAME);
1145
+ }
1146
+
1147
+ /**
1148
+ * @notice Updates artist name for project `_projectId` to be
1149
+ * `_projectArtistName`.
1150
+ * @param _projectId Project ID.
1151
+ * @param _projectArtistName New artist name.
1152
+ */
1153
+ function updateProjectArtistName(
1154
+ uint256 _projectId,
1155
+ string memory _projectArtistName
1156
+ ) external {
1157
+ _onlyUnlocked(_projectId);
1158
+ _onlyArtistOrAdminACL(
1159
+ _projectId,
1160
+ this.updateProjectArtistName.selector
1161
+ );
1162
+ _onlyNonEmptyString(_projectArtistName);
1163
+ projects[_projectId].artist = _projectArtistName;
1164
+ emit ProjectUpdated(_projectId, FIELD_PROJECT_ARTIST_NAME);
1165
+ }
1166
+
1167
+ /**
1168
+ * @notice Updates artist secondary market royalties for project
1169
+ * `_projectId` to be `_secondMarketRoyalty` percent.
1170
+ * This DOES NOT include the secondary market royalty percentages collected
1171
+ * by the issuing platform; it is only the total percentage of royalties
1172
+ * that will be split to artist and additionalSecondaryPayee.
1173
+ * @param _projectId Project ID.
1174
+ * @param _secondMarketRoyalty Percent of secondary sales revenue that will
1175
+ * be split to artist and additionalSecondaryPayee. This must be less than
1176
+ * or equal to ARTIST_MAX_SECONDARY_ROYALTY_PERCENTAGE percent.
1177
+ */
1178
+ function updateProjectSecondaryMarketRoyaltyPercentage(
1179
+ uint256 _projectId,
1180
+ uint256 _secondMarketRoyalty
1181
+ ) external {
1182
+ _onlyArtist(_projectId);
1183
+ require(
1184
+ _secondMarketRoyalty <= ARTIST_MAX_SECONDARY_ROYALTY_PERCENTAGE,
1185
+ "Over max percent"
1186
+ );
1187
+ projectIdToFinancials[_projectId]
1188
+ .secondaryMarketRoyaltyPercentage = uint8(_secondMarketRoyalty);
1189
+ emit ProjectUpdated(
1190
+ _projectId,
1191
+ FIELD_PROJECT_SECONDARY_MARKET_ROYALTY_PERCENTAGE
1192
+ );
1193
+ }
1194
+
1195
+ /**
1196
+ * @notice Updates description of project `_projectId`.
1197
+ * Only artist may call when unlocked, only admin may call when locked.
1198
+ * Note: The BytecodeStorage library is used to store the description to
1199
+ * reduce initial upload cost, however, even minor edits will require an
1200
+ * expensive, entirely new bytecode storage contract to be deployed instead
1201
+ * of relatively cheap updates to already-warm storage slots. This results
1202
+ * in an increased gas cost for minor edits to the description after the
1203
+ * initial upload, but an overall decrease in gas cost for projects with
1204
+ * less than ~3-5 edits (depending on the length of the description).
1205
+ * @param _projectId Project ID.
1206
+ * @param _projectDescription New project description.
1207
+ */
1208
+ function updateProjectDescription(
1209
+ uint256 _projectId,
1210
+ string memory _projectDescription
1211
+ ) external {
1212
+ // checks
1213
+ require(
1214
+ _projectUnlocked(_projectId)
1215
+ ? msg.sender == projectIdToFinancials[_projectId].artistAddress
1216
+ : adminACLAllowed(
1217
+ msg.sender,
1218
+ address(this),
1219
+ this.updateProjectDescription.selector
1220
+ ),
1221
+ "Only artist when unlocked, owner when locked"
1222
+ );
1223
+ // effects
1224
+ // store description in contract bytecode, replacing reference address from
1225
+ // the old storage description with the newly created one
1226
+ projects[_projectId].descriptionAddress = _projectDescription
1227
+ .writeToBytecode();
1228
+ emit ProjectUpdated(_projectId, FIELD_PROJECT_DESCRIPTION);
1229
+ }
1230
+
1231
+ /**
1232
+ * @notice Updates website of project `_projectId` to be `_projectWebsite`.
1233
+ * @param _projectId Project ID.
1234
+ * @param _projectWebsite New project website.
1235
+ * @dev It is intentionally allowed for this to be set to the empty string.
1236
+ */
1237
+ function updateProjectWebsite(
1238
+ uint256 _projectId,
1239
+ string memory _projectWebsite
1240
+ ) external {
1241
+ _onlyArtist(_projectId);
1242
+ projects[_projectId].website = _projectWebsite;
1243
+ emit ProjectUpdated(_projectId, FIELD_PROJECT_WEBSITE);
1244
+ }
1245
+
1246
+ /**
1247
+ * @notice Updates license for project `_projectId`.
1248
+ * @param _projectId Project ID.
1249
+ * @param _projectLicense New project license.
1250
+ */
1251
+ function updateProjectLicense(
1252
+ uint256 _projectId,
1253
+ string memory _projectLicense
1254
+ ) external {
1255
+ _onlyUnlocked(_projectId);
1256
+ _onlyArtistOrAdminACL(_projectId, this.updateProjectLicense.selector);
1257
+ _onlyNonEmptyString(_projectLicense);
1258
+ projects[_projectId].license = _projectLicense;
1259
+ emit ProjectUpdated(_projectId, FIELD_PROJECT_LICENSE);
1260
+ }
1261
+
1262
+ /**
1263
+ * @notice Updates maximum invocations for project `_projectId` to
1264
+ * `_maxInvocations`. Maximum invocations may only be decreased by the
1265
+ * artist, and must be greater than or equal to current invocations.
1266
+ * New projects are created with maximum invocations of 1 million by
1267
+ * default.
1268
+ * @param _projectId Project ID.
1269
+ * @param _maxInvocations New maximum invocations.
1270
+ */
1271
+ function updateProjectMaxInvocations(
1272
+ uint256 _projectId,
1273
+ uint24 _maxInvocations
1274
+ ) external {
1275
+ _onlyArtist(_projectId);
1276
+ // CHECKS
1277
+ Project storage project = projects[_projectId];
1278
+ uint256 _invocations = project.invocations;
1279
+ require(
1280
+ (_maxInvocations < project.maxInvocations),
1281
+ "Only maxInvocations decrease"
1282
+ );
1283
+ require(_maxInvocations >= _invocations, "Only gte invocations");
1284
+ // EFFECTS
1285
+ project.maxInvocations = _maxInvocations;
1286
+ emit ProjectUpdated(_projectId, FIELD_PROJECT_MAX_INVOCATIONS);
1287
+
1288
+ // register completed timestamp if action completed the project
1289
+ if (_maxInvocations == _invocations) {
1290
+ _completeProject(_projectId);
1291
+ }
1292
+ }
1293
+
1294
+ /**
1295
+ * @notice Adds a script to project `_projectId`.
1296
+ * @param _projectId Project to be updated.
1297
+ * @param _script Script to be added. Required to be a non-empty string,
1298
+ * but no further validation is performed.
1299
+ */
1300
+ function addProjectScript(
1301
+ uint256 _projectId,
1302
+ string memory _script
1303
+ ) external {
1304
+ _onlyUnlocked(_projectId);
1305
+ _onlyArtistOrAdminACL(_projectId, this.addProjectScript.selector);
1306
+ _onlyNonEmptyString(_script);
1307
+ Project storage project = projects[_projectId];
1308
+ // store script in contract bytecode
1309
+ project.scriptBytecodeAddresses[project.scriptCount] = _script
1310
+ .writeToBytecode();
1311
+ project.scriptCount = project.scriptCount + 1;
1312
+ emit ProjectUpdated(_projectId, FIELD_PROJECT_SCRIPT);
1313
+ }
1314
+
1315
+ /**
1316
+ * @notice Updates script for project `_projectId` at script ID `_scriptId`.
1317
+ * @param _projectId Project to be updated.
1318
+ * @param _scriptId Script ID to be updated.
1319
+ * @param _script The updated script value. Required to be a non-empty
1320
+ * string, but no further validation is performed.
1321
+ */
1322
+ function updateProjectScript(
1323
+ uint256 _projectId,
1324
+ uint256 _scriptId,
1325
+ string memory _script
1326
+ ) external {
1327
+ _onlyUnlocked(_projectId);
1328
+ _onlyArtistOrAdminACL(_projectId, this.updateProjectScript.selector);
1329
+ _onlyNonEmptyString(_script);
1330
+ Project storage project = projects[_projectId];
1331
+ require(_scriptId < project.scriptCount, "scriptId out of range");
1332
+ // store script in contract bytecode, replacing reference address from
1333
+ // the old storage contract with the newly created one
1334
+ project.scriptBytecodeAddresses[_scriptId] = _script.writeToBytecode();
1335
+ emit ProjectUpdated(_projectId, FIELD_PROJECT_SCRIPT);
1336
+ }
1337
+
1338
+ /**
1339
+ * @notice Removes last script from project `_projectId`.
1340
+ * @param _projectId Project to be updated.
1341
+ */
1342
+ function removeProjectLastScript(uint256 _projectId) external {
1343
+ _onlyUnlocked(_projectId);
1344
+ _onlyArtistOrAdminACL(
1345
+ _projectId,
1346
+ this.removeProjectLastScript.selector
1347
+ );
1348
+ Project storage project = projects[_projectId];
1349
+ require(project.scriptCount > 0, "No scripts to remove");
1350
+ // delete reference to old storage contract address
1351
+ delete project.scriptBytecodeAddresses[project.scriptCount - 1];
1352
+ unchecked {
1353
+ project.scriptCount = project.scriptCount - 1;
1354
+ }
1355
+ emit ProjectUpdated(_projectId, FIELD_PROJECT_SCRIPT);
1356
+ }
1357
+
1358
+ /**
1359
+ * @notice Updates script type for project `_projectId`.
1360
+ * @param _projectId Project to be updated.
1361
+ * @param _scriptTypeAndVersion Script type and version e.g. "p5js@1.0.0",
1362
+ * as bytes32 encoded string.
1363
+ */
1364
+ function updateProjectScriptType(
1365
+ uint256 _projectId,
1366
+ bytes32 _scriptTypeAndVersion
1367
+ ) external {
1368
+ _onlyUnlocked(_projectId);
1369
+ _onlyArtistOrAdminACL(
1370
+ _projectId,
1371
+ this.updateProjectScriptType.selector
1372
+ );
1373
+ Project storage project = projects[_projectId];
1374
+ // require exactly one @ symbol in _scriptTypeAndVersion
1375
+ require(
1376
+ _scriptTypeAndVersion.containsExactCharacterQty(
1377
+ AT_CHARACTER_CODE,
1378
+ uint8(1)
1379
+ ),
1380
+ "must contain exactly one @"
1381
+ );
1382
+ project.scriptTypeAndVersion = _scriptTypeAndVersion;
1383
+ emit ProjectUpdated(_projectId, FIELD_PROJECT_SCRIPT_TYPE);
1384
+ }
1385
+
1386
+ /**
1387
+ * @notice Updates project's aspect ratio.
1388
+ * @param _projectId Project to be updated.
1389
+ * @param _aspectRatio Aspect ratio to be set. Intended to be string in the
1390
+ * format of a decimal, e.g. "1" for square, "1.77777778" for 16:9, etc.,
1391
+ * allowing for a maximum of 10 digits and one (optional) decimal separator.
1392
+ */
1393
+ function updateProjectAspectRatio(
1394
+ uint256 _projectId,
1395
+ string memory _aspectRatio
1396
+ ) external {
1397
+ _onlyUnlocked(_projectId);
1398
+ _onlyArtistOrAdminACL(
1399
+ _projectId,
1400
+ this.updateProjectAspectRatio.selector
1401
+ );
1402
+ _onlyNonEmptyString(_aspectRatio);
1403
+ // Perform more detailed input validation for aspect ratio.
1404
+ bytes memory aspectRatioBytes = bytes(_aspectRatio);
1405
+ uint256 bytesLength = aspectRatioBytes.length;
1406
+ require(bytesLength <= 11, "Aspect ratio format too long");
1407
+ bool hasSeenDecimalSeparator = false;
1408
+ bool hasSeenNumber = false;
1409
+ for (uint256 i; i < bytesLength; i++) {
1410
+ bytes1 character = aspectRatioBytes[i];
1411
+ // Allow as many #s as desired.
1412
+ if (character >= 0x30 && character <= 0x39) {
1413
+ // 9-0
1414
+ // We need to ensure there is at least 1 `9-0` occurrence.
1415
+ hasSeenNumber = true;
1416
+ continue;
1417
+ }
1418
+ if (character == 0x2E) {
1419
+ // .
1420
+ // Allow no more than 1 `.` occurrence.
1421
+ if (!hasSeenDecimalSeparator) {
1422
+ hasSeenDecimalSeparator = true;
1423
+ continue;
1424
+ }
1425
+ }
1426
+ revert("Improperly formatted aspect ratio");
1427
+ }
1428
+ require(hasSeenNumber, "Aspect ratio has no numbers");
1429
+
1430
+ projects[_projectId].aspectRatio = _aspectRatio;
1431
+ emit ProjectUpdated(_projectId, FIELD_PROJECT_ASPECT_RATIO);
1432
+ }
1433
+
1434
+ /**
1435
+ * @notice Updates base URI for project `_projectId` to `_newBaseURI`.
1436
+ * This is the controlling base URI for all tokens in the project. The
1437
+ * contract-level defaultBaseURI is only used when initializing new
1438
+ * projects.
1439
+ * @param _projectId Project to be updated.
1440
+ * @param _newBaseURI New base URI.
1441
+ */
1442
+ function updateProjectBaseURI(
1443
+ uint256 _projectId,
1444
+ string memory _newBaseURI
1445
+ ) external {
1446
+ _onlyArtist(_projectId);
1447
+ _onlyNonEmptyString(_newBaseURI);
1448
+ projects[_projectId].projectBaseURI = _newBaseURI;
1449
+ emit ProjectUpdated(_projectId, FIELD_PROJECT_BASE_URI);
1450
+ }
1451
+
1452
+ /**
1453
+ * @notice Updates default base URI to `_defaultBaseURI`. The
1454
+ * contract-level defaultBaseURI is only used when initializing new
1455
+ * projects. Token URIs are determined by their project's `projectBaseURI`.
1456
+ * @param _defaultBaseURI New default base URI.
1457
+ */
1458
+ function updateDefaultBaseURI(string memory _defaultBaseURI) external {
1459
+ _onlyAdminACL(this.updateDefaultBaseURI.selector);
1460
+ _onlyNonEmptyString(_defaultBaseURI);
1461
+ _updateDefaultBaseURI(_defaultBaseURI);
1462
+ }
1463
+
1464
+ /**
1465
+ * @notice Next project ID to be created on this contract.
1466
+ * @return uint256 Next project ID.
1467
+ */
1468
+ function nextProjectId() external view returns (uint256) {
1469
+ return _nextProjectId;
1470
+ }
1471
+
1472
+ /**
1473
+ * @notice Returns token hash for token ID `_tokenId`. Returns null if hash
1474
+ * has not been set.
1475
+ * @param _tokenId Token ID to be queried.
1476
+ * @return bytes32 Token hash.
1477
+ * @dev token hash is the keccak256 hash of the stored hash seed
1478
+ */
1479
+ function tokenIdToHash(uint256 _tokenId) external view returns (bytes32) {
1480
+ bytes12 _hashSeed = _ownersAndHashSeeds[_tokenId].hashSeed;
1481
+ if (_hashSeed == 0) {
1482
+ return 0;
1483
+ }
1484
+ return keccak256(abi.encode(_hashSeed));
1485
+ }
1486
+
1487
+ /**
1488
+ * @notice Returns token hash **seed** for token ID `_tokenId`. Returns
1489
+ * null if hash seed has not been set. The hash seed id the bytes12 value
1490
+ * which is hashed to produce the token hash.
1491
+ * @param _tokenId Token ID to be queried.
1492
+ * @return bytes12 Token hash seed.
1493
+ * @dev token hash seed is keccak256 hashed to give the token hash
1494
+ */
1495
+ function tokenIdToHashSeed(
1496
+ uint256 _tokenId
1497
+ ) external view returns (bytes12) {
1498
+ return _ownersAndHashSeeds[_tokenId].hashSeed;
1499
+ }
1500
+
1501
+ /**
1502
+ * @notice View function returning the render provider portion of
1503
+ * primary sales, in percent.
1504
+ * @return uint256 The render provider portion of primary sales,
1505
+ * in percent.
1506
+ */
1507
+ function renderProviderPrimarySalesPercentage()
1508
+ external
1509
+ view
1510
+ returns (uint256)
1511
+ {
1512
+ return _renderProviderPrimarySalesPercentage;
1513
+ }
1514
+
1515
+ /**
1516
+ * @notice View function returning the platform provider portion of
1517
+ * primary sales, in percent.
1518
+ * @return uint256 The platform provider portion of primary sales,
1519
+ * in percent.
1520
+ */
1521
+ function platformProviderPrimarySalesPercentage()
1522
+ external
1523
+ view
1524
+ returns (uint256)
1525
+ {
1526
+ return _platformProviderPrimarySalesPercentage;
1527
+ }
1528
+
1529
+ /**
1530
+ * @notice View function returning Artist's address for project
1531
+ * `_projectId`.
1532
+ * @param _projectId Project ID to be queried.
1533
+ * @return address Artist's address.
1534
+ */
1535
+ function projectIdToArtistAddress(
1536
+ uint256 _projectId
1537
+ ) external view returns (address payable) {
1538
+ return projectIdToFinancials[_projectId].artistAddress;
1539
+ }
1540
+
1541
+ /**
1542
+ * @notice View function returning Artist's secondary market royalty
1543
+ * percentage for project `_projectId`.
1544
+ * This does not include render/platform providers portions of secondary
1545
+ * market royalties.
1546
+ * @param _projectId Project ID to be queried.
1547
+ * @return uint256 Artist's secondary market royalty percentage.
1548
+ */
1549
+ function projectIdToSecondaryMarketRoyaltyPercentage(
1550
+ uint256 _projectId
1551
+ ) external view returns (uint256) {
1552
+ return
1553
+ projectIdToFinancials[_projectId].secondaryMarketRoyaltyPercentage;
1554
+ }
1555
+
1556
+ /**
1557
+ * @notice View function returning Artist's additional payee address for
1558
+ * primary sales, for project `_projectId`.
1559
+ * @param _projectId Project ID to be queried.
1560
+ * @return address Artist's additional payee address for primary sales.
1561
+ */
1562
+ function projectIdToAdditionalPayeePrimarySales(
1563
+ uint256 _projectId
1564
+ ) external view returns (address payable) {
1565
+ return projectIdToFinancials[_projectId].additionalPayeePrimarySales;
1566
+ }
1567
+
1568
+ /**
1569
+ * @notice View function returning Artist's additional payee primary sales
1570
+ * percentage, for project `_projectId`.
1571
+ * @param _projectId Project ID to be queried.
1572
+ * @return uint256 Artist's additional payee primary sales percentage.
1573
+ */
1574
+ function projectIdToAdditionalPayeePrimarySalesPercentage(
1575
+ uint256 _projectId
1576
+ ) external view returns (uint256) {
1577
+ return
1578
+ projectIdToFinancials[_projectId]
1579
+ .additionalPayeePrimarySalesPercentage;
1580
+ }
1581
+
1582
+ /**
1583
+ * @notice View function returning Artist's additional payee address for
1584
+ * secondary sales, for project `_projectId`.
1585
+ * @param _projectId Project ID to be queried.
1586
+ * @return address payable Artist's additional payee address for secondary
1587
+ * sales.
1588
+ */
1589
+ function projectIdToAdditionalPayeeSecondarySales(
1590
+ uint256 _projectId
1591
+ ) external view returns (address payable) {
1592
+ return projectIdToFinancials[_projectId].additionalPayeeSecondarySales;
1593
+ }
1594
+
1595
+ /**
1596
+ * @notice View function returning Artist's additional payee secondary
1597
+ * sales percentage, for project `_projectId`.
1598
+ * @param _projectId Project ID to be queried.
1599
+ * @return uint256 Artist's additional payee secondary sales percentage.
1600
+ */
1601
+ function projectIdToAdditionalPayeeSecondarySalesPercentage(
1602
+ uint256 _projectId
1603
+ ) external view returns (uint256) {
1604
+ return
1605
+ projectIdToFinancials[_projectId]
1606
+ .additionalPayeeSecondarySalesPercentage;
1607
+ }
1608
+
1609
+ /**
1610
+ * @notice Returns project details for project `_projectId`.
1611
+ * @param _projectId Project to be queried.
1612
+ * @return projectName Name of project
1613
+ * @return artist Artist of project
1614
+ * @return description Project description
1615
+ * @return website Project website
1616
+ * @return license Project license
1617
+ * @dev this function was named projectDetails prior to V3 core contract.
1618
+ */
1619
+ function projectDetails(
1620
+ uint256 _projectId
1621
+ )
1622
+ external
1623
+ view
1624
+ returns (
1625
+ string memory projectName,
1626
+ string memory artist,
1627
+ string memory description,
1628
+ string memory website,
1629
+ string memory license
1630
+ )
1631
+ {
1632
+ Project storage project = projects[_projectId];
1633
+ projectName = project.name;
1634
+ artist = project.artist;
1635
+ address projectDescriptionBytecodeAddress = project.descriptionAddress;
1636
+ if (projectDescriptionBytecodeAddress == address(0)) {
1637
+ description = "";
1638
+ } else {
1639
+ description = _readFromBytecode(projectDescriptionBytecodeAddress);
1640
+ }
1641
+ website = project.website;
1642
+ license = project.license;
1643
+ }
1644
+
1645
+ /**
1646
+ * @notice Returns project state data for project `_projectId`.
1647
+ * @param _projectId Project to be queried
1648
+ * @return invocations Current number of invocations
1649
+ * @return maxInvocations Maximum allowed invocations
1650
+ * @return active Boolean representing if project is currently active
1651
+ * @return paused Boolean representing if project is paused
1652
+ * @return completedTimestamp zero if project not complete, otherwise
1653
+ * timestamp of project completion.
1654
+ * @return locked Boolean representing if project is locked
1655
+ * @dev price and currency info are located on minter contracts
1656
+ */
1657
+ function projectStateData(
1658
+ uint256 _projectId
1659
+ )
1660
+ external
1661
+ view
1662
+ returns (
1663
+ uint256 invocations,
1664
+ uint256 maxInvocations,
1665
+ bool active,
1666
+ bool paused,
1667
+ uint256 completedTimestamp,
1668
+ bool locked
1669
+ )
1670
+ {
1671
+ Project storage project = projects[_projectId];
1672
+ invocations = project.invocations;
1673
+ maxInvocations = project.maxInvocations;
1674
+ active = project.active;
1675
+ paused = project.paused;
1676
+ completedTimestamp = project.completedTimestamp;
1677
+ locked = !_projectUnlocked(_projectId);
1678
+ }
1679
+
1680
+ /**
1681
+ * @notice Returns artist payment information for project `_projectId`.
1682
+ * @param _projectId Project to be queried
1683
+ * @return artistAddress Project Artist's address
1684
+ * @return additionalPayeePrimarySales Additional payee address for primary
1685
+ * sales
1686
+ * @return additionalPayeePrimarySalesPercentage Percentage of artist revenue
1687
+ * to be sent to the additional payee address for primary sales
1688
+ * @return additionalPayeeSecondarySales Additional payee address for secondary
1689
+ * sales royalties
1690
+ * @return additionalPayeeSecondarySalesPercentage Percentage of artist revenue
1691
+ * to be sent to the additional payee address for secondary sales royalties
1692
+ * @return secondaryMarketRoyaltyPercentage Royalty percentage to be sent to
1693
+ * combination of artist and additional payee. This does not include the
1694
+ * platform's percentage of secondary sales royalties, which is defined as
1695
+ * the sum of `renderProviderSecondarySalesBPS`
1696
+ * and `platformProviderSecondarySalesBPS`.
1697
+ */
1698
+ function projectArtistPaymentInfo(
1699
+ uint256 _projectId
1700
+ )
1701
+ external
1702
+ view
1703
+ returns (
1704
+ address artistAddress,
1705
+ address additionalPayeePrimarySales,
1706
+ uint256 additionalPayeePrimarySalesPercentage,
1707
+ address additionalPayeeSecondarySales,
1708
+ uint256 additionalPayeeSecondarySalesPercentage,
1709
+ uint256 secondaryMarketRoyaltyPercentage
1710
+ )
1711
+ {
1712
+ ProjectFinance storage projectFinance = projectIdToFinancials[
1713
+ _projectId
1714
+ ];
1715
+ artistAddress = projectFinance.artistAddress;
1716
+ additionalPayeePrimarySales = projectFinance
1717
+ .additionalPayeePrimarySales;
1718
+ additionalPayeePrimarySalesPercentage = projectFinance
1719
+ .additionalPayeePrimarySalesPercentage;
1720
+ additionalPayeeSecondarySales = projectFinance
1721
+ .additionalPayeeSecondarySales;
1722
+ additionalPayeeSecondarySalesPercentage = projectFinance
1723
+ .additionalPayeeSecondarySalesPercentage;
1724
+ secondaryMarketRoyaltyPercentage = projectFinance
1725
+ .secondaryMarketRoyaltyPercentage;
1726
+ }
1727
+
1728
+ /**
1729
+ * @notice Returns script information for project `_projectId`.
1730
+ * @param _projectId Project to be queried.
1731
+ * @return scriptTypeAndVersion Project's script type and version
1732
+ * (e.g. "p5js(atSymbol)1.0.0")
1733
+ * @return aspectRatio Aspect ratio of project (e.g. "1" for square,
1734
+ * "1.77777778" for 16:9, etc.)
1735
+ * @return scriptCount Count of scripts for project
1736
+ */
1737
+ function projectScriptDetails(
1738
+ uint256 _projectId
1739
+ )
1740
+ external
1741
+ view
1742
+ override(IGenArt721CoreContractV3_Base, IDependencyRegistryCompatibleV0)
1743
+ returns (
1744
+ string memory scriptTypeAndVersion,
1745
+ string memory aspectRatio,
1746
+ uint256 scriptCount
1747
+ )
1748
+ {
1749
+ Project storage project = projects[_projectId];
1750
+ scriptTypeAndVersion = project.scriptTypeAndVersion.toString();
1751
+ aspectRatio = project.aspectRatio;
1752
+ scriptCount = project.scriptCount;
1753
+ }
1754
+
1755
+ /**
1756
+ * @notice Returns address with bytecode containing project script for
1757
+ * project `_projectId` at script index `_index`.
1758
+ */
1759
+ function projectScriptBytecodeAddressByIndex(
1760
+ uint256 _projectId,
1761
+ uint256 _index
1762
+ ) external view returns (address) {
1763
+ return projects[_projectId].scriptBytecodeAddresses[_index];
1764
+ }
1765
+
1766
+ /**
1767
+ * @notice Returns script for project `_projectId` at script index `_index`.
1768
+ * @param _projectId Project to be queried.
1769
+ * @param _index Index of script to be queried.
1770
+ */
1771
+ function projectScriptByIndex(
1772
+ uint256 _projectId,
1773
+ uint256 _index
1774
+ ) external view returns (string memory) {
1775
+ Project storage project = projects[_projectId];
1776
+ // If trying to access an out-of-index script, return the empty string.
1777
+ if (_index >= project.scriptCount) {
1778
+ return "";
1779
+ }
1780
+ return _readFromBytecode(project.scriptBytecodeAddresses[_index]);
1781
+ }
1782
+
1783
+ /**
1784
+ * @notice Returns base URI for project `_projectId`.
1785
+ * @param _projectId Project to be queried.
1786
+ * @return projectBaseURI Base URI for project
1787
+ */
1788
+ function projectURIInfo(
1789
+ uint256 _projectId
1790
+ ) external view returns (string memory projectBaseURI) {
1791
+ projectBaseURI = projects[_projectId].projectBaseURI;
1792
+ }
1793
+
1794
+ /**
1795
+ * @notice Backwards-compatible (pre-V3) function returning if `_minter` is
1796
+ * minterContract.
1797
+ * @param _minter Address to be queried.
1798
+ * @return bool Boolean representing if `_minter` is minterContract.
1799
+ */
1800
+ function isMintWhitelisted(address _minter) external view returns (bool) {
1801
+ return (minterContract == _minter);
1802
+ }
1803
+
1804
+ /**
1805
+ * @notice Gets qty of randomizers in history of all randomizers used by
1806
+ * this core contract. If a randomizer is switched away from then back to,
1807
+ * it will show up in the history twice.
1808
+ * @return randomizerHistoryCount Count of randomizers in history
1809
+ */
1810
+ function numHistoricalRandomizers() external view returns (uint256) {
1811
+ return _historicalRandomizerAddresses.length;
1812
+ }
1813
+
1814
+ /**
1815
+ * @notice Gets address of randomizer at index `_index` in history of all
1816
+ * randomizers used by this core contract. Index is zero-based.
1817
+ * @param _index Historical index of randomizer to be queried.
1818
+ * @return randomizerAddress Address of randomizer at index `_index`.
1819
+ * @dev If a randomizer is switched away from and then switched back to, it
1820
+ * will show up in the history twice.
1821
+ */
1822
+ function getHistoricalRandomizerAt(
1823
+ uint256 _index
1824
+ ) external view returns (address) {
1825
+ require(
1826
+ _index < _historicalRandomizerAddresses.length,
1827
+ "Index out of bounds"
1828
+ );
1829
+ return _historicalRandomizerAddresses[_index];
1830
+ }
1831
+
1832
+ /**
1833
+ * @notice Gets royalty Basis Points (BPS) for token ID `_tokenId`.
1834
+ * This conforms to the IManifold interface designated in the Royalty
1835
+ * Registry's RoyaltyEngineV1.sol contract.
1836
+ * ref: https://github.com/manifoldxyz/royalty-registry-solidity
1837
+ * @param _tokenId Token ID to be queried.
1838
+ * @return recipients Array of royalty payment recipients
1839
+ * @return bps Array of Basis Points (BPS) allocated to each recipient,
1840
+ * aligned by index.
1841
+ * @dev reverts if invalid _tokenId
1842
+ * @dev only returns recipients that have a non-zero BPS allocation
1843
+ */
1844
+ function getRoyalties(
1845
+ uint256 _tokenId
1846
+ )
1847
+ external
1848
+ view
1849
+ returns (address payable[] memory recipients, uint256[] memory bps)
1850
+ {
1851
+ _onlyValidTokenId(_tokenId);
1852
+ // initialize arrays with maximum potential length
1853
+ recipients = new address payable[](4);
1854
+ bps = new uint256[](4);
1855
+
1856
+ uint256 projectId = tokenIdToProjectId(_tokenId);
1857
+ ProjectFinance storage projectFinance = projectIdToFinancials[
1858
+ projectId
1859
+ ];
1860
+ // load values into memory
1861
+ uint256 royaltyPercentageForArtistAndAdditional = projectFinance
1862
+ .secondaryMarketRoyaltyPercentage;
1863
+ uint256 additionalPayeePercentage = projectFinance
1864
+ .additionalPayeeSecondarySalesPercentage;
1865
+ // calculate BPS = percentage * 100
1866
+ uint256 artistBPS = (ONE_HUNDRED - additionalPayeePercentage) *
1867
+ royaltyPercentageForArtistAndAdditional;
1868
+
1869
+ uint256 additionalBPS = additionalPayeePercentage *
1870
+ royaltyPercentageForArtistAndAdditional;
1871
+ uint256 renderProviderBPS = renderProviderSecondarySalesBPS;
1872
+ uint256 platformProviderBPS = platformProviderSecondarySalesBPS;
1873
+ // populate arrays
1874
+ uint256 payeeCount;
1875
+ if (artistBPS > 0) {
1876
+ recipients[payeeCount] = projectFinance.artistAddress;
1877
+ bps[payeeCount++] = artistBPS;
1878
+ }
1879
+ if (additionalBPS > 0) {
1880
+ recipients[payeeCount] = projectFinance
1881
+ .additionalPayeeSecondarySales;
1882
+ bps[payeeCount++] = additionalBPS;
1883
+ }
1884
+ if (renderProviderBPS > 0) {
1885
+ recipients[payeeCount] = renderProviderSecondarySalesAddress;
1886
+ bps[payeeCount++] = renderProviderBPS;
1887
+ }
1888
+ if (platformProviderBPS > 0) {
1889
+ recipients[payeeCount] = platformProviderSecondarySalesAddress;
1890
+ bps[payeeCount++] = platformProviderBPS;
1891
+ }
1892
+ // trim arrays if necessary
1893
+ if (4 > payeeCount) {
1894
+ assembly {
1895
+ let decrease := sub(4, payeeCount)
1896
+ mstore(recipients, sub(mload(recipients), decrease))
1897
+ mstore(bps, sub(mload(bps), decrease))
1898
+ }
1899
+ }
1900
+ return (recipients, bps);
1901
+ }
1902
+
1903
+ /**
1904
+ * @notice View function that returns appropriate revenue splits between
1905
+ * different render provider, platform provider, Artist, and Artist's
1906
+ * additional primary sales payee given a sale price of `_price` on
1907
+ * project `_projectId`.
1908
+ * This always returns four revenue amounts and four addresses, but if a
1909
+ * revenue is zero for either Artist or additional payee, the corresponding
1910
+ * address returned will also be null (for gas optimization).
1911
+ * Does not account for refund if user overpays for a token (minter should
1912
+ * handle a refund of the difference, if appropriate).
1913
+ * Some minters may have alternative methods of splitting payments, in
1914
+ * which case they should implement their own payment splitting logic.
1915
+ * @param _projectId Project ID to be queried.
1916
+ * @param _price Sale price of token.
1917
+ * @return renderProviderRevenue_ amount of revenue to be sent to the
1918
+ * render provider
1919
+ * @return renderProviderAddress_ address to send render provider revenue to
1920
+ * @return platformProviderRevenue_ amount of revenue to be sent to the
1921
+ * platform provider
1922
+ * @return platformProviderAddress_ address to send platform provider revenue to
1923
+ * @return artistRevenue_ amount of revenue to be sent to Artist
1924
+ * @return artistAddress_ address to send Artist revenue to. Will be null
1925
+ * if no revenue is due to artist (gas optimization).
1926
+ * @return additionalPayeePrimaryRevenue_ amount of revenue to be sent to
1927
+ * additional payee for primary sales
1928
+ * @return additionalPayeePrimaryAddress_ address to send Artist's
1929
+ * additional payee for primary sales revenue to. Will be null if no
1930
+ * revenue is due to additional payee for primary sales (gas optimization).
1931
+ * @dev this always returns four addresses and four revenues, but if the
1932
+ * revenue is zero, the corresponding address will be address(0). It is up
1933
+ * to the contract performing the revenue split to handle this
1934
+ * appropriately.
1935
+ */
1936
+ function getPrimaryRevenueSplits(
1937
+ uint256 _projectId,
1938
+ uint256 _price
1939
+ )
1940
+ external
1941
+ view
1942
+ returns (
1943
+ uint256 renderProviderRevenue_,
1944
+ address payable renderProviderAddress_,
1945
+ uint256 platformProviderRevenue_,
1946
+ address payable platformProviderAddress_,
1947
+ uint256 artistRevenue_,
1948
+ address payable artistAddress_,
1949
+ uint256 additionalPayeePrimaryRevenue_,
1950
+ address payable additionalPayeePrimaryAddress_
1951
+ )
1952
+ {
1953
+ ProjectFinance storage projectFinance = projectIdToFinancials[
1954
+ _projectId
1955
+ ];
1956
+ // calculate revenues – this is a three-way split between the
1957
+ // render provider, the platform provider, and the artist, and
1958
+ // is safe to perform this given that in the case of loss of
1959
+ // precision Solidity will round down.
1960
+ uint256 projectFunds = _price;
1961
+ renderProviderRevenue_ =
1962
+ (_price * uint256(_renderProviderPrimarySalesPercentage)) /
1963
+ ONE_HUNDRED;
1964
+ // renderProviderRevenue_ percentage is always <=100, so guaranteed to never underflow
1965
+ projectFunds -= renderProviderRevenue_;
1966
+ platformProviderRevenue_ =
1967
+ (_price * uint256(_platformProviderPrimarySalesPercentage)) /
1968
+ ONE_HUNDRED;
1969
+ // platformProviderRevenue_ percentage is always <=100, so guaranteed to never underflow
1970
+ projectFunds -= platformProviderRevenue_;
1971
+ additionalPayeePrimaryRevenue_ =
1972
+ (projectFunds *
1973
+ projectFinance.additionalPayeePrimarySalesPercentage) /
1974
+ ONE_HUNDRED;
1975
+ // projectIdToAdditionalPayeePrimarySalesPercentage is always
1976
+ // <=100, so guaranteed to never underflow
1977
+ artistRevenue_ = projectFunds - additionalPayeePrimaryRevenue_;
1978
+ // set addresses from storage
1979
+ renderProviderAddress_ = renderProviderPrimarySalesAddress;
1980
+ platformProviderAddress_ = platformProviderPrimarySalesAddress;
1981
+ if (artistRevenue_ > 0) {
1982
+ artistAddress_ = projectFinance.artistAddress;
1983
+ }
1984
+ if (additionalPayeePrimaryRevenue_ > 0) {
1985
+ additionalPayeePrimaryAddress_ = projectFinance
1986
+ .additionalPayeePrimarySales;
1987
+ }
1988
+ }
1989
+
1990
+ /**
1991
+ * @notice Returns external asset dependency for project `_projectId` at index `_index`.
1992
+ * If the dependencyType is ONCHAIN, the `data` field will contain the extrated bytecode data and `cid`
1993
+ * will be an empty string. Conversly, for any other dependencyType, the `data` field will be an empty string
1994
+ * and the `bytecodeAddress` will point to the zero address.
1995
+ */
1996
+ function projectExternalAssetDependencyByIndex(
1997
+ uint256 _projectId,
1998
+ uint256 _index
1999
+ ) external view returns (ExternalAssetDependencyWithData memory) {
2000
+ ExternalAssetDependency storage _dependency = projects[_projectId]
2001
+ .externalAssetDependencies[_index];
2002
+ address _bytecodeAddress = _dependency.bytecodeAddress;
2003
+
2004
+ return
2005
+ ExternalAssetDependencyWithData({
2006
+ dependencyType: _dependency.dependencyType,
2007
+ cid: _dependency.cid,
2008
+ bytecodeAddress: _bytecodeAddress,
2009
+ data: (_dependency.dependencyType ==
2010
+ ExternalAssetDependencyType.ONCHAIN)
2011
+ ? _readFromBytecode(_bytecodeAddress)
2012
+ : ""
2013
+ });
2014
+ }
2015
+
2016
+ /**
2017
+ * @notice Returns external asset dependency count for project `_projectId` at index `_index`.
2018
+ */
2019
+ function projectExternalAssetDependencyCount(
2020
+ uint256 _projectId
2021
+ ) external view returns (uint256) {
2022
+ return uint256(projects[_projectId].externalAssetDependencyCount);
2023
+ }
2024
+
2025
+ /**
2026
+ * @notice Backwards-compatible (pre-V3) getter returning contract admin
2027
+ * @return address Address of contract admin (same as owner)
2028
+ */
2029
+ function admin() external view returns (address) {
2030
+ return owner();
2031
+ }
2032
+
2033
+ /**
2034
+ * @notice Gets the project ID for a given `_tokenId`.
2035
+ * @param _tokenId Token ID to be queried.
2036
+ * @return _projectId Project ID for given `_tokenId`.
2037
+ */
2038
+ function tokenIdToProjectId(
2039
+ uint256 _tokenId
2040
+ ) public pure returns (uint256 _projectId) {
2041
+ return _tokenId / ONE_MILLION;
2042
+ }
2043
+
2044
+ /**
2045
+ * @notice Convenience function that returns whether `_sender` is allowed
2046
+ * to call function with selector `_selector` on contract `_contract`, as
2047
+ * determined by this contract's current Admin ACL contract. Expected use
2048
+ * cases include minter contracts checking if caller is allowed to call
2049
+ * admin-gated functions on minter contracts.
2050
+ * @param _sender Address of the sender calling function with selector
2051
+ * `_selector` on contract `_contract`.
2052
+ * @param _contract Address of the contract being called by `_sender`.
2053
+ * @param _selector Function selector of the function being called by
2054
+ * `_sender`.
2055
+ * @return bool Whether `_sender` is allowed to call function with selector
2056
+ * `_selector` on contract `_contract`.
2057
+ * @dev assumes the Admin ACL contract is the owner of this contract, which
2058
+ * is expected to always be true.
2059
+ * @dev adminACLContract is expected to either be null address (if owner
2060
+ * has renounced ownership), or conform to IAdminACLV0 interface. Check for
2061
+ * null address first to avoid revert when admin has renounced ownership.
2062
+ */
2063
+ function adminACLAllowed(
2064
+ address _sender,
2065
+ address _contract,
2066
+ bytes4 _selector
2067
+ ) public returns (bool) {
2068
+ return
2069
+ owner() != address(0) &&
2070
+ adminACLContract.allowed(_sender, _contract, _selector);
2071
+ }
2072
+
2073
+ /**
2074
+ * @notice Returns contract owner. Set to deployer's address by default on
2075
+ * contract deployment.
2076
+ * @return address Address of contract owner.
2077
+ * @dev ref: https://docs.openzeppelin.com/contracts/4.x/api/access#Ownable
2078
+ * @dev owner role was called `admin` prior to V3 core contract
2079
+ */
2080
+ function owner()
2081
+ public
2082
+ view
2083
+ override(Ownable, IGenArt721CoreContractV3_Base)
2084
+ returns (address)
2085
+ {
2086
+ return Ownable.owner();
2087
+ }
2088
+
2089
+ /**
2090
+ * @notice Gets token URI for token ID `_tokenId`.
2091
+ * @param _tokenId Token ID to be queried.
2092
+ * @return string URI of token ID `_tokenId`.
2093
+ * @dev token URIs are the concatenation of the project base URI and the
2094
+ * token ID.
2095
+ */
2096
+ function tokenURI(
2097
+ uint256 _tokenId
2098
+ ) public view override returns (string memory) {
2099
+ _onlyValidTokenId(_tokenId);
2100
+ string memory _projectBaseURI = projects[tokenIdToProjectId(_tokenId)]
2101
+ .projectBaseURI;
2102
+ return string.concat(_projectBaseURI, toString(_tokenId));
2103
+ }
2104
+
2105
+ /**
2106
+ * @dev See {IERC165-supportsInterface}.
2107
+ */
2108
+ function supportsInterface(
2109
+ bytes4 interfaceId
2110
+ ) public view virtual override returns (bool) {
2111
+ return
2112
+ interfaceId == type(IManifold).interfaceId ||
2113
+ super.supportsInterface(interfaceId);
2114
+ }
2115
+
2116
+ /**
2117
+ * @notice Forbids new projects from being created
2118
+ * @dev only performs operation and emits event if contract is not already
2119
+ * forbidding new projects.
2120
+ */
2121
+ function _forbidNewProjects() internal {
2122
+ if (!newProjectsForbidden) {
2123
+ newProjectsForbidden = true;
2124
+ emit PlatformUpdated(FIELD_NEW_PROJECTS_FORBIDDEN);
2125
+ }
2126
+ }
2127
+
2128
+ /**
2129
+ * @notice Transfers ownership of the contract to a new account (`newOwner`).
2130
+ * Internal function without access restriction.
2131
+ * @param newOwner New owner.
2132
+ * @dev owner role was called `admin` prior to V3 core contract.
2133
+ * @dev Overrides and wraps OpenZeppelin's _transferOwnership function to
2134
+ * also update adminACLContract for improved introspection.
2135
+ */
2136
+ function _transferOwnership(address newOwner) internal override {
2137
+ Ownable._transferOwnership(newOwner);
2138
+ adminACLContract = IAdminACLV0(newOwner);
2139
+ }
2140
+
2141
+ /**
2142
+ * @notice Updates sales addresses for the platform and render providers to
2143
+ * the input parameters.
2144
+ * @param _renderProviderPrimarySalesAddress Address of new primary sales
2145
+ * payment address.
2146
+ * @param _renderProviderSecondarySalesAddress Address of new secondary sales
2147
+ * payment address.
2148
+ * @param _platformProviderPrimarySalesAddress Address of new primary sales
2149
+ * payment address.
2150
+ * @param _platformProviderSecondarySalesAddress Address of new secondary sales
2151
+ * payment address.
2152
+ * @dev Note that this method does not check that the input address is
2153
+ * not `address(0)`, as it is expected that callers of this method should
2154
+ * perform input validation where applicable.
2155
+ */
2156
+ function _updateProviderSalesAddresses(
2157
+ address _renderProviderPrimarySalesAddress,
2158
+ address _renderProviderSecondarySalesAddress,
2159
+ address _platformProviderPrimarySalesAddress,
2160
+ address _platformProviderSecondarySalesAddress
2161
+ ) internal {
2162
+ platformProviderPrimarySalesAddress = payable(
2163
+ _platformProviderPrimarySalesAddress
2164
+ );
2165
+ platformProviderSecondarySalesAddress = payable(
2166
+ _platformProviderSecondarySalesAddress
2167
+ );
2168
+ renderProviderPrimarySalesAddress = payable(
2169
+ _renderProviderPrimarySalesAddress
2170
+ );
2171
+ renderProviderSecondarySalesAddress = payable(
2172
+ _renderProviderSecondarySalesAddress
2173
+ );
2174
+ emit PlatformUpdated(FIELD_PROVIDER_SALES_ADDRESSES);
2175
+ }
2176
+
2177
+ /**
2178
+ * @notice Updates randomizer address to `_randomizerAddress`.
2179
+ * @param _randomizerAddress New randomizer address.
2180
+ * @dev Note that this method does not check that the input address is
2181
+ * not `address(0)`, as it is expected that callers of this method should
2182
+ * perform input validation where applicable.
2183
+ */
2184
+ function _updateRandomizerAddress(address _randomizerAddress) internal {
2185
+ randomizerContract = IRandomizer_V3CoreBase(_randomizerAddress);
2186
+ // populate historical randomizer array
2187
+ _historicalRandomizerAddresses.push(_randomizerAddress);
2188
+ emit PlatformUpdated(FIELD_RANDOMIZER_ADDRESS);
2189
+ }
2190
+
2191
+ /**
2192
+ * @notice Updates default base URI to `_defaultBaseURI`.
2193
+ * When new projects are added, their `projectBaseURI` is automatically
2194
+ * initialized to `_defaultBaseURI`.
2195
+ * @param _defaultBaseURI New default base URI.
2196
+ * @dev Note that this method does not check that the input string is not
2197
+ * the empty string, as it is expected that callers of this method should
2198
+ * perform input validation where applicable.
2199
+ */
2200
+ function _updateDefaultBaseURI(string memory _defaultBaseURI) internal {
2201
+ defaultBaseURI = _defaultBaseURI;
2202
+ emit PlatformUpdated(FIELD_DEFAULT_BASE_URI);
2203
+ }
2204
+
2205
+ /**
2206
+ * @notice Internal function to complete a project.
2207
+ * @param _projectId Project ID to be completed.
2208
+ */
2209
+ function _completeProject(uint256 _projectId) internal {
2210
+ projects[_projectId].completedTimestamp = uint64(block.timestamp);
2211
+ emit ProjectUpdated(_projectId, FIELD_PROJECT_COMPLETED);
2212
+ }
2213
+
2214
+ /**
2215
+ * @notice Internal function that returns whether a project is unlocked.
2216
+ * Projects automatically lock four weeks after they are completed.
2217
+ * Projects are considered completed when they have been invoked the
2218
+ * maximum number of times.
2219
+ * @param _projectId Project ID to be queried.
2220
+ * @return bool true if project is unlocked, false otherwise.
2221
+ * @dev This also enforces that the `_projectId` passed in is valid.
2222
+ */
2223
+ function _projectUnlocked(uint256 _projectId) internal view returns (bool) {
2224
+ _onlyValidProjectId(_projectId);
2225
+ uint256 projectCompletedTimestamp = projects[_projectId]
2226
+ .completedTimestamp;
2227
+ bool projectOpen = projectCompletedTimestamp == 0;
2228
+ return
2229
+ projectOpen ||
2230
+ (block.timestamp - projectCompletedTimestamp <
2231
+ FOUR_WEEKS_IN_SECONDS);
2232
+ }
2233
+
2234
+ /**
2235
+ * Helper for calling `BytecodeStorageReader` external library reader method,
2236
+ * added for bytecode size reduction purposes.
2237
+ */
2238
+ function _readFromBytecode(
2239
+ address _address
2240
+ ) internal view returns (string memory) {
2241
+ return BytecodeStorageReader.readFromBytecode(_address);
2242
+ }
2243
+
2244
+ // strings library from OpenZeppelin, modified for no constants
2245
+
2246
+ bytes16 private _HEX_SYMBOLS = "0123456789abcdef";
2247
+ uint8 private _ADDRESS_LENGTH = 20;
2248
+
2249
+ /**
2250
+ * @dev Converts a `uint256` to its ASCII `string` decimal representation.
2251
+ */
2252
+ function toString(uint256 value) internal pure returns (string memory) {
2253
+ // Inspired by OraclizeAPI's implementation - MIT licence
2254
+ // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
2255
+
2256
+ if (value == 0) {
2257
+ return "0";
2258
+ }
2259
+ uint256 temp = value;
2260
+ uint256 digits;
2261
+ while (temp != 0) {
2262
+ digits++;
2263
+ temp /= 10;
2264
+ }
2265
+ bytes memory buffer = new bytes(digits);
2266
+ while (value != 0) {
2267
+ digits -= 1;
2268
+ buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
2269
+ value /= 10;
2270
+ }
2271
+ return string(buffer);
2272
+ }
2273
+
2274
+ /**
2275
+ * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
2276
+ */
2277
+ function toHexString(
2278
+ uint256 value,
2279
+ uint256 length
2280
+ ) internal view returns (string memory) {
2281
+ bytes memory buffer = new bytes(2 * length + 2);
2282
+ buffer[0] = "0";
2283
+ buffer[1] = "x";
2284
+ for (uint256 i = 2 * length + 1; i > 1; --i) {
2285
+ buffer[i] = _HEX_SYMBOLS[value & 0xf];
2286
+ value >>= 4;
2287
+ }
2288
+ require(value == 0, "hex length insufficient");
2289
+ return string(buffer);
2290
+ }
2291
+
2292
+ /**
2293
+ * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
2294
+ */
2295
+ function toHexString(address addr) internal view returns (string memory) {
2296
+ return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
2297
+ }
2298
+ }