@artblocks/contracts 1.0.4 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. package/README.md +75 -7
  2. package/artifacts/contracts/AdminACLV0.sol/AdminACLV0.json +2 -2
  3. package/artifacts/contracts/AdminACLV1.sol/AdminACLV1.json +2 -2
  4. package/artifacts/contracts/DependencyRegistryV0.sol/DependencyRegistryV0.json +336 -131
  5. package/artifacts/contracts/archive/GenArt721CoreV3.sol/GenArt721CoreV3.json +2047 -0
  6. package/artifacts/contracts/archive/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +2021 -0
  7. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterBase_v0_1_1.sol/MinterBase.json +1 -1
  8. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV2.sol/MinterDAExpV2.json +2 -2
  9. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV3.sol/MinterDAExpV3.json +2 -2
  10. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDAExp}/MinterDAExpV4.sol/MinterDAExpV4.json +3 -3
  11. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol/MinterDAExpSettlementV0.json +2 -2
  12. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV1.sol/MinterDAExpSettlementV1.json +2 -2
  13. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV2.sol/MinterDAExpSettlementV2.json +1109 -0
  14. package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV2.sol/MinterDALinV2.json +2 -2
  15. package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV3.sol/MinterDALinV3.json +2 -2
  16. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDALin}/MinterDALinV4.sol/MinterDALinV4.json +3 -3
  17. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV1.sol/MinterHolderV1.json +2 -2
  18. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV2.sol/MinterHolderV2.json +2 -2
  19. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV3.sol/MinterHolderV3.json +2 -2
  20. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterHolder}/MinterHolderV4.sol/MinterHolderV4.json +3 -3
  21. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV1.sol/MinterMerkleV1.json +2 -2
  22. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV2.sol/MinterMerkleV2.json +2 -2
  23. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV3.sol/MinterMerkleV3.json +2 -2
  24. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV4.sol/MinterMerkleV4.json +2 -2
  25. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterMerkle}/MinterMerkleV5.sol/MinterMerkleV5.json +3 -3
  26. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterPolyptych}/MinterPolyptychV0.sol/IGenArt721CoreContractV3WithRandomizer.json +31 -63
  27. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterPolyptych}/MinterPolyptychV0.sol/MinterPolyptychV0.json +3 -3
  28. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSEA}/MinterSEAV0.sol/MinterSEAV0.json +3 -3
  29. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV2.sol/MinterSetPriceV2.json +2 -2
  30. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV3.sol/MinterSetPriceV3.json +2 -2
  31. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSetPrice}/MinterSetPriceV4.sol/MinterSetPriceV4.json +3 -3
  32. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V0.sol/MinterSetPriceERC20V0.json +65 -2
  33. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V1.sol/MinterSetPriceERC20V1.json +65 -2
  34. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol/MinterSetPriceERC20V2.json +2 -2
  35. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol/MinterSetPriceERC20V3.json +2 -2
  36. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V4.sol/MinterSetPriceERC20V4.json +807 -0
  37. package/artifacts/contracts/engine/V2/GenArt721MinterBurner_PBAB.sol/GenArt721MinterBurner_PBAB.json +65 -2
  38. package/artifacts/contracts/engine/V2/GenArt721Minter_PBAB.sol/GenArt721Minter_PBAB.json +65 -2
  39. package/artifacts/contracts/engine/V3/EngineFactoryV0.sol/EngineFactoryV0.json +606 -0
  40. package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine.sol/GenArt721CoreV3_Engine.json +565 -209
  41. package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol/GenArt721CoreV3_Engine_Flex.json +785 -227
  42. package/artifacts/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol/GenArt721CoreV3_Engine_Flex_PROOF.json +40 -15
  43. package/artifacts/contracts/engine/V3/forks/PROHIBITION/AdminACLV0_PROHIBITION.sol/AdminACLV0_PROHIBITION.json +2 -2
  44. package/artifacts/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol/GenArt721CoreV3_Engine_Flex_PROHIBITION.json +40 -15
  45. package/artifacts/contracts/engine/V3/forks/PROHIBITION/interfaces/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.sol/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.json +36 -68
  46. package/artifacts/contracts/engine-registry/CoreRegistryV1.sol/CoreRegistryV1.json +12 -12
  47. package/artifacts/contracts/interfaces/v0.8.x/IAdminACLV0_Extended.sol/IAdminACLV0_Extended.json +140 -0
  48. package/artifacts/contracts/interfaces/v0.8.x/IBytecodeStorageReaderV2.sol/IBytecodeStorageReaderV2.json +130 -0
  49. package/artifacts/contracts/interfaces/v0.8.x/ICoreRegistryV1.sol/ICoreRegistryV1.json +6 -6
  50. package/artifacts/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol/IDependencyRegistryV0.json +71 -39
  51. package/artifacts/contracts/interfaces/v0.8.x/IEngineFactoryV0.sol/IEngineFactoryV0.json +283 -0
  52. package/artifacts/contracts/interfaces/v0.8.x/IFilteredMinterDAExpSettlementV0.sol/IFilteredMinterDAExpSettlementV0.json +12 -12
  53. package/artifacts/contracts/interfaces/v0.8.x/IFilteredMinterDAExpSettlementV1.sol/IFilteredMinterDAExpSettlementV1.json +12 -12
  54. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3.sol/IGenArt721CoreContractV3.json +30 -62
  55. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Base.sol/IGenArt721CoreContractV3_Base.json +30 -62
  56. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine.sol/IGenArt721CoreContractV3_Engine.json +170 -104
  57. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex.sol/IGenArt721CoreContractV3_Engine_Flex.json +170 -104
  58. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex_PreV3p2.sol/IGenArt721CoreContractV3_Engine_Flex_PreV3p2.json +1028 -0
  59. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_PreV3p2.sol/IGenArt721CoreContractV3_Engine_PreV3p2.json +741 -0
  60. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_ProjectFinance.sol/IGenArt721CoreContractV3_ProjectFinance.json +87 -0
  61. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721Minter_PBAB.sol/IGenArt721Minter_PBAB.json +279 -0
  62. package/artifacts/contracts/interfaces/v0.8.x/IMinterFilterV1.sol/IMinterFilterV1.json +22 -22
  63. package/artifacts/contracts/interfaces/v0.8.x/IPseudorandomAtomic.sol/IPseudorandomAtomic.json +1 -1
  64. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol/ISharedMinterDAExpSettlementV0.json +26 -101
  65. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAExpV0.sol/ISharedMinterDAExpV0.json +1 -57
  66. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDALinV0.sol/ISharedMinterDALinV0.json +1 -57
  67. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAV0.sol/ISharedMinterDAV0.json +2 -21
  68. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterHolderERC20V0.sol/ISharedMinterHolderERC20V0.json +158 -0
  69. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterHolderV0.sol/ISharedMinterHolderV0.json +15 -90
  70. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterMerkleV0.sol/ISharedMinterMerkleV0.json +10 -36
  71. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterRAMV0.sol/ISharedMinterRAMV0.json +62 -0
  72. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterRequired.sol/ISharedMinterRequired.json +37 -0
  73. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterSEAV0.sol/ISharedMinterSEAV0.json +4 -236
  74. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterSimplePurchaseV0.sol/ISharedMinterSimplePurchaseV0.json +5 -5
  75. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterV0.sol/ISharedMinterV0.json +7 -423
  76. package/artifacts/contracts/interfaces/v0.8.x/ISharedRandomizerV0.sol/ISharedRandomizerV0.json +17 -17
  77. package/artifacts/contracts/interfaces/v0.8.x/ISplitAtomicFactoryV0.sol/ISplitAtomicFactoryV0.json +170 -0
  78. package/artifacts/contracts/interfaces/v0.8.x/ISplitAtomicV0.sol/ISplitAtomicV0.json +126 -0
  79. package/artifacts/contracts/interfaces/v0.8.x/ISplitProviderV0.sol/ISplitProviderV0.json +98 -0
  80. package/artifacts/contracts/interfaces/v0.8.x/integration-refs/splits-0x-v2/ISplitFactoryV2.sol/ISplitFactoryV2.json +123 -0
  81. package/artifacts/contracts/libs/integration-refs/delegation-registry/DelegationRegistry.sol/DelegationRegistry.json +2 -2
  82. package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeMock.sol/GnosisSafeMock.json +2 -2
  83. package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeProxyFactoryMock.sol/GnosisSafeProxyFactoryMock.json +2 -2
  84. package/artifacts/contracts/libs/integration-refs/gnosis-safe/MultiSendMock.sol/MultiSendMock.json +2 -2
  85. package/artifacts/contracts/libs/integration-refs/weth9/weth9.sol/WETH9_.json +2 -2
  86. package/artifacts/contracts/libs/v0.8.x/ABHelpers.sol/ABHelpers.json +2 -2
  87. package/artifacts/contracts/libs/v0.8.x/AuthLib.sol/AuthLib.json +2 -2
  88. package/artifacts/contracts/libs/v0.8.x/BitMap.sol/BitMaps256.json +10 -0
  89. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV0.sol/BytecodeStorage.json +2 -2
  90. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV1.sol/BytecodeStorageReader.json +2 -2
  91. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV1.sol/BytecodeStorageWriter.json +2 -2
  92. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV2.sol/BytecodeStorageReader.json +214 -0
  93. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV2.sol/BytecodeStorageWriter.json +10 -0
  94. package/artifacts/contracts/libs/v0.8.x/Bytes32Strings.sol/Bytes32Strings.json +2 -2
  95. package/artifacts/contracts/libs/v0.8.x/DependencyRegistryStorageLib.sol/DependencyRegistryStorageLib.json +10 -0
  96. package/artifacts/contracts/libs/v0.8.x/ERC721_PackedHashSeed.sol/ERC721_PackedHashSeed.json +2 -2
  97. package/artifacts/contracts/libs/v0.8.x/ERC721_PackedHashSeedV1.sol/ERC721_PackedHashSeedV1.json +444 -0
  98. package/artifacts/contracts/libs/v0.8.x/PackedBools.sol/PackedBools.json +10 -0
  99. package/artifacts/contracts/libs/v0.8.x/SSTORE2.sol/SSTORE2.json +2 -2
  100. package/artifacts/contracts/libs/v0.8.x/V3FlexLib.sol/V3FlexLib.json +208 -0
  101. package/artifacts/contracts/libs/v0.8.x/minter-libs/DAExpLib.sol/DAExpLib.json +60 -3
  102. package/artifacts/contracts/libs/v0.8.x/minter-libs/DALib.sol/DALib.json +30 -0
  103. package/artifacts/contracts/libs/v0.8.x/minter-libs/DALinLib.sol/DALinLib.json +60 -3
  104. package/artifacts/contracts/libs/v0.8.x/minter-libs/GenericMinterEventsLib.sol/GenericMinterEventsLib.json +346 -0
  105. package/artifacts/contracts/libs/v0.8.x/minter-libs/MaxInvocationsLib.sol/MaxInvocationsLib.json +29 -3
  106. package/artifacts/contracts/libs/v0.8.x/minter-libs/MerkleLib.sol/MerkleLib.json +30 -3
  107. package/artifacts/contracts/libs/v0.8.x/minter-libs/PolyptychLib.sol/PolyptychLib.json +2 -2
  108. package/artifacts/contracts/libs/v0.8.x/minter-libs/RAMLib.sol/RAMLib.json +398 -0
  109. package/artifacts/contracts/libs/v0.8.x/minter-libs/SEALib.sol/SEALib.json +254 -3
  110. package/artifacts/contracts/libs/v0.8.x/minter-libs/SetPriceLib.sol/SetPriceLib.json +48 -3
  111. package/artifacts/contracts/libs/v0.8.x/minter-libs/SettlementExpLib.sol/SettlementExpLib.json +41 -3
  112. package/artifacts/contracts/libs/v0.8.x/minter-libs/SplitFundsLib.sol/SplitFundsLib.json +35 -3
  113. package/artifacts/contracts/libs/v0.8.x/minter-libs/TokenHolderLib.sol/TokenHolderLib.json +79 -3
  114. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV1.sol/MinterFilterV1.json +2 -2
  115. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV2.sol/MinterFilterV2.json +41 -41
  116. package/artifacts/contracts/minter-suite/Minters/MinterDAExpHolderV5.sol/MinterDAExpHolderV5.json +66 -632
  117. package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV3.sol/MinterDAExpSettlementV3.json +67 -594
  118. package/artifacts/contracts/minter-suite/Minters/MinterDAExpV5.sol/MinterDAExpV5.json +33 -524
  119. package/artifacts/contracts/minter-suite/Minters/MinterDALinHolderV5.sol/MinterDALinHolderV5.json +66 -632
  120. package/artifacts/contracts/minter-suite/Minters/MinterDALinV5.sol/MinterDALinV5.json +33 -524
  121. package/artifacts/contracts/minter-suite/Minters/MinterRAMV0.sol/MinterRAMV0.json +1374 -0
  122. package/artifacts/contracts/minter-suite/Minters/MinterSEAV1.sol/MinterSEAV1.json +56 -722
  123. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20V5.sol/MinterSetPriceERC20V5.json +58 -454
  124. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceHolderV5.sol/MinterSetPriceHolderV5.json +61 -552
  125. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceMerkleV5.sol/MinterSetPriceMerkleV5.json +55 -497
  126. package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychERC20V5.sol/MinterSetPricePolyptychERC20V5.json +110 -571
  127. package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychV5.sol/MinterSetPricePolyptychV5.json +69 -560
  128. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceV5.sol/MinterSetPriceV5.json +28 -444
  129. package/artifacts/contracts/minter-suite/Minters/one-off/MinterSetPriceV5_SingleCore.sol/MinterSetPriceV5_SingleCore.json +417 -0
  130. package/artifacts/contracts/mock/BytecodeV2LibCallsMock.sol/BytecodeV2LibCallsMock.json +154 -0
  131. package/artifacts/contracts/mock/BytecodeV2TextCR_DMock.sol/BytecodeV2TextCR_DMock.json +428 -0
  132. package/artifacts/contracts/mock/DummySharedMinter.sol/DummySharedMinter.json +2 -2
  133. package/artifacts/contracts/mock/ERC20Mock.sol/ERC20Mock.json +2 -2
  134. package/artifacts/contracts/mock/ForceSendMock.sol/ForceSendMock.json +24 -0
  135. package/artifacts/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol/GenArt721CoreV3_Engine_IncorrectCoreType.json +4 -9
  136. package/artifacts/contracts/mock/Mock0xSplitsV2PullFactory.sol/Mock0xSplitsV2PullFactory.json +149 -0
  137. package/artifacts/contracts/mock/Mock0xSplitsV2Splitter.sol/Mock0xSplitsV2Splitter.json +99 -0
  138. package/artifacts/contracts/mock/MockAdminACLV0.sol/MockAdminACLV0Events.json +20 -2
  139. package/artifacts/contracts/mock/MockAdminACLV0_PROHIBITION.sol/MockAdminACLV0Events_PROHIBITION.json +20 -2
  140. package/artifacts/contracts/mock/OriginRegisterMock.sol/OriginRegisterMock.json +2 -2
  141. package/artifacts/contracts/mock/RandomizerV2_NoAssignMock.sol/RandomizerV2_NoAssignMock.json +2 -2
  142. package/artifacts/contracts/mock/ReentrancyGenArt721MinterMock.sol/ReentrancyGenArt721MinterMock.json +100 -0
  143. package/artifacts/contracts/mock/ReentrancyHolderMock.sol/ReentrancyHolderMock.json +2 -2
  144. package/artifacts/contracts/mock/ReentrancyHolderMockShared.sol/ReentrancyHolderMockShared.json +136 -0
  145. package/artifacts/contracts/mock/ReentrancyMerkleMock.sol/ReentrancyMerkleMock.json +2 -2
  146. package/artifacts/contracts/mock/ReentrancyMerkleMockShared.sol/ReentrancyMerkleMockShared.json +105 -0
  147. package/artifacts/contracts/mock/ReentrancyMock.sol/ReentrancyMock.json +2 -2
  148. package/artifacts/contracts/mock/ReentrancyMockShared.sol/ReentrancyMockShared.json +100 -0
  149. package/artifacts/contracts/mock/ReentrancySEAMock.sol/ReentrancySEAAutoBidderMock.json +2 -2
  150. package/artifacts/contracts/mock/ReentrancySEAMockShared.sol/ReentrancySEAAutoBidderMockShared.json +69 -0
  151. package/artifacts/contracts/mock/ReentrancySplitterMocks.sol/ReentrancySplitterDrainETHMock.json +54 -0
  152. package/artifacts/contracts/mock/ReentrancySplitterMocks.sol/ReentrancySplitterSendETHMock.json +54 -0
  153. package/artifacts/contracts/randomizer/deprecated/PolyptychRandomizerV0.sol/BasicPolyptychRandomizerV0.json +2 -2
  154. package/artifacts/contracts/randomizer/deprecated/RandomizerV2.sol/BasicRandomizerV2.json +2 -2
  155. package/artifacts/contracts/randomizer/primitive/PseudorandomAtomicBasic.sol/PseudorandomAtomic.json +2 -2
  156. package/artifacts/contracts/randomizer/shared/SharedRandomizerV0.sol/SharedRandomizerV0.json +19 -19
  157. package/artifacts/contracts/split/SplitAtomicFactoryV0.sol/SplitAtomicFactoryV0.json +203 -0
  158. package/artifacts/contracts/split/SplitAtomicV0.sol/SplitAtomicV0.json +168 -0
  159. package/artifacts/contracts/split/split-provider/SplitProviderV0.sol/SplitProviderV0.json +141 -0
  160. package/contracts/AdminACLV0.sol +6 -2
  161. package/contracts/AdminACLV1.sol +2 -2
  162. package/contracts/DependencyRegistryV0.sol +737 -390
  163. package/contracts/{GenArt721CoreV3.sol → archive/GenArt721CoreV3.sol} +56 -20
  164. package/contracts/{explorations → archive}/GenArt721CoreV3_Explorations.sol +49 -13
  165. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterBase_v0_1_1.sol +4 -4
  166. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDAExp}/MinterDAExpV4.sol +4 -4
  167. package/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol +4 -4
  168. package/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV1.sol +5 -5
  169. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDAExpSettlement}/MinterDAExpSettlementV2.sol +9 -62
  170. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDALin}/MinterDALinV4.sol +4 -4
  171. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterHolder}/MinterHolderV4.sol +5 -5
  172. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterMerkle}/MinterMerkleV5.sol +5 -5
  173. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterPolyptych}/MinterPolyptychV0.sol +7 -7
  174. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSEA}/MinterSEAV0.sol +13 -13
  175. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSetPrice}/MinterSetPriceV4.sol +4 -4
  176. package/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V0.sol +82 -10
  177. package/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V1.sol +82 -10
  178. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSetPriceERC20}/MinterSetPriceERC20V4.sol +88 -21
  179. package/contracts/engine/V2/GenArt721MinterBurner_PBAB.sol +81 -22
  180. package/contracts/engine/V2/GenArt721Minter_PBAB.sol +80 -22
  181. package/contracts/engine/V3/EngineFactoryV0.sol +419 -0
  182. package/contracts/engine/V3/GenArt721CoreV3_Engine.sol +893 -493
  183. package/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol +1053 -655
  184. package/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol +7 -13
  185. package/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol +5 -11
  186. package/contracts/engine/V3/forks/PROHIBITION/interfaces/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.sol +2 -2
  187. package/contracts/engine-registry/CoreRegistryV1.sol +58 -65
  188. package/contracts/interfaces/v0.8.x/IAdminACLV0_Extended.sol +20 -0
  189. package/contracts/interfaces/v0.8.x/IBytecodeStorageReaderV2.sol +23 -0
  190. package/contracts/interfaces/v0.8.x/ICoreRegistryV1.sol +6 -8
  191. package/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol +48 -43
  192. package/contracts/interfaces/v0.8.x/IEngineFactoryV0.sol +124 -0
  193. package/contracts/interfaces/v0.8.x/IFilteredMinterDAExpSettlementV0.sol +1 -3
  194. package/contracts/interfaces/v0.8.x/IFilteredMinterDAExpSettlementV1.sol +1 -3
  195. package/contracts/interfaces/v0.8.x/IFilteredMinterDAExpV1.sol +1 -3
  196. package/contracts/interfaces/v0.8.x/IFilteredMinterDALinV1.sol +1 -3
  197. package/contracts/interfaces/v0.8.x/IFilteredMinterHolderV2.sol +1 -3
  198. package/contracts/interfaces/v0.8.x/IFilteredMinterMerkleV2.sol +1 -3
  199. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Base.sol +115 -11
  200. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine.sol +84 -8
  201. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex.sol +26 -8
  202. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex_PreV3p2.sol +141 -0
  203. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_PreV3p2.sol +78 -0
  204. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_ProjectFinance.sol +47 -0
  205. package/contracts/interfaces/v0.8.x/IGenArt721Minter_PBAB.sol +91 -0
  206. package/contracts/interfaces/v0.8.x/IMinterFilterV1.sol +25 -25
  207. package/contracts/interfaces/v0.8.x/IPseudorandomAtomic.sol +1 -3
  208. package/contracts/interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol +30 -20
  209. package/contracts/interfaces/v0.8.x/ISharedMinterDAExpV0.sol +1 -14
  210. package/contracts/interfaces/v0.8.x/ISharedMinterDALinV0.sol +1 -15
  211. package/contracts/interfaces/v0.8.x/ISharedMinterDAV0.sol +2 -8
  212. package/contracts/interfaces/v0.8.x/ISharedMinterHolderERC20V0.sol +47 -0
  213. package/contracts/interfaces/v0.8.x/ISharedMinterHolderV0.sol +15 -43
  214. package/contracts/interfaces/v0.8.x/ISharedMinterMerkleV0.sol +10 -20
  215. package/contracts/interfaces/v0.8.x/ISharedMinterRAMV0.sol +23 -0
  216. package/contracts/interfaces/v0.8.x/ISharedMinterRequired.sol +20 -0
  217. package/contracts/interfaces/v0.8.x/ISharedMinterSEAV0.sol +1 -67
  218. package/contracts/interfaces/v0.8.x/ISharedMinterSimplePurchaseV0.sol +5 -5
  219. package/contracts/interfaces/v0.8.x/ISharedMinterV0.sol +18 -160
  220. package/contracts/interfaces/v0.8.x/ISharedRandomizerV0.sol +37 -37
  221. package/contracts/interfaces/v0.8.x/ISplitAtomicFactoryV0.sol +81 -0
  222. package/contracts/interfaces/v0.8.x/ISplitAtomicV0.sol +72 -0
  223. package/contracts/interfaces/v0.8.x/ISplitProviderV0.sol +49 -0
  224. package/contracts/interfaces/v0.8.x/integration-refs/splits-0x-v2/ISplitFactoryV2.sol +62 -0
  225. package/contracts/libs/v0.8.x/ABHelpers.sol +31 -17
  226. package/contracts/libs/v0.8.x/AuthLib.sol +101 -102
  227. package/contracts/libs/v0.8.x/BitMap.sol +112 -0
  228. package/contracts/libs/v0.8.x/BytecodeStorageV2.sol +593 -0
  229. package/contracts/libs/v0.8.x/Bytes32Strings.sol +5 -5
  230. package/contracts/libs/v0.8.x/DependencyRegistryStorageLib.sol +90 -0
  231. package/contracts/libs/v0.8.x/ERC721_PackedHashSeedV1.sol +591 -0
  232. package/contracts/libs/v0.8.x/PackedBools.sol +42 -0
  233. package/contracts/libs/v0.8.x/V3FlexLib.sol +591 -0
  234. package/contracts/libs/v0.8.x/minter-libs/DAExpLib.sol +162 -39
  235. package/contracts/libs/v0.8.x/minter-libs/DALib.sol +26 -0
  236. package/contracts/libs/v0.8.x/minter-libs/DALinLib.sol +139 -37
  237. package/contracts/libs/v0.8.x/minter-libs/GenericMinterEventsLib.sol +171 -0
  238. package/contracts/libs/v0.8.x/minter-libs/MaxInvocationsLib.sol +299 -158
  239. package/contracts/libs/v0.8.x/minter-libs/MerkleLib.sol +268 -55
  240. package/contracts/libs/v0.8.x/minter-libs/PolyptychLib.sol +138 -58
  241. package/contracts/libs/v0.8.x/minter-libs/RAMLib.sol +2927 -0
  242. package/contracts/libs/v0.8.x/minter-libs/SEALib.sol +796 -123
  243. package/contracts/libs/v0.8.x/minter-libs/SetPriceLib.sol +131 -13
  244. package/contracts/libs/v0.8.x/minter-libs/SettlementExpLib.sol +607 -224
  245. package/contracts/libs/v0.8.x/minter-libs/SplitFundsLib.sol +494 -330
  246. package/contracts/libs/v0.8.x/minter-libs/TokenHolderLib.sol +217 -78
  247. package/contracts/minter-suite/MinterFilter/MinterFilterV2.sol +358 -309
  248. package/contracts/minter-suite/Minters/MinterDAExpHolderV5.sol +391 -491
  249. package/contracts/minter-suite/Minters/MinterDAExpSettlementV3.sol +396 -632
  250. package/contracts/minter-suite/Minters/MinterDAExpV5.sol +212 -273
  251. package/contracts/minter-suite/Minters/MinterDALinHolderV5.sol +393 -488
  252. package/contracts/minter-suite/Minters/MinterDALinV5.sol +220 -277
  253. package/contracts/minter-suite/Minters/MinterRAMV0.sol +1205 -0
  254. package/contracts/minter-suite/Minters/MinterSEAV1.sol +329 -677
  255. package/contracts/minter-suite/Minters/MinterSetPriceERC20V5.sol +287 -303
  256. package/contracts/minter-suite/Minters/MinterSetPriceHolderV5.sol +355 -446
  257. package/contracts/minter-suite/Minters/MinterSetPriceMerkleV5.sol +328 -416
  258. package/contracts/minter-suite/Minters/MinterSetPricePolyptychERC20V5.sol +552 -622
  259. package/contracts/minter-suite/Minters/MinterSetPricePolyptychV5.sol +429 -553
  260. package/contracts/minter-suite/Minters/MinterSetPriceV5.sol +180 -227
  261. package/contracts/minter-suite/Minters/one-off/MinterSetPriceV5_SingleCore.sol +446 -0
  262. package/contracts/mock/BytecodeV2LibCallsMock.sol +128 -0
  263. package/contracts/mock/BytecodeV2TextCR_DMock.sol +316 -0
  264. package/contracts/mock/ForceSendMock.sol +22 -0
  265. package/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol +3 -10
  266. package/contracts/mock/Mock0xSplitsV2PullFactory.sol +75 -0
  267. package/contracts/mock/Mock0xSplitsV2Splitter.sol +47 -0
  268. package/contracts/mock/MockAdminACLV0.sol +21 -0
  269. package/contracts/mock/MockAdminACLV0_PROHIBITION.sol +21 -0
  270. package/contracts/mock/ReentrancyGenArt721MinterMock.sol +47 -0
  271. package/contracts/mock/ReentrancyHolderMockShared.sol +59 -0
  272. package/contracts/mock/ReentrancyMerkleMockShared.sol +58 -0
  273. package/contracts/mock/ReentrancyMockShared.sol +48 -0
  274. package/contracts/mock/ReentrancySEAMockShared.sol +40 -0
  275. package/contracts/mock/ReentrancySplitterMocks.sol +67 -0
  276. package/contracts/randomizer/primitive/PseudorandomAtomicBasic.sol +1 -1
  277. package/contracts/randomizer/shared/SharedRandomizerV0.sol +79 -71
  278. package/contracts/split/SplitAtomicFactoryV0.sol +121 -0
  279. package/contracts/split/SplitAtomicV0.sol +265 -0
  280. package/contracts/split/split-provider/SplitProviderV0.sol +201 -0
  281. package/package.json +79 -45
  282. package/artifacts/contracts/GenArt721CoreV3.sol/GenArt721CoreV3.json +0 -1965
  283. package/artifacts/contracts/explorations/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +0 -1939
  284. package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV2.sol/MinterDAExpSettlementV2.json +0 -1127
  285. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20V4.sol/MinterSetPriceERC20V4.json +0 -768
  286. package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverride.sol/GenArt721RoyaltyOverride.json +0 -208
  287. package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverride_PBAB.sol/GenArt721RoyaltyOverride_PBAB.json +0 -301
  288. package/contracts/royalty-registry/GenArt721RoyaltyOverride.sol +0 -168
  289. package/contracts/royalty-registry/GenArt721RoyaltyOverride_PBAB.sol +0 -221
