@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
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
// SPDX-License-Identifier: LGPL-3.0-only
|
|
2
|
+
// Created By: Art Blocks Inc.
|
|
3
|
+
|
|
4
|
+
pragma solidity ^0.8.0;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @title Art Blocks Script Storage Library
|
|
8
|
+
* @notice Utilize contract bytecode as persistent storage for large chunks of script string data.
|
|
9
|
+
* This library is intended to have an external deployed copy that is released in the future,
|
|
10
|
+
* and, as such, has been designed to support both updated V1 (versioned, with purging removed)
|
|
11
|
+
* reads as well as backwards-compatible reads for both a) the unversioned "V0" storage contracts
|
|
12
|
+
* which were deployed by the original version of this libary and b) contracts that were deployed
|
|
13
|
+
* using one of the SSTORE2 implementations referenced below.
|
|
14
|
+
* For these pre-V1 storage contracts (which themselves did not have any explicit versioning semantics)
|
|
15
|
+
* backwards-compatible reads are optimistic, and only expected to work for contracts actually
|
|
16
|
+
* deployed by the original version of this library – and may fail ungracefully if attempted to be
|
|
17
|
+
* used to read from other contracts.
|
|
18
|
+
* This library is split into two components, intended to be updated in tandem, and thus included
|
|
19
|
+
* here in the same source file. One component is an internal library that is intended to be embedded
|
|
20
|
+
* directly into other contracts and provides all _write_ functionality. The other is a public library
|
|
21
|
+
* that is intended to be deployed as a standalone contract and provides all _read_ functionality.
|
|
22
|
+
*
|
|
23
|
+
* @author Art Blocks Inc.
|
|
24
|
+
* @author Modified from 0xSequence (https://github.com/0xsequence/sstore2/blob/master/contracts/SSTORE2.sol)
|
|
25
|
+
* @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SSTORE2.sol)
|
|
26
|
+
*
|
|
27
|
+
* @dev Compared to the above two rerferenced libraries, this contracts-as-storage implementation makes a few
|
|
28
|
+
* notably different design decisions:
|
|
29
|
+
* - uses the `string` data type for input/output on reads, rather than speaking in bytes directly
|
|
30
|
+
* - stores the "writer" address (library user) in the deployed contract bytes, which is useful for
|
|
31
|
+
* on-chain introspection and provenance purposes
|
|
32
|
+
* - stores a very simple versioning string in the deployed contract bytes, which captures the version
|
|
33
|
+
* of the library that was used to deploy the storage contract and useful for supporting future
|
|
34
|
+
* compatibility management as this library evolves (e.g. in response to EOF v1 migration plans)
|
|
35
|
+
* Also, given that much of this library is written in assembly, this library makes use of a slightly
|
|
36
|
+
* different convention (when compared to the rest of the Art Blocks smart contract repo) around
|
|
37
|
+
* pre-defining return values in some cases in order to simplify need to directly memory manage these
|
|
38
|
+
* return values.
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @title Art Blocks Script Storage Library (Public, Reads)
|
|
43
|
+
* @author Art Blocks Inc.
|
|
44
|
+
* @notice The public library for reading from storage contracts. This library is intended to be deployed as a
|
|
45
|
+
* standalone contract, and provides all _read_ functionality.
|
|
46
|
+
*/
|
|
47
|
+
library BytecodeStorageReader {
|
|
48
|
+
// Define the set of known valid version strings that may be stored in the deployed storage contract bytecode
|
|
49
|
+
// note: These are all intentionally exactly 32-bytes and are null-terminated. Null-termination is used due
|
|
50
|
+
// to this being the standard expected formatting in common web3 tooling such as ethers.js. Please see
|
|
51
|
+
// the following for additional context: https://docs.ethers.org/v5/api/utils/strings/#Bytes32String
|
|
52
|
+
// Used for storage contracts that were deployed by an unknown source
|
|
53
|
+
bytes32 public constant UNKNOWN_VERSION_STRING =
|
|
54
|
+
"UNKNOWN_VERSION_STRING_________ ";
|
|
55
|
+
// Pre-dates versioning string, so this doesn't actually exist in any deployed contracts,
|
|
56
|
+
// but is useful for backwards-compatible semantics with original version of this library
|
|
57
|
+
bytes32 public constant V0_VERSION_STRING =
|
|
58
|
+
"BytecodeStorage_V0.0.0_________ ";
|
|
59
|
+
// The first versioned storage contract, deployed by an updated version of this library
|
|
60
|
+
bytes32 public constant V1_VERSION_STRING =
|
|
61
|
+
"BytecodeStorage_V1.0.0_________ ";
|
|
62
|
+
// The current version of this library.
|
|
63
|
+
bytes32 public constant CURRENT_VERSION = V1_VERSION_STRING;
|
|
64
|
+
|
|
65
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
66
|
+
// Starting Index | Size | Ending Index | Description //
|
|
67
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
68
|
+
// 0 | N/A | 0 | //
|
|
69
|
+
// 0 | 1 | 1 | single byte opcode for making the storage contract non-executable //
|
|
70
|
+
// 1 | 32 | 33 | the 32 byte slot used for storing a basic versioning string //
|
|
71
|
+
// 33 | 32 | 65 | the 32 bytes for storing the deploying contract's (0-padded) address //
|
|
72
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
73
|
+
// Define the offset for where the "meta bytes" end, and the "data bytes" begin. Note that this is a manually
|
|
74
|
+
// calculated value, and must be updated if the above table is changed. It is expected that tests will fail
|
|
75
|
+
// loudly if these values are not updated in-step with eachother.
|
|
76
|
+
uint256 private constant VERSION_OFFSET = 1;
|
|
77
|
+
uint256 private constant ADDRESS_OFFSET = 33;
|
|
78
|
+
uint256 private constant DATA_OFFSET = 65;
|
|
79
|
+
|
|
80
|
+
// Define the set of known *historic* offset values for where the "meta bytes" end, and the "data bytes" begin.
|
|
81
|
+
// SSTORE2 deployed storage contracts take the general format of:
|
|
82
|
+
// concat(0x00, data)
|
|
83
|
+
// note: this is true for both variants of the SSTORE2 library
|
|
84
|
+
uint256 private constant SSTORE2_DATA_OFFSET = 1;
|
|
85
|
+
// V0 deployed storage contracts take the general format of:
|
|
86
|
+
// concat(gated-cleanup-logic, deployer-address, data)
|
|
87
|
+
uint256 private constant V0_ADDRESS_OFFSET = 72;
|
|
88
|
+
uint256 private constant V0_DATA_OFFSET = 104;
|
|
89
|
+
// V1 deployed storage contracts take the general format of:
|
|
90
|
+
// concat(invalid opcode, version, deployer-address, data)
|
|
91
|
+
uint256 private constant V1_ADDRESS_OFFSET = ADDRESS_OFFSET;
|
|
92
|
+
uint256 private constant V1_DATA_OFFSET = DATA_OFFSET;
|
|
93
|
+
|
|
94
|
+
/*//////////////////////////////////////////////////////////////
|
|
95
|
+
READ LOGIC
|
|
96
|
+
//////////////////////////////////////////////////////////////*/
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @notice Read a string from contract bytecode
|
|
100
|
+
* @param _address address of deployed contract with bytecode stored in the V0 or V1 format
|
|
101
|
+
* @return data string read from contract bytecode
|
|
102
|
+
* @dev This function performs input validation that the contract to read is in an expected format
|
|
103
|
+
*/
|
|
104
|
+
function readFromBytecode(
|
|
105
|
+
address _address
|
|
106
|
+
) public view returns (string memory data) {
|
|
107
|
+
uint256 dataOffset = _bytecodeDataOffsetAt(_address);
|
|
108
|
+
return string(readBytesFromBytecode(_address, dataOffset));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* @notice Read the bytes from contract bytecode that was written to the EVM using SSTORE2
|
|
113
|
+
* @param _address address of deployed contract with bytecode stored in the SSTORE2 format
|
|
114
|
+
* @return data bytes read from contract bytecode
|
|
115
|
+
* @dev This function performs no input validation on the provided contract,
|
|
116
|
+
* other than that there is content to read (but not that its a "storage contract")
|
|
117
|
+
*/
|
|
118
|
+
function readBytesFromSSTORE2Bytecode(
|
|
119
|
+
address _address
|
|
120
|
+
) public view returns (bytes memory data) {
|
|
121
|
+
return readBytesFromBytecode(_address, SSTORE2_DATA_OFFSET);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @notice Read the bytes from contract bytecode, with an explicitly provided starting offset
|
|
126
|
+
* @param _address address of deployed contract with bytecode stored in the V0 or V1 format
|
|
127
|
+
* @param _offset offset to read from in contract bytecode, explicitly provided (not calculated)
|
|
128
|
+
* @return data bytes read from contract bytecode
|
|
129
|
+
* @dev This function performs no input validation on the provided contract,
|
|
130
|
+
* other than that there is content to read (but not that its a "storage contract")
|
|
131
|
+
*/
|
|
132
|
+
function readBytesFromBytecode(
|
|
133
|
+
address _address,
|
|
134
|
+
uint256 _offset
|
|
135
|
+
) public view returns (bytes memory data) {
|
|
136
|
+
// get the size of the bytecode
|
|
137
|
+
uint256 bytecodeSize = _bytecodeSizeAt(_address);
|
|
138
|
+
// handle case where address contains code < _offset
|
|
139
|
+
if (bytecodeSize < _offset) {
|
|
140
|
+
revert("ContractAsStorage: Read Error");
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// handle case where address contains code >= dataOffset
|
|
144
|
+
// decrement by dataOffset to account for header info
|
|
145
|
+
uint256 size;
|
|
146
|
+
unchecked {
|
|
147
|
+
size = bytecodeSize - _offset;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
assembly {
|
|
151
|
+
// allocate free memory
|
|
152
|
+
data := mload(0x40)
|
|
153
|
+
// update free memory pointer
|
|
154
|
+
// use and(x, not(0x1f) as cheaper equivalent to sub(x, mod(x, 0x20)).
|
|
155
|
+
// adding 0x1f to size + logic above ensures the free memory pointer
|
|
156
|
+
// remains word-aligned, following the Solidity convention.
|
|
157
|
+
mstore(0x40, add(data, and(add(add(size, 0x20), 0x1f), not(0x1f))))
|
|
158
|
+
// store length of data in first 32 bytes
|
|
159
|
+
mstore(data, size)
|
|
160
|
+
// copy code to memory, excluding the deployer-address
|
|
161
|
+
extcodecopy(_address, add(data, 0x20), _offset, size)
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* @notice Get address for deployer for given contract bytecode
|
|
167
|
+
* @param _address address of deployed contract with bytecode stored in the V0 or V1 format
|
|
168
|
+
* @return writerAddress address read from contract bytecode
|
|
169
|
+
*/
|
|
170
|
+
function getWriterAddressForBytecode(
|
|
171
|
+
address _address
|
|
172
|
+
) public view returns (address) {
|
|
173
|
+
// get the size of the data
|
|
174
|
+
uint256 bytecodeSize = _bytecodeSizeAt(_address);
|
|
175
|
+
// the dataOffset for the bytecode
|
|
176
|
+
uint256 addressOffset = _bytecodeAddressOffsetAt(_address);
|
|
177
|
+
// handle case where address contains code < addressOffset + 32 (address takes a whole slot)
|
|
178
|
+
if (bytecodeSize < (addressOffset + 32)) {
|
|
179
|
+
revert("ContractAsStorage: Read Error");
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
assembly {
|
|
183
|
+
// allocate free memory
|
|
184
|
+
let writerAddress := mload(0x40)
|
|
185
|
+
// shift free memory pointer by one slot
|
|
186
|
+
mstore(0x40, add(mload(0x40), 0x20))
|
|
187
|
+
// copy the 32-byte address of the data contract writer to memory
|
|
188
|
+
// note: this relies on the assumption noted at the top-level of
|
|
189
|
+
// this file that the storage layout for the deployed
|
|
190
|
+
// contracts-as-storage contract looks like::
|
|
191
|
+
// | invalid opcode | version-string (unless v0) | deployer-address (padded) | data |
|
|
192
|
+
extcodecopy(
|
|
193
|
+
_address,
|
|
194
|
+
writerAddress,
|
|
195
|
+
addressOffset,
|
|
196
|
+
0x20 // full 32-bytes, as address is expected to be zero-padded
|
|
197
|
+
)
|
|
198
|
+
return(
|
|
199
|
+
writerAddress,
|
|
200
|
+
0x20 // return size is entire slot, as it is zero-padded
|
|
201
|
+
)
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* @notice Get version for given contract bytecode
|
|
207
|
+
* @param _address address of deployed contract with bytecode stored in the V0 or V1 format
|
|
208
|
+
* @return version version read from contract bytecode
|
|
209
|
+
*/
|
|
210
|
+
function getLibraryVersionForBytecode(
|
|
211
|
+
address _address
|
|
212
|
+
) public view returns (bytes32) {
|
|
213
|
+
return _bytecodeVersionAt(_address);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/*//////////////////////////////////////////////////////////////
|
|
217
|
+
INTERNAL HELPER LOGIC
|
|
218
|
+
//////////////////////////////////////////////////////////////*/
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* @notice Returns the size of the bytecode at address `_address`
|
|
222
|
+
* @param _address address that may or may not contain bytecode
|
|
223
|
+
* @return size size of the bytecode code at `_address`
|
|
224
|
+
*/
|
|
225
|
+
function _bytecodeSizeAt(
|
|
226
|
+
address _address
|
|
227
|
+
) private view returns (uint256 size) {
|
|
228
|
+
assembly {
|
|
229
|
+
size := extcodesize(_address)
|
|
230
|
+
}
|
|
231
|
+
if (size == 0) {
|
|
232
|
+
revert("ContractAsStorage: Read Error");
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* @notice Returns the offset of the data in the bytecode at address `_address`
|
|
238
|
+
* @param _address address that may or may not contain bytecode
|
|
239
|
+
* @return dataOffset offset of data in bytecode if a known version, otherwise 0
|
|
240
|
+
*/
|
|
241
|
+
function _bytecodeDataOffsetAt(
|
|
242
|
+
address _address
|
|
243
|
+
) private view returns (uint256 dataOffset) {
|
|
244
|
+
bytes32 version = _bytecodeVersionAt(_address);
|
|
245
|
+
if (version == V1_VERSION_STRING) {
|
|
246
|
+
dataOffset = V1_DATA_OFFSET;
|
|
247
|
+
} else if (version == V0_VERSION_STRING) {
|
|
248
|
+
dataOffset = V0_DATA_OFFSET;
|
|
249
|
+
} else {
|
|
250
|
+
// unknown version, revert
|
|
251
|
+
revert("ContractAsStorage: Unsupported Version");
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* @notice Returns the offset of the address in the bytecode at address `_address`
|
|
257
|
+
* @param _address address that may or may not contain bytecode
|
|
258
|
+
* @return addressOffset offset of address in bytecode if a known version, otherwise 0
|
|
259
|
+
*/
|
|
260
|
+
function _bytecodeAddressOffsetAt(
|
|
261
|
+
address _address
|
|
262
|
+
) private view returns (uint256 addressOffset) {
|
|
263
|
+
bytes32 version = _bytecodeVersionAt(_address);
|
|
264
|
+
if (version == V1_VERSION_STRING) {
|
|
265
|
+
addressOffset = V1_ADDRESS_OFFSET;
|
|
266
|
+
} else if (version == V0_VERSION_STRING) {
|
|
267
|
+
addressOffset = V0_ADDRESS_OFFSET;
|
|
268
|
+
} else {
|
|
269
|
+
// unknown version, revert
|
|
270
|
+
revert("ContractAsStorage: Unsupported Version");
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* @notice Get version string for given contract bytecode
|
|
276
|
+
* @param _address address of deployed contract with bytecode stored in the V0 or V1 format
|
|
277
|
+
* @return version version string read from contract bytecode
|
|
278
|
+
*/
|
|
279
|
+
function _bytecodeVersionAt(
|
|
280
|
+
address _address
|
|
281
|
+
) private view returns (bytes32 version) {
|
|
282
|
+
// get the size of the data
|
|
283
|
+
uint256 bytecodeSize = _bytecodeSizeAt(_address);
|
|
284
|
+
// handle case where address contains code < minimum expected version string size,
|
|
285
|
+
// by returning early with the unknown version string
|
|
286
|
+
if (bytecodeSize < (VERSION_OFFSET + 32)) {
|
|
287
|
+
return UNKNOWN_VERSION_STRING;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
assembly {
|
|
291
|
+
// allocate free memory
|
|
292
|
+
let versionString := mload(0x40)
|
|
293
|
+
// shift free memory pointer by one slot
|
|
294
|
+
mstore(0x40, add(mload(0x40), 0x20))
|
|
295
|
+
// copy the 32-byte version string of the bytecode library to memory
|
|
296
|
+
// note: this relies on the assumption noted at the top-level of
|
|
297
|
+
// this file that the storage layout for the deployed
|
|
298
|
+
// contracts-as-storage contract looks like:
|
|
299
|
+
// | invalid opcode | version-string (unless v0) | deployer-address (padded) | data |
|
|
300
|
+
extcodecopy(
|
|
301
|
+
_address,
|
|
302
|
+
versionString,
|
|
303
|
+
VERSION_OFFSET,
|
|
304
|
+
0x20 // 32-byte version string
|
|
305
|
+
)
|
|
306
|
+
// note: must check against literal strings, as Yul does not allow for
|
|
307
|
+
// dynamic strings in switch statements.
|
|
308
|
+
switch mload(versionString)
|
|
309
|
+
case "BytecodeStorage_V1.0.0_________ " {
|
|
310
|
+
version := V1_VERSION_STRING
|
|
311
|
+
}
|
|
312
|
+
case 0x2060486000396000513314601057fe5b60013614601957fe5b6000357fff0000 {
|
|
313
|
+
// the v0 variant of this library pre-dates formal versioning w/ version strings,
|
|
314
|
+
// so we check the first 32 bytes of the execution bytecode itself which
|
|
315
|
+
// is static and known across all storage contracts deployed with the first version
|
|
316
|
+
// of this library.
|
|
317
|
+
version := V0_VERSION_STRING
|
|
318
|
+
}
|
|
319
|
+
default {
|
|
320
|
+
version := UNKNOWN_VERSION_STRING
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* @title Art Blocks Script Storage Library (Internal, Writes)
|
|
328
|
+
* @author Art Blocks Inc.
|
|
329
|
+
* @notice The internal library for writing to storage contracts. This library is intended to be deployed
|
|
330
|
+
* within library client contracts that use this library to perform _write_ operations on storage.
|
|
331
|
+
*/
|
|
332
|
+
library BytecodeStorageWriter {
|
|
333
|
+
/*//////////////////////////////////////////////////////////////
|
|
334
|
+
WRITE LOGIC
|
|
335
|
+
//////////////////////////////////////////////////////////////*/
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* @notice Write a string to contract bytecode
|
|
339
|
+
* @param _data string to be written to contract. No input validation is performed on this parameter.
|
|
340
|
+
* @param address_ address of deployed contract with bytecode stored in the V0 or V1 format
|
|
341
|
+
*/
|
|
342
|
+
function writeToBytecode(
|
|
343
|
+
string memory _data
|
|
344
|
+
) internal returns (address address_) {
|
|
345
|
+
// prefix bytecode with
|
|
346
|
+
bytes memory creationCode = abi.encodePacked(
|
|
347
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
348
|
+
// Opcode | Opcode + Arguments | Description | Stack View //
|
|
349
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
350
|
+
// a.) creation code returns all code in the contract except for the first 11 (0B in hex) bytes, as these 11
|
|
351
|
+
// bytes are the creation code itself which we do not want to store in the deployed storage contract result
|
|
352
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
353
|
+
// 0x60 | 0x60_0B | PUSH1 11 | codeOffset //
|
|
354
|
+
// 0x59 | 0x59 | MSIZE | 0 codeOffset //
|
|
355
|
+
// 0x81 | 0x81 | DUP2 | codeOffset 0 codeOffset //
|
|
356
|
+
// 0x38 | 0x38 | CODESIZE | codeSize codeOffset 0 codeOffset //
|
|
357
|
+
// 0x03 | 0x03 | SUB | (codeSize - codeOffset) 0 codeOffset //
|
|
358
|
+
// 0x80 | 0x80 | DUP | (codeSize - codeOffset) (codeSize - codeOffset) 0 codeOffset //
|
|
359
|
+
// 0x92 | 0x92 | SWAP3 | codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //
|
|
360
|
+
// 0x59 | 0x59 | MSIZE | 0 codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //
|
|
361
|
+
// 0x39 | 0x39 | CODECOPY | 0 (codeSize - codeOffset) //
|
|
362
|
+
// 0xF3 | 0xF3 | RETURN | //
|
|
363
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
364
|
+
// (11 bytes)
|
|
365
|
+
hex"60_0B_59_81_38_03_80_92_59_39_F3",
|
|
366
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
367
|
+
// b.) ensure that the deployed storage contract is non-executeable (first opcode is the `invalid` opcode)
|
|
368
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
369
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
370
|
+
// 0xFE | 0xFE | INVALID | //
|
|
371
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
372
|
+
// (1 byte)
|
|
373
|
+
hex"FE",
|
|
374
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
375
|
+
// c.) store the version string, which is already represented as a 32-byte value
|
|
376
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
377
|
+
// (32 bytes)
|
|
378
|
+
BytecodeStorageReader.CURRENT_VERSION,
|
|
379
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
380
|
+
// d.) store the deploying-contract's address with 0-padding to fit a 20-byte address into a 32-byte slot
|
|
381
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
382
|
+
// (12 bytes)
|
|
383
|
+
hex"00_00_00_00_00_00_00_00_00_00_00_00",
|
|
384
|
+
// (20 bytes)
|
|
385
|
+
address(this),
|
|
386
|
+
// uploaded data (stored as bytecode) comes last
|
|
387
|
+
_data
|
|
388
|
+
);
|
|
389
|
+
|
|
390
|
+
assembly {
|
|
391
|
+
// deploy a new contract with the generated creation code.
|
|
392
|
+
// start 32 bytes into creationCode to avoid copying the byte length.
|
|
393
|
+
address_ := create(0, add(creationCode, 0x20), mload(creationCode))
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// address must be non-zero if contract was deployed successfully
|
|
397
|
+
require(address_ != address(0), "ContractAsStorage: Write Error");
|
|
398
|
+
}
|
|
399
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
pragma solidity >=0.8.0;
|
|
3
|
+
|
|
4
|
+
/// @notice Read and write to persistent storage at a fraction of the cost.
|
|
5
|
+
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SSTORE2.sol)
|
|
6
|
+
/// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol)
|
|
7
|
+
library SSTORE2 {
|
|
8
|
+
uint256 internal constant DATA_OFFSET = 1; // We skip the first byte as it's a STOP opcode to ensure the contract can't be called.
|
|
9
|
+
|
|
10
|
+
/*//////////////////////////////////////////////////////////////
|
|
11
|
+
WRITE LOGIC
|
|
12
|
+
//////////////////////////////////////////////////////////////*/
|
|
13
|
+
|
|
14
|
+
function write(bytes memory data) internal returns (address pointer) {
|
|
15
|
+
// Prefix the bytecode with a STOP opcode to ensure it cannot be called.
|
|
16
|
+
bytes memory runtimeCode = abi.encodePacked(hex"00", data);
|
|
17
|
+
|
|
18
|
+
bytes memory creationCode = abi.encodePacked(
|
|
19
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
20
|
+
// Opcode | Opcode + Arguments | Description | Stack View //
|
|
21
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
22
|
+
// 0x60 | 0x600B | PUSH1 11 | codeOffset //
|
|
23
|
+
// 0x59 | 0x59 | MSIZE | 0 codeOffset //
|
|
24
|
+
// 0x81 | 0x81 | DUP2 | codeOffset 0 codeOffset //
|
|
25
|
+
// 0x38 | 0x38 | CODESIZE | codeSize codeOffset 0 codeOffset //
|
|
26
|
+
// 0x03 | 0x03 | SUB | (codeSize - codeOffset) 0 codeOffset //
|
|
27
|
+
// 0x80 | 0x80 | DUP | (codeSize - codeOffset) (codeSize - codeOffset) 0 codeOffset //
|
|
28
|
+
// 0x92 | 0x92 | SWAP3 | codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //
|
|
29
|
+
// 0x59 | 0x59 | MSIZE | 0 codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //
|
|
30
|
+
// 0x39 | 0x39 | CODECOPY | 0 (codeSize - codeOffset) //
|
|
31
|
+
// 0xf3 | 0xf3 | RETURN | //
|
|
32
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
33
|
+
hex"60_0B_59_81_38_03_80_92_59_39_F3", // Returns all code in the contract except for the first 11 (0B in hex) bytes.
|
|
34
|
+
runtimeCode // The bytecode we want the contract to have after deployment. Capped at 1 byte less than the code size limit.
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
/// @solidity memory-safe-assembly
|
|
38
|
+
assembly {
|
|
39
|
+
// Deploy a new contract with the generated creation code.
|
|
40
|
+
// We start 32 bytes into the code to avoid copying the byte length.
|
|
41
|
+
pointer := create(0, add(creationCode, 32), mload(creationCode))
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
require(pointer != address(0), "DEPLOYMENT_FAILED");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/*//////////////////////////////////////////////////////////////
|
|
48
|
+
READ LOGIC
|
|
49
|
+
//////////////////////////////////////////////////////////////*/
|
|
50
|
+
|
|
51
|
+
function read(address pointer) internal view returns (bytes memory) {
|
|
52
|
+
return
|
|
53
|
+
readBytecode(
|
|
54
|
+
pointer,
|
|
55
|
+
DATA_OFFSET,
|
|
56
|
+
pointer.code.length - DATA_OFFSET
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function read(
|
|
61
|
+
address pointer,
|
|
62
|
+
uint256 start
|
|
63
|
+
) internal view returns (bytes memory) {
|
|
64
|
+
start += DATA_OFFSET;
|
|
65
|
+
|
|
66
|
+
return readBytecode(pointer, start, pointer.code.length - start);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function read(
|
|
70
|
+
address pointer,
|
|
71
|
+
uint256 start,
|
|
72
|
+
uint256 end
|
|
73
|
+
) internal view returns (bytes memory) {
|
|
74
|
+
start += DATA_OFFSET;
|
|
75
|
+
end += DATA_OFFSET;
|
|
76
|
+
|
|
77
|
+
require(pointer.code.length >= end, "OUT_OF_BOUNDS");
|
|
78
|
+
|
|
79
|
+
return readBytecode(pointer, start, end - start);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/*//////////////////////////////////////////////////////////////
|
|
83
|
+
INTERNAL HELPER LOGIC
|
|
84
|
+
//////////////////////////////////////////////////////////////*/
|
|
85
|
+
|
|
86
|
+
function readBytecode(
|
|
87
|
+
address pointer,
|
|
88
|
+
uint256 start,
|
|
89
|
+
uint256 size
|
|
90
|
+
) private view returns (bytes memory data) {
|
|
91
|
+
/// @solidity memory-safe-assembly
|
|
92
|
+
assembly {
|
|
93
|
+
// Get a pointer to some free memory.
|
|
94
|
+
data := mload(0x40)
|
|
95
|
+
|
|
96
|
+
// Update the free memory pointer to prevent overriding our data.
|
|
97
|
+
// We use and(x, not(31)) as a cheaper equivalent to sub(x, mod(x, 32)).
|
|
98
|
+
// Adding 31 to size and running the result through the logic above ensures
|
|
99
|
+
// the memory pointer remains word-aligned, following the Solidity convention.
|
|
100
|
+
mstore(0x40, add(data, and(add(add(size, 32), 31), not(31))))
|
|
101
|
+
|
|
102
|
+
// Store the size of the data in the first 32 byte chunk of free memory.
|
|
103
|
+
mstore(data, size)
|
|
104
|
+
|
|
105
|
+
// Copy the code into memory right after the 32 bytes we used to store the size.
|
|
106
|
+
extcodecopy(pointer, add(data, 32), start, size)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -10,7 +10,7 @@ import "../../libs/0.8.x/Bytes32Strings.sol";
|
|
|
10
10
|
|
|
11
11
|
import "@openzeppelin-4.5/contracts/utils/structs/EnumerableMap.sol";
|
|
12
12
|
|
|
13
|
-
pragma solidity 0.8.
|
|
13
|
+
pragma solidity 0.8.19;
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* @title Minter filter contract that allows filtered minters to be set
|