@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.
Files changed (196) hide show
  1. package/.env.example +10 -0
  2. package/LICENSE +165 -0
  3. package/README.md +286 -0
  4. package/artifacts/contracts/AdminACLV0.sol/AdminACLV0.json +164 -0
  5. package/artifacts/contracts/AdminACLV1.sol/AdminACLV1.json +248 -0
  6. package/artifacts/contracts/BasicRandomizer.sol/BasicRandomizer.json +24 -0
  7. package/artifacts/contracts/BasicRandomizerV2.sol/BasicRandomizerV2.json +102 -0
  8. package/artifacts/contracts/DependencyRegistryV0.sol/DependencyRegistryV0.json +1020 -0
  9. package/artifacts/contracts/GenArt721CoreV3.sol/GenArt721CoreV3.json +1928 -0
  10. package/artifacts/contracts/GenArt721CoreV3_Engine.sol/GenArt721CoreV3_Engine.json +1942 -0
  11. package/artifacts/contracts/engine/GenArt721CoreV2_ENGINE_FLEX.sol/GenArt721CoreV2_ENGINE_FLEX.json +1708 -0
  12. package/artifacts/contracts/engine/GenArt721CoreV2_PBAB.sol/GenArt721CoreV2_PBAB.json +1410 -0
  13. package/artifacts/contracts/engine/GenArt721CoreV2_PRTNR.sol/GenArt721CoreV2_PRTNR.json +1436 -0
  14. package/artifacts/contracts/engine/GenArt721MinterBurner_PBAB.sol/GenArt721MinterBurner_PBAB.json +437 -0
  15. package/artifacts/contracts/engine/GenArt721MinterDAExp_PBAB.sol/GenArt721MinterDAExp_PBAB.json +508 -0
  16. package/artifacts/contracts/engine/GenArt721Minter_PBAB.sol/GenArt721Minter_PBAB.json +381 -0
  17. package/artifacts/contracts/engine-registry/EngineRegistryV0.sol/EngineRegistryV0.json +109 -0
  18. package/artifacts/contracts/engine-registry/future/EngineRegistryV1.sol/EngineRegistryV1.json +109 -0
  19. package/artifacts/contracts/explorations/GenArt721CoreV3_Explorations.sol/GenArt721CoreV3_Explorations.json +1902 -0
  20. package/artifacts/contracts/interfaces/0.5.x/IBonusContract.sol/IBonusContract.json +47 -0
  21. package/artifacts/contracts/interfaces/0.5.x/IGenArt721CoreContractV1.sol/IGenArt721CoreContractV1.json +413 -0
  22. package/artifacts/contracts/interfaces/0.5.x/IGenArt721CoreV2_PBAB.sol/IGenArt721CoreV2_PBAB.json +392 -0
  23. package/artifacts/contracts/interfaces/0.5.x/IRandomizer.sol/IRandomizer.json +26 -0
  24. package/artifacts/contracts/interfaces/0.8.x/IAdminACLV0.sol/IAdminACLV0.json +122 -0
  25. package/artifacts/contracts/interfaces/0.8.x/IArtblocksRoyaltyOverride.sol/IArtblocksRoyaltyOverride.json +59 -0
  26. package/artifacts/contracts/interfaces/0.8.x/IBonusContract.sol/IBonusContract.json +43 -0
  27. package/artifacts/contracts/interfaces/0.8.x/IDelegationRegistry.sol/IDelegationRegistry.json +510 -0
  28. package/artifacts/contracts/interfaces/0.8.x/IDependencyRegistryCompatibleV0.sol/IDependencyRegistryCompatibleV0.json +53 -0
  29. package/artifacts/contracts/interfaces/0.8.x/IDependencyRegistryV0.sol/IDependencyRegistryV0.json +350 -0
  30. package/artifacts/contracts/interfaces/0.8.x/IEngineRegistryV0.sol/IEngineRegistryV0.json +85 -0
  31. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDAExpSettlementV0.sol/IFilteredMinterDAExpSettlementV0.json +730 -0
  32. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDAExpV0.sol/IFilteredMinterDAExpV0.json +311 -0
  33. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDAExpV1.sol/IFilteredMinterDAExpV1.json +617 -0
  34. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDALinV0.sol/IFilteredMinterDALinV0.json +292 -0
  35. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterDALinV1.sol/IFilteredMinterDALinV1.json +598 -0
  36. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterHolderV0.sol/IFilteredMinterHolderV0.json +355 -0
  37. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterHolderV1.sol/IFilteredMinterHolderV1.json +368 -0
  38. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterHolderV2.sol/IFilteredMinterHolderV2.json +674 -0
  39. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterMerkleV0.sol/IFilteredMinterMerkleV0.json +551 -0
  40. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterMerkleV1.sol/IFilteredMinterMerkleV1.json +564 -0
  41. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterMerkleV2.sol/IFilteredMinterMerkleV2.json +601 -0
  42. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterV0.sol/IFilteredMinterV0.json +216 -0
  43. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterV1.sol/IFilteredMinterV1.json +485 -0
  44. package/artifacts/contracts/interfaces/0.8.x/IFilteredMinterV2.sol/IFilteredMinterV2.json +522 -0
  45. package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreContractV1.sol/IGenArt721CoreContractV1.json +299 -0
  46. package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreContractV3.sol/IGenArt721CoreContractV3.json +609 -0
  47. package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Base.sol/IGenArt721CoreContractV3_Base.json +448 -0
  48. package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Engine.sol/IGenArt721CoreContractV3_Engine.json +649 -0
  49. package/artifacts/contracts/interfaces/0.8.x/IGenArt721CoreV2_PBAB.sol/IGenArt721CoreV2_PBAB.json +362 -0
  50. package/artifacts/contracts/interfaces/0.8.x/IManifold.sol/IManifold.json +35 -0
  51. package/artifacts/contracts/interfaces/0.8.x/IMinterFilterV0.sol/IMinterFilterV0.json +192 -0
  52. package/artifacts/contracts/interfaces/0.8.x/IRandomizer.sol/IRandomizer.json +24 -0
  53. package/artifacts/contracts/interfaces/0.8.x/IRandomizerV2.sol/IRandomizerV2.json +37 -0
  54. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/Address.json +10 -0
  55. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/Counters.json +10 -0
  56. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/CustomERC721Metadata.json +425 -0
  57. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/ERC165.json +38 -0
  58. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/ERC721.json +322 -0
  59. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/ERC721Enumerable.json +384 -0
  60. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/GenArt721CoreV1.json +1773 -0
  61. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/IERC165.json +32 -0
  62. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/IERC721.json +316 -0
  63. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/IERC721Enumerable.json +378 -0
  64. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/IERC721Receiver.json +47 -0
  65. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/SafeMath.json +10 -0
  66. package/artifacts/contracts/legacy/GenArt721CoreV1.sol/Strings.json +10 -0
  67. package/artifacts/contracts/legacy/GenArt721LegacyMinter.sol/GenArt721LegacyMinter.json +338 -0
  68. package/artifacts/contracts/libs/0.5.x/CustomERC721Metadata.sol/CustomERC721Metadata.json +425 -0
  69. package/artifacts/contracts/libs/0.5.x/IERC20.sol/IERC20.json +206 -0
  70. package/artifacts/contracts/libs/0.5.x/SafeMath.sol/SafeMath.json +10 -0
  71. package/artifacts/contracts/libs/0.5.x/Strings.sol/Strings.json +10 -0
  72. package/artifacts/contracts/libs/0.8.x/BytecodeStorage.sol/BytecodeStorage.json +10 -0
  73. package/artifacts/contracts/libs/0.8.x/Bytes32Strings.sol/Bytes32Strings.json +10 -0
  74. package/artifacts/contracts/libs/0.8.x/ERC721_PackedHashSeed.sol/ERC721_PackedHashSeed.json +357 -0
  75. package/artifacts/contracts/libs/integration-refs/delegation-registry/DelegationRegistry.sol/DelegationRegistry.json +529 -0
  76. package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeMock.sol/GnosisSafeMock.json +1037 -0
  77. package/artifacts/contracts/libs/integration-refs/gnosis-safe/GnosisSafeProxyFactoryMock.sol/GnosisSafeProxyFactoryMock.json +172 -0
  78. package/artifacts/contracts/libs/integration-refs/gnosis-safe/MultiSendMock.sol/MultiSendMock.json +24 -0
  79. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV0.sol/MinterFilterV0.json +342 -0
  80. package/artifacts/contracts/minter-suite/MinterFilter/MinterFilterV1.sol/MinterFilterV1.json +322 -0
  81. package/artifacts/contracts/minter-suite/Minters/MinterDAExp/MinterDAExpV2.sol/MinterDAExpV2.json +550 -0
  82. package/artifacts/contracts/minter-suite/Minters/MinterDAExp/MinterDAExpV3.sol/MinterDAExpV3.json +856 -0
  83. package/artifacts/contracts/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol/MinterDAExpSettlementV0.json +1053 -0
  84. package/artifacts/contracts/minter-suite/Minters/MinterDALin/MinterDALinV2.sol/MinterDALinV2.json +526 -0
  85. package/artifacts/contracts/minter-suite/Minters/MinterDALin/MinterDALinV3.sol/MinterDALinV3.json +832 -0
  86. package/artifacts/contracts/minter-suite/Minters/MinterHolder/MinterHolderV2.sol/MinterHolderV2.json +794 -0
  87. package/artifacts/contracts/minter-suite/Minters/MinterHolder/MinterHolderV3.sol/MinterHolderV3.json +1100 -0
  88. package/artifacts/contracts/minter-suite/Minters/MinterMerkle/MinterMerkleV3.sol/MinterMerkleV3.json +1002 -0
  89. package/artifacts/contracts/minter-suite/Minters/MinterMerkle/MinterMerkleV4.sol/MinterMerkleV4.json +1039 -0
  90. package/artifacts/contracts/minter-suite/Minters/MinterSetPrice/MinterSetPriceV2.sol/MinterSetPriceV2.json +365 -0
  91. package/artifacts/contracts/minter-suite/Minters/MinterSetPrice/MinterSetPriceV3.sol/MinterSetPriceV3.json +671 -0
  92. package/artifacts/contracts/minter-suite/Minters/MinterSetPrice/deprecated/MinterSetPriceV1.sol/MinterSetPriceV1.json +288 -0
  93. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol/MinterSetPriceERC20V2.json +436 -0
  94. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol/MinterSetPriceERC20V3.json +742 -0
  95. package/artifacts/contracts/minter-suite/Minters/MinterSetPriceERC20/deprecated/MinterSetPriceERC20V0.sol/MinterSetPriceERC20V0.json +461 -0
  96. package/artifacts/contracts/mock/BytecodeTextCR_DMock.sol/BytecodeTextCR_DMock.json +194 -0
  97. package/artifacts/contracts/mock/DeadReceiverMock.sol/DeadReceiverMock.json +15 -0
  98. package/artifacts/contracts/mock/ERC20Mock.sol/ERC20Mock.json +292 -0
  99. package/artifacts/contracts/mock/MockAdminACLV0.sol/MockAdminACLV0Events.json +165 -0
  100. package/artifacts/contracts/mock/RandomizerV2_NoAssignMock.sol/RandomizerV2_NoAssignMock.json +128 -0
  101. package/artifacts/contracts/mock/ReentrancyHolderMock.sol/ReentrancyHolderMock.json +118 -0
  102. package/artifacts/contracts/mock/ReentrancyMerkleMock.sol/ReentrancyMerkleMock.json +87 -0
  103. package/artifacts/contracts/mock/ReentrancyMock.sol/ReentrancyMock.json +82 -0
  104. package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverride.sol/GenArt721RoyaltyOverride.json +208 -0
  105. package/artifacts/contracts/royalty-registry/GenArt721RoyaltyOverride_PBAB.sol/GenArt721RoyaltyOverride_PBAB.json +301 -0
  106. package/contracts/AdminACLV0.sol +103 -0
  107. package/contracts/AdminACLV1.sol +193 -0
  108. package/contracts/BasicRandomizer.sol +23 -0
  109. package/contracts/BasicRandomizerV2.sol +36 -0
  110. package/contracts/DependencyRegistryV0.sol +893 -0
  111. package/contracts/GenArt721CoreV3.sol +2001 -0
  112. package/contracts/GenArt721CoreV3_Engine.sol +2061 -0
  113. package/contracts/engine/GenArt721CoreV2_ENGINE_FLEX.sol +887 -0
  114. package/contracts/engine/GenArt721CoreV2_PBAB.sol +695 -0
  115. package/contracts/engine/GenArt721CoreV2_PRTNR.sol +749 -0
  116. package/contracts/engine/GenArt721MinterBurner_PBAB.sol +467 -0
  117. package/contracts/engine/GenArt721MinterDAExp_PBAB.sol +614 -0
  118. package/contracts/engine/GenArt721Minter_PBAB.sol +420 -0
  119. package/contracts/engine-registry/EngineRegistryV0.sol +72 -0
  120. package/contracts/engine-registry/future/EngineRegistryV1.sol +86 -0
  121. package/contracts/explorations/GenArt721CoreV3_Explorations.sol +1989 -0
  122. package/contracts/interfaces/0.5.x/IBonusContract.sol +10 -0
  123. package/contracts/interfaces/0.5.x/IGenArt721CoreContractV1.sol +91 -0
  124. package/contracts/interfaces/0.5.x/IGenArt721CoreV2_PBAB.sol +92 -0
  125. package/contracts/interfaces/0.5.x/IRandomizer.sol +8 -0
  126. package/contracts/interfaces/0.8.x/IAdminACLV0.sol +51 -0
  127. package/contracts/interfaces/0.8.x/IArtblocksRoyaltyOverride.sol +34 -0
  128. package/contracts/interfaces/0.8.x/IBonusContract.sol +10 -0
  129. package/contracts/interfaces/0.8.x/IDelegationRegistry.sol +221 -0
  130. package/contracts/interfaces/0.8.x/IDependencyRegistryCompatibleV0.sol +31 -0
  131. package/contracts/interfaces/0.8.x/IDependencyRegistryV0.sol +95 -0
  132. package/contracts/interfaces/0.8.x/IEngineRegistryV0.sol +38 -0
  133. package/contracts/interfaces/0.8.x/IFilteredMinterDAExpSettlementV0.sol +70 -0
  134. package/contracts/interfaces/0.8.x/IFilteredMinterDAExpV0.sol +35 -0
  135. package/contracts/interfaces/0.8.x/IFilteredMinterDAExpV1.sol +16 -0
  136. package/contracts/interfaces/0.8.x/IFilteredMinterDALinV0.sol +32 -0
  137. package/contracts/interfaces/0.8.x/IFilteredMinterDALinV1.sol +16 -0
  138. package/contracts/interfaces/0.8.x/IFilteredMinterHolderV0.sol +68 -0
  139. package/contracts/interfaces/0.8.x/IFilteredMinterHolderV1.sol +19 -0
  140. package/contracts/interfaces/0.8.x/IFilteredMinterHolderV2.sol +19 -0
  141. package/contracts/interfaces/0.8.x/IFilteredMinterMerkleV0.sol +37 -0
  142. package/contracts/interfaces/0.8.x/IFilteredMinterMerkleV1.sol +19 -0
  143. package/contracts/interfaces/0.8.x/IFilteredMinterMerkleV2.sol +19 -0
  144. package/contracts/interfaces/0.8.x/IFilteredMinterV0.sol +74 -0
  145. package/contracts/interfaces/0.8.x/IFilteredMinterV1.sol +127 -0
  146. package/contracts/interfaces/0.8.x/IFilteredMinterV2.sol +30 -0
  147. package/contracts/interfaces/0.8.x/IGenArt721CoreContractV1.sol +73 -0
  148. package/contracts/interfaces/0.8.x/IGenArt721CoreContractV3.sol +79 -0
  149. package/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Base.sol +127 -0
  150. package/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Engine.sol +80 -0
  151. package/contracts/interfaces/0.8.x/IGenArt721CoreV2_PBAB.sol +91 -0
  152. package/contracts/interfaces/0.8.x/IManifold.sol +24 -0
  153. package/contracts/interfaces/0.8.x/IMinterFilterV0.sol +47 -0
  154. package/contracts/interfaces/0.8.x/IRandomizer.sol +8 -0
  155. package/contracts/interfaces/0.8.x/IRandomizerV2.sol +15 -0
  156. package/contracts/legacy/GenArt721CoreV1.sol +1593 -0
  157. package/contracts/legacy/GenArt721LegacyMinter.sol +275 -0
  158. package/contracts/libs/0.5.x/CustomERC721Metadata.sol +52 -0
  159. package/contracts/libs/0.5.x/IERC20.sol +96 -0
  160. package/contracts/libs/0.5.x/SafeMath.sol +98 -0
  161. package/contracts/libs/0.5.x/Strings.sol +92 -0
  162. package/contracts/libs/0.8.x/BytecodeStorage.sol +314 -0
  163. package/contracts/libs/0.8.x/Bytes32Strings.sol +66 -0
  164. package/contracts/libs/0.8.x/ERC721_PackedHashSeed.sol +514 -0
  165. package/contracts/libs/integration-refs/delegation-registry/DelegationRegistry.sol +663 -0
  166. package/contracts/libs/integration-refs/gnosis-safe/GnosisSafeMock.sol +6 -0
  167. package/contracts/libs/integration-refs/gnosis-safe/GnosisSafeProxyFactoryMock.sol +6 -0
  168. package/contracts/libs/integration-refs/gnosis-safe/MultiSendMock.sol +6 -0
  169. package/contracts/minter-suite/MinterFilter/MinterFilterV0.sol +291 -0
  170. package/contracts/minter-suite/MinterFilter/MinterFilterV1.sol +320 -0
  171. package/contracts/minter-suite/Minters/MinterDAExp/MinterDAExpV2.sol +571 -0
  172. package/contracts/minter-suite/Minters/MinterDAExp/MinterDAExpV3.sol +622 -0
  173. package/contracts/minter-suite/Minters/MinterDAExpSettlement/MinterDAExpSettlementV0.sol +1066 -0
  174. package/contracts/minter-suite/Minters/MinterDALin/MinterDALinV2.sol +527 -0
  175. package/contracts/minter-suite/Minters/MinterDALin/MinterDALinV3.sol +576 -0
  176. package/contracts/minter-suite/Minters/MinterHolder/MinterHolderV2.sol +749 -0
  177. package/contracts/minter-suite/Minters/MinterHolder/MinterHolderV3.sol +798 -0
  178. package/contracts/minter-suite/Minters/MinterMerkle/MinterMerkleV3.sol +682 -0
  179. package/contracts/minter-suite/Minters/MinterMerkle/MinterMerkleV4.sol +733 -0
  180. package/contracts/minter-suite/Minters/MinterSetPrice/MinterSetPriceV2.sol +350 -0
  181. package/contracts/minter-suite/Minters/MinterSetPrice/MinterSetPriceV3.sol +401 -0
  182. package/contracts/minter-suite/Minters/MinterSetPrice/deprecated/MinterSetPriceV1.sol +274 -0
  183. package/contracts/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V2.sol +491 -0
  184. package/contracts/minter-suite/Minters/MinterSetPriceERC20/MinterSetPriceERC20V3.sol +542 -0
  185. package/contracts/minter-suite/Minters/MinterSetPriceERC20/deprecated/MinterSetPriceERC20V0.sol +470 -0
  186. package/contracts/mock/BytecodeTextCR_DMock.sol +184 -0
  187. package/contracts/mock/DeadReceiverMock.sol +13 -0
  188. package/contracts/mock/ERC20Mock.sol +11 -0
  189. package/contracts/mock/MockAdminACLV0.sol +65 -0
  190. package/contracts/mock/RandomizerV2_NoAssignMock.sol +43 -0
  191. package/contracts/mock/ReentrancyHolderMock.sol +50 -0
  192. package/contracts/mock/ReentrancyMerkleMock.sol +64 -0
  193. package/contracts/mock/ReentrancyMock.sol +44 -0
  194. package/contracts/royalty-registry/GenArt721RoyaltyOverride.sol +168 -0
  195. package/contracts/royalty-registry/GenArt721RoyaltyOverride_PBAB.sol +221 -0
  196. 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
+ }