@artblocks/contracts 1.3.2 → 1.4.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.
- package/README.md +11 -10
- package/artifacts/contracts/AdminACLV0RoyaltyRegistry.sol/AdminACLV0RoyaltyRegistry.json +193 -0
- package/artifacts/contracts/AdminACLV0RoyaltyRegistry.sol/IRoyaltyRegistry.json +35 -0
- package/artifacts/contracts/AdminACLV1.sol/AdminACLV1.json +2 -2
- package/artifacts/contracts/BytecodeStorageReaders/BytecodeStorageReaderContractV2.sol/BytecodeStorageReaderContractV2.json +2 -2
- package/artifacts/contracts/BytecodeStorageReaders/BytecodeStorageReaderContractV2_Web3Call.sol/BytecodeStorageReaderContractV2_Web3Call.json +2 -2
- package/artifacts/contracts/BytecodeStorageV2Writer.sol/BytecodeStorageV2Writer.json +2 -2
- package/artifacts/contracts/DependencyRegistryV0.sol/DependencyRegistryV0.json +210 -2
- package/artifacts/contracts/GenArt721CoreV3_Curated.sol/GenArt721CoreV3_Curated.json +235 -20
- package/artifacts/contracts/GenArt721CoreV3_Curated_Flex.sol/GenArt721CoreV3_Curated_Flex.json +3197 -0
- package/artifacts/contracts/GenArt721CoreV3_Explorations_Flex.sol/GenArt721CoreV3_Explorations_Flex.json +3192 -0
- package/artifacts/contracts/OwnedCreate2FactoryV0.sol/OwnedCreate2FactoryV0.json +2 -2
- package/artifacts/contracts/archive/GenArt721CoreV3.sol/GenArt721CoreV3.json +27 -2
- package/artifacts/contracts/archive/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +27 -2
- 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/MinterDAExp/MinterDAExpV4.sol/MinterDAExpV4.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/MinterDAExpSettlement/MinterDAExpSettlementV2.sol/MinterDAExpSettlementV2.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/MinterDALin/MinterDALinV4.sol/MinterDALinV4.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/MinterHolder/MinterHolderV4.sol/MinterHolderV4.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/MinterMerkle/MinterMerkleV5.sol/MinterMerkleV5.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterPolyptych/MinterPolyptychV0.sol/IGenArt721CoreContractV3WithRandomizer.json +25 -0
- package/artifacts/contracts/archive/minter-suite/Minters/MinterPolyptych/MinterPolyptychV0.sol/MinterPolyptychV0.json +2 -2
- package/artifacts/contracts/archive/minter-suite/Minters/MinterSEA/MinterSEAV0.sol/MinterSEAV0.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/MinterSetPrice/MinterSetPriceV4.sol/MinterSetPriceV4.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/archive/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V4.sol/MinterSetPriceERC20V4.json +2 -2
- package/artifacts/contracts/engine/V3/EngineFactoryV0.sol/EngineFactoryV0.json +28 -2
- package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine.sol/GenArt721CoreV3_Engine.json +239 -20
- package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol/GenArt721CoreV3_Engine_Flex.json +267 -48
- package/artifacts/contracts/engine/V3/forks/GenArt721CoreV3_Engine_Flex_PROOF.sol/GenArt721CoreV3_Engine_Flex_PROOF.json +27 -2
- package/artifacts/contracts/engine/V3/forks/PROHIBITION/AdminACLV0_PROHIBITION.sol/AdminACLV0_PROHIBITION.json +2 -2
- package/artifacts/contracts/engine/V3/forks/PROHIBITION/GenArt721CoreV3_Engine_Flex_PROHIBITION.sol/GenArt721CoreV3_Engine_Flex_PROHIBITION.json +27 -2
- package/artifacts/contracts/engine/V3/forks/PROHIBITION/interfaces/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.sol/IGenArt721CoreContractV3_Engine_Flex_PROHIBITION.json +25 -0
- package/artifacts/contracts/engine/V3/transfer-hooks/AbstractTransferHook.sol/AbstractTransferHook.json +79 -0
- package/artifacts/contracts/engine/V3/transfer-hooks/OwnerHistoryTransferHook.sol/OwnerHistoryTransferHook.json +315 -0
- package/artifacts/contracts/generator/GenArt721GeneratorV0.sol/GenArt721GeneratorV0.json +2 -2
- package/artifacts/contracts/interfaces/v0.8.x/IClaimMinter.sol/IClaimMinter.json +189 -0
- package/artifacts/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol/IDependencyRegistryV0.json +149 -0
- package/artifacts/contracts/interfaces/v0.8.x/IEngineFactoryV0.sol/IEngineFactoryV0.json +26 -0
- package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3.sol/IGenArt721CoreContractV3.json +25 -0
- package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Base.sol/IGenArt721CoreContractV3_Base.json +25 -0
- package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine.sol/IGenArt721CoreContractV3_Engine.json +123 -0
- package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex.sol/IGenArt721CoreContractV3_Engine_Flex.json +123 -0
- package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex_PreV3p2.sol/IGenArt721CoreContractV3_Engine_Flex_PreV3p2.json +25 -0
- package/artifacts/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_PreV3p2.sol/IGenArt721CoreContractV3_Engine_PreV3p2.json +25 -0
- package/artifacts/contracts/interfaces/v0.8.x/IOwnerHistoryTransferHook.sol/IOwnerHistoryTransferHook.json +299 -0
- package/artifacts/contracts/interfaces/v0.8.x/ISRHooks.sol/ISRHooks.json +432 -0
- package/artifacts/contracts/interfaces/v0.8.x/ISeaDropShimForContract.sol/ISeaDropShimForContract.json +0 -13
- package/artifacts/contracts/interfaces/v0.8.x/ISharedMinterTieredAllowV0.sol/ISharedMinterTieredAllowV0.json +94 -0
- package/artifacts/contracts/interfaces/v0.8.x/ITransferHook.sol/ITransferHook.json +63 -0
- package/artifacts/contracts/libs/v0.8.x/AuthLib.sol/AuthLib.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV2.sol/BytecodeStorageReader.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/BytecodeStorageV2.sol/BytecodeStorageWriter.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/DependencyRegistryStorageLib.sol/DependencyRegistryStorageLib.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/ENSLib.sol/ENSLib.json +10 -0
- package/artifacts/contracts/libs/v0.8.x/ENSLib.sol/IUniversalResolver.json +45 -0
- package/artifacts/contracts/libs/v0.8.x/EnumerableSetUint16.sol/EnumerableSetUint16.json +10 -0
- package/artifacts/contracts/libs/v0.8.x/FeistelWalkLib.sol/FeistelWalkLib.json +10 -0
- package/artifacts/contracts/libs/v0.8.x/ImmutableUint16Array.sol/ImmutableUint16Array.json +10 -0
- package/artifacts/contracts/libs/v0.8.x/V3EngineLib.sol/V3EngineLib.json +163 -0
- package/artifacts/contracts/libs/v0.8.x/V3FlexLib.sol/V3FlexLib.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/V3TransferHookLib.sol/V3TransferHookLib.json +79 -0
- package/artifacts/contracts/libs/v0.8.x/minter-libs/MaxInvocationsLib.sol/MaxInvocationsLib.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/minter-libs/OnChainAllowlistLib.sol/OnChainAllowlistLib.json +10 -0
- package/artifacts/contracts/libs/v0.8.x/minter-libs/PolyptychLib.sol/PolyptychLib.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/minter-libs/RAMLib.sol/RAMLib.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/minter-libs/SEALib.sol/SEALib.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/minter-libs/SettlementExpLib.sol/SettlementExpLib.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/minter-libs/SplitFundsLib.sol/SplitFundsLib.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 +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterDAExpHolderV5.sol/MinterDAExpHolderV5.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlementV3.sol/MinterDAExpSettlementV3.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterDAExpV5.sol/MinterDAExpV5.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterDALinHolderV5.sol/MinterDALinHolderV5.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterDALinV5.sol/MinterDALinV5.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterMinPriceMerkleV0.sol/MinterMinPriceMerkleV0.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterMinPriceV0.sol/MinterMinPriceV0.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterRAMV0.sol/MinterRAMV0.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterSEAV1.sol/MinterSEAV1.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20V5.sol/MinterSetPriceERC20V5.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceHolderV5.sol/MinterSetPriceHolderV5.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceMerkleV5.sol/MinterSetPriceMerkleV5.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceOnChainAllowV0.sol/MinterSetPriceOnChainAllowV0.json +522 -0
- package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychERC20V5.sol/MinterSetPricePolyptychERC20V5.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterSetPricePolyptychV5.sol/MinterSetPricePolyptychV5.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceTieredAllowV1.sol/MinterSetPriceTieredAllowV1.json +715 -0
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceV5.sol/MinterSetPriceV5.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/MinterSlidingScaleV0.sol/MinterSlidingScaleV0.json +431 -0
- package/artifacts/contracts/minter-suite/Minters/one-off/ClaimMinter.sol/ClaimMinter.json +502 -0
- package/artifacts/contracts/minter-suite/Minters/one-off/MinterSetPriceTieredOnChainAllowV0.sol/MinterSetPriceTieredOnChainAllowV0.json +673 -0
- package/artifacts/contracts/minter-suite/Minters/one-off/MinterSetPriceV5_SingleCore.sol/MinterSetPriceV5_SingleCore.json +2 -2
- package/artifacts/contracts/minter-suite/Minters/one-off/SeaDropXArtBlocksShim.sol/SeaDropXArtBlocksShim.json +6 -19
- package/artifacts/contracts/mock/BytecodeV2TextCR_DMock.sol/BytecodeV2TextCR_DMock.json +2 -2
- package/artifacts/contracts/mock/DummySharedMinter.sol/DummySharedMinter.json +2 -2
- package/artifacts/contracts/mock/ENSLibMock.sol/ENSLibMock.json +30 -0
- package/artifacts/contracts/mock/EnumerableSetUint16Mock.sol/EnumerableSetUint16Mock.json +146 -0
- package/artifacts/contracts/mock/FeistelWalkLibMock.sol/FeistelWalkLibMock.json +142 -0
- package/artifacts/contracts/mock/ForceSendMock.sol/ForceSendMock.json +2 -2
- package/artifacts/contracts/mock/GenArt721CoreV3_Engine_IncorrectCoreType.sol/GenArt721CoreV3_Engine_IncorrectCoreType.json +2 -2
- package/artifacts/contracts/mock/ImmutableUint16ArrayMock.sol/ImmutableUint16ArrayMock.json +89 -0
- package/artifacts/contracts/mock/MockAdminACLV0_PROHIBITION.sol/MockAdminACLV0Events_PROHIBITION.json +2 -2
- package/artifacts/contracts/mock/MockGenArt721V3Core.sol/MockGenArt721V3Core.json +490 -0
- package/artifacts/contracts/mock/MockPMP.sol/MockPMP.json +523 -0
- package/artifacts/contracts/mock/MockTransferHook.sol/MockTransferHook.json +453 -0
- package/artifacts/contracts/mock/MockTransferHookTestHelpers.sol/MockBatchTransferrer.json +39 -0
- package/artifacts/contracts/mock/MockTransferHookTestHelpers.sol/MockForwardingERC721Receiver.json +71 -0
- package/artifacts/contracts/mock/MockTransferHookTestHelpers.sol/MockSpoofingCore.json +94 -0
- package/artifacts/contracts/mock/RandomizerV2_NoAssignMock.sol/RandomizerV2_NoAssignMock.json +2 -2
- package/artifacts/contracts/mock/ReentrancyBatchMockShared.sol/IBatchMinter.json +64 -0
- package/artifacts/contracts/mock/ReentrancyBatchMockShared.sol/ReentrancyBatchMockShared.json +113 -0
- package/artifacts/contracts/mock/RelayExecutorTestHelper.sol/MockTarget.json +74 -0
- package/artifacts/contracts/mock/RelayExecutorTestHelper.sol/RelayExecutorPartialRevertsTestHelper.json +138 -0
- package/artifacts/contracts/mock/RelayExecutorTestHelper.sol/RelayExecutorTestHelper.json +119 -0
- package/artifacts/contracts/randomizer/deprecated/PolyptychRandomizerV0.sol/BasicPolyptychRandomizerV0.json +2 -2
- package/artifacts/contracts/randomizer/deprecated/RandomizerV2.sol/BasicRandomizerV2.json +2 -2
- package/artifacts/contracts/randomizer/shared/SharedRandomizerV0.sol/SharedRandomizerV0.json +2 -2
- package/artifacts/contracts/relay/RelayExecutor.sol/RelayExecutor.json +101 -0
- package/artifacts/contracts/relay/RelayExecutorPartialReverts.sol/RelayExecutorPartialReverts.json +120 -0
- package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverrideSplits.sol/GenArt721RoyaltyOverrideSplits.json +263 -0
- package/artifacts/contracts/utils/MintMulticallUtil.sol/IMinterSetPriceV5.json +40 -0
- package/artifacts/contracts/utils/MintMulticallUtil.sol/MintMulticallUtil.json +163 -0
- package/artifacts/contracts/web3call/PMPV0.sol/PMPV0.json +2 -2
- package/artifacts/contracts/web3call/PMPV1.sol/PMPV1.json +648 -0
- package/artifacts/contracts/web3call/augment-hooks/InjectBaseGasFee.sol/InjectBaseGasFee.json +2 -2
- package/artifacts/contracts/web3call/augment-hooks/InjectBlockHeight.sol/InjectBlockHeight.json +83 -0
- package/artifacts/contracts/web3call/augment-hooks/InjectBlockHeightAndArtistProjectOverrides.sol/InjectBlockHeightAndArtistProjectOverrides.json +226 -0
- package/artifacts/contracts/web3call/augment-hooks/InjectBlockHeightAndNumOwnedProjectTokens.sol/InjectBlockHeightAndNumOwnedProjectTokens.json +182 -0
- package/artifacts/contracts/web3call/augment-hooks/InjectBlockHeightProjectInvocationsAndArtistProjectOverrides.sol/InjectBlockHeightProjectInvocationsAndArtistProjectOverrides.json +226 -0
- package/artifacts/contracts/web3call/augment-hooks/InjectBlockTimestamp.sol/InjectBlockTimestamp.json +83 -0
- package/artifacts/contracts/web3call/augment-hooks/InjectBytesPerToken.sol/InjectBytesPerToken.json +358 -0
- package/artifacts/contracts/web3call/augment-hooks/InjectChromieSquiggleFloorPrice.sol/InjectChromieSquiggleFloorPrice.json +2 -2
- package/artifacts/contracts/web3call/augment-hooks/InjectIsNounsDaoMember.sol/InjectIsNounsDaoMember.json +2 -2
- package/artifacts/contracts/web3call/augment-hooks/InjectIsProjectFullyMinted.sol/InjectIsProjectFullyMinted.json +2 -2
- package/artifacts/contracts/web3call/augment-hooks/InjectPolyptychTokenHash.sol/InjectPolyptychTokenHash.json +2 -2
- package/artifacts/contracts/web3call/augment-hooks/InjectTokenHashSeed.sol/InjectTokenHashSeed.json +2 -2
- package/artifacts/contracts/web3call/augment-hooks/InjectTokenOwner.sol/InjectTokenOwner.json +2 -2
- package/artifacts/contracts/web3call/augment-hooks/InjectTokenOwnerEthBalance.sol/InjectTokenOwnerEthBalance.json +2 -2
- package/artifacts/contracts/web3call/augment-hooks/InjectUSDCTotalSupply.sol/InjectUSDCTotalSupply.json +2 -2
- package/artifacts/contracts/web3call/augment-hooks/SRHooks.sol/SRHooks.json +899 -0
- package/artifacts/contracts/web3call/combined-hooks/LiftHooks.sol/IGenArt721V0_Minimal.json +30 -0
- package/artifacts/contracts/web3call/combined-hooks/LiftHooks.sol/IRelic.json +35 -0
- package/artifacts/contracts/web3call/combined-hooks/LiftHooks.sol/LiftHooks.json +256 -0
- package/artifacts/contracts/web3call/configure-hooks/{abstractPMPConfigureHook.sol → AbstractPMPConfigureHook.sol}/AbstractPMPConfigureHook.json +1 -1
- package/artifacts/contracts/web3call/configure-hooks/PMPConfigureLockHook.sol/PMPConfigureLockHook.json +195 -0
- package/contracts/AdminACLV0RoyaltyRegistry.sol +142 -0
- package/contracts/DependencyRegistryV0.sol +143 -13
- package/contracts/GenArt721CoreV3_Curated.sol +1 -1
- package/contracts/GenArt721CoreV3_Curated_Flex.sol +173 -0
- package/contracts/GenArt721CoreV3_Explorations_Flex.sol +159 -0
- package/contracts/engine/V3/EngineFactoryV0.sol +20 -1
- package/contracts/engine/V3/GenArt721CoreV3_Engine.sol +286 -299
- package/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol +292 -301
- package/contracts/engine/V3/transfer-hooks/AbstractTransferHook.sol +101 -0
- package/contracts/engine/V3/transfer-hooks/OwnerHistoryTransferHook.sol +291 -0
- package/contracts/generator/GenArt721GeneratorV0.sol +145 -47
- package/contracts/helpers/ERC1967ProxyImport.sol +5 -0
- package/contracts/interfaces/v0.8.x/IArtblocksRoyaltyOverride.sol +1 -1
- package/contracts/interfaces/v0.8.x/IClaimMinter.sol +70 -0
- package/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol +95 -0
- package/contracts/interfaces/v0.8.x/IEngineFactoryV0.sol +15 -0
- package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Base.sol +21 -2
- package/contracts/interfaces/v0.8.x/IGenArt721CoreContractV3_Engine.sol +72 -0
- package/contracts/interfaces/v0.8.x/IOwnerHistoryTransferHook.sol +119 -0
- package/contracts/interfaces/v0.8.x/ISRHooks.sol +229 -0
- package/contracts/interfaces/v0.8.x/ISeaDropShimForContract.sol +0 -6
- package/contracts/interfaces/v0.8.x/ISharedMinterTieredAllowV0.sol +69 -0
- package/contracts/interfaces/v0.8.x/ITransferHook.sol +48 -0
- package/contracts/libs/v0.8.x/DependencyRegistryStorageLib.sol +12 -0
- package/contracts/libs/v0.8.x/ENSLib.sol +85 -0
- package/contracts/libs/v0.8.x/EnumerableSetUint16.sol +429 -0
- package/contracts/libs/v0.8.x/FeistelWalkLib.sol +221 -0
- package/contracts/libs/v0.8.x/ImmutableUint16Array.sol +201 -0
- package/contracts/libs/v0.8.x/V3EngineLib.sol +490 -0
- package/contracts/libs/v0.8.x/V3TransferHookLib.sol +251 -0
- package/contracts/libs/v0.8.x/minter-libs/OnChainAllowlistLib.sol +165 -0
- package/contracts/minter-suite/Minters/MinterSetPriceOnChainAllowV0.sol +632 -0
- package/contracts/minter-suite/Minters/MinterSetPriceTieredAllowV1.sol +871 -0
- package/contracts/minter-suite/Minters/MinterSlidingScaleV0.sol +493 -0
- package/contracts/minter-suite/Minters/one-off/ClaimMinter.sol +595 -0
- package/contracts/minter-suite/Minters/one-off/MinterSetPriceTieredOnChainAllowV0.sol +894 -0
- package/contracts/minter-suite/Minters/one-off/SeaDropXArtBlocksShim.sol +59 -41
- package/contracts/mock/ENSLibMock.sol +25 -0
- package/contracts/mock/EnumerableSetUint16Mock.sol +88 -0
- package/contracts/mock/FeistelWalkLibMock.sol +81 -0
- package/contracts/mock/ImmutableUint16ArrayMock.sol +62 -0
- package/contracts/mock/MockGenArt721V3Core.sol +416 -0
- package/contracts/mock/MockPMP.sol +287 -0
- package/contracts/mock/MockTransferHook.sol +160 -0
- package/contracts/mock/MockTransferHookTestHelpers.sol +96 -0
- package/contracts/mock/ReentrancyBatchMockShared.sol +53 -0
- package/contracts/mock/RelayExecutorTestHelper.sol +44 -0
- package/contracts/relay/RelayExecutor.sol +61 -0
- package/contracts/relay/RelayExecutorPartialReverts.sol +79 -0
- package/contracts/royalty-registry/GenArt721RoyaltyOverrideSplits.sol +130 -0
- package/contracts/utils/MintMulticallUtil.sol +103 -0
- package/contracts/web3call/PMPV1.sol +1204 -0
- package/contracts/web3call/augment-hooks/AbstractPMPAugmentHook.sol +1 -1
- package/contracts/web3call/augment-hooks/InjectBaseGasFee.sol +1 -1
- package/contracts/web3call/augment-hooks/InjectBlockHeight.sol +57 -0
- package/contracts/web3call/augment-hooks/InjectBlockHeightAndArtistProjectOverrides.sol +310 -0
- package/contracts/web3call/augment-hooks/InjectBlockHeightAndNumOwnedProjectTokens.sol +141 -0
- package/contracts/web3call/augment-hooks/InjectBlockHeightProjectInvocationsAndArtistProjectOverrides.sol +326 -0
- package/contracts/web3call/augment-hooks/InjectBlockTimestamp.sol +57 -0
- package/contracts/web3call/augment-hooks/InjectBytesPerToken.sol +279 -0
- package/contracts/web3call/augment-hooks/InjectIsProjectFullyMinted.sol +1 -1
- package/contracts/web3call/augment-hooks/InjectTokenHashSeed.sol +1 -1
- package/contracts/web3call/augment-hooks/InjectTokenOwner.sol +1 -1
- package/contracts/web3call/augment-hooks/InjectTokenOwnerEthBalance.sol +1 -1
- package/contracts/web3call/augment-hooks/SRHooks.sol +1722 -0
- package/contracts/web3call/combined-hooks/LiftHooks.sol +304 -0
- package/contracts/web3call/configure-hooks/{abstractPMPConfigureHook.sol → AbstractPMPConfigureHook.sol} +1 -1
- package/contracts/web3call/configure-hooks/PMPConfigureLockHook.sol +107 -0
- package/package.json +39 -24
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
// SPDX-License-Identifier: LGPL-3.0-only
|
|
2
|
+
// Created By: Art Blocks Inc.
|
|
3
|
+
|
|
4
|
+
pragma solidity 0.8.22;
|
|
5
|
+
|
|
6
|
+
import {AbstractPMPAugmentHook} from "./AbstractPMPAugmentHook.sol";
|
|
7
|
+
import {ABHelpers} from "../../libs/v0.8.x/ABHelpers.sol";
|
|
8
|
+
|
|
9
|
+
import {IWeb3Call} from "../../interfaces/v0.8.x/IWeb3Call.sol";
|
|
10
|
+
import {IGenArt721CoreContractV3_Base} from "../../interfaces/v0.8.x/IGenArt721CoreContractV3_Base.sol";
|
|
11
|
+
|
|
12
|
+
import {Strings} from "@openzeppelin-5.0/contracts/utils/Strings.sol";
|
|
13
|
+
import {EnumerableMap} from "@openzeppelin-5.0/contracts/utils/structs/EnumerableMap.sol";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @title InjectBlockHeightAndArtistProjectOverrides
|
|
17
|
+
* @author Art Blocks Inc.
|
|
18
|
+
* @notice This hook appends the current block height, current project invocations, and artist project overrides into a token's PMPs.
|
|
19
|
+
* If an input PMP has a key that matches an artist project override, the artist project override value will be used.
|
|
20
|
+
* If an override value is not in the input PMPs, it will be appended to the output, ensuring that the output always contains all override values.
|
|
21
|
+
* @dev This contract is developed open-source, is lightly tested, and should be used at your own risk.
|
|
22
|
+
* The artist can set and clear overrides for a project via the `artistSetProjectOverride` and `artistClearProjectOverride` functions.
|
|
23
|
+
* The artist can only set and clear overrides for their own projects.
|
|
24
|
+
* This contract is not owned, and intended to integrate with Art Blocks core contracts that conform to IGenArt721CoreContractV3_Base.
|
|
25
|
+
*/
|
|
26
|
+
contract InjectBlockHeightProjectInvocationsAndArtistProjectOverrides is
|
|
27
|
+
AbstractPMPAugmentHook
|
|
28
|
+
{
|
|
29
|
+
using Strings for uint256;
|
|
30
|
+
using EnumerableMap for EnumerableMap.Bytes32ToBytes32Map;
|
|
31
|
+
|
|
32
|
+
event ArtistProjectOverrideSet(
|
|
33
|
+
address indexed coreContract,
|
|
34
|
+
uint256 indexed projectId,
|
|
35
|
+
string key,
|
|
36
|
+
string value
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
event ArtistProjectOverrideCleared(
|
|
40
|
+
address indexed coreContract,
|
|
41
|
+
uint256 indexed projectId,
|
|
42
|
+
string key
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// enumerable mapping of project to artist pmp overrides
|
|
46
|
+
// @dev key/value pairs are stored as bytes32 values for gas efficiency and standard library compatibility
|
|
47
|
+
mapping(address coreContract => mapping(uint256 projectId => EnumerableMap.Bytes32ToBytes32Map enumerableOverrides))
|
|
48
|
+
private artistProjectOverrides;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @notice Set a project override for a given key.
|
|
52
|
+
* Only the artist of the project can set the project override.
|
|
53
|
+
* @dev intentionally does not emit events - artist overrides are intended to be not indexed.
|
|
54
|
+
* @param coreContract The address of the core contract.
|
|
55
|
+
* @param projectId The ID of the project.
|
|
56
|
+
* @param key The key to set.
|
|
57
|
+
* @param value The value to set.
|
|
58
|
+
*/
|
|
59
|
+
function artistSetProjectOverride(
|
|
60
|
+
address coreContract,
|
|
61
|
+
uint256 projectId,
|
|
62
|
+
string memory key,
|
|
63
|
+
string memory value
|
|
64
|
+
) external {
|
|
65
|
+
// CHECKS
|
|
66
|
+
_onlyArtist({
|
|
67
|
+
caller: msg.sender,
|
|
68
|
+
coreContract: coreContract,
|
|
69
|
+
projectId: projectId
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// EFFECTS
|
|
73
|
+
EnumerableMap.Bytes32ToBytes32Map
|
|
74
|
+
storage overrides = artistProjectOverrides[coreContract][projectId];
|
|
75
|
+
overrides.set(_toBytes32(key), _toBytes32(value));
|
|
76
|
+
|
|
77
|
+
emit ArtistProjectOverrideSet({
|
|
78
|
+
coreContract: coreContract,
|
|
79
|
+
projectId: projectId,
|
|
80
|
+
key: key,
|
|
81
|
+
value: value
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @notice Clear a project override for a given key.
|
|
87
|
+
* Only the artist of the project can clear the project override.
|
|
88
|
+
* @dev intentionally does not emit events - artist overrides are intended to be not indexed.
|
|
89
|
+
* @param coreContract The address of the core contract.
|
|
90
|
+
* @param projectId The ID of the project.
|
|
91
|
+
* @param key The key to clear.
|
|
92
|
+
*/
|
|
93
|
+
function artistClearProjectOverride(
|
|
94
|
+
address coreContract,
|
|
95
|
+
uint256 projectId,
|
|
96
|
+
string memory key
|
|
97
|
+
) external {
|
|
98
|
+
// CHECKS
|
|
99
|
+
_onlyArtist({
|
|
100
|
+
caller: msg.sender,
|
|
101
|
+
coreContract: coreContract,
|
|
102
|
+
projectId: projectId
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// EFFECTS
|
|
106
|
+
EnumerableMap.Bytes32ToBytes32Map
|
|
107
|
+
storage overrides = artistProjectOverrides[coreContract][projectId];
|
|
108
|
+
require(overrides.remove(_toBytes32(key)), "Key not found");
|
|
109
|
+
|
|
110
|
+
emit ArtistProjectOverrideCleared({
|
|
111
|
+
coreContract: coreContract,
|
|
112
|
+
projectId: projectId,
|
|
113
|
+
key: key
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @notice Get the artist project overrides for a given project.
|
|
119
|
+
* @dev This function is used to get the artist project overrides for a given project.
|
|
120
|
+
* @param coreContract The address of the core contract.
|
|
121
|
+
* @param projectId The ID of the project.
|
|
122
|
+
* @return projectOverrides The artist project overrides for the given project.
|
|
123
|
+
*/
|
|
124
|
+
function getArtistProjectOverrides(
|
|
125
|
+
address coreContract,
|
|
126
|
+
uint256 projectId
|
|
127
|
+
) external view returns (IWeb3Call.TokenParam[] memory projectOverrides) {
|
|
128
|
+
EnumerableMap.Bytes32ToBytes32Map
|
|
129
|
+
storage overrides = artistProjectOverrides[coreContract][projectId];
|
|
130
|
+
uint256 overrideCount = overrides.length();
|
|
131
|
+
// translate enumerable map to expected output format
|
|
132
|
+
projectOverrides = new IWeb3Call.TokenParam[](overrideCount);
|
|
133
|
+
for (uint256 i = 0; i < overrideCount; i++) {
|
|
134
|
+
(bytes32 key, bytes32 value) = overrides.at(i);
|
|
135
|
+
projectOverrides[i] = IWeb3Call.TokenParam({
|
|
136
|
+
key: _fromBytes32(key),
|
|
137
|
+
value: _fromBytes32(value)
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
// @dev implicitly return the projectOverrides array
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @notice Augment the token parameters for a given token.
|
|
145
|
+
* Appends the block height and project invocations into a tokens PMPs, and injects artist project overrides.
|
|
146
|
+
* If an input PMP has a key that matches an artist project override, the artist project override value will be used.
|
|
147
|
+
* If an input PMP has a key that does not match an artist project override, the input PMP will be unaffected in the output.
|
|
148
|
+
* All overrides are appended to the output, ensuring that the output always contains all override values.
|
|
149
|
+
* @dev This hook is called when a token's PostParams are read.
|
|
150
|
+
* @dev This must return all desired tokenParams, not just additional data.
|
|
151
|
+
* @param tokenParams The token parameters for the queried token.
|
|
152
|
+
* @return augmentedTokenParams The augmented token parameters.
|
|
153
|
+
*/
|
|
154
|
+
function onTokenPMPReadAugmentation(
|
|
155
|
+
address coreContract,
|
|
156
|
+
uint256 tokenId,
|
|
157
|
+
IWeb3Call.TokenParam[] calldata tokenParams
|
|
158
|
+
)
|
|
159
|
+
external
|
|
160
|
+
view
|
|
161
|
+
override
|
|
162
|
+
returns (IWeb3Call.TokenParam[] memory augmentedTokenParams)
|
|
163
|
+
{
|
|
164
|
+
// get artist project overrides
|
|
165
|
+
EnumerableMap.Bytes32ToBytes32Map
|
|
166
|
+
storage overrides = artistProjectOverrides[coreContract][
|
|
167
|
+
ABHelpers.tokenIdToProjectId({tokenId: tokenId}) // project id
|
|
168
|
+
];
|
|
169
|
+
uint256 overrideCount = overrides.length();
|
|
170
|
+
|
|
171
|
+
// create a new augmentedTokenParams array with maximum length of
|
|
172
|
+
// input tokenParams + overrideCount + 2 extra elements for BlockHeight and project invocations
|
|
173
|
+
uint256 originalLength = tokenParams.length;
|
|
174
|
+
uint256 augmentedMaxLength = originalLength + overrideCount + 2; // +2 for block height and project invocations
|
|
175
|
+
augmentedTokenParams = new IWeb3Call.TokenParam[](augmentedMaxLength);
|
|
176
|
+
|
|
177
|
+
// copy the original tokenParams into the new array
|
|
178
|
+
for (uint256 i = 0; i < originalLength; i++) {
|
|
179
|
+
augmentedTokenParams[i] = tokenParams[i];
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// get + inject the block height into the new array
|
|
183
|
+
// @dev block scope to avoid stack too deep error
|
|
184
|
+
{
|
|
185
|
+
uint256 currentBlock = block.number;
|
|
186
|
+
augmentedTokenParams[originalLength] = IWeb3Call.TokenParam({
|
|
187
|
+
key: "blockHeight",
|
|
188
|
+
value: currentBlock.toString()
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// get + inject the project invocations into the new array
|
|
193
|
+
{
|
|
194
|
+
uint256 projectId = ABHelpers.tokenIdToProjectId({
|
|
195
|
+
tokenId: tokenId
|
|
196
|
+
});
|
|
197
|
+
(uint256 invocations, , , , , ) = IGenArt721CoreContractV3_Base(
|
|
198
|
+
coreContract
|
|
199
|
+
).projectStateData(projectId);
|
|
200
|
+
augmentedTokenParams[originalLength + 1] = IWeb3Call.TokenParam({
|
|
201
|
+
key: "projectInvocations",
|
|
202
|
+
value: invocations.toString()
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// get + inject the artist project overrides into the new array, overriding any existing param values
|
|
207
|
+
uint256 nextIndex = originalLength + 2;
|
|
208
|
+
// @dev O(i*n) where i is the number of overrides and n is the number of original tokenParams, okay on read function
|
|
209
|
+
for (uint256 i = 0; i < overrideCount; i++) {
|
|
210
|
+
(bytes32 key, bytes32 value) = overrides.at(i);
|
|
211
|
+
// check if the key exists in the original tokenParams, and if so, override the value with artist override
|
|
212
|
+
bool found = false;
|
|
213
|
+
for (uint256 j = 0; j < originalLength; j++) {
|
|
214
|
+
if (_equalsStringAndBytes32({s: tokenParams[j].key, b: key})) {
|
|
215
|
+
augmentedTokenParams[j] = IWeb3Call.TokenParam({
|
|
216
|
+
key: tokenParams[j].key, // @dev key is not changed
|
|
217
|
+
value: _fromBytes32(value) // @dev value is overridden
|
|
218
|
+
});
|
|
219
|
+
found = true;
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// if the key did not exist in the original tokenParams, append it to the augmentedTokenParams array
|
|
224
|
+
if (!found) {
|
|
225
|
+
augmentedTokenParams[nextIndex++] = IWeb3Call.TokenParam({
|
|
226
|
+
key: _fromBytes32(key),
|
|
227
|
+
value: _fromBytes32(value)
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// shorten the augmentedTokenParams array to the new length (which is nextIndex)
|
|
233
|
+
// @dev use assembly to efficiently modify in place
|
|
234
|
+
if (nextIndex < augmentedMaxLength) {
|
|
235
|
+
assembly {
|
|
236
|
+
mstore(augmentedTokenParams, nextIndex)
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// return the augmented tokenParams
|
|
241
|
+
return augmentedTokenParams;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* @notice Only the artist of the project can call the function.
|
|
246
|
+
* @dev reverts if the caller is not the artist of the project.
|
|
247
|
+
* @param caller The address of the caller.
|
|
248
|
+
* @param coreContract The address of the core contract.
|
|
249
|
+
* @param projectId The ID of the project.
|
|
250
|
+
*/
|
|
251
|
+
function _onlyArtist(
|
|
252
|
+
address caller,
|
|
253
|
+
address coreContract,
|
|
254
|
+
uint256 projectId
|
|
255
|
+
) internal view {
|
|
256
|
+
if (
|
|
257
|
+
caller !=
|
|
258
|
+
IGenArt721CoreContractV3_Base(coreContract)
|
|
259
|
+
.projectIdToArtistAddress(projectId)
|
|
260
|
+
) {
|
|
261
|
+
revert("Only artist of project");
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* @notice Convert a string to a bytes32 value.
|
|
267
|
+
* Reverts if the string is longer than 32 bytes.
|
|
268
|
+
* @dev This is a helper function to convert a string to a bytes32 value.
|
|
269
|
+
* @param str The string to convert.
|
|
270
|
+
* @return result The bytes32 value of the string.
|
|
271
|
+
*/
|
|
272
|
+
function _toBytes32(
|
|
273
|
+
string memory str
|
|
274
|
+
) internal pure returns (bytes32 result) {
|
|
275
|
+
bytes memory temp = bytes(str);
|
|
276
|
+
if (temp.length > 32) {
|
|
277
|
+
revert("String too long");
|
|
278
|
+
}
|
|
279
|
+
// copy the string directly to the bytes32 result, skipping the first 32 bytes (string length)
|
|
280
|
+
assembly {
|
|
281
|
+
result := mload(add(str, 32))
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* @notice Convert a bytes32-encoded string value to a string.
|
|
287
|
+
* @dev This is a helper function to convert a bytes32-encoded string value to a string.
|
|
288
|
+
* @param b The bytes32 value to convert.
|
|
289
|
+
* @return The string value of the bytes32 value.
|
|
290
|
+
*/
|
|
291
|
+
function _fromBytes32(bytes32 b) internal pure returns (string memory) {
|
|
292
|
+
// determine the length of the string
|
|
293
|
+
uint256 len = 0;
|
|
294
|
+
for (; len < 32; ++len) {
|
|
295
|
+
if (b[len] == 0) break;
|
|
296
|
+
}
|
|
297
|
+
// create a new string with the length of the string
|
|
298
|
+
// @dev solidity reserves 32 bytes for length, rounds up to full word for data portion
|
|
299
|
+
string memory result = new string(len);
|
|
300
|
+
assembly {
|
|
301
|
+
let resultData := add(result, 0x20) // skip length prefix (already populated)
|
|
302
|
+
mstore(resultData, b) // store full 32 bytes (write-ahead optimization, okay due to solidity reserving 32 bytes for data)
|
|
303
|
+
}
|
|
304
|
+
return result;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* @notice Compare a string and a bytes32 value, assuming the bytes32 is an encoded string.
|
|
309
|
+
* @dev This is a helper function to compare a string and a bytes32 value.
|
|
310
|
+
* @param s The string to compare.
|
|
311
|
+
* @param b The bytes32 value to compare.
|
|
312
|
+
* @return true if the string and bytes32 value are equal, false otherwise.
|
|
313
|
+
*/
|
|
314
|
+
function _equalsStringAndBytes32(
|
|
315
|
+
string memory s,
|
|
316
|
+
bytes32 b
|
|
317
|
+
) internal pure returns (bool) {
|
|
318
|
+
bytes memory strBytes = bytes(s);
|
|
319
|
+
if (strBytes.length > 32) return false;
|
|
320
|
+
bytes32 strBytes32;
|
|
321
|
+
assembly {
|
|
322
|
+
strBytes32 := mload(add(s, 32))
|
|
323
|
+
}
|
|
324
|
+
return strBytes32 == b;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// SPDX-License-Identifier: LGPL-3.0-only
|
|
2
|
+
// Created By: Art Blocks Inc.
|
|
3
|
+
|
|
4
|
+
pragma solidity 0.8.22;
|
|
5
|
+
|
|
6
|
+
import {AbstractPMPAugmentHook} from "./AbstractPMPAugmentHook.sol";
|
|
7
|
+
|
|
8
|
+
import {IWeb3Call} from "../../interfaces/v0.8.x/IWeb3Call.sol";
|
|
9
|
+
import {Strings} from "@openzeppelin-5.0/contracts/utils/Strings.sol";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @title InjectBlockTimestamp
|
|
13
|
+
* @author Art Blocks Inc.
|
|
14
|
+
* @notice This hook injects the current block timestamp into a token's PMPs.
|
|
15
|
+
*/
|
|
16
|
+
contract InjectBlockTimestamp is AbstractPMPAugmentHook {
|
|
17
|
+
using Strings for uint256;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @notice Augment the token parameters for a given token.
|
|
21
|
+
* Appends the block timestamp into a tokens PMPs.
|
|
22
|
+
* @dev This hook is called when a token's PMPs are read.
|
|
23
|
+
* @dev This must return all desired tokenParams, not just additional data.
|
|
24
|
+
* @param tokenParams The token parameters for the queried token.
|
|
25
|
+
* @return augmentedTokenParams The augmented token parameters.
|
|
26
|
+
*/
|
|
27
|
+
function onTokenPMPReadAugmentation(
|
|
28
|
+
address /* coreContract */,
|
|
29
|
+
uint256 /* tokenId */,
|
|
30
|
+
IWeb3Call.TokenParam[] calldata tokenParams
|
|
31
|
+
)
|
|
32
|
+
external
|
|
33
|
+
view
|
|
34
|
+
override
|
|
35
|
+
returns (IWeb3Call.TokenParam[] memory augmentedTokenParams)
|
|
36
|
+
{
|
|
37
|
+
// create a new tokenParam array with one extra element
|
|
38
|
+
uint256 originalLength = tokenParams.length;
|
|
39
|
+
uint256 newLength = originalLength + 1;
|
|
40
|
+
augmentedTokenParams = new IWeb3Call.TokenParam[](newLength);
|
|
41
|
+
|
|
42
|
+
// copy the original tokenParams into the new array
|
|
43
|
+
for (uint256 i = 0; i < originalLength; i++) {
|
|
44
|
+
augmentedTokenParams[i] = tokenParams[i];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// get + inject the block timestamp into the new array
|
|
48
|
+
uint256 currentTimestamp = block.timestamp;
|
|
49
|
+
augmentedTokenParams[originalLength] = IWeb3Call.TokenParam({
|
|
50
|
+
key: "blockTimestamp",
|
|
51
|
+
value: currentTimestamp.toString()
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// return the augmented tokenParams
|
|
55
|
+
return augmentedTokenParams;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
// SPDX-License-Identifier: LGPL-3.0-only
|
|
2
|
+
// Created By: Art Blocks Inc.
|
|
3
|
+
|
|
4
|
+
pragma solidity 0.8.22;
|
|
5
|
+
|
|
6
|
+
import {AbstractPMPAugmentHook} from "./AbstractPMPAugmentHook.sol";
|
|
7
|
+
|
|
8
|
+
import {IWeb3Call} from "../../interfaces/v0.8.x/IWeb3Call.sol";
|
|
9
|
+
import {SSTORE2} from "../../libs/v0.8.x/SSTORE2.sol";
|
|
10
|
+
import {ABHelpers} from "../../libs/v0.8.x/ABHelpers.sol";
|
|
11
|
+
|
|
12
|
+
import {Strings} from "@openzeppelin-5.0/contracts/utils/Strings.sol";
|
|
13
|
+
import {Ownable} from "@openzeppelin-5.0/contracts/access/Ownable.sol";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @title InjectBytesPerToken
|
|
17
|
+
* @author Art Blocks Inc.
|
|
18
|
+
* @notice This hook injects uploaded bytes per token, into a token's PMPs.
|
|
19
|
+
*/
|
|
20
|
+
contract InjectBytesPerToken is AbstractPMPAugmentHook, Ownable {
|
|
21
|
+
using Strings for uint256;
|
|
22
|
+
|
|
23
|
+
event TokenDataUploadedAtIndex(
|
|
24
|
+
uint256 indexed tokenNumber,
|
|
25
|
+
uint256 indexed chunkIndex,
|
|
26
|
+
address dataPointer
|
|
27
|
+
);
|
|
28
|
+
event TokenDataClearedAtIndex(
|
|
29
|
+
uint256 indexed tokenNumber,
|
|
30
|
+
uint256 indexed chunkIndex
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
// mapping of token number to chunk index to data pointer (SSTORE2 pointer)
|
|
34
|
+
mapping(uint256 tokenNumber => mapping(uint256 chunkIndex => address dataPointer))
|
|
35
|
+
public tokenDataPointers;
|
|
36
|
+
|
|
37
|
+
// mapping of token number to highest chunk index
|
|
38
|
+
mapping(uint256 tokenNumber => uint256 numChunks) public numChunksOfToken;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @notice Constructor
|
|
42
|
+
* @param owner_ The owner of the contract.
|
|
43
|
+
*/
|
|
44
|
+
constructor(address owner_) Ownable(owner_) {}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @notice Augment the token parameters for a given token.
|
|
48
|
+
* Appends uploaded bytes per token into a tokens PMPs.
|
|
49
|
+
* @dev This hook is called when a token's PMPs are read.
|
|
50
|
+
* @dev This must return all desired tokenParams, not just additional data.
|
|
51
|
+
* @param tokenParams The token parameters for the queried token.
|
|
52
|
+
* @return augmentedTokenParams The augmented token parameters.
|
|
53
|
+
*/
|
|
54
|
+
function onTokenPMPReadAugmentation(
|
|
55
|
+
address /* coreContract */,
|
|
56
|
+
uint256 tokenId,
|
|
57
|
+
IWeb3Call.TokenParam[] calldata tokenParams
|
|
58
|
+
)
|
|
59
|
+
external
|
|
60
|
+
view
|
|
61
|
+
override
|
|
62
|
+
returns (IWeb3Call.TokenParam[] memory augmentedTokenParams)
|
|
63
|
+
{
|
|
64
|
+
// create a new tokenParam array with one extra element
|
|
65
|
+
uint256 originalLength = tokenParams.length;
|
|
66
|
+
uint256 newLength = originalLength + 1;
|
|
67
|
+
augmentedTokenParams = new IWeb3Call.TokenParam[](newLength);
|
|
68
|
+
|
|
69
|
+
// copy the original tokenParams into the new array
|
|
70
|
+
for (uint256 i = 0; i < originalLength; i++) {
|
|
71
|
+
augmentedTokenParams[i] = tokenParams[i];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// get + inject the uploaded bytes per token into the new array
|
|
75
|
+
uint256 tokenNumber = ABHelpers.tokenIdToTokenNumber(tokenId);
|
|
76
|
+
augmentedTokenParams[originalLength] = IWeb3Call.TokenParam({
|
|
77
|
+
key: "tokenData",
|
|
78
|
+
value: getAllTokenDataAsHexString(tokenNumber)
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// return the augmented tokenParams
|
|
82
|
+
return augmentedTokenParams;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @notice Upload token data at a specific chunk index
|
|
87
|
+
* @param tokenNumber The token number (not token ID) - derived from tokenId % 1,000,000
|
|
88
|
+
* @param chunkIndex The chunk index (must be sequential - either append to end or overwrite existing)
|
|
89
|
+
* @param data The bytes to store (deployed as SSTORE2 contract)
|
|
90
|
+
* @dev Can overwrite existing chunks. Old SSTORE2 contract remains deployed but orphaned.
|
|
91
|
+
* @dev Only owner can call this function.
|
|
92
|
+
* @dev Emits TokenDataUploadedAtIndex event.
|
|
93
|
+
*/
|
|
94
|
+
function uploadTokenDataAtIndex(
|
|
95
|
+
uint256 tokenNumber,
|
|
96
|
+
uint256 chunkIndex,
|
|
97
|
+
bytes memory data
|
|
98
|
+
) external onlyOwner {
|
|
99
|
+
// CHECKS
|
|
100
|
+
// only allow appending to the end of the data
|
|
101
|
+
uint256 numChunksBefore = numChunksOfToken[tokenNumber];
|
|
102
|
+
require(
|
|
103
|
+
chunkIndex <= numChunksBefore,
|
|
104
|
+
"Must append to end of current array of chunks"
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
// EFFECTS
|
|
108
|
+
// update the number of chunks for the token
|
|
109
|
+
if (chunkIndex == numChunksBefore) {
|
|
110
|
+
numChunksOfToken[tokenNumber] = chunkIndex + 1;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// upload the data to SSTORE2
|
|
114
|
+
address dataPointer = SSTORE2.write(data);
|
|
115
|
+
tokenDataPointers[tokenNumber][chunkIndex] = dataPointer;
|
|
116
|
+
|
|
117
|
+
// emit an event
|
|
118
|
+
emit TokenDataUploadedAtIndex({
|
|
119
|
+
tokenNumber: tokenNumber,
|
|
120
|
+
chunkIndex: chunkIndex,
|
|
121
|
+
dataPointer: dataPointer
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @notice Clear token data at a specific chunk index
|
|
127
|
+
* @param tokenNumber The token number (not token ID)
|
|
128
|
+
* @param chunkIndex The chunk index to clear (must be an existing chunk)
|
|
129
|
+
* @dev Sets the chunk pointer to address(0). Does not delete the SSTORE2 contract.
|
|
130
|
+
* @dev If clearing the last chunk, numChunksOfToken is updated by searching backwards for the last non-zero chunk.
|
|
131
|
+
* @dev If clearing a middle chunk, numChunksOfToken remains unchanged (gaps are allowed).
|
|
132
|
+
* @dev Only owner can call this function.
|
|
133
|
+
* @dev Emits TokenDataClearedAtIndex event.
|
|
134
|
+
*/
|
|
135
|
+
function clearTokenDataAtIndex(
|
|
136
|
+
uint256 tokenNumber,
|
|
137
|
+
uint256 chunkIndex
|
|
138
|
+
) external onlyOwner {
|
|
139
|
+
// CHECKS
|
|
140
|
+
// only allow clearing existing chunks
|
|
141
|
+
uint256 numChunksBefore = numChunksOfToken[tokenNumber];
|
|
142
|
+
require(chunkIndex < numChunksBefore, "Must clear an existing chunk");
|
|
143
|
+
|
|
144
|
+
// EFFECTS
|
|
145
|
+
// clear the data from SSTORE2
|
|
146
|
+
tokenDataPointers[tokenNumber][chunkIndex] = address(0);
|
|
147
|
+
|
|
148
|
+
// update the number of chunks for the token if this was the last chunk
|
|
149
|
+
if (chunkIndex == numChunksBefore - 1) {
|
|
150
|
+
// Search backwards from the cleared chunk to find the new last non-zero chunk
|
|
151
|
+
uint256 newNumChunks = 0;
|
|
152
|
+
for (uint256 i = chunkIndex; i > 0; ) {
|
|
153
|
+
unchecked {
|
|
154
|
+
i--;
|
|
155
|
+
}
|
|
156
|
+
if (tokenDataPointers[tokenNumber][i] != address(0)) {
|
|
157
|
+
newNumChunks = i + 1;
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
numChunksOfToken[tokenNumber] = newNumChunks;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// emit an event
|
|
165
|
+
emit TokenDataClearedAtIndex({
|
|
166
|
+
tokenNumber: tokenNumber,
|
|
167
|
+
chunkIndex: chunkIndex
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* @notice Get token data at a specific chunk index
|
|
173
|
+
* @param tokenNumber The token number (not token ID)
|
|
174
|
+
* @param chunkIndex The chunk index to retrieve (must be less than numChunksOfToken)
|
|
175
|
+
* @return The bytes stored at the given chunk index (empty bytes if chunk was cleared)
|
|
176
|
+
* @dev Returns empty bytes (0x) if the chunk pointer is address(0) (cleared chunk).
|
|
177
|
+
*/
|
|
178
|
+
function getTokenDataAtIndex(
|
|
179
|
+
uint256 tokenNumber,
|
|
180
|
+
uint256 chunkIndex
|
|
181
|
+
) public view returns (bytes memory) {
|
|
182
|
+
// CHECKS
|
|
183
|
+
// only allow getting existing chunks
|
|
184
|
+
uint256 numChunks = numChunksOfToken[tokenNumber];
|
|
185
|
+
require(chunkIndex < numChunks, "Must get an existing chunk");
|
|
186
|
+
|
|
187
|
+
// get the data from SSTORE2
|
|
188
|
+
address dataPointer = tokenDataPointers[tokenNumber][chunkIndex];
|
|
189
|
+
// if a cleared chunk, return an empty bytes array
|
|
190
|
+
if (dataPointer == address(0)) {
|
|
191
|
+
return bytes("");
|
|
192
|
+
}
|
|
193
|
+
// return the data from SSTORE2
|
|
194
|
+
return SSTORE2.read(dataPointer);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @notice Get all token data concatenated from all chunks
|
|
199
|
+
* @param tokenNumber The token number (not token ID)
|
|
200
|
+
* @return All bytes concatenated from all chunks (skips cleared chunks with empty data)
|
|
201
|
+
* @dev Iterates through all chunks up to numChunksOfToken and concatenates non-empty chunks.
|
|
202
|
+
* @dev Gas consumption scales with number of chunks and total data size.
|
|
203
|
+
*/
|
|
204
|
+
function getAllTokenData(
|
|
205
|
+
uint256 tokenNumber
|
|
206
|
+
) public view returns (bytes memory) {
|
|
207
|
+
// get the number of chunks for the token
|
|
208
|
+
uint256 numChunks = numChunksOfToken[tokenNumber];
|
|
209
|
+
// iterate over all chunks and get the data from SSTORE2
|
|
210
|
+
bytes memory allData;
|
|
211
|
+
for (uint256 i = 0; i < numChunks; i++) {
|
|
212
|
+
bytes memory chunkData = getTokenDataAtIndex(tokenNumber, i);
|
|
213
|
+
if (chunkData.length > 0) {
|
|
214
|
+
allData = bytes.concat(allData, chunkData);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return allData;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* @notice Get all token data as a hex-encoded string with "0x" prefix
|
|
222
|
+
* @param tokenNumber The token number (not token ID)
|
|
223
|
+
* @return Hex string representation of all concatenated token data (e.g., "0x414243" for "ABC")
|
|
224
|
+
* @dev Returns "0x" if token has no data.
|
|
225
|
+
* @dev Uses Solady's efficient hex encoding implementation.
|
|
226
|
+
*/
|
|
227
|
+
function getAllTokenDataAsHexString(
|
|
228
|
+
uint256 tokenNumber
|
|
229
|
+
) public view returns (string memory) {
|
|
230
|
+
bytes memory data = getAllTokenData(tokenNumber);
|
|
231
|
+
return toHexString(data);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// --- HELPER FUNCTIONS FROM SOLADY https://github.com/Vectorized/solady/blob/main/src/utils/LibString.sol ---
|
|
235
|
+
|
|
236
|
+
/// @dev Returns the hex encoded string from the raw bytes.
|
|
237
|
+
/// The output is encoded using 2 hexadecimal digits per byte.
|
|
238
|
+
function toHexString(
|
|
239
|
+
bytes memory raw
|
|
240
|
+
) internal pure returns (string memory result) {
|
|
241
|
+
result = toHexStringNoPrefix(raw);
|
|
242
|
+
/// @solidity memory-safe-assembly
|
|
243
|
+
assembly {
|
|
244
|
+
let n := add(mload(result), 2) // Compute the length.
|
|
245
|
+
mstore(result, 0x3078) // Store the "0x" prefix.
|
|
246
|
+
result := sub(result, 2) // Move the pointer.
|
|
247
|
+
mstore(result, n) // Store the length.
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/// @dev Returns the hex encoded string from the raw bytes.
|
|
252
|
+
/// The output is encoded using 2 hexadecimal digits per byte.
|
|
253
|
+
function toHexStringNoPrefix(
|
|
254
|
+
bytes memory raw
|
|
255
|
+
) internal pure returns (string memory result) {
|
|
256
|
+
/// @solidity memory-safe-assembly
|
|
257
|
+
assembly {
|
|
258
|
+
let n := mload(raw)
|
|
259
|
+
result := add(mload(0x40), 2) // Skip 2 bytes for the optional prefix.
|
|
260
|
+
mstore(result, add(n, n)) // Store the length of the output.
|
|
261
|
+
|
|
262
|
+
mstore(0x0f, 0x30313233343536373839616263646566) // Store the "0123456789abcdef" lookup.
|
|
263
|
+
let o := add(result, 0x20)
|
|
264
|
+
let end := add(raw, n)
|
|
265
|
+
for {
|
|
266
|
+
|
|
267
|
+
} iszero(eq(raw, end)) {
|
|
268
|
+
|
|
269
|
+
} {
|
|
270
|
+
raw := add(raw, 1)
|
|
271
|
+
mstore8(add(o, 1), mload(and(mload(raw), 15)))
|
|
272
|
+
mstore8(o, mload(and(shr(4, mload(raw)), 15)))
|
|
273
|
+
o := add(o, 2)
|
|
274
|
+
}
|
|
275
|
+
mstore(o, 0) // Zeroize the slot after the string.
|
|
276
|
+
mstore(0x40, add(o, 0x20)) // Allocate memory.
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|