@artblocks/contracts 1.0.4 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. package/README.md +75 -7
  2. package/artifacts/contracts/AdminACLV0.sol/AdminACLV0.json +2 -2
  3. package/artifacts/contracts/AdminACLV1.sol/AdminACLV1.json +2 -2
  4. package/artifacts/contracts/DependencyRegistryV0.sol/DependencyRegistryV0.json +336 -131
  5. package/artifacts/contracts/archive/GenArt721CoreV3.sol/GenArt721CoreV3.json +2047 -0
  6. package/artifacts/contracts/archive/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +2021 -0
  7. package/artifacts/contracts/{minter-suite → archive/minter-suite}/Minters/MinterBase_v0_1_1.sol/MinterBase.json +1 -1
  8. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV2.sol/MinterDAExpV2.json +2 -2
  9. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV3.sol/MinterDAExpV3.json +2 -2
  10. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDAExp}/MinterDAExpV4.sol/MinterDAExpV4.json +3 -3
  11. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol/MinterDAExpSettlementV0.json +2 -2
  12. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV1.sol/MinterDAExpSettlementV1.json +2 -2
  13. package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV2.sol/MinterDAExpSettlementV2.json +1109 -0
  14. package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV2.sol/MinterDALinV2.json +2 -2
  15. package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV3.sol/MinterDALinV3.json +2 -2
  16. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDALin}/MinterDALinV4.sol/MinterDALinV4.json +3 -3
  17. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV1.sol/MinterHolderV1.json +2 -2
  18. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV2.sol/MinterHolderV2.json +2 -2
  19. package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV3.sol/MinterHolderV3.json +2 -2
  20. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterHolder}/MinterHolderV4.sol/MinterHolderV4.json +3 -3
  21. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV1.sol/MinterMerkleV1.json +2 -2
  22. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV2.sol/MinterMerkleV2.json +2 -2
  23. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV3.sol/MinterMerkleV3.json +2 -2
  24. package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV4.sol/MinterMerkleV4.json +2 -2
  25. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterMerkle}/MinterMerkleV5.sol/MinterMerkleV5.json +3 -3
  26. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterPolyptych}/MinterPolyptychV0.sol/IGenArt721CoreContractV3WithRandomizer.json +31 -63
  27. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterPolyptych}/MinterPolyptychV0.sol/MinterPolyptychV0.json +3 -3
  28. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSEA}/MinterSEAV0.sol/MinterSEAV0.json +3 -3
  29. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV2.sol/MinterSetPriceV2.json +2 -2
  30. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV3.sol/MinterSetPriceV3.json +2 -2
  31. package/artifacts/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSetPrice}/MinterSetPriceV4.sol/MinterSetPriceV4.json +3 -3
  32. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V0.sol/MinterSetPriceERC20V0.json +65 -2
  33. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V1.sol/MinterSetPriceERC20V1.json +65 -2
  34. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol/MinterSetPriceERC20V2.json +2 -2
  35. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol/MinterSetPriceERC20V3.json +2 -2
  36. package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V4.sol/MinterSetPriceERC20V4.json +807 -0
  37. package/artifacts/contracts/engine/V2/GenArt721MinterBurner_PBAB.sol/GenArt721MinterBurner_PBAB.json +65 -2
  38. package/artifacts/contracts/engine/V2/GenArt721Minter_PBAB.sol/GenArt721Minter_PBAB.json +65 -2
  39. package/artifacts/contracts/engine/V3/EngineFactoryV0.sol/EngineFactoryV0.json +606 -0
  40. package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine.sol/GenArt721CoreV3_Engine.json +565 -209
  41. package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol/GenArt721CoreV3_Engine_Flex.json +785 -227
  42. package/artifacts/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol/GenArt721CoreV3_Engine_Flex_PROOF.json +40 -15
  43. package/artifacts/contracts/engine/V3/forks/PROHIBITION/AdminACLV0_PROHIBITION.sol/AdminACLV0_PROHIBITION.json +2 -2
  44. package/artifacts/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol/GenArt721CoreV3_Engine_Flex_PROHIBITION.json +40 -15
  45. package/artifacts/contracts/engine/V3/forks/PROHIBITION/interfaces/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.sol/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.json +36 -68
  46. package/artifacts/contracts/engine-registry/CoreRegistryV1.sol/CoreRegistryV1.json +12 -12
  47. package/artifacts/contracts/interfaces/v0.8.x/IAdminACLV0_Extended.sol/IAdminACLV0_Extended.json +140 -0
  48. package/artifacts/contracts/interfaces/v0.8.x/IBytecodeStorageReaderV2.sol/IBytecodeStorageReaderV2.json +130 -0
  49. package/artifacts/contracts/interfaces/v0.8.x/ICoreRegistryV1.sol/ICoreRegistryV1.json +6 -6
  50. package/artifacts/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol/IDependencyRegistryV0.json +71 -39
  51. package/artifacts/contracts/interfaces/v0.8.x/IEngineFactoryV0.sol/IEngineFactoryV0.json +283 -0
  52. package/artifacts/contracts/interfaces/v0.8.x/IFilteredMinterDAExpSettlementV0.sol/IFilteredMinterDAExpSettlementV0.json +12 -12
  53. package/artifacts/contracts/interfaces/v0.8.x/IFilteredMinterDAExpSettlementV1.sol/IFilteredMinterDAExpSettlementV1.json +12 -12
  54. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3.sol/IGenArt721CoreContractV3.json +30 -62
  55. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Base.sol/IGenArt721CoreContractV3_Base.json +30 -62
  56. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine.sol/IGenArt721CoreContractV3_Engine.json +170 -104
  57. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex.sol/IGenArt721CoreContractV3_Engine_Flex.json +170 -104
  58. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex_PreV3p2.sol/IGenArt721CoreContractV3_Engine_Flex_PreV3p2.json +1028 -0
  59. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_PreV3p2.sol/IGenArt721CoreContractV3_Engine_PreV3p2.json +741 -0
  60. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_ProjectFinance.sol/IGenArt721CoreContractV3_ProjectFinance.json +87 -0
  61. package/artifacts/contracts/interfaces/v0.8.x/IGenArt721Minter_PBAB.sol/IGenArt721Minter_PBAB.json +279 -0
  62. package/artifacts/contracts/interfaces/v0.8.x/IMinterFilterV1.sol/IMinterFilterV1.json +22 -22
  63. package/artifacts/contracts/interfaces/v0.8.x/IPseudorandomAtomic.sol/IPseudorandomAtomic.json +1 -1
  64. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol/ISharedMinterDAExpSettlementV0.json +26 -101
  65. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAExpV0.sol/ISharedMinterDAExpV0.json +1 -57
  66. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDALinV0.sol/ISharedMinterDALinV0.json +1 -57
  67. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterDAV0.sol/ISharedMinterDAV0.json +2 -21
  68. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterHolderERC20V0.sol/ISharedMinterHolderERC20V0.json +158 -0
  69. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterHolderV0.sol/ISharedMinterHolderV0.json +15 -90
  70. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterMerkleV0.sol/ISharedMinterMerkleV0.json +10 -36
  71. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterRAMV0.sol/ISharedMinterRAMV0.json +62 -0
  72. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterRequired.sol/ISharedMinterRequired.json +37 -0
  73. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterSEAV0.sol/ISharedMinterSEAV0.json +4 -236
  74. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterSimplePurchaseV0.sol/ISharedMinterSimplePurchaseV0.json +5 -5
  75. package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterV0.sol/ISharedMinterV0.json +7 -423
  76. package/artifacts/contracts/interfaces/v0.8.x/ISharedRandomizerV0.sol/ISharedRandomizerV0.json +17 -17
  77. package/artifacts/contracts/interfaces/v0.8.x/ISplitAtomicFactoryV0.sol/ISplitAtomicFactoryV0.json +170 -0
  78. package/artifacts/contracts/interfaces/v0.8.x/ISplitAtomicV0.sol/ISplitAtomicV0.json +126 -0
  79. package/artifacts/contracts/interfaces/v0.8.x/ISplitProviderV0.sol/ISplitProviderV0.json +98 -0
  80. package/artifacts/contracts/interfaces/v0.8.x/integration-refs/splits-0x-v2/ISplitFactoryV2.sol/ISplitFactoryV2.json +123 -0
  81. package/artifacts/contracts/libs/integration-refs/delegation-registry/DelegationRegistry.sol/DelegationRegistry.json +2 -2
  82. package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeMock.sol/GnosisSafeMock.json +2 -2
  83. package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeProxyFactoryMock.sol/GnosisSafeProxyFactoryMock.json +2 -2
  84. package/artifacts/contracts/libs/integration-refs/gnosis-safe/MultiSendMock.sol/MultiSendMock.json +2 -2
  85. package/artifacts/contracts/libs/integration-refs/weth9/weth9.sol/WETH9_.json +2 -2
  86. package/artifacts/contracts/libs/v0.8.x/ABHelpers.sol/ABHelpers.json +2 -2
  87. package/artifacts/contracts/libs/v0.8.x/AuthLib.sol/AuthLib.json +2 -2
  88. package/artifacts/contracts/libs/v0.8.x/BitMap.sol/BitMaps256.json +10 -0
  89. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV0.sol/BytecodeStorage.json +2 -2
  90. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV1.sol/BytecodeStorageReader.json +2 -2
  91. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV1.sol/BytecodeStorageWriter.json +2 -2
  92. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV2.sol/BytecodeStorageReader.json +214 -0
  93. package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV2.sol/BytecodeStorageWriter.json +10 -0
  94. package/artifacts/contracts/libs/v0.8.x/Bytes32Strings.sol/Bytes32Strings.json +2 -2
  95. package/artifacts/contracts/libs/v0.8.x/DependencyRegistryStorageLib.sol/DependencyRegistryStorageLib.json +10 -0
  96. package/artifacts/contracts/libs/v0.8.x/ERC721_PackedHashSeed.sol/ERC721_PackedHashSeed.json +2 -2
  97. package/artifacts/contracts/libs/v0.8.x/ERC721_PackedHashSeedV1.sol/ERC721_PackedHashSeedV1.json +444 -0
  98. package/artifacts/contracts/libs/v0.8.x/PackedBools.sol/PackedBools.json +10 -0
  99. package/artifacts/contracts/libs/v0.8.x/SSTORE2.sol/SSTORE2.json +2 -2
  100. package/artifacts/contracts/libs/v0.8.x/V3FlexLib.sol/V3FlexLib.json +208 -0
  101. package/artifacts/contracts/libs/v0.8.x/minter-libs/DAExpLib.sol/DAExpLib.json +60 -3
  102. package/artifacts/contracts/libs/v0.8.x/minter-libs/DALib.sol/DALib.json +30 -0
  103. package/artifacts/contracts/libs/v0.8.x/minter-libs/DALinLib.sol/DALinLib.json +60 -3
  104. package/artifacts/contracts/libs/v0.8.x/minter-libs/GenericMinterEventsLib.sol/GenericMinterEventsLib.json +346 -0
  105. package/artifacts/contracts/libs/v0.8.x/minter-libs/MaxInvocationsLib.sol/MaxInvocationsLib.json +29 -3
  106. package/artifacts/contracts/libs/v0.8.x/minter-libs/MerkleLib.sol/MerkleLib.json +30 -3
  107. package/artifacts/contracts/libs/v0.8.x/minter-libs/PolyptychLib.sol/PolyptychLib.json +2 -2
  108. package/artifacts/contracts/libs/v0.8.x/minter-libs/RAMLib.sol/RAMLib.json +398 -0
  109. package/artifacts/contracts/libs/v0.8.x/minter-libs/SEALib.sol/SEALib.json +254 -3
  110. package/artifacts/contracts/libs/v0.8.x/minter-libs/SetPriceLib.sol/SetPriceLib.json +48 -3
  111. package/artifacts/contracts/libs/v0.8.x/minter-libs/SettlementExpLib.sol/SettlementExpLib.json +41 -3
  112. package/artifacts/contracts/libs/v0.8.x/minter-libs/SplitFundsLib.sol/SplitFundsLib.json +35 -3
  113. package/artifacts/contracts/libs/v0.8.x/minter-libs/TokenHolderLib.sol/TokenHolderLib.json +79 -3
  114. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV1.sol/MinterFilterV1.json +2 -2
  115. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV2.sol/MinterFilterV2.json +41 -41
  116. package/artifacts/contracts/minter-suite/Minters/MinterDAExpHolderV5.sol/MinterDAExpHolderV5.json +66 -632
  117. package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV3.sol/MinterDAExpSettlementV3.json +67 -594
  118. package/artifacts/contracts/minter-suite/Minters/MinterDAExpV5.sol/MinterDAExpV5.json +33 -524
  119. package/artifacts/contracts/minter-suite/Minters/MinterDALinHolderV5.sol/MinterDALinHolderV5.json +66 -632
  120. package/artifacts/contracts/minter-suite/Minters/MinterDALinV5.sol/MinterDALinV5.json +33 -524
  121. package/artifacts/contracts/minter-suite/Minters/MinterRAMV0.sol/MinterRAMV0.json +1374 -0
  122. package/artifacts/contracts/minter-suite/Minters/MinterSEAV1.sol/MinterSEAV1.json +56 -722
  123. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20V5.sol/MinterSetPriceERC20V5.json +58 -454
  124. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceHolderV5.sol/MinterSetPriceHolderV5.json +61 -552
  125. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceMerkleV5.sol/MinterSetPriceMerkleV5.json +55 -497
  126. package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychERC20V5.sol/MinterSetPricePolyptychERC20V5.json +110 -571
  127. package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychV5.sol/MinterSetPricePolyptychV5.json +69 -560
  128. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceV5.sol/MinterSetPriceV5.json +28 -444
  129. package/artifacts/contracts/minter-suite/Minters/one-off/MinterSetPriceV5_SingleCore.sol/MinterSetPriceV5_SingleCore.json +417 -0
  130. package/artifacts/contracts/mock/BytecodeV2LibCallsMock.sol/BytecodeV2LibCallsMock.json +154 -0
  131. package/artifacts/contracts/mock/BytecodeV2TextCR_DMock.sol/BytecodeV2TextCR_DMock.json +428 -0
  132. package/artifacts/contracts/mock/DummySharedMinter.sol/DummySharedMinter.json +2 -2
  133. package/artifacts/contracts/mock/ERC20Mock.sol/ERC20Mock.json +2 -2
  134. package/artifacts/contracts/mock/ForceSendMock.sol/ForceSendMock.json +24 -0
  135. package/artifacts/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol/GenArt721CoreV3_Engine_IncorrectCoreType.json +4 -9
  136. package/artifacts/contracts/mock/Mock0xSplitsV2PullFactory.sol/Mock0xSplitsV2PullFactory.json +149 -0
  137. package/artifacts/contracts/mock/Mock0xSplitsV2Splitter.sol/Mock0xSplitsV2Splitter.json +99 -0
  138. package/artifacts/contracts/mock/MockAdminACLV0.sol/MockAdminACLV0Events.json +20 -2
  139. package/artifacts/contracts/mock/MockAdminACLV0_PROHIBITION.sol/MockAdminACLV0Events_PROHIBITION.json +20 -2
  140. package/artifacts/contracts/mock/OriginRegisterMock.sol/OriginRegisterMock.json +2 -2
  141. package/artifacts/contracts/mock/RandomizerV2_NoAssignMock.sol/RandomizerV2_NoAssignMock.json +2 -2
  142. package/artifacts/contracts/mock/ReentrancyGenArt721MinterMock.sol/ReentrancyGenArt721MinterMock.json +100 -0
  143. package/artifacts/contracts/mock/ReentrancyHolderMock.sol/ReentrancyHolderMock.json +2 -2
  144. package/artifacts/contracts/mock/ReentrancyHolderMockShared.sol/ReentrancyHolderMockShared.json +136 -0
  145. package/artifacts/contracts/mock/ReentrancyMerkleMock.sol/ReentrancyMerkleMock.json +2 -2
  146. package/artifacts/contracts/mock/ReentrancyMerkleMockShared.sol/ReentrancyMerkleMockShared.json +105 -0
  147. package/artifacts/contracts/mock/ReentrancyMock.sol/ReentrancyMock.json +2 -2
  148. package/artifacts/contracts/mock/ReentrancyMockShared.sol/ReentrancyMockShared.json +100 -0
  149. package/artifacts/contracts/mock/ReentrancySEAMock.sol/ReentrancySEAAutoBidderMock.json +2 -2
  150. package/artifacts/contracts/mock/ReentrancySEAMockShared.sol/ReentrancySEAAutoBidderMockShared.json +69 -0
  151. package/artifacts/contracts/mock/ReentrancySplitterMocks.sol/ReentrancySplitterDrainETHMock.json +54 -0
  152. package/artifacts/contracts/mock/ReentrancySplitterMocks.sol/ReentrancySplitterSendETHMock.json +54 -0
  153. package/artifacts/contracts/randomizer/deprecated/PolyptychRandomizerV0.sol/BasicPolyptychRandomizerV0.json +2 -2
  154. package/artifacts/contracts/randomizer/deprecated/RandomizerV2.sol/BasicRandomizerV2.json +2 -2
  155. package/artifacts/contracts/randomizer/primitive/PseudorandomAtomicBasic.sol/PseudorandomAtomic.json +2 -2
  156. package/artifacts/contracts/randomizer/shared/SharedRandomizerV0.sol/SharedRandomizerV0.json +19 -19
  157. package/artifacts/contracts/split/SplitAtomicFactoryV0.sol/SplitAtomicFactoryV0.json +203 -0
  158. package/artifacts/contracts/split/SplitAtomicV0.sol/SplitAtomicV0.json +168 -0
  159. package/artifacts/contracts/split/split-provider/SplitProviderV0.sol/SplitProviderV0.json +141 -0
  160. package/contracts/AdminACLV0.sol +6 -2
  161. package/contracts/AdminACLV1.sol +2 -2
  162. package/contracts/DependencyRegistryV0.sol +737 -390
  163. package/contracts/{GenArt721CoreV3.sol → archive/GenArt721CoreV3.sol} +56 -20
  164. package/contracts/{explorations → archive}/GenArt721CoreV3_Explorations.sol +49 -13
  165. package/contracts/{minter-suite → archive/minter-suite}/Minters/MinterBase_v0_1_1.sol +4 -4
  166. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDAExp}/MinterDAExpV4.sol +4 -4
  167. package/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol +4 -4
  168. package/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV1.sol +5 -5
  169. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDAExpSettlement}/MinterDAExpSettlementV2.sol +9 -62
  170. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterDALin}/MinterDALinV4.sol +4 -4
  171. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterHolder}/MinterHolderV4.sol +5 -5
  172. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterMerkle}/MinterMerkleV5.sol +5 -5
  173. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterPolyptych}/MinterPolyptychV0.sol +7 -7
  174. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSEA}/MinterSEAV0.sol +13 -13
  175. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSetPrice}/MinterSetPriceV4.sol +4 -4
  176. package/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V0.sol +82 -10
  177. package/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V1.sol +82 -10
  178. package/contracts/{minter-suite/Minters → archive/minter-suite/Minters/MinterSetPriceERC20}/MinterSetPriceERC20V4.sol +88 -21
  179. package/contracts/engine/V2/GenArt721MinterBurner_PBAB.sol +81 -22
  180. package/contracts/engine/V2/GenArt721Minter_PBAB.sol +80 -22
  181. package/contracts/engine/V3/EngineFactoryV0.sol +419 -0
  182. package/contracts/engine/V3/GenArt721CoreV3_Engine.sol +893 -493
  183. package/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol +1053 -655
  184. package/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol +7 -13
  185. package/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol +5 -11
  186. package/contracts/engine/V3/forks/PROHIBITION/interfaces/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.sol +2 -2
  187. package/contracts/engine-registry/CoreRegistryV1.sol +58 -65
  188. package/contracts/interfaces/v0.8.x/IAdminACLV0_Extended.sol +20 -0
  189. package/contracts/interfaces/v0.8.x/IBytecodeStorageReaderV2.sol +23 -0
  190. package/contracts/interfaces/v0.8.x/ICoreRegistryV1.sol +6 -8
  191. package/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol +48 -43
  192. package/contracts/interfaces/v0.8.x/IEngineFactoryV0.sol +124 -0
  193. package/contracts/interfaces/v0.8.x/IFilteredMinterDAExpSettlementV0.sol +1 -3
  194. package/contracts/interfaces/v0.8.x/IFilteredMinterDAExpSettlementV1.sol +1 -3
  195. package/contracts/interfaces/v0.8.x/IFilteredMinterDAExpV1.sol +1 -3
  196. package/contracts/interfaces/v0.8.x/IFilteredMinterDALinV1.sol +1 -3
  197. package/contracts/interfaces/v0.8.x/IFilteredMinterHolderV2.sol +1 -3
  198. package/contracts/interfaces/v0.8.x/IFilteredMinterMerkleV2.sol +1 -3
  199. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Base.sol +115 -11
  200. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine.sol +84 -8
  201. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex.sol +26 -8
  202. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex_PreV3p2.sol +141 -0
  203. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_PreV3p2.sol +78 -0
  204. package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_ProjectFinance.sol +47 -0
  205. package/contracts/interfaces/v0.8.x/IGenArt721Minter_PBAB.sol +91 -0
  206. package/contracts/interfaces/v0.8.x/IMinterFilterV1.sol +25 -25
  207. package/contracts/interfaces/v0.8.x/IPseudorandomAtomic.sol +1 -3
  208. package/contracts/interfaces/v0.8.x/ISharedMinterDAExpSettlementV0.sol +30 -20
  209. package/contracts/interfaces/v0.8.x/ISharedMinterDAExpV0.sol +1 -14
  210. package/contracts/interfaces/v0.8.x/ISharedMinterDALinV0.sol +1 -15
  211. package/contracts/interfaces/v0.8.x/ISharedMinterDAV0.sol +2 -8
  212. package/contracts/interfaces/v0.8.x/ISharedMinterHolderERC20V0.sol +47 -0
  213. package/contracts/interfaces/v0.8.x/ISharedMinterHolderV0.sol +15 -43
  214. package/contracts/interfaces/v0.8.x/ISharedMinterMerkleV0.sol +10 -20
  215. package/contracts/interfaces/v0.8.x/ISharedMinterRAMV0.sol +23 -0
  216. package/contracts/interfaces/v0.8.x/ISharedMinterRequired.sol +20 -0
  217. package/contracts/interfaces/v0.8.x/ISharedMinterSEAV0.sol +1 -67
  218. package/contracts/interfaces/v0.8.x/ISharedMinterSimplePurchaseV0.sol +5 -5
  219. package/contracts/interfaces/v0.8.x/ISharedMinterV0.sol +18 -160
  220. package/contracts/interfaces/v0.8.x/ISharedRandomizerV0.sol +37 -37
  221. package/contracts/interfaces/v0.8.x/ISplitAtomicFactoryV0.sol +81 -0
  222. package/contracts/interfaces/v0.8.x/ISplitAtomicV0.sol +72 -0
  223. package/contracts/interfaces/v0.8.x/ISplitProviderV0.sol +49 -0
  224. package/contracts/interfaces/v0.8.x/integration-refs/splits-0x-v2/ISplitFactoryV2.sol +62 -0
  225. package/contracts/libs/v0.8.x/ABHelpers.sol +31 -17
  226. package/contracts/libs/v0.8.x/AuthLib.sol +101 -102
  227. package/contracts/libs/v0.8.x/BitMap.sol +112 -0
  228. package/contracts/libs/v0.8.x/BytecodeStorageV2.sol +593 -0
  229. package/contracts/libs/v0.8.x/Bytes32Strings.sol +5 -5
  230. package/contracts/libs/v0.8.x/DependencyRegistryStorageLib.sol +90 -0
  231. package/contracts/libs/v0.8.x/ERC721_PackedHashSeedV1.sol +591 -0
  232. package/contracts/libs/v0.8.x/PackedBools.sol +42 -0
  233. package/contracts/libs/v0.8.x/V3FlexLib.sol +591 -0
  234. package/contracts/libs/v0.8.x/minter-libs/DAExpLib.sol +162 -39
  235. package/contracts/libs/v0.8.x/minter-libs/DALib.sol +26 -0
  236. package/contracts/libs/v0.8.x/minter-libs/DALinLib.sol +139 -37
  237. package/contracts/libs/v0.8.x/minter-libs/GenericMinterEventsLib.sol +171 -0
  238. package/contracts/libs/v0.8.x/minter-libs/MaxInvocationsLib.sol +299 -158
  239. package/contracts/libs/v0.8.x/minter-libs/MerkleLib.sol +268 -55
  240. package/contracts/libs/v0.8.x/minter-libs/PolyptychLib.sol +138 -58
  241. package/contracts/libs/v0.8.x/minter-libs/RAMLib.sol +2927 -0
  242. package/contracts/libs/v0.8.x/minter-libs/SEALib.sol +796 -123
  243. package/contracts/libs/v0.8.x/minter-libs/SetPriceLib.sol +131 -13
  244. package/contracts/libs/v0.8.x/minter-libs/SettlementExpLib.sol +607 -224
  245. package/contracts/libs/v0.8.x/minter-libs/SplitFundsLib.sol +494 -330
  246. package/contracts/libs/v0.8.x/minter-libs/TokenHolderLib.sol +217 -78
  247. package/contracts/minter-suite/MinterFilter/MinterFilterV2.sol +358 -309
  248. package/contracts/minter-suite/Minters/MinterDAExpHolderV5.sol +391 -491
  249. package/contracts/minter-suite/Minters/MinterDAExpSettlementV3.sol +396 -632
  250. package/contracts/minter-suite/Minters/MinterDAExpV5.sol +212 -273
  251. package/contracts/minter-suite/Minters/MinterDALinHolderV5.sol +393 -488
  252. package/contracts/minter-suite/Minters/MinterDALinV5.sol +220 -277
  253. package/contracts/minter-suite/Minters/MinterRAMV0.sol +1205 -0
  254. package/contracts/minter-suite/Minters/MinterSEAV1.sol +329 -677
  255. package/contracts/minter-suite/Minters/MinterSetPriceERC20V5.sol +287 -303
  256. package/contracts/minter-suite/Minters/MinterSetPriceHolderV5.sol +355 -446
  257. package/contracts/minter-suite/Minters/MinterSetPriceMerkleV5.sol +328 -416
  258. package/contracts/minter-suite/Minters/MinterSetPricePolyptychERC20V5.sol +552 -622
  259. package/contracts/minter-suite/Minters/MinterSetPricePolyptychV5.sol +429 -553
  260. package/contracts/minter-suite/Minters/MinterSetPriceV5.sol +180 -227
  261. package/contracts/minter-suite/Minters/one-off/MinterSetPriceV5_SingleCore.sol +446 -0
  262. package/contracts/mock/BytecodeV2LibCallsMock.sol +128 -0
  263. package/contracts/mock/BytecodeV2TextCR_DMock.sol +316 -0
  264. package/contracts/mock/ForceSendMock.sol +22 -0
  265. package/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol +3 -10
  266. package/contracts/mock/Mock0xSplitsV2PullFactory.sol +75 -0
  267. package/contracts/mock/Mock0xSplitsV2Splitter.sol +47 -0
  268. package/contracts/mock/MockAdminACLV0.sol +21 -0
  269. package/contracts/mock/MockAdminACLV0_PROHIBITION.sol +21 -0
  270. package/contracts/mock/ReentrancyGenArt721MinterMock.sol +47 -0
  271. package/contracts/mock/ReentrancyHolderMockShared.sol +59 -0
  272. package/contracts/mock/ReentrancyMerkleMockShared.sol +58 -0
  273. package/contracts/mock/ReentrancyMockShared.sol +48 -0
  274. package/contracts/mock/ReentrancySEAMockShared.sol +40 -0
  275. package/contracts/mock/ReentrancySplitterMocks.sol +67 -0
  276. package/contracts/randomizer/primitive/PseudorandomAtomicBasic.sol +1 -1
  277. package/contracts/randomizer/shared/SharedRandomizerV0.sol +79 -71
  278. package/contracts/split/SplitAtomicFactoryV0.sol +121 -0
  279. package/contracts/split/SplitAtomicV0.sol +265 -0
  280. package/contracts/split/split-provider/SplitProviderV0.sol +201 -0
  281. package/package.json +79 -45
  282. package/artifacts/contracts/GenArt721CoreV3.sol/GenArt721CoreV3.json +0 -1965
  283. package/artifacts/contracts/explorations/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +0 -1939
  284. package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV2.sol/MinterDAExpSettlementV2.json +0 -1127
  285. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20V4.sol/MinterSetPriceERC20V4.json +0 -768
  286. package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverride.sol/GenArt721RoyaltyOverride.json +0 -208
  287. package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverride_PBAB.sol/GenArt721RoyaltyOverride_PBAB.json +0 -301
  288. package/contracts/royalty-registry/GenArt721RoyaltyOverride.sol +0 -168
  289. package/contracts/royalty-registry/GenArt721RoyaltyOverride_PBAB.sol +0 -221
