@artblocks/contracts 1.2.1 → 1.3.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 (71) hide show
  1. package/artifacts/contracts/BytecodeStorageReaders/BytecodeStorageReaderContractV2_Web3Call.sol/BytecodeStorageReaderContractV2_Web3Call.json +201 -0
  2. package/artifacts/contracts/BytecodeStorageReaders/UniversalBytecodeStorageReader.sol/UniversalBytecodeStorageReader.json +2 -2
  3. package/artifacts/contracts/DependencyRegistryV0.sol/DependencyRegistryV0.json +42 -53
  4. package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol/GenArt721CoreV3_Engine_Flex.json +2 -2
  5. package/artifacts/contracts/generator/GenArt721GeneratorV0.sol/GenArt721GeneratorV0.json +2 -2
  6. package/artifacts/contracts/interfaces/v0.8.x/IDelegateRegistry.sol/IDelegateRegistry.json +820 -0
  7. package/artifacts/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol/IDependencyRegistryV0.json +13 -0
  8. package/artifacts/contracts/interfaces/v0.8.x/IPMPAugmentHook.sol/IPMPAugmentHook.json +83 -0
  9. package/artifacts/contracts/interfaces/v0.8.x/IPMPConfigureHook.sol/IPMPConfigureHook.json +80 -0
  10. package/artifacts/contracts/interfaces/v0.8.x/IPMPV0.sol/IPMPV0.json +402 -0
  11. package/artifacts/contracts/interfaces/v0.8.x/IUniversalBytecodeStorageReader.sol/IUniversalBytecodeStorageReader.json +13 -0
  12. package/artifacts/contracts/interfaces/v0.8.x/IWeb3Call.sol/IWeb3Call.json +47 -0
  13. package/artifacts/contracts/libs/integration-refs/delegation-registry/DelegateRegistry.sol/DelegateRegistry.json +846 -0
  14. package/artifacts/contracts/libs/integration-refs/delegation-registry/libraries/RegistryHashes.sol/RegistryHashes.json +10 -0
  15. package/artifacts/contracts/libs/integration-refs/delegation-registry/libraries/RegistryOps.sol/RegistryOps.json +10 -0
  16. package/artifacts/contracts/libs/integration-refs/delegation-registry/libraries/RegistryStorage.sol/RegistryStorage.json +10 -0
  17. package/artifacts/contracts/libs/v0.8.x/DependencyRegistryStorageLib.sol/DependencyRegistryStorageLib.json +2 -2
  18. package/artifacts/contracts/libs/v0.8.x/ImmutableStringArray.sol/ImmutableStringArray.json +10 -0
  19. package/artifacts/contracts/libs/v0.8.x/V3FlexLib.sol/V3FlexLib.json +2 -2
  20. package/artifacts/contracts/mock/ImmutableStringArrayMock.sol/ImmutableStringArrayMock.json +69 -0
  21. package/artifacts/contracts/mock/MockPMPAugmentHook.sol/MockPMPAugmentHook.json +214 -0
  22. package/artifacts/contracts/mock/MockPMPConfigureHook.sol/MockPMPConfigureHook.json +236 -0
  23. package/artifacts/contracts/web3call/PMPV0.sol/PMPV0.json +629 -0
  24. package/artifacts/contracts/web3call/Web3Call.sol/Web3Call.json +66 -0
  25. package/artifacts/contracts/web3call/augment-hooks/AbstractPMPAugmentHook.sol/AbstractPMPAugmentHook.json +83 -0
  26. package/artifacts/contracts/web3call/augment-hooks/InjectBaseGasFee.sol/InjectBaseGasFee.json +83 -0
  27. package/artifacts/contracts/web3call/augment-hooks/InjectChromieSquiggleFloorPrice.sol/IUniswapV2Pair.json +60 -0
  28. package/artifacts/contracts/web3call/augment-hooks/InjectChromieSquiggleFloorPrice.sol/InjectChromieSquiggleFloorPrice.json +107 -0
  29. package/artifacts/contracts/web3call/augment-hooks/InjectIsNounsDaoMember.sol/InjectIsNounsDaoMember.json +96 -0
  30. package/artifacts/contracts/web3call/augment-hooks/InjectIsProjectFullyMinted.sol/InjectIsProjectFullyMinted.json +83 -0
  31. package/artifacts/contracts/web3call/augment-hooks/InjectPolyptychTokenHash.sol/InjectPolyptychTokenHash.json +141 -0
  32. package/artifacts/contracts/web3call/augment-hooks/InjectTokenHashSeed.sol/InjectTokenHashSeed.json +99 -0
  33. package/artifacts/contracts/web3call/augment-hooks/InjectTokenOwner.sol/InjectTokenOwner.json +99 -0
  34. package/artifacts/contracts/web3call/augment-hooks/InjectTokenOwnerEthBalance.sol/InjectTokenOwnerEthBalance.json +83 -0
  35. package/artifacts/contracts/web3call/augment-hooks/InjectUSDCTotalSupply.sol/InjectUSDCTotalSupply.json +107 -0
  36. package/artifacts/contracts/web3call/configure-hooks/abstractPMPConfigureHook.sol/AbstractPMPConfigureHook.json +80 -0
  37. package/contracts/BytecodeStorageReaders/BytecodeStorageReaderContractV2_Web3Call.sol +128 -0
  38. package/contracts/DependencyRegistryV0.sol +67 -28
  39. package/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol +7 -1
  40. package/contracts/generator/GenArt721GeneratorV0.sol +77 -8
  41. package/contracts/interfaces/v0.8.x/IDelegateRegistry.sol +318 -0
  42. package/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol +2 -0
  43. package/contracts/interfaces/v0.8.x/IPMPAugmentHook.sol +31 -0
  44. package/contracts/interfaces/v0.8.x/IPMPConfigureHook.sol +25 -0
  45. package/contracts/interfaces/v0.8.x/IPMPV0.sol +224 -0
  46. package/contracts/interfaces/v0.8.x/IUniversalBytecodeStorageReader.sol +5 -0
  47. package/contracts/interfaces/v0.8.x/IWeb3Call.sol +28 -0
  48. package/contracts/libs/integration-refs/delegation-registry/DelegateRegistry.sol +753 -0
  49. package/contracts/libs/integration-refs/delegation-registry/libraries/RegistryHashes.sol +359 -0
  50. package/contracts/libs/integration-refs/delegation-registry/libraries/RegistryOps.sol +31 -0
  51. package/contracts/libs/integration-refs/delegation-registry/libraries/RegistryStorage.sol +87 -0
  52. package/contracts/libs/v0.8.x/DependencyRegistryStorageLib.sol +3 -0
  53. package/contracts/libs/v0.8.x/ImmutableStringArray.sol +301 -0
  54. package/contracts/libs/v0.8.x/V3FlexLib.sol +7 -1
  55. package/contracts/mock/ImmutableStringArrayMock.sol +47 -0
  56. package/contracts/mock/MockPMPAugmentHook.sol +170 -0
  57. package/contracts/mock/MockPMPConfigureHook.sol +78 -0
  58. package/contracts/web3call/PMPV0.sol +1126 -0
  59. package/contracts/web3call/Web3Call.sol +25 -0
  60. package/contracts/web3call/augment-hooks/AbstractPMPAugmentHook.sol +46 -0
  61. package/contracts/web3call/augment-hooks/InjectBaseGasFee.sol +57 -0
  62. package/contracts/web3call/augment-hooks/InjectChromieSquiggleFloorPrice.sol +103 -0
  63. package/contracts/web3call/augment-hooks/InjectIsNounsDaoMember.sol +66 -0
  64. package/contracts/web3call/augment-hooks/InjectIsProjectFullyMinted.sol +73 -0
  65. package/contracts/web3call/augment-hooks/InjectPolyptychTokenHash.sol +88 -0
  66. package/contracts/web3call/augment-hooks/InjectTokenHashSeed.sol +62 -0
  67. package/contracts/web3call/augment-hooks/InjectTokenOwner.sol +60 -0
  68. package/contracts/web3call/augment-hooks/InjectTokenOwnerEthBalance.sol +61 -0
  69. package/contracts/web3call/augment-hooks/InjectUSDCTotalSupply.sol +69 -0
  70. package/contracts/web3call/configure-hooks/abstractPMPConfigureHook.sol +41 -0
  71. package/package.json +5 -5
