@artblocks/contracts 1.0.2 → 1.0.3
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.
- package/README.md +30 -2
- package/artifacts/contracts/AdminACLV0.sol/AdminACLV0.json +2 -2
- package/artifacts/contracts/AdminACLV1.sol/AdminACLV1.json +2 -2
- package/artifacts/contracts/DependencyRegistryV0.sol/DependencyRegistryV0.json +22 -4
- package/artifacts/contracts/GenArt721CoreV3.sol/GenArt721CoreV3.json +42 -5
- package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV2.sol/MinterDAExpV2.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV3.sol/MinterDAExpV3.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol/MinterDAExpSettlementV0.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV1.sol/MinterDAExpSettlementV1.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV2.sol/MinterDALinV2.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV3.sol/MinterDALinV3.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV1.sol/MinterHolderV1.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV2.sol/MinterHolderV2.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV3.sol/MinterHolderV3.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV1.sol/MinterMerkleV1.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV2.sol/MinterMerkleV2.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV3.sol/MinterMerkleV3.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV4.sol/MinterMerkleV4.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV2.sol/MinterSetPriceV2.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV3.sol/MinterSetPriceV3.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol/MinterSetPriceERC20V2.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol/MinterSetPriceERC20V3.json +2 -2
- package/artifacts/contracts/engine/{GenArt721CoreV2_ENGINE_FLEX.sol → V2/GenArt721CoreV2_ENGINE_FLEX.sol}/GenArt721CoreV2_ENGINE_FLEX.json +3 -3
- package/artifacts/contracts/engine/{GenArt721CoreV2_PBAB.sol → V2/GenArt721CoreV2_PBAB.sol}/GenArt721CoreV2_PBAB.json +3 -3
- package/artifacts/contracts/engine/{GenArt721CoreV2_PRTNR.sol → V2/GenArt721CoreV2_PRTNR.sol}/GenArt721CoreV2_PRTNR.json +3 -3
- package/artifacts/contracts/engine/{GenArt721MinterBurner_PBAB.sol → V2/GenArt721MinterBurner_PBAB.sol}/GenArt721MinterBurner_PBAB.json +3 -3
- package/artifacts/contracts/engine/{GenArt721MinterDAExp_PBAB.sol → V2/GenArt721MinterDAExp_PBAB.sol}/GenArt721MinterDAExp_PBAB.json +3 -3
- package/artifacts/contracts/engine/{GenArt721Minter_PBAB.sol → V2/GenArt721Minter_PBAB.sol}/GenArt721Minter_PBAB.json +3 -3
- package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine.sol/GenArt721CoreV3_Engine.json +1960 -0
- package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol/GenArt721CoreV3_Engine_Flex.json +2247 -0
- package/artifacts/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol/GenArt721CoreV3_Engine_Flex_PROOF.json +2247 -0
- package/artifacts/contracts/engine/V3/forks/PROHIBITION/AdminACLV0_PROHIBITION.sol/AdminACLV0_PROHIBITION.json +401 -0
- package/artifacts/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol/GenArt721CoreV3_Engine_Flex_PROHIBITION.json +2281 -0
- package/artifacts/contracts/engine/V3/forks/PROHIBITION/interfaces/IAdminACLV0_PROHIBITION.sol/IAdminACLV0_PROHIBITION.json +359 -0
- package/artifacts/contracts/engine/V3/forks/PROHIBITION/interfaces/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.sol/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.json +1094 -0
- package/artifacts/contracts/engine-registry/CoreRegistryV1.sol/CoreRegistryV1.json +242 -0
- package/artifacts/contracts/engine-registry/EngineRegistryV0.sol/EngineRegistryV0.json +2 -2
- package/artifacts/contracts/explorations/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +41 -4
- package/artifacts/contracts/interfaces/0.8.x/IBytecodeStorageReader.sol/IBytecodeStorageReader.json +111 -0
- package/artifacts/contracts/interfaces/0.8.x/ICoreRegistryV1.sol/ICoreRegistryV1.json +172 -0
- package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterSEAV0.sol/IFilteredMinterSEAV0.json +55 -53
- package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreContractExposesHashSeed.sol/IGenArt721CoreContractExposesHashSeed.json +30 -0
- package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreContractV3.sol/IGenArt721CoreContractV3.json +13 -0
- package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Base.sol/IGenArt721CoreContractV3_Base.json +13 -0
- package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Engine.sol/IGenArt721CoreContractV3_Engine.json +7 -13
- package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Engine_Flex.sol/IGenArt721CoreContractV3_Engine_Flex.json +7 -13
- package/artifacts/contracts/interfaces/0.8.x/IMinterFilterV1.sol/IMinterFilterV1.json +429 -0
- package/artifacts/contracts/interfaces/0.8.x/IPseudorandomAtomic.sol/IPseudorandomAtomic.json +30 -0
- package/artifacts/contracts/interfaces/0.8.x/IRandomizer_V3CoreBase.sol/IRandomizer_V3CoreBase.json +24 -0
- package/artifacts/contracts/interfaces/0.8.x/ISharedRandomizerV0.sol/ISharedRandomizerV0.json +207 -0
- package/artifacts/contracts/libs/0.8.x/{BytecodeStorage.sol → BytecodeStorageV0.sol}/BytecodeStorage.json +3 -3
- package/artifacts/contracts/libs/0.8.x/BytecodeStorageV1.sol/BytecodeStorageReader.json +163 -0
- package/artifacts/contracts/libs/0.8.x/BytecodeStorageV1.sol/BytecodeStorageWriter.json +10 -0
- package/artifacts/contracts/libs/0.8.x/Bytes32Strings.sol/Bytes32Strings.json +2 -2
- package/artifacts/contracts/libs/0.8.x/ERC721_PackedHashSeed.sol/ERC721_PackedHashSeed.json +2 -2
- package/artifacts/contracts/libs/0.8.x/SSTORE2.sol/SSTORE2.json +10 -0
- package/artifacts/contracts/libs/integration-refs/delegation-registry/DelegationRegistry.sol/DelegationRegistry.json +2 -2
- package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeMock.sol/GnosisSafeMock.json +2 -2
- package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeProxyFactoryMock.sol/GnosisSafeProxyFactoryMock.json +2 -2
- package/artifacts/contracts/libs/integration-refs/gnosis-safe/MultiSendMock.sol/MultiSendMock.json +2 -2
- package/artifacts/contracts/libs/integration-refs/weth9/weth9.sol/WETH9_.json +2 -2
- package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV1.sol/MinterFilterV1.json +2 -2
- package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV2.sol/MinterFilterV2.json +692 -0
- package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV2.sol/MinterDAExpSettlementV2.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterDAExpV4.sol/MinterDAExpV4.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterDALinV4.sol/MinterDALinV4.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterHolderV4.sol/MinterHolderV4.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterMerkleV5.sol/MinterMerkleV5.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterPolyptychV0.sol/IGenArt721CoreContractV3WithRandomizer.json +10 -160
- package/artifacts/contracts/minter-suite/Minters/MinterPolyptychV0.sol/MinterPolyptychV0.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterSEAV0.sol/MinterSEAV0.json +59 -80
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20V4.sol/MinterSetPriceERC20V4.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceV4.sol/MinterSetPriceV4.json +2 -2
- package/artifacts/contracts/mock/{BytecodeTextCR_DMock.sol/BytecodeTextCR_DMock.json → BytecodeV0TextCR_DMock.sol/BytecodeV0TextCR_DMock.json} +4 -4
- package/artifacts/contracts/mock/BytecodeV1LibCallsMock.sol/BytecodeV1LibCallsMock.json +135 -0
- package/artifacts/contracts/mock/BytecodeV1TextCR_DMock.sol/BytecodeV1TextCR_DMock.json +301 -0
- package/artifacts/contracts/mock/DeadReceiverBidderMock.sol/DeadReceiverBidderMock.json +2 -2
- package/artifacts/contracts/mock/DeadReceiverMock.sol/DeadReceiverMock.json +2 -2
- package/artifacts/contracts/mock/DummySharedMinter.sol/DummySharedMinter.json +114 -0
- package/artifacts/contracts/mock/ERC20Mock.sol/ERC20Mock.json +2 -2
- package/artifacts/contracts/mock/GasLimitReceiverBidderMock.sol/GasLimitReceiverBidderMock.json +2 -2
- package/artifacts/contracts/mock/GasLimitReceiverMock.sol/GasLimitReceiverMock.json +2 -2
- package/artifacts/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol/GenArt721CoreV3_Engine_IncorrectCoreType.json +22 -4
- package/artifacts/contracts/mock/MockAdminACLV0.sol/MockAdminACLV0Events.json +2 -2
- package/artifacts/contracts/mock/MockAdminACLV0_PROHIBITION.sol/MockAdminACLV0Events_PROHIBITION.json +440 -0
- package/artifacts/contracts/mock/OriginRegisterMock.sol/OriginRegisterMock.json +39 -0
- package/artifacts/contracts/mock/RandomizerV2_NoAssignMock.sol/RandomizerV2_NoAssignMock.json +2 -2
- package/artifacts/contracts/mock/ReentrancyHolderMock.sol/ReentrancyHolderMock.json +2 -2
- package/artifacts/contracts/mock/ReentrancyMerkleMock.sol/ReentrancyMerkleMock.json +2 -2
- package/artifacts/contracts/mock/ReentrancyMock.sol/ReentrancyMock.json +2 -2
- package/artifacts/contracts/mock/ReentrancySEAMock.sol/ReentrancySEAAutoBidderMock.json +2 -2
- package/artifacts/contracts/mock/SSTORE2Mock.sol/SSTORE2Mock.json +118 -0
- package/artifacts/contracts/randomizer/{BasicRandomizer.sol → deprecated/BasicRandomizer.sol}/BasicRandomizer.json +3 -3
- package/artifacts/contracts/randomizer/{BasicRandomizerBase_v0_0_0.sol → deprecated/BasicRandomizerBase_v0_0_0.sol}/RandomizerBase.json +1 -1
- package/artifacts/contracts/randomizer/{PolyptychRandomizerV0.sol → deprecated/PolyptychRandomizerV0.sol}/BasicPolyptychRandomizerV0.json +3 -3
- package/artifacts/contracts/randomizer/{RandomizerV2.sol → deprecated/RandomizerV2.sol}/BasicRandomizerV2.json +3 -3
- package/artifacts/contracts/randomizer/primitive/PseudorandomAtomicBasic.sol/PseudorandomAtomic.json +30 -0
- package/artifacts/contracts/randomizer/shared/SharedRandomizerV0.sol/SharedRandomizerV0.json +231 -0
- package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverride.sol/GenArt721RoyaltyOverride.json +2 -2
- package/contracts/AdminACLV0.sol +1 -1
- package/contracts/AdminACLV1.sol +1 -1
- package/contracts/DependencyRegistryV0.sol +15 -28
- package/contracts/GenArt721CoreV3.sol +37 -34
- package/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV2.sol +1 -1
- package/contracts/archive/minter-suite/Minters/MinterDAExp/MinterDAExpV3.sol +1 -1
- package/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol +1 -1
- package/contracts/archive/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV1.sol +1 -1
- package/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV2.sol +1 -1
- package/contracts/archive/minter-suite/Minters/MinterDALin/MinterDALinV3.sol +1 -1
- package/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV1.sol +1 -1
- package/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV2.sol +1 -1
- package/contracts/archive/minter-suite/Minters/MinterHolder/MinterHolderV3.sol +1 -1
- package/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV1.sol +1 -1
- package/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV2.sol +1 -1
- package/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV3.sol +1 -1
- package/contracts/archive/minter-suite/Minters/MinterMerkle/MinterMerkleV4.sol +1 -1
- package/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV2.sol +1 -1
- package/contracts/archive/minter-suite/Minters/MinterSetPrice/MinterSetPriceV3.sol +1 -1
- package/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol +1 -1
- package/contracts/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol +1 -1
- package/contracts/engine/{GenArt721CoreV2_ENGINE_FLEX.sol → V2/GenArt721CoreV2_ENGINE_FLEX.sol} +2 -2
- package/contracts/engine/{GenArt721CoreV2_PBAB.sol → V2/GenArt721CoreV2_PBAB.sol} +2 -2
- package/contracts/engine/{GenArt721CoreV2_PRTNR.sol → V2/GenArt721CoreV2_PRTNR.sol} +3 -3
- package/contracts/engine/{GenArt721MinterBurner_PBAB.sol → V2/GenArt721MinterBurner_PBAB.sol} +2 -2
- package/contracts/engine/{GenArt721MinterDAExp_PBAB.sol → V2/GenArt721MinterDAExp_PBAB.sol} +2 -2
- package/contracts/engine/{GenArt721Minter_PBAB.sol → V2/GenArt721Minter_PBAB.sol} +2 -2
- package/contracts/{GenArt721CoreV3_Engine.sol → engine/V3/GenArt721CoreV3_Engine.sol} +29 -20
- package/contracts/{GenArt721CoreV3_Engine_Flex.sol → engine/V3/GenArt721CoreV3_Engine_Flex.sol} +30 -21
- package/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol +2293 -0
- package/contracts/engine/V3/forks/PROHIBITION/AdminACLV0_PROHIBITION.sol +281 -0
- package/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol +2354 -0
- package/contracts/engine/V3/forks/PROHIBITION/interfaces/IAdminACLV0_PROHIBITION.sol +123 -0
- package/contracts/engine/V3/forks/PROHIBITION/interfaces/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.sol +29 -0
- package/contracts/engine-registry/CoreRegistryV1.sol +254 -0
- package/contracts/engine-registry/EngineRegistryV0.sol +1 -1
- package/contracts/explorations/GenArt721CoreV3_Explorations.sol +34 -31
- package/contracts/interfaces/0.8.x/IBytecodeStorageReader.sol +62 -0
- package/contracts/interfaces/0.8.x/ICoreRegistryV1.sol +27 -0
- package/contracts/interfaces/0.8.x/IDelegationRegistry.sol +1 -1
- package/contracts/interfaces/0.8.x/IDependencyRegistryCompatibleV0.sol +1 -1
- package/contracts/interfaces/0.8.x/IDependencyRegistryV0.sol +1 -1
- package/contracts/interfaces/0.8.x/IEngineRegistryV0.sol +1 -1
- package/contracts/interfaces/0.8.x/IFilteredMinterSEAV0.sol +34 -15
- package/contracts/interfaces/0.8.x/IGenArt721CoreContractExposesHashSeed.sol +11 -0
- package/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Base.sol +3 -0
- package/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Engine.sol +0 -5
- package/contracts/interfaces/0.8.x/IMinterFilterV1.sol +158 -0
- package/contracts/interfaces/0.8.x/IPseudorandomAtomic.sol +16 -0
- package/contracts/interfaces/0.8.x/IRandomizerPolyptychV0.sol +1 -1
- package/contracts/interfaces/0.8.x/IRandomizerV2.sol +2 -5
- package/contracts/interfaces/0.8.x/IRandomizer_V3CoreBase.sol +10 -0
- package/contracts/interfaces/0.8.x/ISharedRandomizerV0.sol +105 -0
- package/contracts/libs/0.8.x/BytecodeStorageV1.sol +399 -0
- package/contracts/libs/0.8.x/SSTORE2.sol +109 -0
- package/contracts/libs/integration-refs/delegation-registry/DelegationRegistry.sol +1 -1
- package/contracts/libs/integration-refs/weth9/weth9.sol +2 -0
- package/contracts/minter-suite/MinterFilter/MinterFilterV1.sol +1 -1
- package/contracts/minter-suite/MinterFilter/MinterFilterV2.sol +756 -0
- package/contracts/minter-suite/Minters/MinterDAExpSettlementV2.sol +1 -1
- package/contracts/minter-suite/Minters/MinterDAExpV4.sol +1 -1
- package/contracts/minter-suite/Minters/MinterDALinV4.sol +1 -1
- package/contracts/minter-suite/Minters/MinterHolderV4.sol +1 -1
- package/contracts/minter-suite/Minters/MinterMerkleV5.sol +1 -1
- package/contracts/minter-suite/Minters/MinterPolyptychV0.sol +14 -13
- package/contracts/minter-suite/Minters/MinterSEAV0.sol +232 -183
- package/contracts/minter-suite/Minters/MinterSetPriceERC20V4.sol +1 -1
- package/contracts/minter-suite/Minters/MinterSetPriceV4.sol +1 -1
- package/contracts/mock/{BytecodeTextCR_DMock.sol → BytecodeV0TextCR_DMock.sol} +5 -5
- package/contracts/mock/BytecodeV1LibCallsMock.sol +114 -0
- package/contracts/mock/BytecodeV1TextCR_DMock.sol +233 -0
- package/contracts/mock/DeadReceiverBidderMock.sol +1 -1
- package/contracts/mock/DeadReceiverMock.sol +1 -1
- package/contracts/mock/DummySharedMinter.sol +75 -0
- package/contracts/mock/GasLimitReceiverBidderMock.sol +1 -1
- package/contracts/mock/GasLimitReceiverMock.sol +1 -1
- package/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol +14 -27
- package/contracts/mock/MockAdminACLV0.sol +1 -1
- package/contracts/mock/MockAdminACLV0_PROHIBITION.sol +207 -0
- package/contracts/mock/OriginRegisterMock.sol +27 -0
- package/contracts/mock/RandomizerV2_NoAssignMock.sol +2 -2
- package/contracts/mock/SSTORE2Mock.sol +93 -0
- package/contracts/randomizer/{BasicRandomizer.sol → deprecated/BasicRandomizer.sol} +1 -1
- package/contracts/randomizer/{BasicRandomizerBase_v0_0_0.sol → deprecated/BasicRandomizerBase_v0_0_0.sol} +1 -1
- package/contracts/randomizer/{PolyptychRandomizerV0.sol → deprecated/PolyptychRandomizerV0.sol} +3 -3
- package/contracts/randomizer/{RandomizerV2.sol → deprecated/RandomizerV2.sol} +3 -3
- package/contracts/randomizer/primitive/PseudorandomAtomicBasic.sol +30 -0
- package/contracts/randomizer/shared/SharedRandomizerV0.sol +245 -0
- package/package.json +23 -30
- package/.env.example +0 -17
- package/artifacts/contracts/GenArt721CoreV3_Engine.sol/GenArt721CoreV3_Engine.json +0 -1942
- package/artifacts/contracts/GenArt721CoreV3_Engine_Flex.sol/GenArt721CoreV3_Engine_Flex.json +0 -2229
- package/artifacts/contracts/engine-registry/future/EngineRegistryV1.sol/EngineRegistryV1.json +0 -109
- package/contracts/engine-registry/future/EngineRegistryV1.sol +0 -86
- /package/contracts/libs/0.8.x/{BytecodeStorage.sol → BytecodeStorageV0.sol} +0 -0
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
2
2
|
// Created By: Art Blocks Inc.
|
|
3
3
|
|
|
4
|
-
pragma solidity 0.8.
|
|
5
|
-
|
|
6
|
-
import {IWETH} from "../../interfaces/0.8.x/IWETH.sol";
|
|
4
|
+
pragma solidity 0.8.19;
|
|
7
5
|
|
|
8
6
|
import "../../interfaces/0.8.x/IGenArt721CoreContractV3_Base.sol";
|
|
9
7
|
import "../../interfaces/0.8.x/IMinterFilterV0.sol";
|
|
@@ -35,6 +33,17 @@ import "@openzeppelin-4.7/contracts/utils/math/Math.sol";
|
|
|
35
33
|
* ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
|
|
36
34
|
* ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ *
|
|
37
35
|
*********************************
|
|
36
|
+
* @notice Bid Front-Running:
|
|
37
|
+
* Collectors can front-run bids to become the highest bidder by bidding any
|
|
38
|
+
* amount sufficiently higher than the current highest bid, considering the
|
|
39
|
+
* minter-level configured value of `minterMinBidIncrementPercentage`. For
|
|
40
|
+
* instance, if current bid is 1 ETH, and collector A sends a transaction with
|
|
41
|
+
* a bid of 2.50 ETH, collector B may send a transaction with a bid of 2.499
|
|
42
|
+
* ETH, that if successfully front-runs Collector A's transaction, is able to
|
|
43
|
+
* cause collector A's transaction to revert. This is a difficult problem to
|
|
44
|
+
* get around in a decentralized system with public bids, and we have chosen to
|
|
45
|
+
* keep the minter simple and transparent, and leave it up to collectors to
|
|
46
|
+
* understand the risks of front-running and bid accordingly.
|
|
38
47
|
* @notice Token Ownership:
|
|
39
48
|
* This minter contract may own up to two tokens at a time for a given project.
|
|
40
49
|
* The first possible token owned is the token that is currently being
|
|
@@ -104,44 +113,8 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
104
113
|
/// minter version for this minter
|
|
105
114
|
string public constant minterVersion = "v0.0.1";
|
|
106
115
|
|
|
107
|
-
/// The public WETH contract address
|
|
108
|
-
/// @dev WETH is used as fallback payment method when ETH transfers are
|
|
109
|
-
/// failing during bidding process (e.g. receive function is not payable)
|
|
110
|
-
IWETH public immutable weth;
|
|
111
|
-
|
|
112
116
|
uint256 constant ONE_MILLION = 1_000_000;
|
|
113
117
|
|
|
114
|
-
// project-specific parameters
|
|
115
|
-
struct ProjectConfig {
|
|
116
|
-
bool maxHasBeenInvoked;
|
|
117
|
-
// max uint24 ~= 1.6e7, > max possible project invocations of 1e6
|
|
118
|
-
uint24 maxInvocations;
|
|
119
|
-
// time after which new auctions may be started
|
|
120
|
-
// note: new auctions must always be started with a new bid, at which
|
|
121
|
-
// point the auction will actually start
|
|
122
|
-
// @dev this is a project-level constraint, and individual auctions
|
|
123
|
-
// will each have their own start time defined in `activeAuction`
|
|
124
|
-
// max uint64 ~= 1.8e19 sec ~= 570 billion years
|
|
125
|
-
uint64 timestampStart;
|
|
126
|
-
// duration of each new auction, before any extensions due to late bids
|
|
127
|
-
uint32 auctionDurationSeconds;
|
|
128
|
-
// next token number to be auctioned, owned by minter
|
|
129
|
-
// @dev store token number to enable storage packing, as token ID can
|
|
130
|
-
// be derived from this value in combination with project ID
|
|
131
|
-
// max uint24 ~= 1.6e7, > max possible project invocations of 1e6
|
|
132
|
-
uint24 nextTokenNumber;
|
|
133
|
-
// bool to indicate if next token number has been populated, or is
|
|
134
|
-
// still default value of 0
|
|
135
|
-
// @dev required to handle edge case where next token number is 0
|
|
136
|
-
bool nextTokenNumberIsPopulated;
|
|
137
|
-
// reserve price, i.e. minimum starting bid price, in wei
|
|
138
|
-
// @dev for configured auctions, this will be gt 0, so it may be used
|
|
139
|
-
// to determine if an auction is configured
|
|
140
|
-
uint256 basePrice;
|
|
141
|
-
// active auction for project
|
|
142
|
-
Auction activeAuction;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
118
|
mapping(uint256 => ProjectConfig) public projectConfig;
|
|
146
119
|
|
|
147
120
|
// minter-wide, admin-configurable parameters
|
|
@@ -179,23 +152,12 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
179
152
|
// function to restrict access to only AdminACL allowed calls
|
|
180
153
|
// @dev defers to the ACL contract used on the core contract
|
|
181
154
|
function _onlyCoreAdminACL(bytes4 _selector) internal {
|
|
182
|
-
require(
|
|
183
|
-
genArtCoreContract_Base.adminACLAllowed(
|
|
184
|
-
msg.sender,
|
|
185
|
-
address(this),
|
|
186
|
-
_selector
|
|
187
|
-
),
|
|
188
|
-
"Only Core AdminACL allowed"
|
|
189
|
-
);
|
|
155
|
+
require(_adminACLAllowed(_selector), "Only Core AdminACL allowed");
|
|
190
156
|
}
|
|
191
157
|
|
|
192
158
|
// function to restrict access to only the artist of a project
|
|
193
159
|
function _onlyArtist(uint256 _projectId) internal view {
|
|
194
|
-
require(
|
|
195
|
-
(msg.sender ==
|
|
196
|
-
genArtCoreContract_Base.projectIdToArtistAddress(_projectId)),
|
|
197
|
-
"Only Artist"
|
|
198
|
-
);
|
|
160
|
+
require(_senderIsArtist(_projectId), "Only Artist");
|
|
199
161
|
}
|
|
200
162
|
|
|
201
163
|
// function to restrict access to only the artist of a project or
|
|
@@ -206,22 +168,14 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
206
168
|
bytes4 _selector
|
|
207
169
|
) internal {
|
|
208
170
|
require(
|
|
209
|
-
(
|
|
210
|
-
genArtCoreContract_Base.projectIdToArtistAddress(_projectId)) ||
|
|
211
|
-
(
|
|
212
|
-
genArtCoreContract_Base.adminACLAllowed(
|
|
213
|
-
msg.sender,
|
|
214
|
-
address(this),
|
|
215
|
-
_selector
|
|
216
|
-
)
|
|
217
|
-
),
|
|
171
|
+
_senderIsArtist(_projectId) || _adminACLAllowed(_selector),
|
|
218
172
|
"Only Artist or Admin ACL"
|
|
219
173
|
);
|
|
220
174
|
}
|
|
221
175
|
|
|
222
176
|
// function to require that a value is non-zero
|
|
223
177
|
function _onlyNonZero(uint256 _value) internal pure {
|
|
224
|
-
require(_value
|
|
178
|
+
require(_value != 0, "Only non-zero");
|
|
225
179
|
}
|
|
226
180
|
|
|
227
181
|
/**
|
|
@@ -232,13 +186,11 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
232
186
|
* which this contract will be a minter.
|
|
233
187
|
* @param _minterFilter Minter filter for which
|
|
234
188
|
* this will a filtered minter.
|
|
235
|
-
* @param _wethAddress The WETH contract address to use for fallback
|
|
236
189
|
* payment method when ETH transfers are failing during bidding process
|
|
237
190
|
*/
|
|
238
191
|
constructor(
|
|
239
192
|
address _genArt721Address,
|
|
240
|
-
address _minterFilter
|
|
241
|
-
address _wethAddress
|
|
193
|
+
address _minterFilter
|
|
242
194
|
) ReentrancyGuard() MinterBase(_genArt721Address) {
|
|
243
195
|
genArt721CoreAddress = _genArt721Address;
|
|
244
196
|
genArtCoreContract_Base = IGenArt721CoreContractV3_Base(
|
|
@@ -250,7 +202,16 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
250
202
|
minterFilter.genArt721CoreAddress() == _genArt721Address,
|
|
251
203
|
"Illegal contract pairing"
|
|
252
204
|
);
|
|
253
|
-
|
|
205
|
+
// emit events indicating default minter configuration values
|
|
206
|
+
emit AuctionDurationSecondsRangeUpdated({
|
|
207
|
+
minAuctionDurationSeconds: minAuctionDurationSeconds,
|
|
208
|
+
maxAuctionDurationSeconds: maxAuctionDurationSeconds
|
|
209
|
+
});
|
|
210
|
+
emit MinterMinBidIncrementPercentageUpdated(
|
|
211
|
+
minterMinBidIncrementPercentage
|
|
212
|
+
);
|
|
213
|
+
emit MinterTimeBufferUpdated(minterTimeBufferSeconds);
|
|
214
|
+
emit MinterRefundGasLimitUpdated(minterRefundGasLimit);
|
|
254
215
|
}
|
|
255
216
|
|
|
256
217
|
/**
|
|
@@ -277,7 +238,10 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
277
238
|
projectConfig[_projectId].maxHasBeenInvoked =
|
|
278
239
|
invocations == maxInvocations;
|
|
279
240
|
|
|
280
|
-
emit ProjectMaxInvocationsLimitUpdated(
|
|
241
|
+
emit ProjectMaxInvocationsLimitUpdated({
|
|
242
|
+
_projectId: _projectId,
|
|
243
|
+
_maxInvocations: maxInvocations
|
|
244
|
+
});
|
|
281
245
|
|
|
282
246
|
// for convenience, try to mint and assign a token to the project's
|
|
283
247
|
// next slot
|
|
@@ -322,7 +286,10 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
322
286
|
projectConfig[_projectId].maxHasBeenInvoked =
|
|
323
287
|
invocations == _maxInvocations;
|
|
324
288
|
|
|
325
|
-
emit ProjectMaxInvocationsLimitUpdated(
|
|
289
|
+
emit ProjectMaxInvocationsLimitUpdated({
|
|
290
|
+
_projectId: _projectId,
|
|
291
|
+
_maxInvocations: _maxInvocations
|
|
292
|
+
});
|
|
326
293
|
|
|
327
294
|
// for convenience, try to mint and assign a token to the project's
|
|
328
295
|
// next slot
|
|
@@ -342,9 +309,9 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
342
309
|
uint32 _minAuctionDurationSeconds,
|
|
343
310
|
uint32 _maxAuctionDurationSeconds
|
|
344
311
|
) external {
|
|
312
|
+
_onlyNonZero(_minAuctionDurationSeconds);
|
|
345
313
|
_onlyCoreAdminACL(this.updateAllowableAuctionDurationSeconds.selector);
|
|
346
314
|
// CHECKS
|
|
347
|
-
_onlyNonZero(_minAuctionDurationSeconds);
|
|
348
315
|
require(
|
|
349
316
|
_maxAuctionDurationSeconds > _minAuctionDurationSeconds,
|
|
350
317
|
"Only max gt min"
|
|
@@ -352,10 +319,10 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
352
319
|
// EFFECTS
|
|
353
320
|
minAuctionDurationSeconds = _minAuctionDurationSeconds;
|
|
354
321
|
maxAuctionDurationSeconds = _maxAuctionDurationSeconds;
|
|
355
|
-
emit AuctionDurationSecondsRangeUpdated(
|
|
356
|
-
_minAuctionDurationSeconds,
|
|
357
|
-
_maxAuctionDurationSeconds
|
|
358
|
-
);
|
|
322
|
+
emit AuctionDurationSecondsRangeUpdated({
|
|
323
|
+
minAuctionDurationSeconds: _minAuctionDurationSeconds,
|
|
324
|
+
maxAuctionDurationSeconds: _maxAuctionDurationSeconds
|
|
325
|
+
});
|
|
359
326
|
}
|
|
360
327
|
|
|
361
328
|
/**
|
|
@@ -366,13 +333,14 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
366
333
|
* wars do not dominate the economics of an auction.
|
|
367
334
|
* @dev the input value is considered to be a percentage, so that a value
|
|
368
335
|
* of 5 represents 5%.
|
|
336
|
+
* @param _minterMinBidIncrementPercentage Minimum bid increment percentage
|
|
369
337
|
*/
|
|
370
338
|
function updateMinterMinBidIncrementPercentage(
|
|
371
339
|
uint8 _minterMinBidIncrementPercentage
|
|
372
340
|
) external {
|
|
341
|
+
_onlyNonZero(_minterMinBidIncrementPercentage);
|
|
373
342
|
_onlyCoreAdminACL(this.updateMinterMinBidIncrementPercentage.selector);
|
|
374
343
|
// CHECKS
|
|
375
|
-
_onlyNonZero(_minterMinBidIncrementPercentage);
|
|
376
344
|
// EFFECTS
|
|
377
345
|
minterMinBidIncrementPercentage = _minterMinBidIncrementPercentage;
|
|
378
346
|
emit MinterMinBidIncrementPercentageUpdated(
|
|
@@ -385,13 +353,14 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
385
353
|
* the minimum amount of time that must pass between the final bid and the
|
|
386
354
|
* the end of an auction. Auctions are extended if a new bid is placed
|
|
387
355
|
* within this time buffer of the auction end time.
|
|
356
|
+
* @param _minterTimeBufferSeconds Time buffer in seconds.
|
|
388
357
|
*/
|
|
389
358
|
function updateMinterTimeBufferSeconds(
|
|
390
359
|
uint32 _minterTimeBufferSeconds
|
|
391
360
|
) external {
|
|
361
|
+
_onlyNonZero(_minterTimeBufferSeconds);
|
|
392
362
|
_onlyCoreAdminACL(this.updateMinterTimeBufferSeconds.selector);
|
|
393
363
|
// CHECKS
|
|
394
|
-
_onlyNonZero(_minterTimeBufferSeconds);
|
|
395
364
|
// EFFECTS
|
|
396
365
|
minterTimeBufferSeconds = _minterTimeBufferSeconds;
|
|
397
366
|
emit MinterTimeBufferUpdated(_minterTimeBufferSeconds);
|
|
@@ -424,8 +393,9 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
424
393
|
* @notice Warning: Disabling purchaseTo is not supported on this minter.
|
|
425
394
|
* This method exists purely for interface-conformance purposes.
|
|
426
395
|
*/
|
|
427
|
-
function togglePurchaseToDisabled(uint256 _projectId) external
|
|
428
|
-
_onlyArtist
|
|
396
|
+
function togglePurchaseToDisabled(uint256 /*_projectId*/) external pure {
|
|
397
|
+
// @dev access control to _onlyArtist is required if this method is
|
|
398
|
+
// ever re-implemented
|
|
429
399
|
revert("Action not supported");
|
|
430
400
|
}
|
|
431
401
|
|
|
@@ -444,9 +414,8 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
444
414
|
* the end of an auction.
|
|
445
415
|
* @param _basePrice reserve price (minimum starting bid price), in wei.
|
|
446
416
|
* Must be greater than 0, but may be as low as 1 wei.
|
|
447
|
-
* @dev `_basePrice` of zero not allowed
|
|
448
|
-
*
|
|
449
|
-
* project.
|
|
417
|
+
* @dev `_basePrice` of zero not allowed to prevent accidental
|
|
418
|
+
* misconfiguration of auctions
|
|
450
419
|
*/
|
|
451
420
|
function configureFutureAuctions(
|
|
452
421
|
uint256 _projectId,
|
|
@@ -454,9 +423,9 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
454
423
|
uint256 _auctionDurationSeconds,
|
|
455
424
|
uint256 _basePrice
|
|
456
425
|
) external {
|
|
426
|
+
_onlyNonZero(_basePrice);
|
|
457
427
|
_onlyArtist(_projectId);
|
|
458
428
|
// CHECKS
|
|
459
|
-
_onlyNonZero(_basePrice);
|
|
460
429
|
ProjectConfig storage _projectConfig = projectConfig[_projectId];
|
|
461
430
|
require(
|
|
462
431
|
_timestampStart == 0 || block.timestamp < _timestampStart,
|
|
@@ -473,12 +442,12 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
473
442
|
.toUint32();
|
|
474
443
|
_projectConfig.basePrice = _basePrice;
|
|
475
444
|
|
|
476
|
-
emit ConfiguredFutureAuctions(
|
|
477
|
-
_projectId,
|
|
478
|
-
_timestampStart.toUint64(),
|
|
479
|
-
_auctionDurationSeconds.toUint32(),
|
|
480
|
-
_basePrice
|
|
481
|
-
);
|
|
445
|
+
emit ConfiguredFutureAuctions({
|
|
446
|
+
projectId: _projectId,
|
|
447
|
+
timestampStart: _timestampStart.toUint64(),
|
|
448
|
+
auctionDurationSeconds: _auctionDurationSeconds.toUint32(),
|
|
449
|
+
basePrice: _basePrice
|
|
450
|
+
});
|
|
482
451
|
|
|
483
452
|
// sync local max invocations if not initially populated
|
|
484
453
|
// @dev if local max invocations and maxHasBeenInvoked are both
|
|
@@ -547,9 +516,10 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
547
516
|
// CHECKS
|
|
548
517
|
// only if project is not configured (i.e. artist called
|
|
549
518
|
// `resetAuctionDetails`)
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
519
|
+
require(
|
|
520
|
+
!_projectIsConfigured(_projectConfig),
|
|
521
|
+
"Only unconfigured projects"
|
|
522
|
+
);
|
|
553
523
|
// only if minter has a next token assigned
|
|
554
524
|
require(
|
|
555
525
|
_projectConfig.nextTokenNumberIsPopulated == true,
|
|
@@ -561,11 +531,11 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
561
531
|
// @dev overflow automatically handled by Sol ^0.8.0
|
|
562
532
|
uint256 nextTokenId = (_projectId * ONE_MILLION) +
|
|
563
533
|
_projectConfig.nextTokenNumber;
|
|
564
|
-
IERC721(genArt721CoreAddress).transferFrom(
|
|
565
|
-
address(this),
|
|
566
|
-
_to,
|
|
567
|
-
nextTokenId
|
|
568
|
-
);
|
|
534
|
+
IERC721(genArt721CoreAddress).transferFrom({
|
|
535
|
+
from: address(this),
|
|
536
|
+
to: _to,
|
|
537
|
+
tokenId: nextTokenId
|
|
538
|
+
});
|
|
569
539
|
emit ProjectNextTokenEjected(_projectId);
|
|
570
540
|
}
|
|
571
541
|
|
|
@@ -610,7 +580,7 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
610
580
|
* one or more transactions to settle and/or initialize a new auction,
|
|
611
581
|
* potentially still placing a bid on the auction for the token ID if the
|
|
612
582
|
* bid value is sufficiently higher than the current highest bid.
|
|
613
|
-
* Note that the use of `
|
|
583
|
+
* Note that the use of `_bidTokenId` is to prevent the possibility of
|
|
614
584
|
* transactions that are stuck in the pending pool for long periods of time
|
|
615
585
|
* from unintentionally bidding on auctions for future tokens.
|
|
616
586
|
* Note that calls to `settleAuction` and `createBid` are possible
|
|
@@ -618,6 +588,7 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
618
588
|
* convenience and executes both of those functions in a single
|
|
619
589
|
* transaction, while handling front-running as gracefully as possible.
|
|
620
590
|
* @param _settleTokenId Token ID to settle auction for.
|
|
591
|
+
* @param _bidTokenId Token ID to bid on.
|
|
621
592
|
* @dev this function is not non-reentrant, but the underlying calls are
|
|
622
593
|
* to non-reentrant functions.
|
|
623
594
|
*/
|
|
@@ -652,10 +623,14 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
652
623
|
uint256 _projectId = _tokenId / ONE_MILLION;
|
|
653
624
|
ProjectConfig storage _projectConfig = projectConfig[_projectId];
|
|
654
625
|
Auction storage _auction = _projectConfig.activeAuction;
|
|
626
|
+
// load from storage to memory for gas efficiency
|
|
627
|
+
address currentBidder = _auction.currentBidder;
|
|
628
|
+
uint256 currentBid = _auction.currentBid;
|
|
629
|
+
address genArt721CoreAddress_ = genArt721CoreAddress;
|
|
655
630
|
// CHECKS
|
|
656
631
|
// @dev this check is not strictly necessary, but is included for
|
|
657
632
|
// clear error messaging
|
|
658
|
-
require(_auction
|
|
633
|
+
require(_auctionIsInitialized(_auction), "Auction not initialized");
|
|
659
634
|
if (_auction.settled || (_auction.tokenId != _tokenId)) {
|
|
660
635
|
// auction already settled or is for a different token ID, so
|
|
661
636
|
// return early and do not modify state
|
|
@@ -663,24 +638,24 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
663
638
|
}
|
|
664
639
|
// @dev important that the following check is after the early return
|
|
665
640
|
// block above to maintain desired behavior
|
|
666
|
-
require(block.timestamp
|
|
641
|
+
require(block.timestamp >= _auction.endTime, "Auction not yet ended");
|
|
667
642
|
// EFFECTS
|
|
668
643
|
_auction.settled = true;
|
|
669
644
|
// INTERACTIONS
|
|
670
645
|
// send token to the winning bidder
|
|
671
|
-
IERC721(
|
|
672
|
-
address(this),
|
|
673
|
-
|
|
674
|
-
_tokenId
|
|
675
|
-
);
|
|
646
|
+
IERC721(genArt721CoreAddress_).transferFrom({
|
|
647
|
+
from: address(this),
|
|
648
|
+
to: currentBidder,
|
|
649
|
+
tokenId: _tokenId
|
|
650
|
+
});
|
|
676
651
|
// distribute revenues from auction
|
|
677
|
-
splitRevenuesETH(_projectId,
|
|
652
|
+
splitRevenuesETH(_projectId, currentBid, genArt721CoreAddress_);
|
|
678
653
|
|
|
679
|
-
emit AuctionSettled(
|
|
680
|
-
_tokenId,
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
);
|
|
654
|
+
emit AuctionSettled({
|
|
655
|
+
tokenId: _tokenId,
|
|
656
|
+
winner: currentBidder,
|
|
657
|
+
price: currentBid
|
|
658
|
+
});
|
|
684
659
|
}
|
|
685
660
|
|
|
686
661
|
/**
|
|
@@ -698,9 +673,13 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
698
673
|
* If the bid is successful, but outbid by another bid before the auction
|
|
699
674
|
* ends, the funds will be noncustodially returned to the bidder's address,
|
|
700
675
|
* `msg.sender`. A fallback method of sending funds back to the bidder via
|
|
701
|
-
*
|
|
702
|
-
*
|
|
703
|
-
*
|
|
676
|
+
* SELFDESTRUCT (SENDALL) prevents denial of service attacks, even if the
|
|
677
|
+
* original bidder reverts or runs out of gas during receive or fallback.
|
|
678
|
+
* ------------------------------------------------------------------------
|
|
679
|
+
* WARNING: bidders must be prepared to handle the case where their bid is
|
|
680
|
+
* outbid and their funds are returned to the original `msg.sender` address
|
|
681
|
+
* via SELFDESTRUCT (SENDALL).
|
|
682
|
+
* ------------------------------------------------------------------------
|
|
704
683
|
* Note that the use of `_tokenId` is to prevent the possibility of
|
|
705
684
|
* transactions that are stuck in the pending pool for long periods of time
|
|
706
685
|
* from unintentionally bidding on auctions for future tokens.
|
|
@@ -726,11 +705,14 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
726
705
|
// CHECKS
|
|
727
706
|
ProjectConfig storage _projectConfig = projectConfig[_projectId];
|
|
728
707
|
Auction storage _auction = _projectConfig.activeAuction;
|
|
708
|
+
// load from storage to memory for gas efficiency
|
|
709
|
+
uint256 auctionEndTime = _auction.endTime;
|
|
710
|
+
uint256 previousBid = _auction.currentBid;
|
|
729
711
|
|
|
730
712
|
// if no auction exists, or current auction is already settled, attempt
|
|
731
713
|
// to initialize a new auction for the input token ID and immediately
|
|
732
714
|
// return
|
|
733
|
-
if ((!_auction
|
|
715
|
+
if ((!_auctionIsInitialized(_auction)) || _auction.settled) {
|
|
734
716
|
_initializeAuctionWithBid(_projectId, _tokenId);
|
|
735
717
|
return;
|
|
736
718
|
}
|
|
@@ -745,36 +727,37 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
745
727
|
);
|
|
746
728
|
|
|
747
729
|
// ensure auction is not already ended
|
|
748
|
-
require(
|
|
730
|
+
require(auctionEndTime > block.timestamp, "Auction already ended");
|
|
749
731
|
|
|
750
732
|
// require bid to be sufficiently greater than current highest bid
|
|
751
|
-
// @dev no overflow enforced automatically by solidity ^8.0
|
|
733
|
+
// @dev no overflow enforced automatically by solidity ^0.8.0
|
|
752
734
|
require(
|
|
753
735
|
msg.value >=
|
|
754
|
-
(
|
|
755
|
-
(100 + minterMinBidIncrementPercentage)) /
|
|
756
|
-
100,
|
|
736
|
+
(previousBid * (100 + minterMinBidIncrementPercentage)) / 100,
|
|
757
737
|
"Bid is too low"
|
|
758
738
|
);
|
|
759
739
|
|
|
760
740
|
// EFFECTS
|
|
761
|
-
// record previous highest
|
|
762
|
-
uint256 previousBid = _auction.currentBid;
|
|
741
|
+
// record previous highest bider for refunding
|
|
763
742
|
address payable previousBidder = _auction.currentBidder;
|
|
764
743
|
|
|
765
744
|
// update auction state
|
|
766
745
|
_auction.currentBid = msg.value;
|
|
767
746
|
_auction.currentBidder = payable(msg.sender);
|
|
768
747
|
uint256 minEndTime = block.timestamp + minterTimeBufferSeconds;
|
|
769
|
-
if (
|
|
748
|
+
if (auctionEndTime < minEndTime) {
|
|
770
749
|
_auction.endTime = minEndTime.toUint64();
|
|
771
750
|
}
|
|
772
751
|
|
|
773
752
|
// INTERACTIONS
|
|
774
753
|
// refund previous highest bidder
|
|
775
|
-
|
|
754
|
+
_forceSafeTransferETH(previousBidder, previousBid);
|
|
776
755
|
|
|
777
|
-
emit AuctionBid(
|
|
756
|
+
emit AuctionBid({
|
|
757
|
+
tokenId: _tokenId,
|
|
758
|
+
bidder: msg.sender,
|
|
759
|
+
bidAmount: msg.value
|
|
760
|
+
});
|
|
778
761
|
}
|
|
779
762
|
|
|
780
763
|
/**
|
|
@@ -874,48 +857,17 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
874
857
|
* Note that in the case of no auction being initialized for the project,
|
|
875
858
|
* the returned `auction` will be the default struct.
|
|
876
859
|
* @param _projectId The project ID
|
|
877
|
-
* @return
|
|
878
|
-
* allowed on this minter
|
|
879
|
-
* @return timestampStart The project's start timestamp, after which new
|
|
880
|
-
* auctions may be created (one at a time)
|
|
881
|
-
* @return auctionDurationSeconds The project's default auction duration,
|
|
882
|
-
* before any extensions due to buffer time
|
|
883
|
-
* @return basePrice The project's minimum starting bid price
|
|
884
|
-
* @return nextTokenNumberIsPopulated Whether or not the project's next
|
|
885
|
-
* token number has been populated
|
|
886
|
-
* @return nextTokenNumber The project's next token number to be auctioned,
|
|
887
|
-
* dummy value of 0 if `nextTokenNumberIsPopulated` is false. Note that 0
|
|
888
|
-
* is a valid token number, so `nextTokenNumberIsPopulated` should be used
|
|
889
|
-
* to distinguish between a valid token number of 0 and a dummy value of 0.
|
|
890
|
-
* @return auction The project's active auction details. Will be the
|
|
891
|
-
* default struct (w/ `auction.initialized = false`) if no auction has been
|
|
892
|
-
* initialized for the project.
|
|
860
|
+
* @return projectConfig_ The project configuration details
|
|
893
861
|
*/
|
|
894
862
|
function projectConfigurationDetails(
|
|
895
863
|
uint256 _projectId
|
|
896
|
-
)
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
uint32 auctionDurationSeconds,
|
|
903
|
-
uint256 basePrice,
|
|
904
|
-
bool nextTokenNumberIsPopulated,
|
|
905
|
-
uint24 nextTokenNumber,
|
|
906
|
-
Auction memory auction
|
|
907
|
-
)
|
|
908
|
-
{
|
|
909
|
-
ProjectConfig storage _projectConfig = projectConfig[_projectId];
|
|
910
|
-
maxInvocations = _projectConfig.maxInvocations;
|
|
911
|
-
timestampStart = _projectConfig.timestampStart;
|
|
912
|
-
auctionDurationSeconds = _projectConfig.auctionDurationSeconds;
|
|
913
|
-
basePrice = _projectConfig.basePrice;
|
|
914
|
-
nextTokenNumberIsPopulated = _projectConfig.nextTokenNumberIsPopulated;
|
|
915
|
-
nextTokenNumber = _projectConfig.nextTokenNumberIsPopulated
|
|
916
|
-
? _projectConfig.nextTokenNumber
|
|
864
|
+
) external view returns (ProjectConfig memory projectConfig_) {
|
|
865
|
+
projectConfig_ = projectConfig[_projectId];
|
|
866
|
+
// clean up next token number to handle case where it is stale
|
|
867
|
+
projectConfig_.nextTokenNumber = projectConfig_
|
|
868
|
+
.nextTokenNumberIsPopulated
|
|
869
|
+
? projectConfig_.nextTokenNumber
|
|
917
870
|
: 0;
|
|
918
|
-
auction = _projectConfig.activeAuction;
|
|
919
871
|
}
|
|
920
872
|
|
|
921
873
|
/**
|
|
@@ -926,10 +878,15 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
926
878
|
uint256 _projectId
|
|
927
879
|
) external view returns (Auction memory auction) {
|
|
928
880
|
ProjectConfig storage _projectConfig = projectConfig[_projectId];
|
|
929
|
-
|
|
881
|
+
Auction storage _auction = _projectConfig.activeAuction;
|
|
930
882
|
// do not return uninitialized auctions (i.e. auctions that do not
|
|
931
|
-
// exist,
|
|
932
|
-
require(
|
|
883
|
+
// exist, where currentBidder is still the default value)
|
|
884
|
+
require(
|
|
885
|
+
_auctionIsInitialized(_auction),
|
|
886
|
+
"No auction exists on project"
|
|
887
|
+
);
|
|
888
|
+
// load entire auction into memory
|
|
889
|
+
auction = _projectConfig.activeAuction;
|
|
933
890
|
return auction;
|
|
934
891
|
}
|
|
935
892
|
|
|
@@ -952,7 +909,10 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
952
909
|
Auction storage _auction = _projectConfig.activeAuction;
|
|
953
910
|
// if project has an active token auction that is not settled, return
|
|
954
911
|
// that token ID
|
|
955
|
-
if (
|
|
912
|
+
if (
|
|
913
|
+
_auctionIsInitialized(_auction) &&
|
|
914
|
+
(_auction.endTime > block.timestamp)
|
|
915
|
+
) {
|
|
956
916
|
return _auction.tokenId;
|
|
957
917
|
}
|
|
958
918
|
// otherwise, return the next expected token ID to be auctioned
|
|
@@ -1022,7 +982,7 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
1022
982
|
// check is not present
|
|
1023
983
|
// @dev no cover else branch of next line because unreachable
|
|
1024
984
|
require(
|
|
1025
|
-
(!_auction
|
|
985
|
+
(!_auctionIsInitialized(_auction)) || _auction.settled,
|
|
1026
986
|
"Existing auction not settled"
|
|
1027
987
|
);
|
|
1028
988
|
// require valid bid value
|
|
@@ -1052,8 +1012,7 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
1052
1012
|
currentBid: msg.value,
|
|
1053
1013
|
currentBidder: payable(msg.sender),
|
|
1054
1014
|
endTime: endTime,
|
|
1055
|
-
settled: false
|
|
1056
|
-
initialized: true
|
|
1015
|
+
settled: false
|
|
1057
1016
|
});
|
|
1058
1017
|
// mark next token number as not populated
|
|
1059
1018
|
// @dev intentionally not setting nextTokenNumber to zero to avoid
|
|
@@ -1062,7 +1021,12 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
1062
1021
|
|
|
1063
1022
|
// @dev we intentionally emit event here due to potential of early
|
|
1064
1023
|
// return in INTERACTIONS section
|
|
1065
|
-
emit AuctionInitialized(
|
|
1024
|
+
emit AuctionInitialized({
|
|
1025
|
+
tokenId: _targetTokenId,
|
|
1026
|
+
bidder: msg.sender,
|
|
1027
|
+
bidAmount: msg.value,
|
|
1028
|
+
endTime: endTime
|
|
1029
|
+
});
|
|
1066
1030
|
|
|
1067
1031
|
// INTERACTIONS
|
|
1068
1032
|
// attempt to mint new token to this minter contract, only if max
|
|
@@ -1078,6 +1042,10 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
1078
1042
|
* contract or minter
|
|
1079
1043
|
* - the project config's `nextTokenNumberIsPopulated` is already true
|
|
1080
1044
|
* @param _projectId The ID of the project to mint a new token for.
|
|
1045
|
+
* @dev this calls mint with `msg.sender` as the sender, allowing artists
|
|
1046
|
+
* to mint tokens to the next token slot for their project while a project
|
|
1047
|
+
* is still paused. This happens when an artist is configuring their
|
|
1048
|
+
* project's auction parameters or minter max invocations.
|
|
1081
1049
|
*/
|
|
1082
1050
|
function _tryMintTokenToNextSlot(uint256 _projectId) internal {
|
|
1083
1051
|
ProjectConfig storage _projectConfig = projectConfig[_projectId];
|
|
@@ -1114,7 +1082,7 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
1114
1082
|
uint256 nextTokenId = minterFilter.mint(
|
|
1115
1083
|
address(this),
|
|
1116
1084
|
_projectId,
|
|
1117
|
-
|
|
1085
|
+
msg.sender
|
|
1118
1086
|
);
|
|
1119
1087
|
// update state to reflect new token number
|
|
1120
1088
|
// @dev state changes after trusted contract interaction
|
|
@@ -1128,33 +1096,114 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
1128
1096
|
if (tokenInvocation == localMaxInvocations) {
|
|
1129
1097
|
_projectConfig.maxHasBeenInvoked = true;
|
|
1130
1098
|
}
|
|
1131
|
-
emit ProjectNextTokenUpdated(
|
|
1099
|
+
emit ProjectNextTokenUpdated({
|
|
1100
|
+
projectId: _projectId,
|
|
1101
|
+
tokenId: nextTokenId
|
|
1102
|
+
});
|
|
1132
1103
|
}
|
|
1133
1104
|
|
|
1134
1105
|
/**
|
|
1135
|
-
* @notice
|
|
1106
|
+
* @notice Force sends `amount` (in wei) ETH to `to`, with a gas stipend
|
|
1107
|
+
* equal to `minterRefundGasLimit`.
|
|
1108
|
+
* If sending via the normal procedure fails, force sends the ETH by
|
|
1109
|
+
* creating a temporary contract which uses `SELFDESTRUCT` to force send
|
|
1110
|
+
* the ETH.
|
|
1111
|
+
* Reverts if the current contract has insufficient balance.
|
|
1112
|
+
* @param _to The address to send ETH to.
|
|
1113
|
+
* @param _amount The amount of ETH to send.
|
|
1114
|
+
* @dev This function is adapted from the `forceSafeTransferETH` function
|
|
1115
|
+
* in the `https://github.com/Vectorized/solady` repository, with
|
|
1116
|
+
* modifications to not check if the current contract has sufficient
|
|
1117
|
+
* balance.
|
|
1136
1118
|
*/
|
|
1137
|
-
function
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1119
|
+
function _forceSafeTransferETH(address _to, uint256 _amount) internal {
|
|
1120
|
+
// load state variable into memory for use in inline assembly
|
|
1121
|
+
uint256 minterRefundGasLimit_ = minterRefundGasLimit;
|
|
1122
|
+
// Manually inlined because the compiler doesn't inline functions with
|
|
1123
|
+
// branches.
|
|
1124
|
+
/// @solidity memory-safe-assembly
|
|
1125
|
+
assembly {
|
|
1126
|
+
// @dev intentionally do not check if this contract has sufficient
|
|
1127
|
+
// balance, because that is not intended to be a valid state.
|
|
1128
|
+
|
|
1129
|
+
// Transfer the ETH and check if it succeeded or not.
|
|
1130
|
+
if iszero(call(minterRefundGasLimit_, _to, _amount, 0, 0, 0, 0)) {
|
|
1131
|
+
// if the transfer failed, we create a temporary contract with
|
|
1132
|
+
// initialization code that uses `SELFDESTRUCT` to force send
|
|
1133
|
+
// the ETH.
|
|
1134
|
+
// note: Compatible with `SENDALL`:
|
|
1135
|
+
// https://eips.ethereum.org/EIPS/eip-4758
|
|
1136
|
+
|
|
1137
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
1138
|
+
// Opcode | Opcode + Arguments | Description | Stack View //
|
|
1139
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
1140
|
+
// Contract creation code that uses `SELFDESTRUCT` to force send ETH to a specified address. //
|
|
1141
|
+
// Creation code summary: 0x73<20-byte toAddress>0xff //
|
|
1142
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
1143
|
+
// 0x73 | 0x73_toAddress | PUSH20 toAddress | toAddress //
|
|
1144
|
+
// 0xFF | 0xFF | SELFDESTRUCT | //
|
|
1145
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
1146
|
+
// Store the address in scratch space, starting at 0x00, which begins the 20-byte address at 32-20=12 in memory
|
|
1147
|
+
// @dev use scratch space because we have enough space for simple creation code (less than 0x40 bytes)
|
|
1148
|
+
mstore(0x00, _to)
|
|
1149
|
+
// store opcode PUSH20 immediately before the address, starting at 0x0b (11) in memory
|
|
1150
|
+
mstore8(0x0b, 0x73)
|
|
1151
|
+
// store opcode SELFDESTRUCT immediately after the address, starting at 0x20 (32) in memory
|
|
1152
|
+
mstore8(0x20, 0xff)
|
|
1153
|
+
// this will always succeed because the contract creation code is
|
|
1154
|
+
// valid, and the address is valid because it is a 20-byte value
|
|
1155
|
+
if iszero(create(_amount, 0x0b, 0x16)) {
|
|
1156
|
+
// @dev For better gas estimation.
|
|
1157
|
+
if iszero(gt(gas(), 1000000)) {
|
|
1158
|
+
revert(0, 0)
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1144
1162
|
}
|
|
1145
1163
|
}
|
|
1146
1164
|
|
|
1147
1165
|
/**
|
|
1148
1166
|
* @notice Determines if a project is configured or not on this minter.
|
|
1149
|
-
* Uses project config's `
|
|
1150
|
-
* because `
|
|
1167
|
+
* Uses project config's `auctionDurationSeconds` to determine if project
|
|
1168
|
+
* is configured, because `auctionDurationSeconds` is required to be
|
|
1151
1169
|
* non-zero when configured.
|
|
1152
1170
|
* @param _projectConfig The project config to check.
|
|
1153
1171
|
*/
|
|
1154
1172
|
function _projectIsConfigured(
|
|
1155
1173
|
ProjectConfig storage _projectConfig
|
|
1156
1174
|
) internal view returns (bool) {
|
|
1157
|
-
return _projectConfig.
|
|
1175
|
+
return _projectConfig.auctionDurationSeconds != 0;
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
/**
|
|
1179
|
+
* @notice Determines if an auction is initialized.
|
|
1180
|
+
* Uses auction's `currentBidder` address to determine if auction is
|
|
1181
|
+
* initialized, because `currentBidder` is always non-zero after an auction
|
|
1182
|
+
* has been initialized.
|
|
1183
|
+
* @param _auction The auction to check.
|
|
1184
|
+
*/
|
|
1185
|
+
function _auctionIsInitialized(
|
|
1186
|
+
Auction storage _auction
|
|
1187
|
+
) internal view returns (bool isInitialized) {
|
|
1188
|
+
// auction is initialized if currentBidder is non-zero
|
|
1189
|
+
return _auction.currentBidder != address(0);
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
function _senderIsArtist(
|
|
1193
|
+
uint256 _projectId
|
|
1194
|
+
) private view returns (bool senderIsArtist) {
|
|
1195
|
+
return
|
|
1196
|
+
msg.sender ==
|
|
1197
|
+
genArtCoreContract_Base.projectIdToArtistAddress(_projectId);
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
function _adminACLAllowed(bytes4 _selector) private returns (bool) {
|
|
1201
|
+
return
|
|
1202
|
+
genArtCoreContract_Base.adminACLAllowed({
|
|
1203
|
+
_sender: msg.sender,
|
|
1204
|
+
_contract: address(this),
|
|
1205
|
+
_selector: _selector
|
|
1206
|
+
});
|
|
1158
1207
|
}
|
|
1159
1208
|
|
|
1160
1209
|
/**
|
|
@@ -1198,7 +1247,7 @@ contract MinterSEAV0 is ReentrancyGuard, MinterBase, IFilteredMinterSEAV0 {
|
|
|
1198
1247
|
// base price of zero not allowed when configuring auctions, so use it
|
|
1199
1248
|
// as indicator of whether auctions are configured for the project
|
|
1200
1249
|
bool projectIsConfigured = _projectIsConfigured(_projectConfig);
|
|
1201
|
-
bool auctionIsAcceptingBids = (_auction
|
|
1250
|
+
bool auctionIsAcceptingBids = (_auctionIsInitialized(_auction) &&
|
|
1202
1251
|
block.timestamp < _auction.endTime);
|
|
1203
1252
|
isConfigured = projectIsConfigured || auctionIsAcceptingBids;
|
|
1204
1253
|
// only return non-zero price if auction is configured
|