@@ -3,7 +3,14 @@
3
3
 
4
4
  pragma solidity ^0.8.0;
5
5
 
6
- import "@openzeppelin-4.7/contracts/utils/math/SafeCast.sol";
6
+ import {IMinterFilterV1} from "../../../interfaces/v0.8.x/IMinterFilterV1.sol";
7
+
8
+ import {ABHelpers} from "../ABHelpers.sol";
9
+ import {SplitFundsLib} from "./SplitFundsLib.sol";
10
+ import {MaxInvocationsLib} from "./MaxInvocationsLib.sol";
11
+
12
+ import {IERC721} from "@openzeppelin-4.7/contracts/token/ERC721/IERC721.sol";
13
+ import {SafeCast} from "@openzeppelin-4.7/contracts/utils/math/SafeCast.sol";
7
14
 
8
15
  /**
9
16
  * @title Art Blocks SEA Minter Library
@@ -14,12 +21,146 @@ import "@openzeppelin-4.7/contracts/utils/math/SafeCast.sol";
14
21
 
15
22
  library SEALib {
16
23
  using SafeCast for uint256;
24
+ /**
25
+ * @notice Minimum auction length, in seconds, was updated to be the
26
+ * provided value.
27
+ * @param minAuctionDurationSeconds Minimum auction length, in seconds
28
+ */
29
+ event MinAuctionDurationSecondsUpdated(uint256 minAuctionDurationSeconds);
30
+
31
+ /**
32
+ * @notice Admin-controlled time buffer updated
33
+ * @param minterTimeBufferSeconds Time buffer, in seconds
34
+ */
35
+ event MinterTimeBufferUpdated(uint32 minterTimeBufferSeconds);
36
+
37
+ /**
38
+ * @notice Admin-controlled refund gas limit updated
39
+ * @param refundGasLimit Gas limit to use when refunding the previous
40
+ * highest bidder, prior to using fallback force-send to refund
41
+ */
42
+ event MinterRefundGasLimitUpdated(uint24 refundGasLimit);
17
43
 
