@artblocks/contracts 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/artifacts/contracts/BytecodeStorageReaders/BytecodeStorageReaderContractV2_Web3Call.sol/BytecodeStorageReaderContractV2_Web3Call.json +201 -0
- package/artifacts/contracts/BytecodeStorageReaders/UniversalBytecodeStorageReader.sol/UniversalBytecodeStorageReader.json +2 -2
- package/artifacts/contracts/DependencyRegistryV0.sol/DependencyRegistryV0.json +42 -53
- package/artifacts/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol/GenArt721CoreV3_Engine_Flex.json +2 -2
- package/artifacts/contracts/generator/GenArt721GeneratorV0.sol/GenArt721GeneratorV0.json +2 -2
- package/artifacts/contracts/interfaces/v0.8.x/IDelegateRegistry.sol/IDelegateRegistry.json +820 -0
- package/artifacts/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol/IDependencyRegistryV0.json +13 -0
- package/artifacts/contracts/interfaces/v0.8.x/IPMPAugmentHook.sol/IPMPAugmentHook.json +83 -0
- package/artifacts/contracts/interfaces/v0.8.x/IPMPConfigureHook.sol/IPMPConfigureHook.json +80 -0
- package/artifacts/contracts/interfaces/v0.8.x/IPMPV0.sol/IPMPV0.json +402 -0
- package/artifacts/contracts/interfaces/v0.8.x/IUniversalBytecodeStorageReader.sol/IUniversalBytecodeStorageReader.json +13 -0
- package/artifacts/contracts/interfaces/v0.8.x/IWeb3Call.sol/IWeb3Call.json +47 -0
- package/artifacts/contracts/libs/integration-refs/delegation-registry/DelegateRegistry.sol/DelegateRegistry.json +846 -0
- package/artifacts/contracts/libs/integration-refs/delegation-registry/libraries/RegistryHashes.sol/RegistryHashes.json +10 -0
- package/artifacts/contracts/libs/integration-refs/delegation-registry/libraries/RegistryOps.sol/RegistryOps.json +10 -0
- package/artifacts/contracts/libs/integration-refs/delegation-registry/libraries/RegistryStorage.sol/RegistryStorage.json +10 -0
- package/artifacts/contracts/libs/v0.8.x/DependencyRegistryStorageLib.sol/DependencyRegistryStorageLib.json +2 -2
- package/artifacts/contracts/libs/v0.8.x/ImmutableStringArray.sol/ImmutableStringArray.json +10 -0
- package/artifacts/contracts/libs/v0.8.x/V3FlexLib.sol/V3FlexLib.json +2 -2
- package/artifacts/contracts/mock/ImmutableStringArrayMock.sol/ImmutableStringArrayMock.json +69 -0
- package/artifacts/contracts/mock/MockPMPAugmentHook.sol/MockPMPAugmentHook.json +214 -0
- package/artifacts/contracts/mock/MockPMPConfigureHook.sol/MockPMPConfigureHook.json +236 -0
- package/artifacts/contracts/web3call/PMPV0.sol/PMPV0.json +629 -0
- package/artifacts/contracts/web3call/Web3Call.sol/Web3Call.json +66 -0
- package/artifacts/contracts/web3call/augment-hooks/AbstractPMPAugmentHook.sol/AbstractPMPAugmentHook.json +83 -0
- package/artifacts/contracts/web3call/augment-hooks/InjectBaseGasFee.sol/InjectBaseGasFee.json +83 -0
- package/artifacts/contracts/web3call/augment-hooks/InjectChromieSquiggleFloorPrice.sol/IUniswapV2Pair.json +60 -0
- package/artifacts/contracts/web3call/augment-hooks/InjectChromieSquiggleFloorPrice.sol/InjectChromieSquiggleFloorPrice.json +107 -0
- package/artifacts/contracts/web3call/augment-hooks/InjectIsNounsDaoMember.sol/InjectIsNounsDaoMember.json +96 -0
- package/artifacts/contracts/web3call/augment-hooks/InjectIsProjectFullyMinted.sol/InjectIsProjectFullyMinted.json +83 -0
- package/artifacts/contracts/web3call/augment-hooks/InjectPolyptychTokenHash.sol/InjectPolyptychTokenHash.json +141 -0
- package/artifacts/contracts/web3call/augment-hooks/InjectTokenHashSeed.sol/InjectTokenHashSeed.json +99 -0
- package/artifacts/contracts/web3call/augment-hooks/InjectTokenOwner.sol/InjectTokenOwner.json +99 -0
- package/artifacts/contracts/web3call/augment-hooks/InjectTokenOwnerEthBalance.sol/InjectTokenOwnerEthBalance.json +83 -0
- package/artifacts/contracts/web3call/augment-hooks/InjectUSDCTotalSupply.sol/InjectUSDCTotalSupply.json +107 -0
- package/artifacts/contracts/web3call/configure-hooks/abstractPMPConfigureHook.sol/AbstractPMPConfigureHook.json +80 -0
- package/contracts/BytecodeStorageReaders/BytecodeStorageReaderContractV2_Web3Call.sol +128 -0
- package/contracts/DependencyRegistryV0.sol +67 -28
- package/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol +7 -1
- package/contracts/generator/GenArt721GeneratorV0.sol +77 -8
- package/contracts/interfaces/v0.8.x/IDelegateRegistry.sol +318 -0
- package/contracts/interfaces/v0.8.x/IDependencyRegistryV0.sol +2 -0
- package/contracts/interfaces/v0.8.x/IPMPAugmentHook.sol +31 -0
- package/contracts/interfaces/v0.8.x/IPMPConfigureHook.sol +25 -0
- package/contracts/interfaces/v0.8.x/IPMPV0.sol +224 -0
- package/contracts/interfaces/v0.8.x/IUniversalBytecodeStorageReader.sol +5 -0
- package/contracts/interfaces/v0.8.x/IWeb3Call.sol +28 -0
- package/contracts/libs/integration-refs/delegation-registry/DelegateRegistry.sol +753 -0
- package/contracts/libs/integration-refs/delegation-registry/libraries/RegistryHashes.sol +359 -0
- package/contracts/libs/integration-refs/delegation-registry/libraries/RegistryOps.sol +31 -0
- package/contracts/libs/integration-refs/delegation-registry/libraries/RegistryStorage.sol +87 -0
- package/contracts/libs/v0.8.x/DependencyRegistryStorageLib.sol +3 -0
- package/contracts/libs/v0.8.x/ImmutableStringArray.sol +289 -0
- package/contracts/libs/v0.8.x/V3FlexLib.sol +7 -1
- package/contracts/mock/ImmutableStringArrayMock.sol +47 -0
- package/contracts/mock/MockPMPAugmentHook.sol +170 -0
- package/contracts/mock/MockPMPConfigureHook.sol +78 -0
- package/contracts/web3call/PMPV0.sol +1125 -0
- package/contracts/web3call/Web3Call.sol +25 -0
- package/contracts/web3call/augment-hooks/AbstractPMPAugmentHook.sol +46 -0
- package/contracts/web3call/augment-hooks/InjectBaseGasFee.sol +57 -0
- package/contracts/web3call/augment-hooks/InjectChromieSquiggleFloorPrice.sol +103 -0
- package/contracts/web3call/augment-hooks/InjectIsNounsDaoMember.sol +66 -0
- package/contracts/web3call/augment-hooks/InjectIsProjectFullyMinted.sol +73 -0
- package/contracts/web3call/augment-hooks/InjectPolyptychTokenHash.sol +88 -0
- package/contracts/web3call/augment-hooks/InjectTokenHashSeed.sol +62 -0
- package/contracts/web3call/augment-hooks/InjectTokenOwner.sol +60 -0
- package/contracts/web3call/augment-hooks/InjectTokenOwnerEthBalance.sol +61 -0
- package/contracts/web3call/augment-hooks/InjectUSDCTotalSupply.sol +69 -0
- package/contracts/web3call/configure-hooks/abstractPMPConfigureHook.sol +41 -0
- package/package.json +5 -5
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_format": "hh-sol-artifact-1",
|
|
3
|
+
"contractName": "AbstractPMPConfigureHook",
|
|
4
|
+
"sourceName": "contracts/web3call/configure-hooks/abstractPMPConfigureHook.sol",
|
|
5
|
+
"abi": [
|
|
6
|
+
{
|
|
7
|
+
"inputs": [
|
|
8
|
+
{
|
|
9
|
+
"internalType": "address",
|
|
10
|
+
"name": "coreContract",
|
|
11
|
+
"type": "address"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"internalType": "uint256",
|
|
15
|
+
"name": "tokenId",
|
|
16
|
+
"type": "uint256"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"components": [
|
|
20
|
+
{
|
|
21
|
+
"internalType": "string",
|
|
22
|
+
"name": "key",
|
|
23
|
+
"type": "string"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"internalType": "enum IPMPV0.ParamType",
|
|
27
|
+
"name": "configuredParamType",
|
|
28
|
+
"type": "uint8"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"internalType": "bytes32",
|
|
32
|
+
"name": "configuredValue",
|
|
33
|
+
"type": "bytes32"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"internalType": "bool",
|
|
37
|
+
"name": "configuringArtistString",
|
|
38
|
+
"type": "bool"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"internalType": "string",
|
|
42
|
+
"name": "configuredValueString",
|
|
43
|
+
"type": "string"
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"internalType": "struct IPMPV0.PMPInput",
|
|
47
|
+
"name": "pmpInput",
|
|
48
|
+
"type": "tuple"
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"name": "onTokenPMPConfigure",
|
|
52
|
+
"outputs": [],
|
|
53
|
+
"stateMutability": "nonpayable",
|
|
54
|
+
"type": "function"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"inputs": [
|
|
58
|
+
{
|
|
59
|
+
"internalType": "bytes4",
|
|
60
|
+
"name": "interfaceId",
|
|
61
|
+
"type": "bytes4"
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"name": "supportsInterface",
|
|
65
|
+
"outputs": [
|
|
66
|
+
{
|
|
67
|
+
"internalType": "bool",
|
|
68
|
+
"name": "",
|
|
69
|
+
"type": "bool"
|
|
70
|
+
}
|
|
71
|
+
],
|
|
72
|
+
"stateMutability": "view",
|
|
73
|
+
"type": "function"
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
"bytecode": "0x",
|
|
77
|
+
"deployedBytecode": "0x",
|
|
78
|
+
"linkReferences": {},
|
|
79
|
+
"deployedLinkReferences": {}
|
|
80
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// SPDX-License-Identifier: LGPL-3.0-only
|
|
2
|
+
pragma solidity 0.8.22;
|
|
3
|
+
|
|
4
|
+
// Created By: Art Blocks Inc.
|
|
5
|
+
|
|
6
|
+
import {IBytecodeStorageReaderV2} from "../interfaces/v0.8.x/IBytecodeStorageReaderV2.sol";
|
|
7
|
+
import {IWeb3Call} from "../interfaces/v0.8.x/IWeb3Call.sol";
|
|
8
|
+
|
|
9
|
+
import {BytecodeStorageReader} from "../libs/v0.8.x/BytecodeStorageV2.sol";
|
|
10
|
+
|
|
11
|
+
import {ERC165Checker} from "@openzeppelin-5.0/contracts/utils/introspection/ERC165Checker.sol";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @title Art Blocks Bytecode Storage Reader Contract V2 w/ Web3Call Support
|
|
15
|
+
* @author Art Blocks Inc.
|
|
16
|
+
* @notice This contract is used to read the bytecode of a contract deployed by Art Blocks' BytecodeStorage library,
|
|
17
|
+
* for versions 0, 1, and 2 of the Art Blocks BytecodeStorage library.
|
|
18
|
+
* It includes support for returning the special string "#web3call_contract#" when reading a non-bytecode storage
|
|
19
|
+
* contract that does indicate ERC165 support for the IWeb3Call interface, enabling backwards-compatibility with
|
|
20
|
+
* Web3Call-based projects on exiting Art Blocks contracts. This only affects the readFromBytecode function.
|
|
21
|
+
* It is permissionless and can be used by anyone to read the bytecode of any contract deployed by Art Blocks.
|
|
22
|
+
* Future versions of BytecodeStorage will not be compatible with this reader.
|
|
23
|
+
* For a single location to read current and future versions of the Art Blocks BytecodeStorage library, see
|
|
24
|
+
* the UniversalBytecodeStorageReader contract, maintained by the Art Blocks team.
|
|
25
|
+
* Additional functionality is provided to read bytes data stored using the SSTORE2 library.
|
|
26
|
+
* This contract also provides an interface to read additional metadata stored by the Art Blocks BytecodeStorage
|
|
27
|
+
* library, such as the contract's version, deployer, and other metadata.
|
|
28
|
+
* @dev For simplicity and reduce code changes, this contract uses the BytecodeStorageReader external library to
|
|
29
|
+
* perform many operations. Future reader contract versions may choose to make the library internal to this contract to
|
|
30
|
+
* improve read operation performance.
|
|
31
|
+
*/
|
|
32
|
+
contract BytecodeStorageReaderContractV2_Web3Call is IBytecodeStorageReaderV2 {
|
|
33
|
+
using BytecodeStorageReader for address;
|
|
34
|
+
|
|
35
|
+
string public constant VERSION = "BytecodeStorageReaderContractV2_Web3Call";
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @notice Read a string from a data contract deployed via BytecodeStorage V2 or earlier.
|
|
39
|
+
* Also supports returning "#web3call_contract#" when the contract is not a
|
|
40
|
+
* BytecodeStorage contract, but does support the IWeb3Call interface.
|
|
41
|
+
* Reverts if the contract is not a BytecodeStorage contract and does not indicate
|
|
42
|
+
* ERC165 support for the IWeb3Call interface.
|
|
43
|
+
* @param address_ address of contract deployed via BytecodeStorage to be read
|
|
44
|
+
* @return The string data stored at the specific address.
|
|
45
|
+
*/
|
|
46
|
+
function readFromBytecode(
|
|
47
|
+
address address_
|
|
48
|
+
) external view returns (string memory) {
|
|
49
|
+
try address_.readFromBytecode() returns (string memory data) {
|
|
50
|
+
return data;
|
|
51
|
+
} catch {
|
|
52
|
+
if (
|
|
53
|
+
ERC165Checker.supportsInterface(
|
|
54
|
+
address_,
|
|
55
|
+
type(IWeb3Call).interfaceId
|
|
56
|
+
)
|
|
57
|
+
) {
|
|
58
|
+
return "#web3call_contract#";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// reading from bytecode failed, and does not indicate Web3Call support, so revert
|
|
62
|
+
revert(
|
|
63
|
+
"BytecodeStorageReaderContractV2_Web3Call: Failed to read from bytecode"
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @notice Read a bytes array from the SSTORE2-formatted bytecode of a contract.
|
|
69
|
+
* Note that this function is only compatible with contracts that have been deployed using the popular SSTORE2
|
|
70
|
+
* library.
|
|
71
|
+
* @param address_ address of contract with SSTORE2-formatted bytecode to be read
|
|
72
|
+
* @return data The bytes data stored at the specific address.
|
|
73
|
+
*/
|
|
74
|
+
function readBytesFromSSTORE2Bytecode(
|
|
75
|
+
address address_
|
|
76
|
+
) external view returns (bytes memory) {
|
|
77
|
+
return address_.readBytesFromSSTORE2Bytecode();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @notice Read a bytes array from the a contract deployed via BytecodeStorage V2 or earlier.
|
|
82
|
+
* @param address_ address of contract with valid bytecode to be read
|
|
83
|
+
* @param offset offset to read from in contract bytecode, explicitly provided (not calculated)
|
|
84
|
+
* @return The bytes data stored at the specific address.
|
|
85
|
+
*/
|
|
86
|
+
function readBytesFromBytecode(
|
|
87
|
+
address address_,
|
|
88
|
+
uint256 offset
|
|
89
|
+
) external view returns (bytes memory) {
|
|
90
|
+
return address_.readBytesFromBytecode(offset);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
//------ Metadata Functions ------//
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @notice Get address of deployer for given contract deployed via BytecodeStorage V2 or earlier.
|
|
97
|
+
* @param address_ address of deployed contract
|
|
98
|
+
* @return writerAddress address of deployer
|
|
99
|
+
*/
|
|
100
|
+
function getWriterAddressForBytecode(
|
|
101
|
+
address address_
|
|
102
|
+
) external view returns (address) {
|
|
103
|
+
return address_.getWriterAddressForBytecode();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @notice Get version for given contract deployed via BytecodeStorage V2 or earlier.
|
|
108
|
+
* @param address_ address of deployed contract
|
|
109
|
+
* @return version version of the contract
|
|
110
|
+
*/
|
|
111
|
+
function getLibraryVersionForBytecode(
|
|
112
|
+
address address_
|
|
113
|
+
) external view returns (bytes32) {
|
|
114
|
+
return address_.getLibraryVersionForBytecode();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @notice Get if data are stored in compressed format for given contract deployed via BytecodeStorage V2 or
|
|
119
|
+
* earlier.
|
|
120
|
+
* @param _address address of deployed contract
|
|
121
|
+
* @return isCompressed boolean indicating if the stored data are compressed
|
|
122
|
+
*/
|
|
123
|
+
function getIsCompressedForBytecode(
|
|
124
|
+
address _address
|
|
125
|
+
) external view returns (bool) {
|
|
126
|
+
return _address.getIsCompressedForBytecode();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -7,6 +7,8 @@ import "./interfaces/v0.8.x/IAdminACLV0.sol";
|
|
|
7
7
|
import "./interfaces/v0.8.x/IDependencyRegistryCompatibleV0.sol";
|
|
8
8
|
import "./interfaces/v0.8.x/IDependencyRegistryV0.sol";
|
|
9
9
|
import "./interfaces/v0.8.x/ICoreRegistryV1.sol";
|
|
10
|
+
import "./interfaces/v0.8.x/IBytecodeStorageReaderV2.sol";
|
|
11
|
+
import "./interfaces/v0.8.x/IUniversalBytecodeStorageReader.sol";
|
|
10
12
|
|
|
11
13
|
import "@openzeppelin-4.7/contracts/utils/Strings.sol";
|
|
12
14
|
import "@openzeppelin-4.7/contracts/utils/structs/EnumerableSet.sol";
|
|
@@ -15,7 +17,7 @@ import "@openzeppelin-4.8/contracts-upgradeable/proxy/utils/Initializable.sol";
|
|
|
15
17
|
import "@openzeppelin-4.5/contracts/utils/math/SafeCast.sol";
|
|
16
18
|
|
|
17
19
|
import "./libs/v0.8.x/DependencyRegistryStorageLib.sol";
|
|
18
|
-
import "./libs/v0.8.x/
|
|
20
|
+
import "./libs/v0.8.x/BytecodeStorageV2.sol";
|
|
19
21
|
import "./libs/v0.8.x/Bytes32Strings.sol";
|
|
20
22
|
|
|
21
23
|
/**
|
|
@@ -112,6 +114,15 @@ contract DependencyRegistryV0 is
|
|
|
112
114
|
_transferOwnership(adminACLContract_);
|
|
113
115
|
}
|
|
114
116
|
|
|
117
|
+
function updateUniversalBytecodeStorageReader(address newReader) external {
|
|
118
|
+
_onlyAdminACL(this.updateUniversalBytecodeStorageReader.selector);
|
|
119
|
+
_onlyNonZeroAddress(newReader);
|
|
120
|
+
DependencyRegistryStorageLib
|
|
121
|
+
.s()
|
|
122
|
+
.universalReader = IUniversalBytecodeStorageReader(newReader);
|
|
123
|
+
emit UniversalBytecodeStorageReaderUpdated(newReader);
|
|
124
|
+
}
|
|
125
|
+
|
|
115
126
|
/**
|
|
116
127
|
* @notice Updates the core registry address.
|
|
117
128
|
* @param _coreRegistryAddress Address of core registry contract.
|
|
@@ -969,18 +980,7 @@ contract DependencyRegistryV0 is
|
|
|
969
980
|
});
|
|
970
981
|
|
|
971
982
|
address licenseAddress = licenseEntry.licenseBytecodeAddresses[index];
|
|
972
|
-
|
|
973
|
-
.getLibraryVersionForBytecode(licenseAddress);
|
|
974
|
-
if (storageVersion == BytecodeStorageReader.UNKNOWN_VERSION_STRING) {
|
|
975
|
-
return
|
|
976
|
-
string(
|
|
977
|
-
BytecodeStorageReader.readBytesFromSSTORE2Bytecode(
|
|
978
|
-
licenseAddress
|
|
979
|
-
)
|
|
980
|
-
);
|
|
981
|
-
} else {
|
|
982
|
-
return BytecodeStorageReader.readFromBytecode(licenseAddress);
|
|
983
|
-
}
|
|
983
|
+
return _readFromBytecodeWithSSTORE2Fallback(licenseAddress);
|
|
984
984
|
}
|
|
985
985
|
|
|
986
986
|
/**
|
|
@@ -1250,9 +1250,10 @@ contract DependencyRegistryV0 is
|
|
|
1250
1250
|
.dependencyRecords[dependencyNameAndVersion];
|
|
1251
1251
|
_onlyInRangeIndex({index: index, length: dependency.scriptCount});
|
|
1252
1252
|
return
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1253
|
+
_getActiveBytecodeStorageReaderContract()
|
|
1254
|
+
.getLibraryVersionForBytecode(
|
|
1255
|
+
dependency.scriptBytecodeAddresses[index]
|
|
1256
|
+
);
|
|
1256
1257
|
}
|
|
1257
1258
|
|
|
1258
1259
|
/**
|
|
@@ -1279,19 +1280,8 @@ contract DependencyRegistryV0 is
|
|
|
1279
1280
|
_onlyInRangeIndex({index: index, length: dependency.scriptCount});
|
|
1280
1281
|
|
|
1281
1282
|
address scriptAddress = dependency.scriptBytecodeAddresses[index];
|
|
1282
|
-
bytes32 storageVersion = BytecodeStorageReader
|
|
1283
|
-
.getLibraryVersionForBytecode(scriptAddress);
|
|
1284
1283
|
|
|
1285
|
-
|
|
1286
|
-
return
|
|
1287
|
-
string(
|
|
1288
|
-
BytecodeStorageReader.readBytesFromSSTORE2Bytecode(
|
|
1289
|
-
scriptAddress
|
|
1290
|
-
)
|
|
1291
|
-
);
|
|
1292
|
-
} else {
|
|
1293
|
-
return BytecodeStorageReader.readFromBytecode(scriptAddress);
|
|
1294
|
-
}
|
|
1284
|
+
return _readFromBytecodeWithSSTORE2Fallback(scriptAddress);
|
|
1295
1285
|
}
|
|
1296
1286
|
|
|
1297
1287
|
/**
|
|
@@ -1329,6 +1319,14 @@ contract DependencyRegistryV0 is
|
|
|
1329
1319
|
}
|
|
1330
1320
|
}
|
|
1331
1321
|
|
|
1322
|
+
/**
|
|
1323
|
+
* @notice returns the address of the core registry currently being used by the dependency registry.
|
|
1324
|
+
* @return address Address of the core registry contract.
|
|
1325
|
+
*/
|
|
1326
|
+
function currentCoreRegistry() external view returns (address) {
|
|
1327
|
+
return address(DependencyRegistryStorageLib.s().coreRegistryContract);
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1332
1330
|
/**
|
|
1333
1331
|
* @notice utility function to convert from string to bytes32.
|
|
1334
1332
|
* Useful when a human is calling functions that take bytes32 as input.
|
|
@@ -1463,4 +1461,45 @@ contract DependencyRegistryV0 is
|
|
|
1463
1461
|
newOwner
|
|
1464
1462
|
);
|
|
1465
1463
|
}
|
|
1464
|
+
|
|
1465
|
+
/**
|
|
1466
|
+
* @notice Reads data from bytecode with SSTORE2 fallback.
|
|
1467
|
+
* @param dataAddress Address of the data to read.
|
|
1468
|
+
* @return data String representation of the data.
|
|
1469
|
+
*/
|
|
1470
|
+
function _readFromBytecodeWithSSTORE2Fallback(
|
|
1471
|
+
address dataAddress
|
|
1472
|
+
) internal view returns (string memory) {
|
|
1473
|
+
IBytecodeStorageReaderV2 activeReader = _getActiveBytecodeStorageReaderContract();
|
|
1474
|
+
bytes32 storageVersion = activeReader.getLibraryVersionForBytecode(
|
|
1475
|
+
dataAddress
|
|
1476
|
+
);
|
|
1477
|
+
if (storageVersion == BytecodeStorageReader.UNKNOWN_VERSION_STRING) {
|
|
1478
|
+
return
|
|
1479
|
+
string(activeReader.readBytesFromSSTORE2Bytecode(dataAddress));
|
|
1480
|
+
} else {
|
|
1481
|
+
return activeReader.readFromBytecode(dataAddress);
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
/**
|
|
1486
|
+
* @notice Returns the active bytecode storage reader contract, being used by the universal reader contract.
|
|
1487
|
+
* @dev assumes the versioned reader is IBytecodeStorageReaderV2 or higher.
|
|
1488
|
+
* @return IBytecodeStorageReaderV2 The active bytecode storage reader contract.
|
|
1489
|
+
*/
|
|
1490
|
+
function _getActiveBytecodeStorageReaderContract()
|
|
1491
|
+
internal
|
|
1492
|
+
view
|
|
1493
|
+
returns (IBytecodeStorageReaderV2)
|
|
1494
|
+
{
|
|
1495
|
+
return
|
|
1496
|
+
IBytecodeStorageReaderV2(
|
|
1497
|
+
address(
|
|
1498
|
+
DependencyRegistryStorageLib
|
|
1499
|
+
.s()
|
|
1500
|
+
.universalReader
|
|
1501
|
+
.activeBytecodeStorageReaderContract()
|
|
1502
|
+
)
|
|
1503
|
+
);
|
|
1504
|
+
}
|
|
1466
1505
|
}
|
|
@@ -527,6 +527,8 @@ contract GenArt721CoreV3_Engine_Flex is
|
|
|
527
527
|
* @notice Updates external asset dependency for project `_projectId` at
|
|
528
528
|
* index `_index`, with data at BytecodeStorage-compatible address
|
|
529
529
|
* `_assetAddress`.
|
|
530
|
+
* @dev This function may point to any BytecodeStorageReader-compatible
|
|
531
|
+
* on-chain asset, including a web3call contract.
|
|
530
532
|
* @param _projectId Project to be updated.
|
|
531
533
|
* @param _index Asset index.
|
|
532
534
|
* @param _assetAddress Address of the on-chain asset.
|
|
@@ -624,6 +626,8 @@ contract GenArt721CoreV3_Engine_Flex is
|
|
|
624
626
|
* @notice Adds an on-chain external asset dependency for project
|
|
625
627
|
* `_projectId`, with data at BytecodeStorage-compatible address
|
|
626
628
|
* `_assetAddress`.
|
|
629
|
+
* @dev This function may point to any BytecodeStorageReader-compatible
|
|
630
|
+
* on-chain asset, including a web3call contract.
|
|
627
631
|
* @param _projectId Project to be updated.
|
|
628
632
|
* @param _assetAddress Address of the BytecodeStorageReader-compatible on-chain asset.
|
|
629
633
|
*/
|
|
@@ -2289,9 +2293,11 @@ contract GenArt721CoreV3_Engine_Flex is
|
|
|
2289
2293
|
|
|
2290
2294
|
/**
|
|
2291
2295
|
* @notice Returns external asset dependency for project `_projectId` at index `_index`.
|
|
2292
|
-
* If the dependencyType is ONCHAIN, the `data` field will contain the
|
|
2296
|
+
* If the dependencyType is ONCHAIN, the `data` field will contain the read BytecodeStorage data and `cid`
|
|
2293
2297
|
* will be an empty string. Conversly, for any other dependencyType, the `data` field will be an empty string
|
|
2294
2298
|
* and the `bytecodeAddress` will point to the zero address.
|
|
2299
|
+
* @dev If an ONCHAIN dependency is a web3call, the `data` field will be returned per the BytecodeStorageReader
|
|
2300
|
+
* contract's active spec, which at the time of this writing is the special string "#web3call_contract#".
|
|
2295
2301
|
* If the dependencyType is ART_BLOCKS_DEPENDENCY_REGISTRY, the `cid` field will contain the string
|
|
2296
2302
|
* representation of the dependencyNameAndVersion bytes32 value stored in the dependency registry (
|
|
2297
2303
|
* at public address `artblocksDependencyRegistryAddress`)
|
|
@@ -9,11 +9,14 @@ import "../interfaces/v0.8.x/IGenArt721CoreTokenHashProviderV1.sol";
|
|
|
9
9
|
import "../interfaces/v0.8.x/IGenArt721GeneratorV0.sol";
|
|
10
10
|
import {IGenArt721CoreContractV3_Engine_Flex} from "../interfaces/v0.8.x/IGenArt721CoreContractV3_Engine_Flex.sol";
|
|
11
11
|
import {IUniversalBytecodeStorageReader} from "../interfaces/v0.8.x/IUniversalBytecodeStorageReader.sol";
|
|
12
|
+
import {IWeb3Call} from "../interfaces/v0.8.x/IWeb3Call.sol";
|
|
13
|
+
|
|
12
14
|
import "../libs/v0.8.x/Bytes32Strings.sol";
|
|
13
15
|
import {JsonStatic} from "../libs/v0.8.x/JsonStatic.sol";
|
|
14
16
|
import {ABHelpers} from "../libs/v0.8.x/ABHelpers.sol";
|
|
15
17
|
import {AddressChunks} from "./AddressChunks.sol";
|
|
16
18
|
|
|
19
|
+
import {Base64} from "@openzeppelin-5.0/contracts/utils/Base64.sol";
|
|
17
20
|
import "@openzeppelin-4.7/contracts/utils/Strings.sol";
|
|
18
21
|
import "@openzeppelin-4.8/contracts-upgradeable/proxy/utils/Initializable.sol";
|
|
19
22
|
|
|
@@ -562,12 +565,12 @@ contract GenArt721GeneratorV0 is Initializable, IGenArt721GeneratorV0 {
|
|
|
562
565
|
* as well as any dependency name and version if the dependency is an
|
|
563
566
|
* ART_BLOCKS_DEPENDENCY_REGISTRY dependency.
|
|
564
567
|
* @param coreContract The core contract address the project belongs to.
|
|
565
|
-
* @param
|
|
568
|
+
* @param tokenId The ID of the token to retrieve the external asset dependency for.
|
|
566
569
|
* @param index The index of the external asset dependency to retrieve.
|
|
567
570
|
*/
|
|
568
571
|
function _getExternalAssetDependencyKeysAndValues(
|
|
569
572
|
address coreContract,
|
|
570
|
-
uint256
|
|
573
|
+
uint256 tokenId,
|
|
571
574
|
uint256 index
|
|
572
575
|
)
|
|
573
576
|
internal
|
|
@@ -578,6 +581,8 @@ contract GenArt721GeneratorV0 is Initializable, IGenArt721GeneratorV0 {
|
|
|
578
581
|
bytes32 /*dependencyNameAndVersion*/
|
|
579
582
|
)
|
|
580
583
|
{
|
|
584
|
+
// get project id from token id
|
|
585
|
+
uint256 projectId = ABHelpers.tokenIdToProjectId(tokenId);
|
|
581
586
|
// default as not an art blocks dependency registry dependency
|
|
582
587
|
bytes32 dependencyNameAndVersion; // default as not an art blocks dependency registry dependency
|
|
583
588
|
// each external asset dependency has 3 fields, so pre-allocate array to avoid dynamic memory allocation
|
|
@@ -612,10 +617,33 @@ contract GenArt721GeneratorV0 is Initializable, IGenArt721GeneratorV0 {
|
|
|
612
617
|
.ExternalAssetDependencyType
|
|
613
618
|
.ONCHAIN
|
|
614
619
|
) {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
620
|
+
if (
|
|
621
|
+
keccak256(
|
|
622
|
+
abi.encodePacked(externalAssetDependencyWithData.data)
|
|
623
|
+
) == keccak256(abi.encodePacked("#web3call_contract#")) // @dev special string indicating a web3call contract
|
|
624
|
+
) {
|
|
625
|
+
// treat as a web3call contract, inject token parameters based on the web3call contract
|
|
626
|
+
// @dev prepend with "#web3call#" to indicate that the data should be decoded as a web3call
|
|
627
|
+
// with base64 encoded key/value pairs
|
|
628
|
+
dependencyValues[2] = JsonStatic.newStringElement({
|
|
629
|
+
value: string.concat(
|
|
630
|
+
"#web3call#",
|
|
631
|
+
_getWeb3CallParameters({
|
|
632
|
+
web3callContract: externalAssetDependencyWithData
|
|
633
|
+
.bytecodeAddress,
|
|
634
|
+
coreContract: coreContract,
|
|
635
|
+
tokenId: tokenId
|
|
636
|
+
})
|
|
637
|
+
),
|
|
638
|
+
stringEncodingFlag: JsonStatic.StringEncodingFlag.NONE // we base64 encode everything in the _getWeb3CallParameters function
|
|
639
|
+
});
|
|
640
|
+
} else {
|
|
641
|
+
// @dev typical ONCHAIN dependency, assign data for ONCHAIN dependencies
|
|
642
|
+
dependencyValues[2] = JsonStatic.newStringElement({
|
|
643
|
+
value: externalAssetDependencyWithData.data,
|
|
644
|
+
stringEncodingFlag: JsonStatic.StringEncodingFlag.BASE64
|
|
645
|
+
});
|
|
646
|
+
}
|
|
619
647
|
} else {
|
|
620
648
|
dependencyValues[2] = JsonStatic.newStringElement({
|
|
621
649
|
value: "", // empty string for non-ONCHAIN dependencies
|
|
@@ -744,7 +772,7 @@ contract GenArt721GeneratorV0 is Initializable, IGenArt721GeneratorV0 {
|
|
|
744
772
|
bytes32 dependencyNameAndVersion
|
|
745
773
|
) = _getExternalAssetDependencyKeysAndValues({
|
|
746
774
|
coreContract: coreContract,
|
|
747
|
-
|
|
775
|
+
tokenId: tokenId,
|
|
748
776
|
index: i
|
|
749
777
|
});
|
|
750
778
|
// handle ART_BLOCKS_DEPENDENCY_REGISTRY dependency type
|
|
@@ -870,7 +898,7 @@ contract GenArt721GeneratorV0 is Initializable, IGenArt721GeneratorV0 {
|
|
|
870
898
|
headTags[1].tagContent = abi.encodePacked(
|
|
871
899
|
"let tokenData = JSON.parse(`",
|
|
872
900
|
tokenDataJson,
|
|
873
|
-
'`, (key, value) => key === "data" && value !== null ? atob(value) : value);'
|
|
901
|
+
'`, (key, value) => key === "data" && value !== null ? value.startsWith("#web3call#") ? Object.entries(JSON.parse(atob(value.slice(10)))).reduce((acc, [k, v]) => ((acc[atob(k)] = atob(v)), acc), {}) : atob(value) : value);'
|
|
874
902
|
);
|
|
875
903
|
headTags[1].tagType = HTMLTagType.script;
|
|
876
904
|
for (
|
|
@@ -997,6 +1025,47 @@ contract GenArt721GeneratorV0 is Initializable, IGenArt721GeneratorV0 {
|
|
|
997
1025
|
.getDependencyDetails(dependencyNameAndVersion);
|
|
998
1026
|
}
|
|
999
1027
|
|
|
1028
|
+
/**
|
|
1029
|
+
* @dev Helper function to get the web3call parameters for a given token.
|
|
1030
|
+
* Assumes the contract supports the IWeb3Call interface.
|
|
1031
|
+
* @param web3callContract The address of the contract to call.
|
|
1032
|
+
* @param coreContract The address of the core contract.
|
|
1033
|
+
* @param tokenId The ID of the token.
|
|
1034
|
+
* @return The web3call parameters for the token as a json string, keys and values encoded
|
|
1035
|
+
* as base64 strings, then the entire json string is encoded as base64.
|
|
1036
|
+
*/
|
|
1037
|
+
function _getWeb3CallParameters(
|
|
1038
|
+
address web3callContract,
|
|
1039
|
+
address coreContract,
|
|
1040
|
+
uint256 tokenId
|
|
1041
|
+
) internal view returns (string memory) {
|
|
1042
|
+
// get the onchain data for the contract
|
|
1043
|
+
IWeb3Call.TokenParam[] memory tokenParams = IWeb3Call(web3callContract)
|
|
1044
|
+
.getTokenParams({coreContract: coreContract, tokenId: tokenId});
|
|
1045
|
+
uint256 tokenParamsLength = tokenParams.length;
|
|
1046
|
+
// build key/value arrays for the token params
|
|
1047
|
+
string[] memory keys = JsonStatic.newKeysArray(tokenParamsLength);
|
|
1048
|
+
JsonStatic.Json[] memory values = JsonStatic.newValuesArray(
|
|
1049
|
+
tokenParamsLength
|
|
1050
|
+
);
|
|
1051
|
+
for (uint256 i = 0; i < tokenParamsLength; i++) {
|
|
1052
|
+
// @dev encode the key here as base64 string, to handle any special characters
|
|
1053
|
+
IWeb3Call.TokenParam memory tokenParam = tokenParams[i];
|
|
1054
|
+
keys[i] = Base64.encode(bytes(tokenParam.key));
|
|
1055
|
+
values[i] = JsonStatic.newStringElement({
|
|
1056
|
+
value: (tokenParam.value),
|
|
1057
|
+
stringEncodingFlag: JsonStatic.StringEncodingFlag.BASE64
|
|
1058
|
+
});
|
|
1059
|
+
}
|
|
1060
|
+
// use JsonStatic to build a printable json object from the key/value arrays
|
|
1061
|
+
JsonStatic.Json memory tokenParamsJson = JsonStatic.newObjectElement({
|
|
1062
|
+
keys: keys,
|
|
1063
|
+
values: values
|
|
1064
|
+
});
|
|
1065
|
+
// @dev base64 encode the entire json object for consistent encoding of data field
|
|
1066
|
+
return Base64.encode(bytes(tokenParamsJson.write()));
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1000
1069
|
/**
|
|
1001
1070
|
* @dev Helper function to get a canvas tag or an empty tag depending on the dependency name.
|
|
1002
1071
|
* @return The canvas tag or an empty tag.
|