@artblocks/contracts 0.0.1
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/.env.example +10 -0
- package/LICENSE +165 -0
- package/README.md +286 -0
- package/artifacts/contracts/AdminACLV0.sol/AdminACLV0.json +164 -0
- package/artifacts/contracts/AdminACLV1.sol/AdminACLV1.json +248 -0
- package/artifacts/contracts/BasicRandomizer.sol/BasicRandomizer.json +24 -0
- package/artifacts/contracts/BasicRandomizerV2.sol/BasicRandomizerV2.json +102 -0
- package/artifacts/contracts/DependencyRegistryV0.sol/DependencyRegistryV0.json +1020 -0
- package/artifacts/contracts/GenArt721CoreV3.sol/GenArt721CoreV3.json +1928 -0
- package/artifacts/contracts/GenArt721CoreV3_Engine.sol/GenArt721CoreV3_Engine.json +1942 -0
- package/artifacts/contracts/engine/GenArt721CoreV2_ENGINE_FLEX.sol/GenArt721CoreV2_ENGINE_FLEX.json +1708 -0
- package/artifacts/contracts/engine/GenArt721CoreV2_PBAB.sol/GenArt721CoreV2_PBAB.json +1410 -0
- package/artifacts/contracts/engine/GenArt721CoreV2_PRTNR.sol/GenArt721CoreV2_PRTNR.json +1436 -0
- package/artifacts/contracts/engine/GenArt721MinterBurner_PBAB.sol/GenArt721MinterBurner_PBAB.json +437 -0
- package/artifacts/contracts/engine/GenArt721MinterDAExp_PBAB.sol/GenArt721MinterDAExp_PBAB.json +508 -0
- package/artifacts/contracts/engine/GenArt721Minter_PBAB.sol/GenArt721Minter_PBAB.json +381 -0
- package/artifacts/contracts/engine-registry/EngineRegistryV0.sol/EngineRegistryV0.json +109 -0
- package/artifacts/contracts/engine-registry/future/EngineRegistryV1.sol/EngineRegistryV1.json +109 -0
- package/artifacts/contracts/explorations/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +1902 -0
- package/artifacts/contracts/interfaces/0.5.x/IBonusContract.sol/IBonusContract.json +47 -0
- package/artifacts/contracts/interfaces/0.5.x/IGenArt721CoreContractV1.sol/IGenArt721CoreContractV1.json +413 -0
- package/artifacts/contracts/interfaces/0.5.x/IGenArt721CoreV2_PBAB.sol/IGenArt721CoreV2_PBAB.json +392 -0
- package/artifacts/contracts/interfaces/0.5.x/IRandomizer.sol/IRandomizer.json +26 -0
- package/artifacts/contracts/interfaces/0.8.x/IAdminACLV0.sol/IAdminACLV0.json +122 -0
- package/artifacts/contracts/interfaces/0.8.x/IArtblocksRoyaltyOverride.sol/IArtblocksRoyaltyOverride.json +59 -0
- package/artifacts/contracts/interfaces/0.8.x/IBonusContract.sol/IBonusContract.json +43 -0
- package/artifacts/contracts/interfaces/0.8.x/IDelegationRegistry.sol/IDelegationRegistry.json +510 -0
- package/artifacts/contracts/interfaces/0.8.x/IDependencyRegistryCompatibleV0.sol/IDependencyRegistryCompatibleV0.json +53 -0
- package/artifacts/contracts/interfaces/0.8.x/IDependencyRegistryV0.sol/IDependencyRegistryV0.json +350 -0
- package/artifacts/contracts/interfaces/0.8.x/IEngineRegistryV0.sol/IEngineRegistryV0.json +85 -0
- package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDAExpSettlementV0.sol/IFilteredMinterDAExpSettlementV0.json +730 -0
- package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDAExpV0.sol/IFilteredMinterDAExpV0.json +311 -0
- package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDAExpV1.sol/IFilteredMinterDAExpV1.json +617 -0
- package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDALinV0.sol/IFilteredMinterDALinV0.json +292 -0
- package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDALinV1.sol/IFilteredMinterDALinV1.json +598 -0
- package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterHolderV0.sol/IFilteredMinterHolderV0.json +355 -0
- package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterHolderV1.sol/IFilteredMinterHolderV1.json +368 -0
- package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterHolderV2.sol/IFilteredMinterHolderV2.json +674 -0
- package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterMerkleV0.sol/IFilteredMinterMerkleV0.json +551 -0
- package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterMerkleV1.sol/IFilteredMinterMerkleV1.json +564 -0
- package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterMerkleV2.sol/IFilteredMinterMerkleV2.json +601 -0
- package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterV0.sol/IFilteredMinterV0.json +216 -0
- package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterV1.sol/IFilteredMinterV1.json +485 -0
- package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterV2.sol/IFilteredMinterV2.json +522 -0
- package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreContractV1.sol/IGenArt721CoreContractV1.json +299 -0
- package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreContractV3.sol/IGenArt721CoreContractV3.json +609 -0
- package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Base.sol/IGenArt721CoreContractV3_Base.json +448 -0
- package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Engine.sol/IGenArt721CoreContractV3_Engine.json +649 -0
- package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreV2_PBAB.sol/IGenArt721CoreV2_PBAB.json +362 -0
- package/artifacts/contracts/interfaces/0.8.x/IManifold.sol/IManifold.json +35 -0
- package/artifacts/contracts/interfaces/0.8.x/IMinterFilterV0.sol/IMinterFilterV0.json +192 -0
- package/artifacts/contracts/interfaces/0.8.x/IRandomizer.sol/IRandomizer.json +24 -0
- package/artifacts/contracts/interfaces/0.8.x/IRandomizerV2.sol/IRandomizerV2.json +37 -0
- package/artifacts/contracts/legacy/GenArt721CoreV1.sol/Address.json +10 -0
- package/artifacts/contracts/legacy/GenArt721CoreV1.sol/Counters.json +10 -0
- package/artifacts/contracts/legacy/GenArt721CoreV1.sol/CustomERC721Metadata.json +425 -0
- package/artifacts/contracts/legacy/GenArt721CoreV1.sol/ERC165.json +38 -0
- package/artifacts/contracts/legacy/GenArt721CoreV1.sol/ERC721.json +322 -0
- package/artifacts/contracts/legacy/GenArt721CoreV1.sol/ERC721Enumerable.json +384 -0
- package/artifacts/contracts/legacy/GenArt721CoreV1.sol/GenArt721CoreV1.json +1773 -0
- package/artifacts/contracts/legacy/GenArt721CoreV1.sol/IERC165.json +32 -0
- package/artifacts/contracts/legacy/GenArt721CoreV1.sol/IERC721.json +316 -0
- package/artifacts/contracts/legacy/GenArt721CoreV1.sol/IERC721Enumerable.json +378 -0
- package/artifacts/contracts/legacy/GenArt721CoreV1.sol/IERC721Receiver.json +47 -0
- package/artifacts/contracts/legacy/GenArt721CoreV1.sol/SafeMath.json +10 -0
- package/artifacts/contracts/legacy/GenArt721CoreV1.sol/Strings.json +10 -0
- package/artifacts/contracts/legacy/GenArt721LegacyMinter.sol/GenArt721LegacyMinter.json +338 -0
- package/artifacts/contracts/libs/0.5.x/CustomERC721Metadata.sol/CustomERC721Metadata.json +425 -0
- package/artifacts/contracts/libs/0.5.x/IERC20.sol/IERC20.json +206 -0
- package/artifacts/contracts/libs/0.5.x/SafeMath.sol/SafeMath.json +10 -0
- package/artifacts/contracts/libs/0.5.x/Strings.sol/Strings.json +10 -0
- package/artifacts/contracts/libs/0.8.x/BytecodeStorage.sol/BytecodeStorage.json +10 -0
- package/artifacts/contracts/libs/0.8.x/Bytes32Strings.sol/Bytes32Strings.json +10 -0
- package/artifacts/contracts/libs/0.8.x/ERC721_PackedHashSeed.sol/ERC721_PackedHashSeed.json +357 -0
- package/artifacts/contracts/libs/integration-refs/delegation-registry/DelegationRegistry.sol/DelegationRegistry.json +529 -0
- package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeMock.sol/GnosisSafeMock.json +1037 -0
- package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeProxyFactoryMock.sol/GnosisSafeProxyFactoryMock.json +172 -0
- package/artifacts/contracts/libs/integration-refs/gnosis-safe/MultiSendMock.sol/MultiSendMock.json +24 -0
- package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV0.sol/MinterFilterV0.json +342 -0
- package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV1.sol/MinterFilterV1.json +322 -0
- package/artifacts/contracts/minter-suite/Minters/MinterDAExp/MinterDAExpV2.sol/MinterDAExpV2.json +550 -0
- package/artifacts/contracts/minter-suite/Minters/MinterDAExp/MinterDAExpV3.sol/MinterDAExpV3.json +856 -0
- package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol/MinterDAExpSettlementV0.json +1053 -0
- package/artifacts/contracts/minter-suite/Minters/MinterDALin/MinterDALinV2.sol/MinterDALinV2.json +526 -0
- package/artifacts/contracts/minter-suite/Minters/MinterDALin/MinterDALinV3.sol/MinterDALinV3.json +832 -0
- package/artifacts/contracts/minter-suite/Minters/MinterHolder/MinterHolderV2.sol/MinterHolderV2.json +794 -0
- package/artifacts/contracts/minter-suite/Minters/MinterHolder/MinterHolderV3.sol/MinterHolderV3.json +1100 -0
- package/artifacts/contracts/minter-suite/Minters/MinterMerkle/MinterMerkleV3.sol/MinterMerkleV3.json +1002 -0
- package/artifacts/contracts/minter-suite/Minters/MinterMerkle/MinterMerkleV4.sol/MinterMerkleV4.json +1039 -0
- package/artifacts/contracts/minter-suite/Minters/MinterSetPrice/MinterSetPriceV2.sol/MinterSetPriceV2.json +365 -0
- package/artifacts/contracts/minter-suite/Minters/MinterSetPrice/MinterSetPriceV3.sol/MinterSetPriceV3.json +671 -0
- package/artifacts/contracts/minter-suite/Minters/MinterSetPrice/deprecated/MinterSetPriceV1.sol/MinterSetPriceV1.json +288 -0
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol/MinterSetPriceERC20V2.json +436 -0
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol/MinterSetPriceERC20V3.json +742 -0
- package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20/deprecated/MinterSetPriceERC20V0.sol/MinterSetPriceERC20V0.json +461 -0
- package/artifacts/contracts/mock/BytecodeTextCR_DMock.sol/BytecodeTextCR_DMock.json +194 -0
- package/artifacts/contracts/mock/DeadReceiverMock.sol/DeadReceiverMock.json +15 -0
- package/artifacts/contracts/mock/ERC20Mock.sol/ERC20Mock.json +292 -0
- package/artifacts/contracts/mock/MockAdminACLV0.sol/MockAdminACLV0Events.json +165 -0
- package/artifacts/contracts/mock/RandomizerV2_NoAssignMock.sol/RandomizerV2_NoAssignMock.json +128 -0
- package/artifacts/contracts/mock/ReentrancyHolderMock.sol/ReentrancyHolderMock.json +118 -0
- package/artifacts/contracts/mock/ReentrancyMerkleMock.sol/ReentrancyMerkleMock.json +87 -0
- package/artifacts/contracts/mock/ReentrancyMock.sol/ReentrancyMock.json +82 -0
- package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverride.sol/GenArt721RoyaltyOverride.json +208 -0
- package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverride_PBAB.sol/GenArt721RoyaltyOverride_PBAB.json +301 -0
- package/contracts/AdminACLV0.sol +103 -0
- package/contracts/AdminACLV1.sol +193 -0
- package/contracts/BasicRandomizer.sol +23 -0
- package/contracts/BasicRandomizerV2.sol +36 -0
- package/contracts/DependencyRegistryV0.sol +893 -0
- package/contracts/GenArt721CoreV3.sol +2001 -0
- package/contracts/GenArt721CoreV3_Engine.sol +2061 -0
- package/contracts/engine/GenArt721CoreV2_ENGINE_FLEX.sol +887 -0
- package/contracts/engine/GenArt721CoreV2_PBAB.sol +695 -0
- package/contracts/engine/GenArt721CoreV2_PRTNR.sol +749 -0
- package/contracts/engine/GenArt721MinterBurner_PBAB.sol +467 -0
- package/contracts/engine/GenArt721MinterDAExp_PBAB.sol +614 -0
- package/contracts/engine/GenArt721Minter_PBAB.sol +420 -0
- package/contracts/engine-registry/EngineRegistryV0.sol +72 -0
- package/contracts/engine-registry/future/EngineRegistryV1.sol +86 -0
- package/contracts/explorations/GenArt721CoreV3_Explorations.sol +1989 -0
- package/contracts/interfaces/0.5.x/IBonusContract.sol +10 -0
- package/contracts/interfaces/0.5.x/IGenArt721CoreContractV1.sol +91 -0
- package/contracts/interfaces/0.5.x/IGenArt721CoreV2_PBAB.sol +92 -0
- package/contracts/interfaces/0.5.x/IRandomizer.sol +8 -0
- package/contracts/interfaces/0.8.x/IAdminACLV0.sol +51 -0
- package/contracts/interfaces/0.8.x/IArtblocksRoyaltyOverride.sol +34 -0
- package/contracts/interfaces/0.8.x/IBonusContract.sol +10 -0
- package/contracts/interfaces/0.8.x/IDelegationRegistry.sol +221 -0
- package/contracts/interfaces/0.8.x/IDependencyRegistryCompatibleV0.sol +31 -0
- package/contracts/interfaces/0.8.x/IDependencyRegistryV0.sol +95 -0
- package/contracts/interfaces/0.8.x/IEngineRegistryV0.sol +38 -0
- package/contracts/interfaces/0.8.x/IFilteredMinterDAExpSettlementV0.sol +70 -0
- package/contracts/interfaces/0.8.x/IFilteredMinterDAExpV0.sol +35 -0
- package/contracts/interfaces/0.8.x/IFilteredMinterDAExpV1.sol +16 -0
- package/contracts/interfaces/0.8.x/IFilteredMinterDALinV0.sol +32 -0
- package/contracts/interfaces/0.8.x/IFilteredMinterDALinV1.sol +16 -0
- package/contracts/interfaces/0.8.x/IFilteredMinterHolderV0.sol +68 -0
- package/contracts/interfaces/0.8.x/IFilteredMinterHolderV1.sol +19 -0
- package/contracts/interfaces/0.8.x/IFilteredMinterHolderV2.sol +19 -0
- package/contracts/interfaces/0.8.x/IFilteredMinterMerkleV0.sol +37 -0
- package/contracts/interfaces/0.8.x/IFilteredMinterMerkleV1.sol +19 -0
- package/contracts/interfaces/0.8.x/IFilteredMinterMerkleV2.sol +19 -0
- package/contracts/interfaces/0.8.x/IFilteredMinterV0.sol +74 -0
- package/contracts/interfaces/0.8.x/IFilteredMinterV1.sol +127 -0
- package/contracts/interfaces/0.8.x/IFilteredMinterV2.sol +30 -0
- package/contracts/interfaces/0.8.x/IGenArt721CoreContractV1.sol +73 -0
- package/contracts/interfaces/0.8.x/IGenArt721CoreContractV3.sol +79 -0
- package/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Base.sol +127 -0
- package/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Engine.sol +80 -0
- package/contracts/interfaces/0.8.x/IGenArt721CoreV2_PBAB.sol +91 -0
- package/contracts/interfaces/0.8.x/IManifold.sol +24 -0
- package/contracts/interfaces/0.8.x/IMinterFilterV0.sol +47 -0
- package/contracts/interfaces/0.8.x/IRandomizer.sol +8 -0
- package/contracts/interfaces/0.8.x/IRandomizerV2.sol +15 -0
- package/contracts/legacy/GenArt721CoreV1.sol +1593 -0
- package/contracts/legacy/GenArt721LegacyMinter.sol +275 -0
- package/contracts/libs/0.5.x/CustomERC721Metadata.sol +52 -0
- package/contracts/libs/0.5.x/IERC20.sol +96 -0
- package/contracts/libs/0.5.x/SafeMath.sol +98 -0
- package/contracts/libs/0.5.x/Strings.sol +92 -0
- package/contracts/libs/0.8.x/BytecodeStorage.sol +314 -0
- package/contracts/libs/0.8.x/Bytes32Strings.sol +66 -0
- package/contracts/libs/0.8.x/ERC721_PackedHashSeed.sol +514 -0
- package/contracts/libs/integration-refs/delegation-registry/DelegationRegistry.sol +663 -0
- package/contracts/libs/integration-refs/gnosis-safe/GnosisSafeMock.sol +6 -0
- package/contracts/libs/integration-refs/gnosis-safe/GnosisSafeProxyFactoryMock.sol +6 -0
- package/contracts/libs/integration-refs/gnosis-safe/MultiSendMock.sol +6 -0
- package/contracts/minter-suite/MinterFilter/MinterFilterV0.sol +291 -0
- package/contracts/minter-suite/MinterFilter/MinterFilterV1.sol +320 -0
- package/contracts/minter-suite/Minters/MinterDAExp/MinterDAExpV2.sol +571 -0
- package/contracts/minter-suite/Minters/MinterDAExp/MinterDAExpV3.sol +622 -0
- package/contracts/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol +1066 -0
- package/contracts/minter-suite/Minters/MinterDALin/MinterDALinV2.sol +527 -0
- package/contracts/minter-suite/Minters/MinterDALin/MinterDALinV3.sol +576 -0
- package/contracts/minter-suite/Minters/MinterHolder/MinterHolderV2.sol +749 -0
- package/contracts/minter-suite/Minters/MinterHolder/MinterHolderV3.sol +798 -0
- package/contracts/minter-suite/Minters/MinterMerkle/MinterMerkleV3.sol +682 -0
- package/contracts/minter-suite/Minters/MinterMerkle/MinterMerkleV4.sol +733 -0
- package/contracts/minter-suite/Minters/MinterSetPrice/MinterSetPriceV2.sol +350 -0
- package/contracts/minter-suite/Minters/MinterSetPrice/MinterSetPriceV3.sol +401 -0
- package/contracts/minter-suite/Minters/MinterSetPrice/deprecated/MinterSetPriceV1.sol +274 -0
- package/contracts/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol +491 -0
- package/contracts/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol +542 -0
- package/contracts/minter-suite/Minters/MinterSetPriceERC20/deprecated/MinterSetPriceERC20V0.sol +470 -0
- package/contracts/mock/BytecodeTextCR_DMock.sol +184 -0
- package/contracts/mock/DeadReceiverMock.sol +13 -0
- package/contracts/mock/ERC20Mock.sol +11 -0
- package/contracts/mock/MockAdminACLV0.sol +65 -0
- package/contracts/mock/RandomizerV2_NoAssignMock.sol +43 -0
- package/contracts/mock/ReentrancyHolderMock.sol +50 -0
- package/contracts/mock/ReentrancyMerkleMock.sol +64 -0
- package/contracts/mock/ReentrancyMock.sol +44 -0
- package/contracts/royalty-registry/GenArt721RoyaltyOverride.sol +168 -0
- package/contracts/royalty-registry/GenArt721RoyaltyOverride_PBAB.sol +221 -0
- package/package.json +83 -0
|
@@ -0,0 +1,314 @@
|
|
|
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 persistant storage for large chunks of script string data.
|
|
9
|
+
*
|
|
10
|
+
* @author Art Blocks Inc.
|
|
11
|
+
* @author Modified from 0xSequence (https://github.com/0xsequence/sstore2/blob/master/contracts/SSTORE2.sol)
|
|
12
|
+
* @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SSTORE2.sol)
|
|
13
|
+
*
|
|
14
|
+
* @dev Compared to the above two rerferenced libraries, this contracts-as-storage implementation makes a few
|
|
15
|
+
* notably different design decisions:
|
|
16
|
+
* - uses the `string` data type for input/output on reads, rather than speaking in bytes directly
|
|
17
|
+
* - exposes "delete" functionality, allowing no-longer-used storage to be purged from chain state
|
|
18
|
+
* - stores the "writer" address (library user) in the deployed contract bytes, which is useful for both:
|
|
19
|
+
* a) providing necessary information for safe deletion; and
|
|
20
|
+
* b) allowing this to be introspected on-chain
|
|
21
|
+
* Also, given that much of this library is written in assembly, this library makes use of a slightly
|
|
22
|
+
* different convention (when compared to the rest of the Art Blocks smart contract repo) around
|
|
23
|
+
* pre-defining return values in some cases in order to simplify need to directly memory manage these
|
|
24
|
+
* return values.
|
|
25
|
+
*/
|
|
26
|
+
library BytecodeStorage {
|
|
27
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
28
|
+
// Starting Index | Size | Ending Index | Description //
|
|
29
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
30
|
+
// 0 | N/A | 0 | //
|
|
31
|
+
// 0 | 72 | 72 | the bytes of the gated-cleanup-logic allowing for `selfdestruct`ion //
|
|
32
|
+
// 72 | 32 | 104 | the 32 bytes for storing the deploying contract's (0-padded) address //
|
|
33
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
34
|
+
// Define the offset for where the "logic bytes" end, and the "data bytes" begin. Note that this is a manually
|
|
35
|
+
// calculated value, and must be updated if the above table is changed. It is expected that tests will fail
|
|
36
|
+
// loudly if these values are not updated in-step with eachother.
|
|
37
|
+
uint256 internal constant DATA_OFFSET = 104;
|
|
38
|
+
uint256 internal constant ADDRESS_OFFSET = 72;
|
|
39
|
+
|
|
40
|
+
/*//////////////////////////////////////////////////////////////
|
|
41
|
+
WRITE LOGIC
|
|
42
|
+
//////////////////////////////////////////////////////////////*/
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @notice Write a string to contract bytecode
|
|
46
|
+
* @param _data string to be written to contract. No input validation is performed on this parameter.
|
|
47
|
+
* @return address_ address of deployed contract with bytecode containing concat(gated-cleanup-logic, address, data)
|
|
48
|
+
*/
|
|
49
|
+
function writeToBytecode(
|
|
50
|
+
string memory _data
|
|
51
|
+
) internal returns (address address_) {
|
|
52
|
+
// prefix bytecode with
|
|
53
|
+
bytes memory creationCode = abi.encodePacked(
|
|
54
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
55
|
+
// Opcode | Opcode + Arguments | Description | Stack View //
|
|
56
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
57
|
+
// (0) creation code returns all code in the contract except for the first 11 (0B in hex) bytes, as these 11
|
|
58
|
+
// bytes are the creation code itself which we do not want to store in the deployed storage contract result
|
|
59
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
60
|
+
// 0x60 | 0x60_0B | PUSH1 11 | codeOffset //
|
|
61
|
+
// 0x59 | 0x59 | MSIZE | 0 codeOffset //
|
|
62
|
+
// 0x81 | 0x81 | DUP2 | codeOffset 0 codeOffset //
|
|
63
|
+
// 0x38 | 0x38 | CODESIZE | codeSize codeOffset 0 codeOffset //
|
|
64
|
+
// 0x03 | 0x03 | SUB | (codeSize - codeOffset) 0 codeOffset //
|
|
65
|
+
// 0x80 | 0x80 | DUP | (codeSize - codeOffset) (codeSize - codeOffset) 0 codeOffset //
|
|
66
|
+
// 0x92 | 0x92 | SWAP3 | codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //
|
|
67
|
+
// 0x59 | 0x59 | MSIZE | 0 codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //
|
|
68
|
+
// 0x39 | 0x39 | CODECOPY | 0 (codeSize - codeOffset) //
|
|
69
|
+
// 0xf3 | 0xf3 | RETURN | //
|
|
70
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
71
|
+
// (11 bytes)
|
|
72
|
+
hex"60_0B_59_81_38_03_80_92_59_39_F3",
|
|
73
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
74
|
+
// Opcode | Opcode + Arguments | Description | Stack View //
|
|
75
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
76
|
+
// (1a) conditional logic for determing purge-gate (only the bytecode contract deployer can `selfdestruct`)
|
|
77
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
78
|
+
// 0x60 | 0x60_20 | PUSH1 32 | 32 //
|
|
79
|
+
// 0x60 | 0x60_48 | PUSH1 72 (*) | contractOffset 32 //
|
|
80
|
+
// 0x60 | 0x60_00 | PUSH1 0 | 0 contractOffset 32 //
|
|
81
|
+
// 0x39 | 0x39 | CODECOPY | //
|
|
82
|
+
// 0x60 | 0x60_00 | PUSH1 0 | 0 //
|
|
83
|
+
// 0x51 | 0x51 | MLOAD | byteDeployerAddress //
|
|
84
|
+
// 0x33 | 0x33 | CALLER | msg.sender byteDeployerAddress //
|
|
85
|
+
// 0x14 | 0x14 | EQ | (msg.sender == byteDeployerAddress) //
|
|
86
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
87
|
+
// (12 bytes: 0-11 in deployed contract)
|
|
88
|
+
hex"60_20_60_48_60_00_39_60_00_51_33_14",
|
|
89
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
90
|
+
// (1b) load up the destination jump address for `(2a) calldata length check` logic, jump or raise `invalid` op-code
|
|
91
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
92
|
+
// 0x60 | 0x60_10 | PUSH1 16 (^) | jumpDestination (msg.sender == byteDeployerAddress) //
|
|
93
|
+
// 0x57 | 0x57 | JUMPI | //
|
|
94
|
+
// 0xFE | 0xFE | INVALID | //
|
|
95
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
96
|
+
// (4 bytes: 12-15 in deployed contract)
|
|
97
|
+
hex"60_10_57_FE",
|
|
98
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
99
|
+
// (2a) conditional logic for determing purge-gate (only if calldata length is 1 byte)
|
|
100
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
101
|
+
// 0x5B | 0x5B | JUMPDEST (16) | //
|
|
102
|
+
// 0x60 | 0x60_01 | PUSH1 1 | 1 //
|
|
103
|
+
// 0x36 | 0x36 | CALLDATASIZE | calldataSize 1 //
|
|
104
|
+
// 0x14 | 0x14 | EQ | (calldataSize == 1) //
|
|
105
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
106
|
+
// (5 bytes: 16-20 in deployed contract)
|
|
107
|
+
hex"5B_60_01_36_14",
|
|
108
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
109
|
+
// (2b) load up the destination jump address for `(3a) calldata value check` logic, jump or raise `invalid` op-code
|
|
110
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
111
|
+
// 0x60 | 0x60_19 | PUSH1 25 (^) | jumpDestination (calldataSize == 1) //
|
|
112
|
+
// 0x57 | 0x57 | JUMPI | //
|
|
113
|
+
// 0xFE | 0xFE | INVALID | //
|
|
114
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
115
|
+
// (4 bytes: 21-24 in deployed contract)
|
|
116
|
+
hex"60_19_57_FE",
|
|
117
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
118
|
+
// (3a) conditional logic for determing purge-gate (only if calldata is `0xFF`)
|
|
119
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
120
|
+
// 0x5B | 0x5B | JUMPDEST (25) | //
|
|
121
|
+
// 0x60 | 0x60_00 | PUSH1 0 | 0 //
|
|
122
|
+
// 0x35 | 0x35 | CALLDATALOAD | calldata //
|
|
123
|
+
// 0x7F | 0x7F_FF_00_..._00 | PUSH32 0xFF00...00 | 0xFF0...00 calldata //
|
|
124
|
+
// 0x14 | 0x14 | EQ | (0xFF00...00 == calldata) //
|
|
125
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
126
|
+
// (4 bytes: 25-28 in deployed contract)
|
|
127
|
+
hex"5B_60_00_35",
|
|
128
|
+
// (33 bytes: 29-61 in deployed contract)
|
|
129
|
+
hex"7F_FF_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00",
|
|
130
|
+
// (1 byte: 62 in deployed contract)
|
|
131
|
+
hex"14",
|
|
132
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
133
|
+
// (3b) load up the destination jump address for actual purging (4), jump or raise `invalid` op-code
|
|
134
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
135
|
+
// 0x60 | 0x60_43 | PUSH1 67 (^) | jumpDestination (0xFF00...00 == calldata) //
|
|
136
|
+
// 0x57 | 0x57 | JUMPI | //
|
|
137
|
+
// 0xFE | 0xFE | INVALID | //
|
|
138
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
139
|
+
// (4 bytes: 63-66 in deployed contract)
|
|
140
|
+
hex"60_43_57_FE",
|
|
141
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
142
|
+
// (4) perform actual purging
|
|
143
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
144
|
+
// 0x5B | 0x5B | JUMPDEST (67) | //
|
|
145
|
+
// 0x60 | 0x60_00 | PUSH1 0 | 0 //
|
|
146
|
+
// 0x51 | 0x51 | MLOAD | byteDeployerAddress //
|
|
147
|
+
// 0xFF | 0xFF | SELFDESTRUCT | //
|
|
148
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
149
|
+
// (5 bytes: 67-71 in deployed contract)
|
|
150
|
+
hex"5B_60_00_51_FF",
|
|
151
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
152
|
+
// (*) Note: this value must be adjusted if selfdestruct purge logic is adjusted, to refer to the correct start //
|
|
153
|
+
// offset for where the `msg.sender` address was stored in deployed bytecode. //
|
|
154
|
+
// //
|
|
155
|
+
// (^) Note: this value must be adjusted if portions of the selfdestruct purge logic are adjusted. //
|
|
156
|
+
//---------------------------------------------------------------------------------------------------------------//
|
|
157
|
+
//
|
|
158
|
+
// store the deploying-contract's address (to be used to gate and call `selfdestruct`),
|
|
159
|
+
// with expected 0-padding to fit a 20-byte address into a 30-byte slot.
|
|
160
|
+
//
|
|
161
|
+
// note: it is important that this address is the executing contract's address
|
|
162
|
+
// (the address that represents the client-application smart contract of this library)
|
|
163
|
+
// which means that it is the responsibility of the client-application smart contract
|
|
164
|
+
// to determine how deletes are gated (or if they are exposed at all) as it is only
|
|
165
|
+
// this contract that will be able to call `purgeBytecode` as the `CALLER` that is
|
|
166
|
+
// checked above (op-code 0x33).
|
|
167
|
+
hex"00_00_00_00_00_00_00_00_00_00_00_00", // left-pad 20-byte address with 12 0x00 bytes
|
|
168
|
+
address(this),
|
|
169
|
+
// uploaded data (stored as bytecode) comes last
|
|
170
|
+
_data
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
assembly {
|
|
174
|
+
// deploy a new contract with the generated creation code.
|
|
175
|
+
// start 32 bytes into creationCode to avoid copying the byte length.
|
|
176
|
+
address_ := create(0, add(creationCode, 0x20), mload(creationCode))
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// address must be non-zero if contract was deployed successfully
|
|
180
|
+
require(address_ != address(0), "ContractAsStorage: Write Error");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/*//////////////////////////////////////////////////////////////
|
|
184
|
+
READ LOGIC
|
|
185
|
+
//////////////////////////////////////////////////////////////*/
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* @notice Read a string from contract bytecode
|
|
189
|
+
* @param _address address of deployed contract with bytecode containing concat(gated-cleanup-logic, address, data)
|
|
190
|
+
* @return data string read from contract bytecode
|
|
191
|
+
*/
|
|
192
|
+
function readFromBytecode(
|
|
193
|
+
address _address
|
|
194
|
+
) internal view returns (string memory data) {
|
|
195
|
+
// get the size of the bytecode
|
|
196
|
+
uint256 bytecodeSize = _bytecodeSizeAt(_address);
|
|
197
|
+
// handle case where address contains code < DATA_OFFSET
|
|
198
|
+
// note: the first check here also captures the case where
|
|
199
|
+
// (bytecodeSize == 0) implicitly, but we add the second check of
|
|
200
|
+
// (bytecodeSize == 0) as a fall-through that will never execute
|
|
201
|
+
// unless `DATA_OFFSET` is set to 0 at some point.
|
|
202
|
+
if ((bytecodeSize < DATA_OFFSET) || (bytecodeSize == 0)) {
|
|
203
|
+
revert("ContractAsStorage: Read Error");
|
|
204
|
+
}
|
|
205
|
+
// handle case where address contains code >= DATA_OFFSET
|
|
206
|
+
// decrement by DATA_OFFSET to account for purge logic
|
|
207
|
+
uint256 size;
|
|
208
|
+
unchecked {
|
|
209
|
+
size = bytecodeSize - DATA_OFFSET;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
assembly {
|
|
213
|
+
// allocate free memory
|
|
214
|
+
data := mload(0x40)
|
|
215
|
+
// update free memory pointer
|
|
216
|
+
// use and(x, not(0x1f) as cheaper equivalent to sub(x, mod(x, 0x20)).
|
|
217
|
+
// adding 0x1f to size + logic above ensures the free memory pointer
|
|
218
|
+
// remains word-aligned, following the Solidity convention.
|
|
219
|
+
mstore(0x40, add(data, and(add(add(size, 0x20), 0x1f), not(0x1f))))
|
|
220
|
+
// store length of data in first 32 bytes
|
|
221
|
+
mstore(data, size)
|
|
222
|
+
// copy code to memory, excluding the gated-cleanup-logic and address
|
|
223
|
+
extcodecopy(_address, add(data, 0x20), DATA_OFFSET, size)
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* @notice Get address for deployer for given contract bytecode
|
|
229
|
+
* @param _address address of deployed contract with bytecode containing concat(gated-cleanup-logic, address, data)
|
|
230
|
+
* @return writerAddress address read from contract bytecode
|
|
231
|
+
*/
|
|
232
|
+
function getWriterAddressForBytecode(
|
|
233
|
+
address _address
|
|
234
|
+
) internal view returns (address) {
|
|
235
|
+
// get the size of the data
|
|
236
|
+
uint256 bytecodeSize = _bytecodeSizeAt(_address);
|
|
237
|
+
// handle case where address contains code < DATA_OFFSET
|
|
238
|
+
// note: the first check here also captures the case where
|
|
239
|
+
// (bytecodeSize == 0) implicitly, but we add the second check of
|
|
240
|
+
// (bytecodeSize == 0) as a fall-through that will never execute
|
|
241
|
+
// unless `DATA_OFFSET` is set to 0 at some point.
|
|
242
|
+
if ((bytecodeSize < DATA_OFFSET) || (bytecodeSize == 0)) {
|
|
243
|
+
revert("ContractAsStorage: Read Error");
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
assembly {
|
|
247
|
+
// allocate free memory
|
|
248
|
+
let writerAddress := mload(0x40)
|
|
249
|
+
// shift free memory pointer by one slot
|
|
250
|
+
mstore(0x40, add(mload(0x40), 0x20))
|
|
251
|
+
// copy the 32-byte address of the data contract writer to memory
|
|
252
|
+
// note: this relies on the assumption noted at the top-level of
|
|
253
|
+
// this file that the storage layout for the deployed
|
|
254
|
+
// contracts-as-storage contract looks like:
|
|
255
|
+
// | gated-cleanup-logic | deployer-address (padded) | data |
|
|
256
|
+
extcodecopy(
|
|
257
|
+
_address,
|
|
258
|
+
writerAddress,
|
|
259
|
+
ADDRESS_OFFSET,
|
|
260
|
+
0x20 // full 32-bytes, as address is expected to be zero-padded
|
|
261
|
+
)
|
|
262
|
+
return(
|
|
263
|
+
writerAddress,
|
|
264
|
+
0x20 // return size is entire slot, as it is zero-padded
|
|
265
|
+
)
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/*//////////////////////////////////////////////////////////////
|
|
270
|
+
DELETE LOGIC
|
|
271
|
+
//////////////////////////////////////////////////////////////*/
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* @notice Purge contract bytecode for cleanup purposes
|
|
275
|
+
* note: Although this does reduce usage of Ethereum state, it does not reduce the gas costs of removal
|
|
276
|
+
* transactions. We believe this is the best behavior at the time of writing, and do not expect this to
|
|
277
|
+
* result in any breaking changes in the future. All current proposals to change the self-destruct opcode
|
|
278
|
+
* are backwards compatible, but may result in not removing the bytecode from the blockchain state. This
|
|
279
|
+
* implementation is compatible with that architecture, as it does not rely on the bytecode being removed
|
|
280
|
+
* from the blockchain state (as opposed to using a CREATE2 style opcode when creating bytecode contracts,
|
|
281
|
+
* which could be used in a way that may rely on the bytecode being removed from the blockchain state,
|
|
282
|
+
* e.g. replacing a contract at a given deployed address).
|
|
283
|
+
* @param _address address of deployed contract with bytecode containing concat(gated-cleanup-logic, address, data)
|
|
284
|
+
* @dev This contract is only callable by the address of the contract that originally deployed the bytecode
|
|
285
|
+
* being purged. If this method is called by any other address, it will revert with the `INVALID` op-code.
|
|
286
|
+
* Additionally, for security purposes, the contract must be called with calldata `0xFF` to ensure that
|
|
287
|
+
* the `selfdestruct` op-code is intentionally being invoked, otherwise the `INVALID` op-code will be raised.
|
|
288
|
+
*/
|
|
289
|
+
function purgeBytecode(address _address) internal {
|
|
290
|
+
// deployed bytecode (above) handles all logic for purging state, so no
|
|
291
|
+
// call data is expected to be passed along to perform data purge
|
|
292
|
+
(bool success /* `data` not needed */, ) = _address.call(hex"FF");
|
|
293
|
+
if (!success) {
|
|
294
|
+
revert("ContractAsStorage: Delete Error");
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/*//////////////////////////////////////////////////////////////
|
|
299
|
+
INTERNAL HELPER LOGIC
|
|
300
|
+
//////////////////////////////////////////////////////////////*/
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
@notice Returns the size of the bytecode at address `_address`
|
|
304
|
+
@param _address address that may or may not contain bytecode
|
|
305
|
+
@return size size of the bytecode code at `_address`
|
|
306
|
+
*/
|
|
307
|
+
function _bytecodeSizeAt(
|
|
308
|
+
address _address
|
|
309
|
+
) private view returns (uint256 size) {
|
|
310
|
+
assembly {
|
|
311
|
+
size := extcodesize(_address)
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// SPDX-License-Identifier: LGPL-3.0-only
|
|
2
|
+
// Created By: Art Blocks Inc.
|
|
3
|
+
// Inspired by: https://ethereum.stackexchange.com/a/123950/103422
|
|
4
|
+
|
|
5
|
+
pragma solidity ^0.8.0;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @dev Operations on bytes32 data type, dealing with conversion to string.
|
|
9
|
+
*/
|
|
10
|
+
library Bytes32Strings {
|
|
11
|
+
/**
|
|
12
|
+
* @dev Intended to convert a `bytes32`-encoded string literal to `string`.
|
|
13
|
+
* Trims zero padding to arrive at original string literal.
|
|
14
|
+
*/
|
|
15
|
+
function toString(
|
|
16
|
+
bytes32 source
|
|
17
|
+
) internal pure returns (string memory result) {
|
|
18
|
+
uint8 length = 0;
|
|
19
|
+
while (source[length] != 0 && length < 32) {
|
|
20
|
+
length++;
|
|
21
|
+
}
|
|
22
|
+
assembly {
|
|
23
|
+
// free memory pointer
|
|
24
|
+
result := mload(0x40)
|
|
25
|
+
// update free memory pointer to new "memory end"
|
|
26
|
+
// (offset is 64-bytes: 32 for length, 32 for data)
|
|
27
|
+
mstore(0x40, add(result, 0x40))
|
|
28
|
+
// store length in first 32-byte memory slot
|
|
29
|
+
mstore(result, length)
|
|
30
|
+
// write actual data in second 32-byte memory slot
|
|
31
|
+
mstore(add(result, 0x20), source)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @dev Intended to check if a `bytes32`-encoded string contains a given
|
|
37
|
+
* character with UTF-8 character code `utf8CharCode exactly `targetQty`
|
|
38
|
+
* times. Does not support searching for multi-byte characters, only
|
|
39
|
+
* characters with UTF-8 character codes < 0x80.
|
|
40
|
+
*/
|
|
41
|
+
function containsExactCharacterQty(
|
|
42
|
+
bytes32 source,
|
|
43
|
+
uint8 utf8CharCode,
|
|
44
|
+
uint8 targetQty
|
|
45
|
+
) internal pure returns (bool) {
|
|
46
|
+
uint8 _occurrences = 0;
|
|
47
|
+
uint8 i;
|
|
48
|
+
for (i = 0; i < 32; ) {
|
|
49
|
+
uint8 _charCode = uint8(source[i]);
|
|
50
|
+
// if not a null byte, or a multi-byte UTF-8 character, check match
|
|
51
|
+
if (_charCode != 0 && _charCode < 0x80) {
|
|
52
|
+
if (_charCode == utf8CharCode) {
|
|
53
|
+
unchecked {
|
|
54
|
+
// no risk of overflow since max 32 iterations < max uin8=255
|
|
55
|
+
++_occurrences;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
unchecked {
|
|
60
|
+
// no risk of overflow since max 32 iterations < max uin8=255
|
|
61
|
+
++i;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return _occurrences == targetQty;
|
|
65
|
+
}
|
|
66
|
+
}
|