18
- uint256 constant ONE_MILLION = 1_000_000;
44
+ /**
45
+ * @notice Future auctions for project `projectId` on core contract
46
+ * `coreContract` configured.
47
+ * @param projectId Project Id configured
48
+ * @param coreContract Core contract address configured
49
+ * @param timestampStart Start timestamp after which future auctions may be
50
+ * started. If zero, auctions can start immediately.
51
+ * @param auctionDurationSeconds Duration of each new auction, before any
52
+ * extensions due to late bids
53
+ * @param basePrice Minimum bid price for the token auctions
54
+ * @param minBidIncrementPercentage Minimum bid increment percentage. Each
55
+ * subsequent bid must be at least this percentage greater than the
56
+ * previous bid. The value is expressed as a whole percentage, e.g. 5% is
57
+ * 5, 10% is 10, etc.
58
+ */
59
+ event ConfiguredFutureAuctions(
60
+ uint256 indexed projectId,
61
+ address indexed coreContract,
62
+ uint64 timestampStart,
63
+ uint32 auctionDurationSeconds,
64
+ uint256 basePrice,
65
+ uint8 minBidIncrementPercentage
66
+ );
67
+
68
+ /**
69
+ * @notice New token auction created, token created and sent to minter
70
+ * @param tokenId Token Id for which auction was created
71
+ * @param coreContract Core contract address for the given token
72
+ * @param bidder Bidder's address who initialized the auction
73
+ * @param bidAmount Bid amount
74
+ * @param endTime Auction end time
75
+ * @param minBidIncrementPercentage Minimum bid increment percentage. Each
76
+ * subsequent bid must be at least this percentage greater than the
77
+ * previous bid. The value is expressed as a whole percentage, e.g. 5% is
78
+ * 5, 10% is 10, etc.
79
+ */
80
+ event AuctionInitialized(
81
+ uint256 indexed tokenId,
82
+ address indexed coreContract,
83
+ address indexed bidder,
84
+ uint256 bidAmount,
85
+ uint64 endTime,
86
+ uint8 minBidIncrementPercentage
87
+ );
88
+
89
+ /**
90
+ * @notice Successful bid placed on token auction
91
+ * @param tokenId Token Id of auction bid on
92
+ * @param coreContract Core contract address for the given token
93
+ * @param bidder Bidder's address who placed the bid
94
+ * @param bidAmount Bid amount
95
+ */
96
+ event AuctionBid(
97
+ uint256 indexed tokenId,
98
+ address indexed coreContract,
99
+ address indexed bidder,
100
+ uint256 bidAmount
101
+ );
102
+
103
+ /**
104
+ * @notice Token auction was settled (token distributed to winner)
105
+ * @param tokenId Token Id of auction settled
106
+ * @param coreContract Core contract address for the given token
107
+ * @param winner Winner's address
108
+ * @param price Winning bid amount
109
+ */
110
+ event AuctionSettled(
111
+ uint256 indexed tokenId,
112
+ address indexed coreContract,
113
+ address indexed winner,
114
+ uint256 price
115
+ );
116
+
117
+ /**
118
+ * @notice Future auction details for project `projectId` reset
119
+ * @param projectId Project Id that was reset
120
+ * @param coreContract Core contract address that was reset
121
+ */
122
+ event ResetAuctionDetails(
123
+ uint256 indexed projectId,
124
+ address indexed coreContract
125
+ );
126
+
127
+ /**
128
+ * @notice Next token ID for project `projectId` updated
129
+ * @param projectId Project Id of next token updated
130
+ * @param coreContract Core contract address of next token updated
131
+ * @param tokenId Token Id of next token updated
132
+ */
133
+ event ProjectNextTokenUpdated(
134
+ uint256 indexed projectId,
135
+ address indexed coreContract,
136
+ uint256 tokenId
137
+ );
138
+
139
+ /**
140
+ * @notice Next token ID for project `projectId` ejected from the minter
141
+ * and is no longer populated
142
+ * @param projectId Project Id of next token ejected
143
+ * @param coreContract Core contract address of next token ejected
144
+ */
145
+ event ProjectNextTokenEjected(
146
+ uint256 indexed projectId,
147
+ address indexed coreContract
148
+ );
149
+
150
+ // position of SEA Lib storage, using a diamond storage pattern
151
+ // for this library
152
+ bytes32 constant SEA_LIB_STORAGE_POSITION = keccak256("sealib.storage");
19
153
 