@@ -1,13 +1,15 @@
1
1
  // SPDX-License-Identifier: LGPL-3.0-only
2
2
  // Created By: Art Blocks Inc.
3
3
 
4
- import "./MaxInvocationsLib.sol";
5
- import "./DAExpLib.sol";
6
- import "./SplitFundsLib.sol";
4
+ pragma solidity ^0.8.0;
7
5
 
8
- import "@openzeppelin-4.7/contracts/utils/math/SafeCast.sol";
6
+ import {MaxInvocationsLib} from "./MaxInvocationsLib.sol";
7
+ import {DAExpLib} from "./DAExpLib.sol";
8
+ import {SplitFundsLib} from "./SplitFundsLib.sol";
9
+ import {AuthLib} from "../AuthLib.sol";
10
+ import {GenericMinterEventsLib} from "./GenericMinterEventsLib.sol";
9
11
 
10
- pragma solidity ^0.8.0;
12
+ import {SafeCast} from "@openzeppelin-4.7/contracts/utils/math/SafeCast.sol";
11
13
 
12
14
  /**
13
15
  * @title Art Blocks Settlement Library for Exponential Auctions
@@ -20,6 +22,26 @@ pragma solidity ^0.8.0;
20
22
 
21
23
  library SettlementExpLib {
22
24
  using SafeCast for uint256;
25
+ /**
26
+ * @notice Receipt updated event. Emitted when a receipt is updated.
27
+ * @param purchaser purchaser address of updated receipt
28
+ * @param projectId project ID of updated receipt
29
+ * @param coreContract core contract address of updated receipt
30
+ * @param numPurchased new number of tokens purchased on project
31
+ * @param netPosted new net funds posted on project
32
+ */
33
+ event ReceiptUpdated(
34
+ address indexed purchaser,
35
+ uint256 indexed projectId,
36
+ address indexed coreContract,
37
+ uint24 numPurchased,
38
+ uint256 netPosted
39
+ );
40
+
41
+ // position of Settlement Exp Lib storage, using a diamond storage pattern
42
+ // for this library
43
+ bytes32 constant SETTLEMENT_EXP_LIB_STORAGE_POSITION =
44
+ keccak256("settlementexplib.storage");
23
45
 