@@ -0,0 +1,359 @@
1
+ // SPDX-License-Identifier: CC0-1.0
2
+ pragma solidity ^0.8.21;
3
+
4
+ import {IDelegateRegistry} from "../../../../interfaces/v0.8.x/IDelegateRegistry.sol";
5
+
6
+ /**
7
+ * @title Library for calculating the hashes and storage locations used in the delegate registry
8
+ *
9
+ * The encoding for the 5 types of delegate registry hashes should be as follows:
10
+ *
11
+ * ALL: keccak256(abi.encodePacked(rights, from, to))
12
+ * CONTRACT: keccak256(abi.encodePacked(rights, from, to, contract_))
13
+ * ERC721: keccak256(abi.encodePacked(rights, from, to, contract_, tokenId))
14
+ * ERC20: keccak256(abi.encodePacked(rights, from, to, contract_))
15
+ * ERC1155: keccak256(abi.encodePacked(rights, from, to, contract_, tokenId))
16
+ *
17
+ * To avoid collisions between the hashes with respect to type, the hash is shifted left by one byte
18
+ * and the last byte is then encoded with a unique number for the delegation type
19
+ *
20
+ */
21
+ library RegistryHashes {
22
+ /// @dev Used to delete everything but the last byte of a 32 byte word with and(word, EXTRACT_LAST_BYTE)
23
+ uint256 internal constant EXTRACT_LAST_BYTE = 0xff;
24
+ /// @dev Constants for the delegate registry delegation type enumeration
25
+ uint256 internal constant ALL_TYPE = 1;
26
+ uint256 internal constant CONTRACT_TYPE = 2;
27
+ uint256 internal constant ERC721_TYPE = 3;
28
+ uint256 internal constant ERC20_TYPE = 4;
29
+ uint256 internal constant ERC1155_TYPE = 5;
30
+ /// @dev Constant for the location of the delegations array in the delegate registry, defined to be zero
31
+ uint256 internal constant DELEGATION_SLOT = 0;
32
+
33
+ /**
34
+ * @notice Helper function to decode last byte of a delegation hash into its delegation type enum
35
+ * @param inputHash The bytehash to decode the type from
36
+ * @return decodedType The delegation type
37
+ */
38
+ function decodeType(
39
+ bytes32 inputHash
40
+ ) internal pure returns (IDelegateRegistry.DelegationType decodedType) {
41
+ assembly {
42
+ decodedType := and(inputHash, EXTRACT_LAST_BYTE)
43
+ }
44
+ }
45
+
46
+ /**
47
+ * @notice Helper function that computes the storage location of a particular delegation array
48
+ * @dev Storage keys further down the array can be obtained by adding computedLocation with the element position
49
+ * @dev Follows the solidity storage location encoding for a mapping(bytes32 => fixedArray) at the position of the delegationSlot
50
+ * @param inputHash The bytehash to decode the type from
51
+ * @return computedLocation is the storage key of the delegation array at position 0
52
+ */
53
+ function location(
54
+ bytes32 inputHash
55
+ ) internal pure returns (bytes32 computedLocation) {
56
+ assembly ("memory-safe") {
57
+ // This block only allocates memory in the scratch space
58
+ mstore(0, inputHash)
59
+ mstore(32, DELEGATION_SLOT)
60
+ computedLocation := keccak256(0, 64) // Run keccak256 over bytes in scratch space to obtain the storage key
61
+ }
62
+ }
63
+
64
+ /**
65
+ * @notice Helper function to compute delegation hash for `DelegationType.ALL`
66
+ * @dev Equivalent to `keccak256(abi.encodePacked(rights, from, to))` then left-shift by 1 byte and write the delegation type to the cleaned last byte
67
+ * @dev Will not revert if `from` or `to` are > uint160, any input larger than uint160 for `from` and `to` will be cleaned to its lower 20 bytes
68
+ * @param from The address making the delegation
69
+ * @param rights The rights specified by the delegation
70
+ * @param to The address receiving the delegation
71
+ * @return hash The delegation parameters encoded with ALL_TYPE
72
+ */
73
+ function allHash(
74
+ address from,
75
+ bytes32 rights,
76
+ address to
77
+ ) internal pure returns (bytes32 hash) {
78
+ assembly ("memory-safe") {
79
+ // This block only allocates memory after the free memory pointer
80
+ let ptr := mload(64) // Load the free memory pointer
81
+ // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
82
+ mstore(add(ptr, 40), to)
83
+ mstore(add(ptr, 20), from)
84
+ mstore(ptr, rights)
85
+ hash := or(shl(8, keccak256(ptr, 72)), ALL_TYPE) // Keccak-hashes the packed encoding, left-shifts by one byte, then writes type to the lowest-order byte
86
+ }
87
+ }
88
+
89
+ /**
90
+ * @notice Helper function to compute delegation location for `DelegationType.ALL`
91
+ * @dev Equivalent to `location(allHash(rights, from, to))`
92
+ * @dev Will not revert if `from` or `to` are > uint160, any input larger than uint160 for `from` and `to` will be cleaned to its lower 20 bytes
93
+ * @param from The address making the delegation
94
+ * @param rights The rights specified by the delegation
95
+ * @param to The address receiving the delegation
96
+ * @return computedLocation The storage location of the all delegation with those parameters in the delegations mapping
97
+ */
98
+ function allLocation(
99
+ address from,
100
+ bytes32 rights,
101
+ address to
102
+ ) internal pure returns (bytes32 computedLocation) {
103
+ assembly ("memory-safe") {
104
+ // This block only allocates memory after the free memory pointer and in the scratch space
105
+ let ptr := mload(64) // Load the free memory pointer
106
+ // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
107
+ mstore(add(ptr, 40), to)
108
+ mstore(add(ptr, 20), from)
109
+ mstore(ptr, rights)
110
+ mstore(0, or(shl(8, keccak256(ptr, 72)), ALL_TYPE)) // Computes `allHash`, then stores the result in scratch space
111
+ mstore(32, DELEGATION_SLOT)
112
+ computedLocation := keccak256(0, 64) // Runs keccak over the scratch space to obtain the storage key
113
+ }
114
+ }
115
+
116
+ /**
117
+ * @notice Helper function to compute delegation hash for `DelegationType.CONTRACT`
118
+ * @dev Equivalent to keccak256(abi.encodePacked(rights, from, to, contract_)) left-shifted by 1 then last byte overwritten with CONTRACT_TYPE
119
+ * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes
120
+ * @param from The address making the delegation
121
+ * @param rights The rights specified by the delegation
122
+ * @param to The address receiving the delegation
123
+ * @param contract_ The address of the contract specified by the delegation
124
+ * @return hash The delegation parameters encoded with CONTRACT_TYPE
125
+ */
126
+ function contractHash(
127
+ address from,
128
+ bytes32 rights,
129
+ address to,
130
+ address contract_
131
+ ) internal pure returns (bytes32 hash) {
132
+ assembly ("memory-safe") {
133
+ // This block only allocates memory after the free memory pointer
134
+ let ptr := mload(64) // Load the free memory pointer
135
+ // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
136
+ mstore(add(ptr, 60), contract_)
137
+ mstore(add(ptr, 40), to)
138
+ mstore(add(ptr, 20), from)
139
+ mstore(ptr, rights)
140
+ hash := or(shl(8, keccak256(ptr, 92)), CONTRACT_TYPE) // Keccak-hashes the packed encoding, left-shifts by one byte, then writes type to the lowest-order byte
141
+ }
142
+ }
143
+
144
+ /**
145
+ * @notice Helper function to compute delegation location for `DelegationType.CONTRACT`
146
+ * @dev Equivalent to `location(contractHash(rights, from, to, contract_))`
147
+ * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes
148
+ * @param from The address making the delegation
149
+ * @param rights The rights specified by the delegation
150
+ * @param to The address receiving the delegation
151
+ * @param contract_ The address of the contract specified by the delegation
152
+ * @return computedLocation The storage location of the contract delegation with those parameters in the delegations mapping
153
+ */
154
+ function contractLocation(
155
+ address from,
156
+ bytes32 rights,
157
+ address to,
158
+ address contract_
159
+ ) internal pure returns (bytes32 computedLocation) {
160
+ assembly ("memory-safe") {
161
+ // This block only allocates memory after the free memory pointer and in the scratch space
162
+ let ptr := mload(64) // Load free memory pointer
163
+ // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
164
+ mstore(add(ptr, 60), contract_)
165
+ mstore(add(ptr, 40), to)
166
+ mstore(add(ptr, 20), from)
167
+ mstore(ptr, rights)
168
+ mstore(0, or(shl(8, keccak256(ptr, 92)), CONTRACT_TYPE)) // Computes `contractHash`, then stores the result in scratch space
169
+ mstore(32, DELEGATION_SLOT)
170
+ computedLocation := keccak256(0, 64) // Runs keccak over the scratch space to obtain the storage key
171
+ }
172
+ }
173
+
174
+ /**
175
+ * @notice Helper function to compute delegation hash for `DelegationType.ERC721`
176
+ * @dev Equivalent to `keccak256(abi.encodePacked(rights, from, to, contract_, tokenId)) left-shifted by 1 then last byte overwritten with ERC721_TYPE
177
+ * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes
178
+ * @param from The address making the delegation
179
+ * @param rights The rights specified by the delegation
180
+ * @param to The address receiving the delegation
181
+ * @param tokenId The id of the token specified by the delegation
182
+ * @param contract_ The address of the contract specified by the delegation
183
+ * @return hash The delegation parameters encoded with ERC721_TYPE
184
+ */
185
+ function erc721Hash(
186
+ address from,
187
+ bytes32 rights,
188
+ address to,
189
+ uint256 tokenId,
190
+ address contract_
191
+ ) internal pure returns (bytes32 hash) {
192
+ assembly ("memory-safe") {
193
+ // This block only allocates memory after the free memory pointer
194
+ let ptr := mload(64) // Cache the free memory pointer.
195
+ // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
196
+ mstore(add(ptr, 92), tokenId)
197
+ mstore(add(ptr, 60), contract_)
198
+ mstore(add(ptr, 40), to)
199
+ mstore(add(ptr, 20), from)
200
+ mstore(ptr, rights)
201
+ hash := or(shl(8, keccak256(ptr, 124)), ERC721_TYPE) // Keccak-hashes the packed encoding, left-shifts by one byte, then writes type to the lowest-order byte
202
+ }
203
+ }
204
+
205
+ /**
206
+ * @notice Helper function to compute delegation location for `DelegationType.ERC721`
207
+ * @dev Equivalent to `location(ERC721Hash(rights, from, to, contract_, tokenId))`
208
+ * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes
209
+ * @param from The address making the delegation
210
+ * @param rights The rights specified by the delegation
211
+ * @param to The address receiving the delegation
212
+ * @param tokenId The id of the ERC721 token
213
+ * @param contract_ The address of the ERC721 token contract
214
+ * @return computedLocation The storage location of the ERC721 delegation with those parameters in the delegations mapping
215
+ */
216
+ function erc721Location(
217
+ address from,
218
+ bytes32 rights,
219
+ address to,
220
+ uint256 tokenId,
221
+ address contract_
222
+ ) internal pure returns (bytes32 computedLocation) {
223
+ assembly ("memory-safe") {
224
+ // This block only allocates memory after the free memory pointer and in the scratch space
225
+ let ptr := mload(64) // Cache the free memory pointer.
226
+ // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
227
+ mstore(add(ptr, 92), tokenId)
228
+ mstore(add(ptr, 60), contract_)
229
+ mstore(add(ptr, 40), to)
230
+ mstore(add(ptr, 20), from)
231
+ mstore(ptr, rights)
232
+ mstore(0, or(shl(8, keccak256(ptr, 124)), ERC721_TYPE)) // Computes erc721Hash, then stores the result in scratch space
233
+ mstore(32, DELEGATION_SLOT)
234
+ computedLocation := keccak256(0, 64) // Runs keccak256 over the scratch space to obtain the storage key
235
+ }
236
+ }
237
+
238
+ /**
239
+ * @notice Helper function to compute delegation hash for `DelegationType.ERC20`
240
+ * @dev Equivalent to `keccak256(abi.encodePacked(rights, from, to, contract_))` with the last byte overwritten with ERC20_TYPE
241
+ * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes
242
+ * @param from The address making the delegation
243
+ * @param rights The rights specified by the delegation
244
+ * @param to The address receiving the delegation
245
+ * @param contract_ The address of the ERC20 token contract
246
+ * @return hash The parameters encoded with ERC20_TYPE
247
+ */
248
+ function erc20Hash(
249
+ address from,
250
+ bytes32 rights,
251
+ address to,
252
+ address contract_
253
+ ) internal pure returns (bytes32 hash) {
254
+ assembly ("memory-safe") {
255
+ // This block only allocates memory after the free memory pointer
256
+ let ptr := mload(64) // Load free memory pointer
257
+ // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
258
+ mstore(add(ptr, 60), contract_)
259
+ mstore(add(ptr, 40), to)
260
+ mstore(add(ptr, 20), from)
261
+ mstore(ptr, rights)
262
+ hash := or(shl(8, keccak256(ptr, 92)), ERC20_TYPE) // Keccak-hashes the packed encoding, left-shifts by one byte, then writes type to the lowest-order byte
263
+ }
264
+ }
265
+
266
+ /**
267
+ * @notice Helper function to compute delegation location for `DelegationType.ERC20`
268
+ * @dev Equivalent to `location(ERC20Hash(rights, from, to, contract_))`
269
+ * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes
270
+ * @param from The address making the delegation
271
+ * @param rights The rights specified by the delegation
272
+ * @param to The address receiving the delegation
273
+ * @param contract_ The address of the ERC20 token contract
274
+ * @return computedLocation The storage location of the ERC20 delegation with those parameters in the delegations mapping
275
+ */
276
+ function erc20Location(
277
+ address from,
278
+ bytes32 rights,
279
+ address to,
280
+ address contract_
281
+ ) internal pure returns (bytes32 computedLocation) {
282
+ assembly ("memory-safe") {
283
+ // This block only allocates memory after the free memory pointer and in the scratch space
284
+ let ptr := mload(64) // Loads the free memory pointer
285
+ // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
286
+ mstore(add(ptr, 60), contract_)
287
+ mstore(add(ptr, 40), to)
288
+ mstore(add(ptr, 20), from)
289
+ mstore(ptr, rights)
290
+ mstore(0, or(shl(8, keccak256(ptr, 92)), ERC20_TYPE)) // Computes erc20Hash, then stores the result in scratch space
291
+ mstore(32, DELEGATION_SLOT)
292
+ computedLocation := keccak256(0, 64) // Runs keccak over the scratch space to obtain the storage key
293
+ }
294
+ }
295
+
296
+ /**
297
+ * @notice Helper function to compute delegation hash for `DelegationType.ERC1155`
298
+ * @dev Equivalent to keccak256(abi.encodePacked(rights, from, to, contract_, tokenId)) left-shifted with the last byte overwritten with ERC1155_TYPE
299
+ * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes
300
+ * @param from The address making the delegation
301
+ * @param rights The rights specified by the delegation
302
+ * @param to The address receiving the delegation
303
+ * @param tokenId The id of the ERC1155 token
304
+ * @param contract_ The address of the ERC1155 token contract
305
+ * @return hash The parameters encoded with ERC1155_TYPE
306
+ */
307
+ function erc1155Hash(
308
+ address from,
309
+ bytes32 rights,
310
+ address to,
311
+ uint256 tokenId,
312
+ address contract_
313
+ ) internal pure returns (bytes32 hash) {
314
+ assembly ("memory-safe") {
315
+ // This block only allocates memory after the free memory pointer
316
+ let ptr := mload(64) // Load the free memory pointer.
317
+ // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
318
+ mstore(add(ptr, 92), tokenId)
319
+ mstore(add(ptr, 60), contract_)
320
+ mstore(add(ptr, 40), to)
321
+ mstore(add(ptr, 20), from)
322
+ mstore(ptr, rights)
323
+ hash := or(shl(8, keccak256(ptr, 124)), ERC1155_TYPE) // Keccak-hashes the packed encoding, left-shifts by one byte, then writes type to the lowest-order byte
324
+ }
325
+ }
326
+
327
+ /**
328
+ * @notice Helper function to compute delegation location for `DelegationType.ERC1155`
329
+ * @dev Equivalent to `location(ERC1155Hash(rights, from, to, contract_, tokenId))`
330
+ * @dev Will not revert if `from`, `to` or `contract_` are > uint160, these inputs will be cleaned to their lower 20 bytes
331
+ * @param from The address making the delegation
332
+ * @param rights The rights specified by the delegation
333
+ * @param to The address receiving the delegation
334
+ * @param tokenId The id of the ERC1155 token
335
+ * @param contract_ The address of the ERC1155 token contract
336
+ * @return computedLocation The storage location of the ERC1155 delegation with those parameters in the delegations mapping
337
+ */
338
+ function erc1155Location(
339
+ address from,
340
+ bytes32 rights,
341
+ address to,
342
+ uint256 tokenId,
343
+ address contract_
344
+ ) internal pure returns (bytes32 computedLocation) {
345
+ assembly ("memory-safe") {
346
+ // This block only allocates memory after the free memory pointer and in the scratch space
347
+ let ptr := mload(64) // Cache the free memory pointer.
348
+ // Lay out the variables from last to first, agnostic to upper 96 bits of address words.
349
+ mstore(add(ptr, 92), tokenId)
350
+ mstore(add(ptr, 60), contract_)
351
+ mstore(add(ptr, 40), to)
352
+ mstore(add(ptr, 20), from)
353
+ mstore(ptr, rights)
354
+ mstore(0, or(shl(8, keccak256(ptr, 124)), ERC1155_TYPE)) // Computes erc1155Hash, then stores the result in scratch space
355
+ mstore(32, DELEGATION_SLOT)
356
+ computedLocation := keccak256(0, 64) // Runs keccak over the scratch space to obtain the storage key
357
+ }
358
+ }
359
+ }
@@ -0,0 +1,31 @@
1
+ // SPDX-License-Identifier: CC0-1.0
2
+ pragma solidity ^0.8.21;
3
+
4
+ library RegistryOps {
5
+ /// @dev `x > y ? x : y`.
6
+ function max(uint256 x, uint256 y) internal pure returns (uint256 z) {
7
+ assembly {
8
+ // `gt(y, x)` will evaluate to 1 if `y > x`, else 0.
9
+ //
10
+ // If `y > x`:
11
+ // `x ^ ((x ^ y) * 1) = x ^ (x ^ y) = (x ^ x) ^ y = 0 ^ y = y`.
12
+ // otherwise:
13
+ // `x ^ ((x ^ y) * 0) = x ^ 0 = x`.
14
+ z := xor(x, mul(xor(x, y), gt(y, x)))
15
+ }
16
+ }
17
+
18
+ /// @dev `x & y`.
19
+ function and(bool x, bool y) internal pure returns (bool z) {
20
+ assembly {
21
+ z := and(iszero(iszero(x)), iszero(iszero(y))) // Compiler cleans dirty booleans on the stack to 1, so do the same here
22
+ }
23
+ }
24
+
25
+ /// @dev `x | y`.
26
+ function or(bool x, bool y) internal pure returns (bool z) {
27
+ assembly {
28
+ z := or(iszero(iszero(x)), iszero(iszero(y))) // Compiler cleans dirty booleans on the stack to 1, so do the same here
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,87 @@
1
+ // SPDX-License-Identifier: CC0-1.0
2
+ pragma solidity ^0.8.21;
3
+
4
+ library RegistryStorage {
5
+ /// @dev Standardizes `from` storage flags to prevent double-writes in the delegation in/outbox if the same delegation is revoked and rewritten
6
+ address internal constant DELEGATION_EMPTY = address(0);
7
+ address internal constant DELEGATION_REVOKED = address(1);
8
+
9
+ /// @dev Standardizes storage positions of delegation data
10
+ uint256 internal constant POSITIONS_FIRST_PACKED = 0; // | 4 bytes empty | first 8 bytes of contract address | 20 bytes of from address |
11
+ uint256 internal constant POSITIONS_SECOND_PACKED = 1; // | last 12 bytes of contract address | 20 bytes of to address |
12
+ uint256 internal constant POSITIONS_RIGHTS = 2;
13
+ uint256 internal constant POSITIONS_TOKEN_ID = 3;
14
+ uint256 internal constant POSITIONS_AMOUNT = 4;
15
+
16
+ /// @dev Used to clean address types of dirty bits with `and(address, CLEAN_ADDRESS)`
17
+ uint256 internal constant CLEAN_ADDRESS =
18
+ 0x00ffffffffffffffffffffffffffffffffffffffff;
19
+
20
+ /// @dev Used to clean everything but the first 8 bytes of an address
21
+ uint256 internal constant CLEAN_FIRST8_BYTES_ADDRESS =
22
+ 0xffffffffffffffff << 96;
23
+
24
+ /// @dev Used to clean everything but the first 8 bytes of an address in the packed position
25
+ uint256 internal constant CLEAN_PACKED8_BYTES_ADDRESS =
26
+ 0xffffffffffffffff << 160;
27
+
28
+ /**
29
+ * @notice Helper function that packs from, to, and contract_ address to into the two slot configuration
30
+ * @param from The address making the delegation
31
+ * @param to The address receiving the delegation
32
+ * @param contract_ The contract address associated with the delegation (optional)
33
+ * @return firstPacked The firstPacked storage configured with the parameters
34
+ * @return secondPacked The secondPacked storage configured with the parameters
35
+ * @dev Will not revert if `from`, `to`, and `contract_` are > uint160, any inputs with dirty bits outside the last 20 bytes will be cleaned
36
+ */
37
+ function packAddresses(
38
+ address from,
39
+ address to,
40
+ address contract_
41
+ ) internal pure returns (bytes32 firstPacked, bytes32 secondPacked) {
42
+ assembly {
43
+ firstPacked := or(
44
+ shl(64, and(contract_, CLEAN_FIRST8_BYTES_ADDRESS)),
45
+ and(from, CLEAN_ADDRESS)
46
+ )
47
+ secondPacked := or(shl(160, contract_), and(to, CLEAN_ADDRESS))
48
+ }
49
+ }
50
+
51
+ /**
52
+ * @notice Helper function that unpacks from, to, and contract_ address inside the firstPacked secondPacked storage configuration
53
+ * @param firstPacked The firstPacked storage to be decoded
54
+ * @param secondPacked The secondPacked storage to be decoded
55
+ * @return from The address making the delegation
56
+ * @return to The address receiving the delegation
57
+ * @return contract_ The contract address associated with the delegation
58
+ * @dev Will not revert if `from`, `to`, and `contract_` are > uint160, any inputs with dirty bits outside the last 20 bytes will be cleaned
59
+ */
60
+ function unpackAddresses(
61
+ bytes32 firstPacked,
62
+ bytes32 secondPacked
63
+ ) internal pure returns (address from, address to, address contract_) {
64
+ assembly {
65
+ from := and(firstPacked, CLEAN_ADDRESS)
66
+ to := and(secondPacked, CLEAN_ADDRESS)
67
+ contract_ := or(
68
+ shr(64, and(firstPacked, CLEAN_PACKED8_BYTES_ADDRESS)),
69
+ shr(160, secondPacked)
70
+ )
71
+ }
72
+ }
73
+
74
+ /**
75
+ * @notice Helper function that can unpack the from or to address from their respective packed slots in the registry
76
+ * @param packedSlot The slot containing the from or to address
77
+ * @return unpacked The `from` or `to` address
78
+ * @dev Will not work if you want to obtain the contract address, use unpackAddresses
79
+ */
80
+ function unpackAddress(
81
+ bytes32 packedSlot
82
+ ) internal pure returns (address unpacked) {
83
+ assembly {
84
+ unpacked := and(packedSlot, CLEAN_ADDRESS)
85
+ }
86
+ }
87
+ }
@@ -3,6 +3,7 @@ pragma solidity ^0.8.19;
3
3
 
4
4
  import "../../interfaces/v0.8.x/IAdminACLV0.sol";
5
5
  import "../../interfaces/v0.8.x/ICoreRegistryV1.sol";
6
+ import "../../interfaces/v0.8.x/IUniversalBytecodeStorageReader.sol";
6
7
  import "@openzeppelin-4.7/contracts/utils/structs/EnumerableSet.sol";
7
8
 
8
9
  /**
@@ -82,6 +83,8 @@ library DependencyRegistryStorageLib {
82
83
  // that are supported by the CoreRegistry contract
83
84
  // @dev possible there is overlap between the two sets, but not intentionally configured by admin.
84
85
  EnumerableSet.AddressSet supportedCoreContractsOverride;
86
+ // address of the UniversalBytecodeStorageReader contract
87
+ IUniversalBytecodeStorageReader universalReader;
85
88
  }
86
89
 
87
90
  /**