20
154
  // project-specific parameters
21
155
  struct SEAProjectConfig {
156
+ // bool to indicate if next token number has been populated, or is
157
+ // still default value of 0
158
+ // @dev required to handle edge case where next token number is 0
159
+ bool nextTokenNumberIsPopulated;
160
+ // timestamp at/after which new auctions may be created
22
161
  uint64 timestampStart;
162
+ //
163
+ // ---- Auction Factory Settings Start ----
23
164
  // duration of each new auction, before any extensions due to late bids
24
165
  // @dev for configured auctions, this will be gt 0, so it may be used
25
166
  // to determine if an auction is configured
@@ -37,12 +178,10 @@ library SEALib {
37
178
  // be derived from this value in combination with project ID
38
179
  // max uint24 ~= 1.6e7, > max possible project invocations of 1e6
39
180
  uint24 nextTokenNumber;
40
- // bool to indicate if next token number has been populated, or is
41
- // still default value of 0
42
- // @dev required to handle edge case where next token number is 0
43
- bool nextTokenNumberIsPopulated;
44
181
  // reserve price, i.e. minimum starting bid price, in wei
45
182
  uint256 basePrice;
183
+ // ---- Auction Factory Settings End ----
184
+ //
46
185
  // active auction for project
47
186
  Auction activeAuction;
48
187
  }
@@ -67,80 +206,422 @@ library SEALib {
67
206
  bool settled;
68
207
  }
69
208
 
209
+ // Diamond storage pattern is used in this library
210
+ struct SEALibStorage {
211
+ mapping(address coreContract => mapping(uint256 projectId => SEAProjectConfig)) SEAProjectConfigs;
212
+ }
213
+
70
214
  /**
71
215
  * @notice Updates the SEAProjectConfig to clear the current settings for
72
216
  * future auctions on the project. Values are reset to their default
73
217
  * initial values.
74
218
  * Current auction details are not cleared or affected.
75
- * @param _SEAProjectConfig SEAProjectConfig to update
219
+ * @param projectId Project ID to reset
220
+ * @param coreContract Core contract address to reset
76
221
  */
77
222
  function resetFutureAuctionDetails(
78
- SEAProjectConfig storage _SEAProjectConfig
223
+ uint256 projectId,
224
+ address coreContract
79
225
  ) internal {
226
+ SEAProjectConfig storage SEAProjectConfig_ = getSEAProjectConfig({
227
+ projectId: projectId,
228
+ coreContract: coreContract
229
+ });
80
230
  // reset future auction details
81
- _SEAProjectConfig.auctionDurationSeconds = 0;
82
- _SEAProjectConfig.minBidIncrementPercentage = 0;
83
- _SEAProjectConfig.basePrice = 0;
84
- _SEAProjectConfig.timestampStart = 0;
231
+ SEAProjectConfig_.auctionDurationSeconds = 0;
232
+ SEAProjectConfig_.minBidIncrementPercentage = 0;
233
+ SEAProjectConfig_.basePrice = 0;
234
+ SEAProjectConfig_.timestampStart = 0;
235
+
236
+ emit ResetAuctionDetails({
237
+ projectId: projectId,
238
+ coreContract: coreContract
239
+ });
85
240
  }
86
241
 
87
242
  /**
88
- * Overwrite the active auction for a project with a new auction.
89
- * @dev This function is used to initialize a new auction. Care must be
90
- * taken to ensure that the existing auction is fully complete and settled.
91
- * @param _SEAProjectConfig SEAProjectConfig to update
92
- * @param _targetTokenId token ID to create the auction for
93
- * @param _bidAmount initial bid amount
94
- * @param _bidder initial bidder's payable address
95
- * @return endTime end time of the newly created auction
243
+ * @notice Configures future auctions for project `projectId` on core
244
+ * contract `coreContract`.
245
+ * Reverts if `timestampStart` is in the past and not zero.
246
+ * @param projectId Project ID to configure
247
+ * @param coreContract Core contract address to configure
248
+ * @param timestampStart Timestamp to start future auctions at. If zero,
249
+ * auctions can start immediately.
250
+ * @param auctionDurationSeconds Duration of each new auction, before any
251
+ * extensions due to late bids
252
+ * @param basePrice Minimum bid price for the token auctions
253
+ * @param minBidIncrementPercentage Minimum bid increment percentage. Each
254
+ * subsequent bid must be at least this percentage greater than the
255
+ * previous bid. The value is expressed as a whole percentage, e.g. 5% is
256
+ * 5, 10% is 10, etc.
96
257
  */
97
- function overwriteProjectActiveAuction(
98
- SEAProjectConfig storage _SEAProjectConfig,
99
- uint256 _targetTokenId,
100
- uint256 _bidAmount,
101
- address payable _bidder
102
- ) internal returns (uint64 endTime) {
103
- // calculate auction end time
104
- endTime = (block.timestamp + _SEAProjectConfig.auctionDurationSeconds)
105
- .toUint64();
106
- // set active auction on SEAProjectConfig
107
- _SEAProjectConfig.activeAuction = Auction({
108
- tokenId: _targetTokenId,
109
- currentBid: _bidAmount,
110
- currentBidder: _bidder,
111
- endTime: endTime,
112
- minBidIncrementPercentage: _SEAProjectConfig
113
- .minBidIncrementPercentage,
114
- settled: false
258
+ function configureFutureAuctions(
259
+ uint256 projectId,
260
+ address coreContract,
261
+ uint256 timestampStart,
262
+ uint256 auctionDurationSeconds,
263
+ uint256 basePrice,
264
+ uint8 minBidIncrementPercentage
265
+ ) internal {
266
+ SEAProjectConfig storage SEAProjectConfig_ = getSEAProjectConfig({
267
+ projectId: projectId,
268
+ coreContract: coreContract
269
+ });
270
+ // base price of zero breaks auction system as percent min increase
271
+ // makes no sense
272
+ require(basePrice != 0, "Only non-zero");
273
+ // midBidIncrementPercentage of zero would allow a bidder to "outbid"
274
+ // previous users without posting more, so don't allow it
275
+ require(minBidIncrementPercentage != 0, "Only non-zero");
276
+
277
+ require(
278
+ timestampStart == 0 || block.timestamp < timestampStart,
279
+ "Only future start times or 0"
280
+ );
281
+ // EFFECTS
282
+ SEAProjectConfig_.timestampStart = timestampStart.toUint64(); // @dev rely on this safe-cast check in event emit below
283
+ SEAProjectConfig_.auctionDurationSeconds = auctionDurationSeconds
284
+ .toUint32();
285
+ SEAProjectConfig_.basePrice = basePrice;
286
+ SEAProjectConfig_.minBidIncrementPercentage = minBidIncrementPercentage;
287
+
288
+ emit ConfiguredFutureAuctions({
289
+ projectId: projectId,
290
+ coreContract: coreContract,
291
+ timestampStart: uint64(timestampStart), // @dev safe-casting already previously checked
292
+ auctionDurationSeconds: uint32(auctionDurationSeconds), // @dev safe-casting already previously checked
293
+ basePrice: basePrice,
294
+ minBidIncrementPercentage: minBidIncrementPercentage
115
295
  });
116
- return endTime;
117
296
  }
118
297
 
119
298
  /**
120
299
  * @notice Updates the bid state of an Auction.
121
300
  * Note that the auction's end time is extended if the bid is placed within
122
- * the last `_timeBufferSeconds` of the auction.
301
+ * the last `timeBufferSeconds` of the auction.
123
302
  * NOTE: This function does not check if the bid is valid. It is assumed
124
303
  * that the bid has already been checked for validity by the caller.
125
- * @param _auction Auction to update
126
- * @param _timeBufferSeconds Time buffer to extend the auction to if the
127
- * bid is placed within the last `_timeBufferSeconds` of the auction.
128
- * @param _bidAmount bid amount
129
- * @param _bidder bidder's payable address
304
+ * @param auction Auction to update
305
+ * @param timeBufferSeconds Time buffer to extend the auction to if the
306
+ * bid is placed within the last `timeBufferSeconds` of the auction.
307
+ * @param bidAmount bid amount
308
+ * @param bidder bidder's payable address
130
309
  */
131
310
  function auctionUpdateBid(
132
- Auction storage _auction,
133
- uint256 _timeBufferSeconds,
134
- uint256 _bidAmount,
135
- address payable _bidder
311
+ Auction storage auction,
312
+ uint256 timeBufferSeconds,
313
+ uint256 bidAmount,
314
+ address payable bidder
136
315
  ) internal {
137
316
  // update auction state
138
- _auction.currentBid = _bidAmount;
139
- _auction.currentBidder = _bidder;
140
- uint256 minEndTime = block.timestamp + _timeBufferSeconds;
141
- if (_auction.endTime < minEndTime) {
142
- _auction.endTime = minEndTime.toUint64();
317
+ auction.currentBid = bidAmount;
318
+ auction.currentBidder = bidder;
319
+ uint256 minEndTime = block.timestamp + timeBufferSeconds;
320
+ if (auction.endTime < minEndTime) {
321
+ auction.endTime = minEndTime.toUint64();
322
+ }
323
+ }
324
+
325
+ /**
326
+ * @notice Ejects a project's "next token" from the minter and sends it to
327
+ * the input `to` address.
328
+ * This function is only intended for use in the edge case where the minter
329
+ * has a "next token" assigned to a project, but the project has been reset
330
+ * via `resetAuctionDetails`, and the artist does not want an auction to be
331
+ * started for the "next token". This function also protects against the
332
+ * unforseen case where the minter is in an unexpected state where it has a
333
+ * "next token" assigned to a project, but for some reason the project is
334
+ * unable to begin a new auction due to a bug.
335
+ * @param projectId The project ID being ejected
336
+ * @param coreContract The core contract address being ejected
337
+ * @param to The address to send the ejected token to
338
+ */
339
+ function ejectNextTokenTo(
340
+ uint256 projectId,
341
+ address coreContract,
342
+ address to
343
+ ) internal {
344
+ SEAProjectConfig storage SEAProjectConfig_ = getSEAProjectConfig({
345
+ projectId: projectId,
346
+ coreContract: coreContract
347
+ });
348
+ // CHECKS
349
+ // only if project is not configured (i.e. artist called
350
+ // `resetAuctionDetails`)
351
+ require(
352
+ !projectIsConfigured({
353
+ projectId: projectId,
354
+ coreContract: coreContract
355
+ }),
356
+ "Only unconfigured projects"
357
+ );
358
+ // only if project has a next token assigned
359
+ require(
360
+ SEAProjectConfig_.nextTokenNumberIsPopulated == true,
361
+ "No next token"
362
+ );
363
+ // EFFECTS
364
+ SEAProjectConfig_.nextTokenNumberIsPopulated = false;
365
+ // INTERACTIONS
366
+ // @dev overflow automatically handled by Sol ^0.8.0
367
+ uint256 nextTokenId = ABHelpers.tokenIdFromProjectIdAndTokenNumber({
368
+ projectId: projectId,
369
+ tokenNumber: SEAProjectConfig_.nextTokenNumber
370
+ });
371
+ IERC721(coreContract).transferFrom({
372
+ from: address(this),
373
+ to: to,
374
+ tokenId: nextTokenId
375
+ });
376
+ emit ProjectNextTokenEjected({
377
+ projectId: projectId,
378
+ coreContract: coreContract
379
+ });
380
+ }
381
+
382
+ /**
383
+ * @notice Settles a completed auction for `tokenId`, if it exists and is
384
+ * not yet settled.
385
+ * Returns early (does not modify state) if
386
+ * - there is no initialized auction for the project
387
+ * - there is an auction that has already been settled for the project
388
+ * - there is an auction for a different token ID on the project
389
+ * (likely due to a front-run)
390
+ * This function reverts if the auction for `tokenId` exists, but has not
391
+ * yet ended. Function also reverts if there is no initialized auction.
392
+ * @param tokenId Token ID to settle auction for.
393
+ * @param coreContract Core contract address for the given token.
394
+ */
395
+ function settleAuction(uint256 tokenId, address coreContract) internal {
396
+ uint256 projectId = ABHelpers.tokenIdToProjectId(tokenId);
397
+ SEAProjectConfig storage _SEAProjectConfig = getSEAProjectConfig({
398
+ projectId: projectId,
399
+ coreContract: coreContract
400
+ });
401
+ Auction storage auction = _SEAProjectConfig.activeAuction;
402
+ // load from storage to memory for gas efficiency
403
+ address currentBidder = auction.currentBidder;
404
+ uint256 currentBid = auction.currentBid;
405
+ // CHECKS
406
+ require(auctionIsInitialized(auction), "Auction not initialized");
407
+ if (auction.settled || (auction.tokenId != tokenId)) {
408
+ // auction already settled or is for a different token ID, so
409
+ // return early and do not modify state
410
+ return;
411
+ }
412
+ // @dev important that the following check is after the early return
413
+ // block above to maintain desired behavior
414
+ require(block.timestamp >= auction.endTime, "Auction not yet ended");
415
+ // EFFECTS
416
+ auction.settled = true;
417
+ // INTERACTIONS
418
+ // send token to the winning bidder
419
+ IERC721(coreContract).transferFrom({
420
+ from: address(this),
421
+ to: currentBidder,
422
+ tokenId: tokenId
423
+ });
424
+ // distribute revenues from auction
425
+ SplitFundsLib.splitRevenuesETHNoRefund({
426
+ projectId: projectId,
427
+ valueInWei: currentBid,
428
+ coreContract: coreContract
429
+ });
430
+
431
+ emit AuctionSettled({
432
+ tokenId: tokenId,
433
+ coreContract: coreContract,
434
+ winner: currentBidder,
435
+ price: currentBid
436
+ });
437
+ }
438
+
439
+ /**
440
+ * @notice Enters a bid for token `tokenId`.
441
+ * If an auction for token `tokenId` does not exist, an auction will be
442
+ * initialized as long as any existing auction for the project has been
443
+ * settled.
444
+ * In order to successfully place the bid, the token bid must be:
445
+ * - greater than or equal to a project's minimum bid price if a new
446
+ * auction is initialized
447
+ * - sufficiently greater than the current highest bid, according to the
448
+ * minter's bid increment percentage `minterMinBidIncrementPercentage`,
449
+ * if an auction for the token already exists
450
+ * If the bid is unsuccessful, the transaction will revert.
451
+ * If the bid is successful, but outbid by another bid before the auction
452
+ * ends, the funds will be noncustodially returned to the bidder's address,
453
+ * `msg.sender`. A fallback method of sending funds back to the bidder via
454
+ * SELFDESTRUCT (SENDALL) prevents denial of service attacks, even if the
455
+ * original bidder reverts or runs out of gas during receive or fallback.
456
+ * ------------------------------------------------------------------------
457
+ * WARNING: bidders must be prepared to handle the case where their bid is
458
+ * outbid and their funds are returned to the original `msg.sender` address
459
+ * via SELFDESTRUCT (SENDALL).
460
+ * ------------------------------------------------------------------------
461
+ * Note that the use of `tokenId` is to prevent the possibility of
462
+ * transactions that are stuck in the pending pool for long periods of time
463
+ * from unintentionally bidding on auctions for future tokens.
464
+ * If a new auction is initialized during this call, the project's next
465
+ * token will be attempted to be minted to this minter contract, preparing
466
+ * it for the next auction. If the project's next token cannot be minted
467
+ * due to e.g. reaching the maximum invocations on the core contract or
468
+ * minter, the project's next token will not be minted.
469
+ * @param tokenId Token ID being bid on.
470
+ * @param coreContract Core contract address for the given project.
471
+ * @param minterTimeBufferSeconds Time buffer to extend the auction to if
472
+ * the bid is placed within the last `minterTimeBufferSeconds` of the
473
+ * auction.
474
+ * @param minterRefundGasLimit Gas limit to use when refunding the previous
475
+ * highest bidder.
476
+ * @param minterFilter Minter filter to use when minting the next token for
477
+ * the project.
478
+ * @dev nonReentrant modifier is used to prevent reentrancy attacks, e.g.
479
+ * an an auto-bidder that would be able to atomically outbid a user's
480
+ * new bid via a reentrant call to createBid.
481
+ */
482
+ function createBid(
483
+ uint256 tokenId,
484
+ address coreContract,
485
+ uint256 minterTimeBufferSeconds,
486
+ uint256 minterRefundGasLimit,
487
+ IMinterFilterV1 minterFilter
488
+ ) internal {
489
+ uint256 projectId = ABHelpers.tokenIdToProjectId(tokenId);
490
+ SEAProjectConfig storage SEAProjectConfig_ = getSEAProjectConfig({
491
+ projectId: projectId,
492
+ coreContract: coreContract
493
+ });
494
+ Auction storage auction = SEAProjectConfig_.activeAuction;
495
+ // CHECKS
496
+ // if no auction exists, or current auction is already settled, attempt
497
+ // to initialize a new auction for the input token ID and immediately
498
+ // return
499
+ if ((!auctionIsInitialized(auction)) || auction.settled) {
500
+ _initializeAuctionWithBid({
501
+ projectId: projectId,
502
+ coreContract: coreContract,
503
+ targetTokenId: tokenId,
504
+ minterFilter: minterFilter
505
+ });
506
+ return;
143
507
  }
508
+ // @dev this branch is guaranteed to have an initialized auction that
509
+ // not settled, so no need to check for initialized or not settled
510
+
511
+ // ensure bids for a specific token ID are only applied to the auction
512
+ // for that token ID.
513
+ require(auction.tokenId == tokenId, "Token ID does not match auction");
514
+
515
+ // ensure auction is not already ended
516
+ require(auction.endTime > block.timestamp, "Auction already ended");
517
+
518
+ // require bid to be sufficiently greater than current highest bid
519
+ // @dev no overflow enforced automatically by solidity ^0.8.0
520
+ require(msg.value >= getMinimumNextBid(auction), "Bid is too low");
521
+
522
+ // EFFECTS
523
+ // record previous highest bidder and bid for refunding
524
+ address payable previousBidder = auction.currentBidder;
525
+ uint256 previousBid = auction.currentBid;
526
+
527
+ // update auction bid state
528
+ auctionUpdateBid({
529
+ auction: auction,
530
+ timeBufferSeconds: minterTimeBufferSeconds,
531
+ bidAmount: msg.value,
532
+ bidder: payable(msg.sender)
533
+ });
534
+
535
+ // INTERACTIONS
536
+ // refund previous highest bidder
537
+ SplitFundsLib.forceSafeTransferETH({
538
+ to: previousBidder,
539
+ amount: previousBid,
540
+ minterRefundGasLimit: minterRefundGasLimit
541
+ });
542
+
543
+ emit AuctionBid({
544
+ tokenId: tokenId,
545
+ coreContract: coreContract,
546
+ bidder: msg.sender,
547
+ bidAmount: msg.value
548
+ });
549
+ }
550
+
551
+ /**
552
+ * @notice Internal function that attempts to mint a new token to the next
553
+ * token slot for the project `projectId`.
554
+ * This function returns early and does not modify state if
555
+ * - the project has reached its maximum invocations on either the core
556
+ * contract or minter
557
+ * - the project config's `nextTokenNumberIsPopulated` is already true
558
+ * @param projectId The ID of the project to mint a new token for.
559
+ * @param coreContract The core contract address
560
+ * @param minterFilter The minter filter contract address
561
+ * @dev this calls mint with `msg.sender` as the sender, allowing artists
562
+ * to mint tokens to the next token slot for their project while a project
563
+ * is still paused. This happens when an artist is configuring their
564
+ * project's auction parameters or minter max invocations.
565
+ */
566
+ function tryMintTokenToNextSlot(
567
+ uint256 projectId,
568
+ address coreContract,
569
+ IMinterFilterV1 minterFilter
570
+ ) internal {
571
+ SEAProjectConfig storage SEAProjectConfig_ = getSEAProjectConfig({
572
+ projectId: projectId,
573
+ coreContract: coreContract
574
+ });
575
+ if (SEAProjectConfig_.nextTokenNumberIsPopulated) {
576
+ return;
577
+ }
578
+ // INTERACTIONS
579
+ // attempt to mint new token to this minter contract, only if max
580
+ // invocations has not been reached
581
+ // we require up-to-date invocation data to properly handle last token
582
+ // and avoid revert if relying on core to limit invocations, therefore
583
+ // use MaxInvocationsLib.invocationsRemainOnCore, which calls core contract
584
+ // to get latest invocation data
585
+ if (
586
+ !MaxInvocationsLib.invocationsRemainOnCore({
587
+ projectId: projectId,
588
+ coreContract: coreContract
589
+ })
590
+ ) {
591
+ // we have reached the max invocations, so we do not mint a new
592
+ // token as the "next token", and leave the next token number as
593
+ // not populated
594
+ return;
595
+ }
596
+ // @dev this is an effect after a trusted contract interaction
597
+ SEAProjectConfig_.nextTokenNumberIsPopulated = true;
598
+ // mint a new token to this project's "next token" slot
599
+ // @dev this is an interaction with a trusted contract
600
+ uint256 nextTokenId = minterFilter.mint_joo({
601
+ to: address(this),
602
+ projectId: projectId,
603
+ coreContract: coreContract,
604
+ sender: msg.sender
605
+ });
606
+ // update state to reflect new token number
607
+ // @dev state changes after trusted contract interaction
608
+ // @dev unchecked is safe because mod 1e6 is guaranteed to be less than
609
+ // max uint24
610
+ unchecked {
611
+ SEAProjectConfig_.nextTokenNumber = uint24(
612
+ ABHelpers.tokenIdToTokenNumber(nextTokenId)
613
+ );
614
+ }
615
+ // update local maxHasBeenInvoked value if necessary
616
+ MaxInvocationsLib.validateMintEffectsInvocations({
617
+ tokenId: nextTokenId,
618
+ coreContract: coreContract
619
+ });
620
+ emit ProjectNextTokenUpdated({
621
+ projectId: projectId,
622
+ coreContract: coreContract,
623
+ tokenId: nextTokenId
624
+ });
144
625
  }
145
626
 
146
627
  /**
@@ -148,12 +629,18 @@ library SEALib {
148
629
  * Uses project config's `auctionDurationSeconds` to determine if project
149
630
  * is configured, because `auctionDurationSeconds` is required to be
150
631
  * non-zero when configured.
151
- * @param _SEAProjectConfig The project config to check.
632
+ * @param projectId The project ID being queried
633
+ * @param coreContract The core contract address being queried
152
634
  */
153
635
  function projectIsConfigured(
154
- SEAProjectConfig storage _SEAProjectConfig
636
+ uint256 projectId,
637
+ address coreContract
155
638
  ) internal view returns (bool) {
156
- return _SEAProjectConfig.auctionDurationSeconds != 0;
639
+ SEAProjectConfig storage SEAProjectConfig_ = getSEAProjectConfig({
640
+ projectId: projectId,
641
+ coreContract: coreContract
642
+ });
643
+ return SEAProjectConfig_.auctionDurationSeconds != 0;
157
644
  }
158
645
 
159
646
  /**
@@ -161,46 +648,51 @@ library SEALib {
161
648
  * Uses auction's `currentBidder` address to determine if auction is
162
649
  * initialized, because `currentBidder` is always non-zero after an auction
163
650
  * has been initialized.
164
- * @param _auction The auction to check.
651
+ * @param auction The auction to check.
165
652
  */
166
653
  function auctionIsInitialized(
167
- Auction storage _auction
654
+ Auction storage auction
168
655
  ) internal view returns (bool isInitialized) {
169
656
  // auction is initialized if currentBidder is non-zero
170
- return _auction.currentBidder != address(0);
657
+ return auction.currentBidder != address(0);
171
658
  }
172
659
 
173
660
  /**
174
- * Returns bool representing if an auction is accepting bids above base
175
- * price. It is accepting bids if it is initialized and has not reached its
176
- * end time.
177
- * @param _auction The auction to check.
661
+ * @notice Function returns bool representing if an auction is live and
662
+ * accepting bids above base price. It is live if it is initialized and
663
+ * has not reached its end time.
664
+ * @param auction The auction to check.
178
665
  */
179
- function auctionIsAcceptingIncreasingBids(
180
- Auction storage _auction
666
+ function isAuctionLive(
667
+ Auction storage auction
181
668
  ) internal view returns (bool isAcceptingBids) {
182
669
  // auction is accepting bids if it is initialized and has not reached
183
670
  // its end time
184
- isAcceptingBids = (auctionIsInitialized(_auction) &&
185
- block.timestamp < _auction.endTime);
186
- return isAcceptingBids;
671
+ isAcceptingBids = (auctionIsInitialized(auction) &&
672
+ block.timestamp < auction.endTime);
187
673
  }
188
674
 
189
675
  /**
190
676
  * @notice SEAProjectConfig => active auction details.
191
677
  * @dev reverts if no auction exists for the project.
192
- * @param _SEAProjectConfig SEAProjectConfig to query
678
+ * @param projectId The project ID being queried
679
+ * @param coreContract The core contract address being queried
193
680
  */
194
681
  function projectActiveAuctionDetails(
195
- SEAProjectConfig storage _SEAProjectConfig
682
+ uint256 projectId,
683
+ address coreContract
196
684
  ) internal view returns (Auction memory auction) {
197
- Auction storage _auction = _SEAProjectConfig.activeAuction;
685
+ SEAProjectConfig storage SEAProjectConfig_ = getSEAProjectConfig({
686
+ projectId: projectId,
687
+ coreContract: coreContract
688
+ });
689
+ // load auction storage pointer to pass ref to utility function
690
+ Auction storage auction_ = SEAProjectConfig_.activeAuction;
198
691
  // do not return uninitialized auctions (i.e. auctions that do not
199
692
  // exist, where currentBidder is still the default value)
200
- require(auctionIsInitialized(_auction), "No auction exists on project");
201
- // load entire auction into memory
202
- auction = _SEAProjectConfig.activeAuction;
203
- return auction;
693
+ require(auctionIsInitialized(auction_), "No auction exists on project");
694
+ // load entire auction into memory to return
695
+ auction = SEAProjectConfig_.activeAuction;
204
696
  }
205
697
 
206
698
  /**
@@ -213,47 +705,53 @@ library SEALib {
213
705
  * target bid token ID to be passed in as an argument.
214
706
  * The function reverts if a project does not have an active auction and
215
707
  * the next expected token ID has not been populated.
216
- * @param _SEAProjectConfig SEAProjectConfig to query
217
- * @param _projectId The project ID being queried
708
+ * @param projectId The project ID being queried
709
+ * @param coreContract The core contract address being queried
218
710
  * @return The current token ID being auctioned, or the next token ID to be
219
711
  * auctioned if a new auction is ready to be created.
220
712
  */
221
713
  function getTokenToBid(
222
- SEAProjectConfig storage _SEAProjectConfig,
223
- uint256 _projectId
714
+ uint256 projectId,
715
+ address coreContract
224
716
  ) internal view returns (uint256) {
225
- Auction storage _auction = _SEAProjectConfig.activeAuction;
717
+ SEAProjectConfig storage SEAProjectConfig_ = getSEAProjectConfig({
718
+ projectId: projectId,
719
+ coreContract: coreContract
720
+ });
721
+ Auction storage auction = SEAProjectConfig_.activeAuction;
226
722
  // if project has an active token auction that is not settled, return
227
723
  // that token ID
228
- if (
229
- auctionIsInitialized(_auction) &&
230
- (_auction.endTime > block.timestamp)
231
- ) {
232
- return _auction.tokenId;
724
+ if (isAuctionLive(auction)) {
725
+ return auction.tokenId;
233
726
  }
234
727
  // otherwise, return the next expected token ID to be auctioned.
235
- return getNextTokenId(_SEAProjectConfig, _projectId);
728
+ return getNextTokenId(projectId, coreContract);
236
729
  }
237
730
 
238
731
  /**
239
732
  * @notice View function that returns the next token ID to be auctioned
240
- * by this minter for project `_projectId`.
733
+ * by this minter for project `projectId`.
241
734
  * Reverts if the next token ID has not been populated for the project.
242
- * @param _SEAProjectConfig SEAProjectConfig to query
243
- * @param _projectId The project ID being queried
735
+ * @param projectId The project ID being queried
736
+ * @param coreContract The core contract address being queried
244
737
  */
245
738
  function getNextTokenId(
246
- SEAProjectConfig storage _SEAProjectConfig,
247
- uint256 _projectId
739
+ uint256 projectId,
740
+ address coreContract
248
741
  ) internal view returns (uint256 nextTokenId) {
249
- if (!_SEAProjectConfig.nextTokenNumberIsPopulated) {
250
- revert("Next token not populated");
251
- }
252
- // @dev overflow automatically checked in Solidity ^0.8.0
253
- nextTokenId =
254
- (_projectId * ONE_MILLION) +
255
- _SEAProjectConfig.nextTokenNumber;
256
- return nextTokenId;
742
+ SEAProjectConfig storage SEAProjectConfig_ = getSEAProjectConfig({
743
+ projectId: projectId,
744
+ coreContract: coreContract
745
+ });
746
+ require(
747
+ SEAProjectConfig_.nextTokenNumberIsPopulated,
748
+ "Next token not populated"
749
+ );
750
+
751
+ nextTokenId = ABHelpers.tokenIdFromProjectIdAndTokenNumber({
752
+ projectId: projectId,
753
+ tokenNumber: SEAProjectConfig_.nextTokenNumber
754
+ });
257
755
  }
258
756
 
259
757
  /**
@@ -269,34 +767,37 @@ library SEALib {
269
767
  * the project is configured, `isConfigured` will be true, and
270
768
  * `tokenPriceInWei` will be the minimum initial bid price for the next
271
769
  * token auction.
272
- * @param _SEAProjectConfig SEAProjectConfig to be evaluated.
770
+ * @param projectId Project ID to get price info for
771
+ * @param coreContract Core contract address to get price info for
273
772
  * @return isConfigured true only if project auctions are configured.
274
773
  * @return tokenPriceInWei price in wei to become the leading bidder on a
275
774
  * token auction.
276
775
  */
277
- function getPriceInfoFromSEAProjectConfig(
278
- SEAProjectConfig storage _SEAProjectConfig
776
+ function getPriceInfo(
777
+ uint256 projectId,
778
+ address coreContract
279
779
  ) internal view returns (bool isConfigured, uint256 tokenPriceInWei) {
280
- Auction storage _auction = _SEAProjectConfig.activeAuction;
281
- // base price of zero not allowed when configuring auctions, so use it
282
- // as indicator of whether auctions are configured for the project
283
- bool projectIsConfigured_ = projectIsConfigured(_SEAProjectConfig);
284
- bool auctionIsAcceptingIncreasingBids_ = auctionIsAcceptingIncreasingBids(
285
- _auction
286
- );
287
- isConfigured =
288
- projectIsConfigured_ ||
289
- auctionIsAcceptingIncreasingBids_;
780
+ SEAProjectConfig storage SEAProjectConfig_ = getSEAProjectConfig({
781
+ projectId: projectId,
782
+ coreContract: coreContract
783
+ });
784
+ Auction storage auction = SEAProjectConfig_.activeAuction;
785
+ bool projectIsConfigured_ = projectIsConfigured({
786
+ projectId: projectId,
787
+ coreContract: coreContract
788
+ });
789
+ bool isAuctionLive_ = isAuctionLive(auction);
790
+ isConfigured = projectIsConfigured_ || isAuctionLive_;
290
791
  // only return non-zero price if auction is configured
291
792
  if (isConfigured) {
292
- if (auctionIsAcceptingIncreasingBids_) {
793
+ if (isAuctionLive_) {
293
794
  // return minimum next bid, given current bid
294
- tokenPriceInWei = getMinimumNextBid(_auction);
795
+ tokenPriceInWei = getMinimumNextBid(auction);
295
796
  } else {
296
797
  // return base (starting) price if if current auction is not
297
798
  // accepting bids (i.e. the minimum initial bid price for the
298
799
  // next token auction)
299
- tokenPriceInWei = _SEAProjectConfig.basePrice;
800
+ tokenPriceInWei = SEAProjectConfig_.basePrice;
300
801
  }
301
802
  }
302
803
  // else leave tokenPriceInWei as default value of zero
@@ -304,17 +805,189 @@ library SEALib {
304
805
  }
305
806
 
306
807
  /**
307
- * Returns the minimum next bid amount in a configured auction, given the
808
+ * @notice Function returns the minimum next bid amount in a configured auction, given the
308
809
  * current bid amount and the project's configured minimum bid increment
309
810
  * percentage.
310
- * @param _auction Auction to query
811
+ * @param auction Auction to query
311
812
  */
312
813
  function getMinimumNextBid(
313
- Auction storage _auction
814
+ Auction storage auction
314
815
  ) internal view returns (uint256 minimumNextBid) {
315
- // @dev overflow automatically checked in Solidity ^0.8.0
316
- return
317
- (_auction.currentBid * (100 + _auction.minBidIncrementPercentage)) /
318
- 100;
816
+ // @dev unchecked due to 0 <= minBidIncrementPercentage <= 255, and
817
+ // currentBid is capped at supply of ETH, so no risk of overflow
818
+ unchecked {
819
+ return
820
+ (auction.currentBid *
821
+ (100 + auction.minBidIncrementPercentage)) / 100;
822
+ }
823
+ }
824
+
825
+ /**
826
+ * @dev Private function to initialize an auction for the next token ID
827
+ * on project `projectId` with a bid of `msg.value` from `msg.sender`.
828
+ * This function reverts in any of the following cases:
829
+ * - project is not configured on this minter
830
+ * - project is configured but has not yet reached its start time
831
+ * - project has a current active auction that is not settled
832
+ * - insufficient bid amount (msg.value < basePrice)
833
+ * - no next token has been minted for the project (artist may need to
834
+ * call `tryPopulateNextToken`)
835
+ * - `targetTokenId` does not match the next token ID for the project
836
+ * After initializing a new auction, this function attempts to mint a new
837
+ * token and assign it to the project's next token slot, in preparation for
838
+ * a future token auction. However, if the project has reached its maximum
839
+ * invocations on either the core contract or minter, the next token slot
840
+ * for the project will remain empty.
841
+ * @dev This should be executed in a nonReentrant context to provide redundant
842
+ * protection against reentrancy.
843
+ * @param projectId The project ID to initialize an auction for
844
+ * @param coreContract The core contract address to initialize an auction for
845
+ * @param targetTokenId The token ID to initialize an auction for
846
+ * @param minterFilter The minter filter contract address
847
+ */
848
+ function _initializeAuctionWithBid(
849
+ uint256 projectId,
850
+ address coreContract,
851
+ uint256 targetTokenId,
852
+ IMinterFilterV1 minterFilter
853
+ ) private {
854
+ SEAProjectConfig storage SEAProjectConfig_ = getSEAProjectConfig({
855
+ projectId: projectId,
856
+ coreContract: coreContract
857
+ });
858
+ Auction storage auction = SEAProjectConfig_.activeAuction;
859
+ // CHECKS
860
+ // ensure project auctions are configured
861
+ require(
862
+ projectIsConfigured({
863
+ projectId: projectId,
864
+ coreContract: coreContract
865
+ }),
866
+ "Project not configured"
867
+ );
868
+ // only initialize new auctions if they meet the start time
869
+ // requirement
870
+ require(
871
+ block.timestamp >= SEAProjectConfig_.timestampStart,
872
+ "Only gte project start time"
873
+ );
874
+ // the following require statement is redundant based on how this
875
+ // internal function is called, but it is included for protection
876
+ // against future changes that could easily introduce a bug if this
877
+ // check is not present
878
+ // @dev no cover else branch of next line because unreachable
879
+ require(
880
+ (!auctionIsInitialized(auction)) || auction.settled,
881
+ "Existing auction not settled"
882
+ );
883
+ // require valid bid value
884
+ require(
885
+ msg.value >= SEAProjectConfig_.basePrice,
886
+ "Insufficient initial bid"
887
+ );
888
+ // require next token number is populated
889
+ // @dev this should only be encountered if the project has reached
890
+ // its maximum invocations on either the core contract or minter
891
+ require(
892
+ SEAProjectConfig_.nextTokenNumberIsPopulated,
893
+ "No next token, check max invocations"
894
+ );
895
+ // require next token number is the target token ID
896
+ require(
897
+ SEAProjectConfig_.nextTokenNumber ==
898
+ ABHelpers.tokenIdToTokenNumber(targetTokenId),
899
+ "Incorrect target token ID"
900
+ );
901
+
902
+ // EFFECTS
903
+ // create new auction, overwriting previous auction if it exists
904
+ uint64 endTime = _overwriteProjectActiveAuction({
905
+ SEAProjectConfig_: SEAProjectConfig_,
906
+ targetTokenId: targetTokenId,
907
+ bidAmount: msg.value,
908
+ bidder: payable(msg.sender)
909
+ });
910
+ // mark next token number as not populated
911
+ // @dev intentionally not setting nextTokenNumber to zero to avoid
912
+ // unnecessary gas costs
913
+ SEAProjectConfig_.nextTokenNumberIsPopulated = false;
914
+
915
+ // @dev we intentionally emit event here due to potential of early
916
+ // return in INTERACTIONS section
917
+ emit AuctionInitialized({
918
+ tokenId: targetTokenId,
919
+ coreContract: coreContract,
920
+ bidder: msg.sender,
921
+ bidAmount: msg.value,
922
+ endTime: endTime,
923
+ minBidIncrementPercentage: SEAProjectConfig_
924
+ .activeAuction
925
+ .minBidIncrementPercentage
926
+ });
927
+
928
+ // INTERACTIONS
929
+ // attempt to mint new token to this minter contract, only if max
930
+ // invocations has not been reached
931
+ tryMintTokenToNextSlot({
932
+ projectId: projectId,
933
+ coreContract: coreContract,
934
+ minterFilter: minterFilter
935
+ });
936
+ }
937
+
938
+ /**
939
+ * Loads the SEAProjectConfig for a given project and core
940
+ * contract.
941
+ * @param projectId Project Id to get config for
942
+ * @param coreContract Core contract address to get config for
943
+ */
944
+ function getSEAProjectConfig(
945
+ uint256 projectId,
946
+ address coreContract
947
+ ) internal view returns (SEAProjectConfig storage) {
948
+ return s().SEAProjectConfigs[coreContract][projectId];
949
+ }
950
+
951
+ /**
952
+ * @notice Return the storage struct for reading and writing. This library
953
+ * uses a diamond storage pattern when managing storage.
954
+ * @return storageStruct The SEALibStorage struct.
955
+ */
956
+ function s() internal pure returns (SEALibStorage storage storageStruct) {
957
+ bytes32 position = SEA_LIB_STORAGE_POSITION;
958
+ assembly ("memory-safe") {
959
+ storageStruct.slot := position
960
+ }
961
+ }
962
+
963
+ /**
964
+ * @notice Function to overwrite the active auction for a project with a new auction.
965
+ * @dev This function is used to initialize a new auction. Care must be
966
+ * taken to ensure that the existing auction is fully complete and settled.
967
+ * @param SEAProjectConfig_ SEAProjectConfig to update
968
+ * @param targetTokenId token ID to create the auction for
969
+ * @param bidAmount initial bid amount
970
+ * @param bidder initial bidder's payable address
971
+ * @return endTime end time of the newly created auction
972
+ */
973
+ function _overwriteProjectActiveAuction(
974
+ SEAProjectConfig storage SEAProjectConfig_,
975
+ uint256 targetTokenId,
976
+ uint256 bidAmount,
977
+ address payable bidder
978
+ ) private returns (uint64 endTime) {
979
+ // calculate auction end time
980
+ endTime = (block.timestamp + SEAProjectConfig_.auctionDurationSeconds)
981
+ .toUint64();
982
+ // set active auction on SEAProjectConfig
983
+ SEAProjectConfig_.activeAuction = Auction({
984
+ tokenId: targetTokenId,
985
+ currentBid: bidAmount,
986
+ currentBidder: bidder,
987
+ endTime: endTime,
988
+ minBidIncrementPercentage: SEAProjectConfig_
989
+ .minBidIncrementPercentage,
990
+ settled: false
991
+ });
319
992
  }
320
993
  }