24
46
  bytes32 internal constant CONFIG_CURRENT_SETTLED_PRICE =
25
47
  "currentSettledPrice";
@@ -42,10 +64,30 @@ library SettlementExpLib {
42
64
  // In that case, the new auction will be required to have a starting
43
65
  // price less than or equal to this value, if one or more purchases
44
66
  // have been made on this minter.
45
- // @dev max uint128 allows for > 1e51 ETH (much more than max supply)
46
- // This enables struct packing, and is consistent with prices value
47
- // limits in DAExpLib's DAProjectConfig struct.
48
- uint128 latestPurchasePrice;
67
+ // @dev max uint88 ~= 3e26 Wei = ~300 million ETH, which is well above
68
+ // the expected prices of any NFT mint in the foreseeable future.
69
+ // This enables struct packing.
70
+ uint88 latestPurchasePrice;
71
+ // Track per-project fund balance, in wei. This is used as a redundant
72
+ // backstop to prevent one project from draining the minter's balance
73
+ // of ETH from other projects, which is a worthwhile failsafe on this
74
+ // shared minter.
75
+ // @dev max uint88 ~= 3e26 Wei = ~300 million ETH, which is well above
76
+ // the expected revenues for a single auction.
77
+ // This enables struct packing.
78
+ uint88 projectBalance;
79
+ // field to store the number of purchases that have been made on the
80
+ // project, on this minter. This is used to track if unexpected mints
81
+ // from sources other than this minter occur during an auction.
82
+ // @dev max uint24 allows for > max project supply of 1 million tokens
83
+ // @dev important to pack this field with other fields updated during a
84
+ // purchase, for gas efficiency
85
+ uint24 numPurchasesOnMinter;
86
+ // The number of tokens to be auctioned for the project on this minter.
87
+ // This is defined as the number of invocations remaining at the time
88
+ // of a project's first mint.
89
+ uint24 numTokensToBeAuctioned;
90
+ // --- @dev end of storage slot ---
49
91
  }
50
92
 
51
93
  // The Receipt struct tracks the state of a user's settlement on a given
@@ -58,101 +100,10 @@ library SettlementExpLib {
58
100
  uint24 numPurchased;
59
101
  }
60
102
 
61
- /**
62
- * This function updates the _receipt to include `msg.value` and increments
63
- * the number of tokens purchased by 1. It then checks that the updated
64
- * receipt is valid (i.e. sufficient funds have been posted for the
65
- * number of tokens purchased on the updated receipt), and reverts if not.
66
- * The new receipt net posted and num purchased are then returned to make
67
- * the values available in a gas-efficient manner to the caller of this
68
- * function.
69
- * @param _receipt Receipt struct for the user on the project being checked
70
- * @param _currentPriceInWei current price of token in Wei
71
- * @return netPosted total funds posted by user on project (that have not
72
- * been yet settled), including the current transaction
73
- * @return numPurchased total number of tokens purchased by user on
74
- * project, including the current transaction
75
- */
76
- function validateReceiptEffects(
77
- Receipt storage _receipt,
78
- uint256 _currentPriceInWei
79
- ) internal returns (uint232 netPosted, uint24 numPurchased) {
80
- // in memory copy + update
81
- netPosted = (_receipt.netPosted + msg.value).toUint232();
82
- numPurchased = _receipt.numPurchased + 1;
83
-
84
- // require sufficient payment on project
85
- require(
86
- netPosted >= numPurchased * _currentPriceInWei,
87
- "Min value to mint req."
88
- );
89
-
90
- // update Receipt in storage
91
- // @dev overflow checks are not required since the added values cannot
92
- // be enough to overflow due to maximum invocations or supply of ETH
93
- _receipt.netPosted = netPosted;
94
- _receipt.numPurchased = numPurchased;
95
- }
96
-
97
- /**
98
- * @notice Emergency override function that allows a sellout price of a
99
- * completed auction to be reduced to something below current latest
100
- * purchase price, but gte base price. This is useful in the case that a
101
- * project's auction artifically sold out at a price higher than the
102
- * project's base price, and the artist wishes to allow settlement at a
103
- * lower price (and thus lower settlement revenues, increasing purchaser
104
- * returned settlement funds by the minter to collectors).
105
- * @param _projectId Project ID to reduce auction sellout price for.
106
- * @param _newSelloutPrice New sellout price to set for the auction. Must
107
- * be less than the current sellout price, gte base price.
108
- */
109
- function adminEmergencyReduceSelloutPrice(
110
- uint256 _projectId,
111
- address _coreContract,
112
- uint128 _newSelloutPrice,
113
- SettlementAuctionProjectConfig storage _settlementAuctionProjectConfig,
114
- MaxInvocationsLib.MaxInvocationsProjectConfig
115
- storage _maxInvocationsProjectConfig,
116
- DAExpLib.DAProjectConfig storage _DAProjectConfig
117
- ) internal returns (bool maxInvocationsUpdated) {
118
- // CHECKS
119
- require(
120
- !_settlementAuctionProjectConfig.auctionRevenuesCollected,
121
- "Only before revenues collected"
122
- );
123
-
124
- // refresh max invocations, updating any local values that are
125
- // illogical with respect to the current core contract state, and
126
- // ensuring that local hasMaxBeenInvoked is accurate.
127
- maxInvocationsUpdated = MaxInvocationsLib.refreshMaxInvocations(
128
- _projectId,
129
- _coreContract,
130
- _maxInvocationsProjectConfig
131
- );
132
- require(
133
- _newSelloutPrice >= _DAProjectConfig.basePrice,
134
- "Only gte base price"
135
- );
136
- // require max invocations has been reached
137
- require(
138
- _maxInvocationsProjectConfig.maxHasBeenInvoked,
139
- "Auction must be complete"
140
- );
141
- // @dev no need to check that auction max invocations has been reached,
142
- // because if it was, the sellout price will be zero, and the following
143
- // check will fail.
144
- require(
145
- _newSelloutPrice <
146
- _settlementAuctionProjectConfig.latestPurchasePrice,
147
- "May only reduce sellout price"
148
- );
149
- // ensure _newSelloutPrice is non-zero
150
- // @dev this is a redundant check since minter doesn't allow base price
151
- // of zero, but is included in case that logic changes in the future.
152
- // @dev no coverage else branch of following line because redundant
153
- require(_newSelloutPrice > 0, "Only sellout prices > 0");
154
- // EFFECTS
155
- _settlementAuctionProjectConfig.latestPurchasePrice = _newSelloutPrice;
103
+ // Diamond storage pattern is used in this library
104
+ struct SettlementExpLibStorage {
105
+ mapping(address coreContract => mapping(uint256 projectId => SettlementAuctionProjectConfig)) settlementAuctionProjectConfigs;
106
+ mapping(address walletAddress => mapping(address coreContract => mapping(uint256 projectId => Receipt))) receipts;
156
107
  }
157
108
 
158
109
  /**
@@ -160,111 +111,423 @@ library SettlementExpLib {
160
111
  * marks the auction as having had its revenues collected.
161
112
  * IMPORTANT - this affects state and distributes revenue funds, so it
162
113
  * performs all three of CHECKS, EFFECTS and INTERACTIONS.
163
- * @param _projectId Project ID to get revenues for
164
- * @param _coreContract Core contract address
165
- * @param _settlementAuctionProjectConfig SettlementAuctionProjectConfig
166
- * struct for the project.
167
- * @param _maxInvocationsProjectConfig MaxInvocationProjectConfig struct
168
- * for the project.
169
- * @param _DAProjectConfig DAProjectConfig struct for the project.
170
- * @param _isEngine bool indicating whether the core contract is an engine
171
- * @return maxInvocationsUpdated whether or not the minter's local max
172
- * invocations state was updated during this function call.
114
+ * This function updates a project's balance to reflect the amount of
115
+ * revenues distributed, and will revert if underflow occurs.
116
+ * @param projectId Project ID to get revenues for
117
+ * @param coreContract Core contract address
173
118
  */
174
119
  function distributeArtistAndAdminRevenues(
175
- uint256 _projectId,
176
- address _coreContract,
177
- SettlementAuctionProjectConfig storage _settlementAuctionProjectConfig,
178
- MaxInvocationsLib.MaxInvocationsProjectConfig
179
- storage _maxInvocationsProjectConfig,
180
- DAExpLib.DAProjectConfig storage _DAProjectConfig,
181
- bool _isEngine
182
- ) internal returns (bool maxInvocationsUpdated) {
120
+ uint256 projectId,
121
+ address coreContract
122
+ ) internal {
123
+ // load the project's settlement auction config
124
+ SettlementAuctionProjectConfig
125
+ storage settlementAuctionProjectConfig = getSettlementAuctionProjectConfig({
126
+ projectId: projectId,
127
+ coreContract: coreContract
128
+ });
183
129
  // require revenues to not have already been collected
184
130
  require(
185
- !_settlementAuctionProjectConfig.auctionRevenuesCollected,
131
+ !settlementAuctionProjectConfig.auctionRevenuesCollected,
186
132
  "Revenues already collected"
187
133
  );
188
134
  // refresh max invocations, updating any local values that are
189
135
  // illogical with respect to the current core contract state, and
190
- // ensuring that local hasMaxBeenInvoked is accurate.
191
- maxInvocationsUpdated = MaxInvocationsLib.refreshMaxInvocations(
192
- _projectId,
193
- _coreContract,
194
- _maxInvocationsProjectConfig
195
- );
136
+ // ensuring that local maxHasBeenInvoked is accurate.
137
+ MaxInvocationsLib.refreshMaxInvocations({
138
+ projectId: projectId,
139
+ coreContract: coreContract
140
+ });
196
141
 
197
142
  // get the current net price of the auction - reverts if no auction
198
143
  // is configured.
199
- // @dev we use _getPriceUnsafe here, since we just safely synced the
144
+ // @dev we use getPriceUnsafe here, since we just safely synced the
200
145
  // project's max invocations and maxHasBeenInvoked, which guarantees
201
- // an accurate price calculation from _getPriceUnsafe, while being
202
- // more gas efficient than _getPriceSafe.
146
+ // an accurate price calculation from getPriceUnsafe, while being
147
+ // more gas efficient than getPriceSafe.
203
148
  // @dev price is guaranteed <= _projectConfig.latestPurchasePrice,
204
149
  // since this minter enforces monotonically decreasing purchase prices.
205
- uint256 _price = getPriceUnsafe({
206
- _settlementAuctionProjectConfig: _settlementAuctionProjectConfig,
207
- _maxInvocationsProjectConfig: _maxInvocationsProjectConfig,
208
- _DAProjectConfig: _DAProjectConfig
150
+ // @dev we can trust maxHasBeenInvoked, since we just
151
+ // refreshed it above with refreshMaxInvocations, preventing any
152
+ // false negatives
153
+ bool maxHasBeenInvoked = MaxInvocationsLib.getMaxHasBeenInvoked({
154
+ projectId: projectId,
155
+ coreContract: coreContract
156
+ });
157
+ uint256 price = getPriceUnsafe({
158
+ projectId: projectId,
159
+ coreContract: coreContract,
160
+ maxHasBeenInvoked: maxHasBeenInvoked
209
161
  });
210
162
  // if the price is not base price, require that the auction have
211
163
  // reached max invocations. This prevents premature withdrawl
212
164
  // before final auction price is possible to know.
213
- if (_price != _DAProjectConfig.basePrice) {
214
- // @dev we can trust maxHasBeenInvoked, since we just
215
- // refreshed it above with refreshMaxInvocations, preventing any
216
- // false negatives
217
- require(
218
- _maxInvocationsProjectConfig.maxHasBeenInvoked,
219
- "Active auction not yet sold out"
220
- );
165
+ uint256 basePrice = DAExpLib.getAuctionBasePrice({
166
+ projectId: projectId,
167
+ coreContract: coreContract
168
+ });
169
+ if (price != basePrice) {
170
+ require(maxHasBeenInvoked, "Active auction not yet sold out");
171
+ // if max has been invoked, but all tokens to be auctioned were not
172
+ // sold, nonstandard activity has been detected (e.g. project max
173
+ // invocations were reduced on core contract after initial
174
+ // purchase, purchases were made on a different minter after
175
+ // initial purchase, etc.), which could artifically inflate
176
+ // sellout price and harm purchasers. In that case, we should
177
+ // not revert (since max invocations have been reached), but we
178
+ // should require admin to be the caller of this function.
179
+ // This provides separation of powers to protect collectors who
180
+ // participated in the auction.
181
+ // Note that if admin determines the artist has been malicious,
182
+ // admin should replace artist address with a wallet controlled by
183
+ // admin on the core contract, update payee address on the core,
184
+ // collect revenues using this function, then distribute any
185
+ // additional settlement funds to purchasers at admin's discretion.
186
+ if (
187
+ !_allTokensToBeAuctionedWereSold(settlementAuctionProjectConfig)
188
+ ) {
189
+ AuthLib.onlyCoreAdminACL({
190
+ coreContract: coreContract,
191
+ sender: msg.sender,
192
+ contract_: address(this),
193
+ selector: bytes4(
194
+ keccak256(
195
+ "distributeArtistAndAdminRevenues(uint256,address)"
196
+ )
197
+ )
198
+ });
199
+ }
221
200
  } else {
222
- uint128 basePrice = _DAProjectConfig.basePrice;
223
- // base price of zero indicates no sales, since base price of zero
224
- // is not allowed when configuring an auction.
225
- // @dev no coverage else branch of following line because redundant
201
+ // base price of zero indicates that the auction has not been configured,
202
+ // since base price of zero is not allowed when configuring an auction.
203
+ // @dev no coverage else branch of following line because redundant,
204
+ // acknowledge redundant check
226
205
  require(basePrice > 0, "Only latestPurchasePrice > 0");
227
206
  // if the price is base price, the auction is valid and may be claimed
228
207
  // update the latest purchase price to the base price, to ensure
229
208
  // the base price is used for all future settlement calculations
230
209
  // EFFECTS
231
- _settlementAuctionProjectConfig.latestPurchasePrice = basePrice;
210
+ // @dev base price value was just loaded from uint88 in storage,
211
+ // so no safe cast required
212
+ settlementAuctionProjectConfig.latestPurchasePrice = uint88(
213
+ basePrice
214
+ );
215
+ // notify indexing service of settled price update
216
+ // @dev acknowledge that this event may be emitted prior to
217
+ // other state updates in this function, but that is okay because
218
+ // the settled price is the only value updated with this event
219
+ emit GenericMinterEventsLib.ConfigValueSet({
220
+ projectId: projectId,
221
+ coreContract: coreContract,
222
+ key: CONFIG_CURRENT_SETTLED_PRICE,
223
+ value: basePrice
224
+ });
232
225
  }
233
- _settlementAuctionProjectConfig.auctionRevenuesCollected = true;
226
+ settlementAuctionProjectConfig.auctionRevenuesCollected = true;
234
227
  // calculate the artist and admin revenues
235
- uint256 netRevenues = _settlementAuctionProjectConfig
236
- .numSettleableInvocations * _price;
228
+ uint256 netRevenues = settlementAuctionProjectConfig
229
+ .numSettleableInvocations * price;
230
+
231
+ // reduce project balance by the amount of ETH being distributed
232
+ // @dev underflow checked automatically in solidity ^0.8
233
+ settlementAuctionProjectConfig.projectBalance -= netRevenues.toUint88();
234
+
237
235
  // INTERACTIONS
238
- SplitFundsLib.splitRevenuesETH({
239
- _projectId: _projectId,
240
- _valueInWei: netRevenues,
241
- _coreContract: _coreContract,
242
- _isEngine: _isEngine
236
+ SplitFundsLib.splitRevenuesETHNoRefund({
237
+ projectId: projectId,
238
+ valueInWei: netRevenues,
239
+ coreContract: coreContract
240
+ });
241
+
242
+ emit GenericMinterEventsLib.ConfigValueSet({
243
+ projectId: projectId,
244
+ coreContract: coreContract,
245
+ key: CONFIG_AUCTION_REVENUES_COLLECTED,
246
+ value: true
247
+ });
248
+ }
249
+
250
+ /**
251
+ * @notice Reclaims excess settlement funds for purchaser wallet
252
+ * `purchaserAddress` on project `projectId`. Excess settlement funds are
253
+ * the amount of funds posted by the purchaser that are in excess of the
254
+ * amount required to settle the purchaser's tokens on the project.
255
+ * Excess settlement funds are sent to address `to`, and function reverts
256
+ * if send fails.
257
+ * @param projectId Project ID to reclaim excess settlement funds for
258
+ * @param coreContract Core contract address
259
+ * @param purchaserAddress Address to reclaim excess settlement funds for
260
+ * @param to Address to send excess settlement funds to
261
+ * @param doSendFunds If true, sends funds to `to`. If false, only updates
262
+ * the receipt to reflect the new funds posted, and returns the amount of
263
+ * excess settlement funds that still need to be sent to `to`.
264
+ * @return remainingUnsentExcessSettlementFunds amount of excess settlement
265
+ * funds that still need to be sent to `to`, in wei. If doSendFunds, this
266
+ * value will be zero, because funds will have been sent to `to`.
267
+ */
268
+ function reclaimProjectExcessSettlementFundsTo(
269
+ address payable to,
270
+ uint256 projectId,
271
+ address coreContract,
272
+ address purchaserAddress,
273
+ bool doSendFunds
274
+ ) internal returns (uint256 remainingUnsentExcessSettlementFunds) {
275
+ (
276
+ uint256 excessSettlementFunds,
277
+ uint256 requiredAmountPosted
278
+ ) = getProjectExcessSettlementFunds({
279
+ projectId: projectId,
280
+ coreContract: coreContract,
281
+ walletAddress: purchaserAddress
282
+ });
283
+
284
+ SettlementAuctionProjectConfig
285
+ storage settlementAuctionProjectConfig = getSettlementAuctionProjectConfig({
286
+ projectId: projectId,
287
+ coreContract: coreContract
288
+ });
289
+ Receipt storage receipt = getReceipt({
290
+ walletAddress: purchaserAddress,
291
+ coreContract: coreContract,
292
+ projectId: projectId
293
+ });
294
+
295
+ uint232 newNetPosted = requiredAmountPosted.toUint232();
296
+ receipt.netPosted = newNetPosted;
297
+
298
+ // reduce project balance by the amount of ETH being distributed
299
+ // @dev underflow checked automatically in solidity ^0.8
300
+ settlementAuctionProjectConfig.projectBalance -= excessSettlementFunds
301
+ .toUint88();
302
+
303
+ emit ReceiptUpdated({
304
+ purchaser: purchaserAddress,
305
+ projectId: projectId,
306
+ coreContract: coreContract,
307
+ numPurchased: receipt.numPurchased,
308
+ netPosted: newNetPosted
243
309
  });
244
- // @dev maxInvocationsUpdated is returned
310
+
311
+ // INTERACTIONS
312
+ if (doSendFunds) {
313
+ bool success_;
314
+ (success_, ) = to.call{value: excessSettlementFunds}("");
315
+ require(success_, "Reclaiming failed");
316
+ } else {
317
+ // return unsent funds amount to caller
318
+ remainingUnsentExcessSettlementFunds = excessSettlementFunds;
319
+ }
245
320
  }
246
321
 
247
322
  /**
248
- *
249
- * @param _settlementAuctionProjectConfig SettlementAuctionProjectConfig
250
- * struct for the project.
251
- * Reverts if no purchases have been made on the project by the collector
252
- * being checked.
253
- * @param _receipt Receipt struct for the collector on the project being
254
- * checked
323
+ * @notice Performs updates to project state prior to a mint being
324
+ * initiated, during a purchase transaction. Specifically, this updates the
325
+ * number of purchases on this minter (and populates expected number of
326
+ * tokens to be auctioned if this is first purchase), increases the
327
+ * project's balance by the amount of funds sent with the transaction,
328
+ * updates the purchaser's receipt to reflect the new funds posted, checks
329
+ * that the updated receipt has sufficient funds posted for the number of
330
+ * tokens to be purchased after this transaction, and updates the project's
331
+ * latest purchase price to the current price of the token.
332
+ * Reverts if insuffient funds have been posted for the number of tokens to
333
+ * be purchased after this transaction.
334
+ * @param projectId Project ID to perform the pre-mint effects for
335
+ * @param coreContract Core contract address
336
+ * @param currentPriceInWei current price of token in Wei
337
+ * @param msgValue msg.value sent with mint transaction
338
+ * @param purchaserAddress Wallet address of purchaser
339
+ */
340
+ function preMintEffects(
341
+ uint256 projectId,
342
+ address coreContract,
343
+ uint256 currentPriceInWei,
344
+ uint256 msgValue,
345
+ address purchaserAddress
346
+ ) internal {
347
+ // load the project's settlement auction config and receipt
348
+ SettlementAuctionProjectConfig
349
+ storage settlementAuctionProjectConfig = getSettlementAuctionProjectConfig({
350
+ projectId: projectId,
351
+ coreContract: coreContract
352
+ });
353
+
354
+ // if this is the first purchase on this minter, set the number of
355
+ // of tokens to be auctioned to:
356
+ // (minter max invocations) - (current core contract invocations)
357
+ if (settlementAuctionProjectConfig.numPurchasesOnMinter == 0) {
358
+ // get up-to-data invocation data from core contract
359
+ (
360
+ uint256 coreInvocations,
361
+ uint256 coreMaxInvocations
362
+ ) = MaxInvocationsLib.coreContractInvocationData({
363
+ projectId: projectId,
364
+ coreContract: coreContract
365
+ });
366
+ // snap chalkline on the number of tokens to be auctioned on this
367
+ // minter
368
+ // @dev acknowledge that this value may be stale if the core
369
+ // contract's max invocations were reduced since the last time
370
+ // the minter's max invocations were updated, but that is desired.
371
+ // That case would be classified as "nonstandard activity", so we
372
+ // want to require admin to be the withdrawer of revenues in that
373
+ // case.
374
+ uint256 minterMaxInvocations = MaxInvocationsLib.getMaxInvocations({
375
+ projectId: projectId,
376
+ coreContract: coreContract
377
+ });
378
+ // @dev prefer to use stale value minterMaxInvocations here, since
379
+ // if it is stale, the artist could have decreased max invocations
380
+ // on core contract at last moment unexpectedly, and we want to
381
+ // equire admin to be the withdrawer of revenues in that case.
382
+ settlementAuctionProjectConfig.numTokensToBeAuctioned = uint24(
383
+ minterMaxInvocations - coreInvocations
384
+ );
385
+ // edge case: minter max invocations > core contract max invocations.
386
+ // could be caused by either:
387
+ // - core contract max invocations reduced after configuring
388
+ // auction (this is generally accidental by artist), and did not
389
+ // subsequently update minter's max invocations
390
+ // - artist decreased max invocations on core contract at last
391
+ // moment prior to this initial mint (this is suspicious)
392
+ // either way, we want to update minter's local max invocations, so
393
+ // that the minter returns the most up-to-date value from function
394
+ // `projectMaxHasBeenInvoked` in the future.
395
+ // @dev note that this edge case will end up being classified as
396
+ // "nonstandard activity" in case of sellout above base price, and
397
+ // will require admin concurrence in those cases.
398
+ if (minterMaxInvocations > coreMaxInvocations) {
399
+ // update minter's max invocations to match core contract
400
+ MaxInvocationsLib.syncProjectMaxInvocationsToCore({
401
+ projectId: projectId,
402
+ coreContract: coreContract
403
+ });
404
+ }
405
+ }
406
+
407
+ // increment the number of purchases on this minter during every purchase
408
+ settlementAuctionProjectConfig.numPurchasesOnMinter++;
409
+
410
+ // update project balance
411
+ settlementAuctionProjectConfig.projectBalance += msgValue.toUint88();
412
+
413
+ _validateReceiptEffects({
414
+ walletAddress: purchaserAddress,
415
+ projectId: projectId,
416
+ coreContract: coreContract,
417
+ currentPriceInWei: currentPriceInWei
418
+ });
419
+
420
+ // update latest purchase price (on this minter) in storage
421
+ // @dev this is used to enforce monotonically decreasing purchase price
422
+ // across multiple auctions
423
+ settlementAuctionProjectConfig.latestPurchasePrice = currentPriceInWei
424
+ .toUint88();
425
+ }
426
+
427
+ /**
428
+ * @notice Performs updates to project state after a mint has been
429
+ * successfully completed.
430
+ * Specifically, this function distributes revenues if the auction revenues
431
+ * have been collected, or increments the number of settleable invocations
432
+ * if the auction revenues have not been collected.
433
+ * @param projectId Project ID to perform post-mint updates for
434
+ * @param coreContract Core contract address
435
+ * @param currentPriceInWei current price of token in Wei (the value to be
436
+ * distributed if revenues have been collected)
437
+ */
438
+ function postMintInteractions(
439
+ uint256 projectId,
440
+ address coreContract,
441
+ uint256 currentPriceInWei
442
+ ) internal {
443
+ // load the project's settlement auction config
444
+ SettlementAuctionProjectConfig
445
+ storage settlementAuctionProjectConfig = getSettlementAuctionProjectConfig({
446
+ projectId: projectId,
447
+ coreContract: coreContract
448
+ });
449
+ if (settlementAuctionProjectConfig.auctionRevenuesCollected) {
450
+ // if revenues have been collected, split revenues immediately.
451
+ // @dev note that we are guaranteed to be at auction base price,
452
+ // since we know we didn't sellout prior to this tx.
453
+ // note that we don't refund msg.sender here, since a separate
454
+ // settlement mechanism is provided on this minter, unrelated to
455
+ // msg.value
456
+
457
+ // reduce project balance by the amount of ETH being distributed
458
+ // @dev specifically, this is not decremented by msg.value, as
459
+ // msg.sender is not refunded here
460
+ // @dev underflow checked automatically in solidity ^0.8
461
+ settlementAuctionProjectConfig.projectBalance -= currentPriceInWei
462
+ .toUint88();
463
+
464
+ // INTERACTIONS
465
+ SplitFundsLib.splitRevenuesETHNoRefund({
466
+ projectId: projectId,
467
+ valueInWei: currentPriceInWei,
468
+ coreContract: coreContract
469
+ });
470
+ } else {
471
+ // increment the number of settleable invocations that will be
472
+ // claimable by the artist and admin once auction is validated.
473
+ // do not split revenue here since will be claimed at a later time.
474
+ settlementAuctionProjectConfig.numSettleableInvocations++;
475
+ // @dev project balance is unaffected because no funds are distributed
476
+ }
477
+ }
478
+
479
+ /**
480
+ * @notice Returns number of purchases that have been made on the minter, for a
481
+ * given project.
482
+ * @param projectId The id of the project.
483
+ * @param coreContract The address of the core contract.
484
+ */
485
+ function getNumPurchasesOnMinter(
486
+ uint256 projectId,
487
+ address coreContract
488
+ ) internal view returns (uint256) {
489
+ SettlementAuctionProjectConfig
490
+ storage settlementAuctionProjectConfig = getSettlementAuctionProjectConfig({
491
+ projectId: projectId,
492
+ coreContract: coreContract
493
+ });
494
+ return settlementAuctionProjectConfig.numPurchasesOnMinter;
495
+ }
496
+
497
+ /**
498
+ * @notice Returns the excess settlement funds for purchaser wallet
499
+ * `walletAddress` on project `projectId`. Excess settlement funds are
500
+ * the amount of funds posted by the purchaser that are in excess of the
501
+ * amount required to settle the purchaser's tokens on the project.
502
+ * @param projectId Project ID to get revenues for
503
+ * @param coreContract Core contract address
504
+ * @param walletAddress Address to get excess settlement funds for
255
505
  * @return excessSettlementFunds excess settlement funds, in wei
256
506
  * @return requiredAmountPosted required amount to be posted by user, in wei
257
507
  */
258
508
  function getProjectExcessSettlementFunds(
259
- SettlementAuctionProjectConfig storage _settlementAuctionProjectConfig,
260
- Receipt storage _receipt
509
+ uint256 projectId,
510
+ address coreContract,
511
+ address walletAddress
261
512
  )
262
513
  internal
263
514
  view
264
515
  returns (uint256 excessSettlementFunds, uint256 requiredAmountPosted)
265
516
  {
517
+ // load the project's settlement auction config
518
+ SettlementAuctionProjectConfig
519
+ storage _settlementAuctionProjectConfig = getSettlementAuctionProjectConfig({
520
+ projectId: projectId,
521
+ coreContract: coreContract
522
+ });
523
+ // load the user's receipt
524
+ Receipt storage receipt = getReceipt({
525
+ walletAddress: walletAddress,
526
+ projectId: projectId,
527
+ coreContract: coreContract
528
+ });
266
529
  // require that a user has purchased at least one token on this project
267
- uint256 numPurchased = _receipt.numPurchased;
530
+ uint256 numPurchased = receipt.numPurchased;
268
531
  require(numPurchased > 0, "No purchases made by this address");
269
532
 
270
533
  uint256 currentSettledTokenPrice = _settlementAuctionProjectConfig
@@ -273,12 +536,11 @@ library SettlementExpLib {
273
536
  // calculate the excess settlement funds amount
274
537
  // implicit overflow/underflow checks in solidity ^0.8
275
538
  requiredAmountPosted = numPurchased * currentSettledTokenPrice;
276
- excessSettlementFunds = _receipt.netPosted - requiredAmountPosted;
277
- return (excessSettlementFunds, requiredAmountPosted);
539
+ excessSettlementFunds = receipt.netPosted - requiredAmountPosted;
278
540
  }
279
541
 
280
542
  /**
281
- * @notice Gets price of minting a token on project `_projectId` given
543
+ * @notice Gets price of minting a token on project `projectId` given
282
544
  * the project's AuctionParameters and current block timestamp.
283
545
  * Reverts if auction has not yet started or auction is unconfigured, and
284
546
  * local hasMaxBeenInvoked is false and revenues have not been withdrawn.
@@ -286,105 +548,226 @@ library SettlementExpLib {
286
548
  * hasMaxBeenInvoked is stale and returning a false negative.
287
549
  * @dev when an accurate price is required regardless of the current state
288
550
  * state of the locally cached minter max invocations, use the less gas
289
- * efficient function `_getPriceSafe`.
290
- * @param _settlementAuctionProjectConfig SettlementAuctionProjectConfig
291
- * struct for the project.
292
- * @param _maxInvocationsProjectConfig MaxInvocationsProjectConfig
293
- * struct for the project.
294
- * @param _DAProjectConfig DAProjectConfig struct for the project.
551
+ * efficient function `getPriceSafe`.
552
+ * @param projectId Project ID to get price of token for.
553
+ * @param coreContract Core contract address to get price for.
554
+ * @param maxHasBeenInvoked Bool representing if maxHasBeenInvoked for the
555
+ * project.
295
556
  * @return uint256 current price of token in Wei, accurate if minter max
296
557
  * invocations are up to date
297
558
  * @dev This method calculates price decay using a linear interpolation
298
559
  * of exponential decay based on the artist-provided half-life for price
299
- * decay, `_priceDecayHalfLifeSeconds`.
560
+ * decay, `priceDecayHalfLifeSeconds`.
300
561
  */
301
562
  function getPriceUnsafe(
302
- SettlementAuctionProjectConfig storage _settlementAuctionProjectConfig,
303
- MaxInvocationsLib.MaxInvocationsProjectConfig
304
- storage _maxInvocationsProjectConfig,
305
- DAExpLib.DAProjectConfig storage _DAProjectConfig
563
+ uint256 projectId,
564
+ address coreContract,
565
+ bool maxHasBeenInvoked
306
566
  ) internal view returns (uint256) {
567
+ // load the project's settlement auction config
568
+ SettlementAuctionProjectConfig
569
+ storage settlementAuctionProjectConfig = getSettlementAuctionProjectConfig({
570
+ projectId: projectId,
571
+ coreContract: coreContract
572
+ });
307
573
  // return latest purchase price if:
308
574
  // - minter is aware of a sold-out auction (without updating max
309
575
  // invocation value)
310
576
  // - auction revenues have been collected, at which point the latest
311
577
  // purchase price will never change again
312
578
  if (
313
- _maxInvocationsProjectConfig.maxHasBeenInvoked ||
314
- _settlementAuctionProjectConfig.auctionRevenuesCollected
579
+ maxHasBeenInvoked ||
580
+ settlementAuctionProjectConfig.auctionRevenuesCollected
315
581
  ) {
316
- return _settlementAuctionProjectConfig.latestPurchasePrice;
582
+ return settlementAuctionProjectConfig.latestPurchasePrice;
317
583
  }
318
584
  // otherwise calculate price based on current block timestamp and
319
585
  // auction configuration
320
586
  // @dev this will revert if auction has not yet started or auction is
321
587
  // unconfigured, which is relied upon for security.
322
- return DAExpLib.getPriceExp({_DAProjectConfig: _DAProjectConfig});
588
+ return
589
+ DAExpLib.getPriceExp({
590
+ projectId: projectId,
591
+ coreContract: coreContract
592
+ });
323
593
  }
324
594
 
325
595
  /**
326
- * @notice Gets price of minting a token on project `_projectId` given
596
+ * @notice Gets price of minting a token on project `projectId` given
327
597
  * the project's AuctionParameters and current block timestamp.
328
598
  * This is labeled as "safe", because price is guaranteed to be accurate
329
599
  * even in the case of a stale locally cached minter max invocations.
330
600
  * Reverts if auction has not yet started or auction is unconfigured, and
331
601
  * auction has not sold out or revenues have not been withdrawn.
332
- * @dev This method is less gas efficient than `_getPriceUnsafe`, but is
602
+ * @dev This method is less gas efficient than `getPriceUnsafe`, but is
333
603
  * guaranteed to be accurate.
334
- * @param _projectId Project ID to get price of token for.
604
+ * @param projectId Project ID to get price of token for.
605
+ * @param coreContract Core contract address to get price for.
335
606
  * @return tokenPriceInWei current price of token in Wei
336
607
  * @dev This method calculates price decay using a linear interpolation
337
608
  * of exponential decay based on the artist-provided half-life for price
338
- * decay, `_priceDecayHalfLifeSeconds`.
609
+ * decay, `priceDecayHalfLifeSeconds`.
339
610
  */
340
611
  function getPriceSafe(
341
- uint256 _projectId,
342
- address _coreContract,
343
- SettlementAuctionProjectConfig storage _settlementAuctionProjectConfig,
344
- MaxInvocationsLib.MaxInvocationsProjectConfig
345
- storage _maxInvocationsProjectConfig,
346
- DAExpLib.DAProjectConfig storage _DAProjectConfig
612
+ uint256 projectId,
613
+ address coreContract
347
614
  ) internal view returns (uint256 tokenPriceInWei) {
348
- // accurately check if project has sold out
349
- if (
350
- MaxInvocationsLib.projectMaxHasBeenInvokedSafe({
351
- _projectId: _projectId,
352
- _coreContract: _coreContract,
353
- _maxInvocationsProjectConfig: _maxInvocationsProjectConfig
354
- })
355
- ) {
356
- // max invocations have been reached, return the latest purchased
357
- // price
358
- tokenPriceInWei = _settlementAuctionProjectConfig
359
- .latestPurchasePrice;
360
- } else {
361
- // if not sold out, return the current price via getPriceUnsafe
362
- tokenPriceInWei = getPriceUnsafe({
363
- _settlementAuctionProjectConfig: _settlementAuctionProjectConfig,
364
- _maxInvocationsProjectConfig: _maxInvocationsProjectConfig,
365
- _DAProjectConfig: _DAProjectConfig
615
+ // get up-to-date maxHasBeenInvoked state from core contract
616
+ bool maxHasBeenInvokedSafe = MaxInvocationsLib
617
+ .projectMaxHasBeenInvokedSafe({
618
+ projectId: projectId,
619
+ coreContract: coreContract
366
620
  });
367
- }
368
- return tokenPriceInWei;
621
+ // get price using up-to-date maxHasBeenInvoked state
622
+ tokenPriceInWei = getPriceUnsafe({
623
+ projectId: projectId,
624
+ coreContract: coreContract,
625
+ maxHasBeenInvoked: maxHasBeenInvokedSafe
626
+ });
369
627
  }
370
628
 
371
629
  /**
372
- * Returns if a new auction's start price is valid, given the current
630
+ * @notice Returns if a new auction's start price is valid, given the current
373
631
  * state of the project's settlement auction configuration.
374
- * @param _startPrice starting price of new auction, in wei
375
- * @param _settlementAuctionProjectConfig SettlementAuctionProjectConfig
376
- * struct for the project being configured for a new auction.
632
+ * @dev does not check for non-zero start price, since startPrice > basePrice
633
+ * is checked in DAExpLib.
634
+ * @param projectId Project ID to check start price for
635
+ * @param coreContract Core contract address to check start price for
636
+ * @param startPrice starting price of new auction, in wei
377
637
  */
378
638
  function isValidStartPrice(
379
- uint256 _startPrice,
380
- SettlementAuctionProjectConfig storage _settlementAuctionProjectConfig
639
+ uint256 projectId,
640
+ address coreContract,
641
+ uint256 startPrice
381
642
  ) internal view returns (bool) {
643
+ // load the project's settlement auction config
644
+ SettlementAuctionProjectConfig
645
+ storage settlementAuctionProjectConfig = getSettlementAuctionProjectConfig({
646
+ projectId: projectId,
647
+ coreContract: coreContract
648
+ });
382
649
  // If previous purchases have been made, require monotonically
383
650
  // decreasing purchase prices to preserve settlement and revenue
384
651
  // claiming logic. Since base price is always non-zero, if
385
652
  // latestPurchasePrice is zero, then no previous purchases have been
386
653
  // made, and startPrice may be set to any value.
387
- return (_settlementAuctionProjectConfig.latestPurchasePrice == 0 || // never purchased
388
- _startPrice <= _settlementAuctionProjectConfig.latestPurchasePrice);
654
+ // @dev DAExpLib checks that startPrice > basePrice, so no need to
655
+ // check for non-zero startPrice here.
656
+ return (settlementAuctionProjectConfig.latestPurchasePrice == 0 || // never purchased
657
+ startPrice <= settlementAuctionProjectConfig.latestPurchasePrice);
658
+ }
659
+
660
+ /**
661
+ * @notice Loads the SettlementAuctionProjectConfig for a given project and
662
+ * core contract.
663
+ * @param projectId Project Id to get config for
664
+ * @param coreContract Core contract address to get config for
665
+ */
666
+ function getSettlementAuctionProjectConfig(
667
+ uint256 projectId,
668
+ address coreContract
669
+ ) internal view returns (SettlementAuctionProjectConfig storage) {
670
+ return s().settlementAuctionProjectConfigs[coreContract][projectId];
671
+ }
672
+
673
+ /**
674
+ * @notice Loads the Receipt for a given user, project and core contract.
675
+ * @param walletAddress User address to get receipt for
676
+ * @param projectId Project Id to get config for
677
+ * @param coreContract Core contract address to get config for
678
+ */
679
+ function getReceipt(
680
+ address walletAddress,
681
+ uint256 projectId,
682
+ address coreContract
683
+ ) internal view returns (Receipt storage) {
684
+ return s().receipts[walletAddress][coreContract][projectId];
685
+ }
686
+
687
+ /**
688
+ * @notice Return the storage struct for reading and writing. This library
689
+ * uses a diamond storage pattern when managing storage.
690
+ * @return storageStruct The SettlementExpLibStorage struct.
691
+ */
692
+ function s()
693
+ internal
694
+ pure
695
+ returns (SettlementExpLibStorage storage storageStruct)
696
+ {
697
+ bytes32 position = SETTLEMENT_EXP_LIB_STORAGE_POSITION;
698
+ assembly ("memory-safe") {
699
+ storageStruct.slot := position
700
+ }
701
+ }
702
+
703
+ /**
704
+ * @notice Returns if all tokens to be auctioned were sold, for a given project.
705
+ * Returns false if the number of tokens to be auctioned is zero, since
706
+ * that is the default value for unconfigured values.
707
+ * @param settlementAuctionProjectConfig The SettlementAuctionProjectConfig
708
+ * struct of the project to check.
709
+ */
710
+ function _allTokensToBeAuctionedWereSold(
711
+ SettlementAuctionProjectConfig storage settlementAuctionProjectConfig
712
+ ) private view returns (bool) {
713
+ // @dev load numAllocations into memory for gas efficiency
714
+ uint256 numTokensToBeAuctioned = settlementAuctionProjectConfig
715
+ .numTokensToBeAuctioned;
716
+ return
717
+ numTokensToBeAuctioned > 0 &&
718
+ settlementAuctionProjectConfig.numPurchasesOnMinter ==
719
+ numTokensToBeAuctioned;
720
+ }
721
+
722
+ /**
723
+ * @notice This function updates the receipt to include `msg.value` and increments
724
+ * the number of tokens purchased by 1. It then checks that the updated
725
+ * receipt is valid (i.e. sufficient funds have been posted for the
726
+ * number of tokens purchased on the updated receipt), and reverts if not.
727
+ * The new receipt net posted and num purchased are then returned to make
728
+ * the values available in a gas-efficient manner to the caller of this
729
+ * function.
730
+ * @param walletAddress Address of user to update receipt for
731
+ * @param projectId Project ID to update receipt for
732
+ * @param coreContract Core contract address
733
+ * @param currentPriceInWei current price of token in Wei
734
+ * @return netPosted total funds posted by user on project (that have not
735
+ * been yet settled), including the current transaction
736
+ * @return numPurchased total number of tokens purchased by user on
737
+ * project, including the current transaction
738
+ */
739
+ function _validateReceiptEffects(
740
+ address walletAddress,
741
+ uint256 projectId,
742
+ address coreContract,
743
+ uint256 currentPriceInWei
744
+ ) private returns (uint232 netPosted, uint24 numPurchased) {
745
+ Receipt storage receipt = getReceipt({
746
+ walletAddress: walletAddress,
747
+ projectId: projectId,
748
+ coreContract: coreContract
749
+ });
750
+ // in memory copy + update
751
+ netPosted = (receipt.netPosted + msg.value).toUint232();
752
+ numPurchased = receipt.numPurchased + 1;
753
+
754
+ // require sufficient payment on project
755
+ require(
756
+ netPosted >= numPurchased * currentPriceInWei,
757
+ "Min value to mint req."
758
+ );
759
+
760
+ // update Receipt in storage
761
+ receipt.netPosted = netPosted;
762
+ receipt.numPurchased = numPurchased;
763
+
764
+ // emit event indicating new receipt state
765
+ emit ReceiptUpdated({
766
+ purchaser: msg.sender,
767
+ projectId: projectId,
768
+ coreContract: coreContract,
769
+ numPurchased: numPurchased,
770
+ netPosted: netPosted
771
+ });
389
772
  }
390
773
  }