@zoralabs/comments-contracts 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +11 -0
- package/.turbo/turbo-build.log +60 -0
- package/LICENSE +21 -0
- package/README.md +70 -0
- package/_imagine/Enjoy.sol +41 -0
- package/abis/AccessControlUpgradeable.json +250 -0
- package/abis/Address.json +29 -0
- package/abis/Comments.json +62 -0
- package/abis/CommentsDeployerBase.json +15 -0
- package/abis/CommentsImpl.json +1750 -0
- package/abis/CommentsPermitTest.json +847 -0
- package/abis/CommentsTest.json +986 -0
- package/abis/CommentsTestBase.json +577 -0
- package/abis/Comments_mintAndCommentTest.json +690 -0
- package/abis/ContextUpgradeable.json +25 -0
- package/abis/ContractVersionBase.json +15 -0
- package/abis/Create2.json +28 -0
- package/abis/DeployImpl.json +22 -0
- package/abis/DeployNonDeterministic.json +22 -0
- package/abis/DeployScript.json +22 -0
- package/abis/DeterministicDeployerAndCaller.json +315 -0
- package/abis/DeterministicUUPSProxyDeployer.json +167 -0
- package/abis/ECDSA.json +29 -0
- package/abis/EIP712.json +67 -0
- package/abis/EIP712UpgradeableWithChainId.json +25 -0
- package/abis/ERC1155.json +416 -0
- package/abis/ERC1155Holder.json +99 -0
- package/abis/ERC165.json +21 -0
- package/abis/ERC165Upgradeable.json +44 -0
- package/abis/ERC1967Proxy.json +67 -0
- package/abis/ERC1967Utils.json +85 -0
- package/abis/GenerateDeterministicParams.json +22 -0
- package/abis/IAccessControl.json +195 -0
- package/abis/IBeacon.json +15 -0
- package/abis/IComments.json +654 -0
- package/abis/IContractMetadata.json +28 -0
- package/abis/IERC1155.json +295 -0
- package/abis/IERC1155Errors.json +104 -0
- package/abis/IERC1155MetadataURI.json +314 -0
- package/abis/IERC1155Receiver.json +99 -0
- package/abis/IERC1271.json +26 -0
- package/abis/IERC165.json +21 -0
- package/abis/IERC1822Proxiable.json +15 -0
- package/abis/IERC20.json +224 -0
- package/abis/IERC20Errors.json +88 -0
- package/abis/IERC5267.json +51 -0
- package/abis/IERC721.json +287 -0
- package/abis/IERC721Enumerable.json +343 -0
- package/abis/IERC721Errors.json +105 -0
- package/abis/IERC721Metadata.json +332 -0
- package/abis/IERC721TokenReceiver.json +36 -0
- package/abis/IHasContractName.json +15 -0
- package/abis/IImmutableCreate2Factory.json +93 -0
- package/abis/IMulticall3.json +440 -0
- package/abis/IProtocolRewards.json +342 -0
- package/abis/ISafe.json +15 -0
- package/abis/ISymbol.json +15 -0
- package/abis/IVersionedContract.json +15 -0
- package/abis/IZoraCreator1155.json +343 -0
- package/abis/ImmutableCreate2FactoryUtils.json +15 -0
- package/abis/Initializable.json +25 -0
- package/abis/LibString.json +7 -0
- package/abis/Math.json +7 -0
- package/abis/Mock1155.json +547 -0
- package/abis/MockERC20.json +322 -0
- package/abis/MockERC721.json +350 -0
- package/abis/MockMinter.json +64 -0
- package/abis/OwnableUpgradeable.json +99 -0
- package/abis/ProtocolRewards.json +494 -0
- package/abis/Proxy.json +6 -0
- package/abis/ProxyDeployerScript.json +15 -0
- package/abis/ProxyShim.json +112 -0
- package/abis/Script.json +15 -0
- package/abis/ShortStrings.json +18 -0
- package/abis/StdAssertions.json +379 -0
- package/abis/StdInvariant.json +180 -0
- package/abis/Strings.json +18 -0
- package/abis/Test.json +570 -0
- package/abis/UUPSUpgradeable.json +130 -0
- package/abis/UnorderedNoncesUpgradeable.json +42 -0
- package/abis/Vm.json +8627 -0
- package/abis/VmSafe.json +7297 -0
- package/abis/stdError.json +119 -0
- package/abis/stdStorageSafe.json +52 -0
- package/addresses/999999999.json +4 -0
- package/deterministicConfig/comments.json +8 -0
- package/dist/index.cjs +935 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +908 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/wagmiGenerated.d.ts +1354 -0
- package/dist/wagmiGenerated.d.ts.map +1 -0
- package/foundry.toml +24 -0
- package/package/index.ts +4 -0
- package/package/types.ts +5 -0
- package/package/wagmiGenerated.ts +907 -0
- package/package.json +62 -0
- package/remappings.txt +8 -0
- package/script/CommentsDeployerBase.sol +60 -0
- package/script/Deploy.s.sol +66 -0
- package/script/DeployImpl.s.sol +26 -0
- package/script/DeployNonDeterministic.s.sol +43 -0
- package/script/GenerateDeterministicParams.s.sol +55 -0
- package/script/bundle-abis.ts +109 -0
- package/script/storage-check.sh +57 -0
- package/script/update-contract-version.ts +63 -0
- package/scripts/abis.ts +3 -0
- package/scripts/backfillComments.ts +176 -0
- package/scripts/generateCommentsTestData.ts +247 -0
- package/scripts/getCommentsAddresses.ts +10 -0
- package/scripts/queries.ts +73 -0
- package/scripts/queryAndSaveComments.ts +48 -0
- package/scripts/queryQuantityOfComments.ts +53 -0
- package/scripts/signDeployAndCall.ts +51 -0
- package/scripts/turnkey.ts +36 -0
- package/scripts/utils.ts +127 -0
- package/scripts/writeComments.ts +198 -0
- package/slither.config.json +7 -0
- package/src/CommentsImpl.sol +552 -0
- package/src/deployments/CommentsDeployment.sol +14 -0
- package/src/interfaces/IComments.sol +156 -0
- package/src/interfaces/IZoraCreator1155.sol +12 -0
- package/src/proxy/Comments.sol +43 -0
- package/src/utils/EIP712UpgradeableWithChainId.sol +36 -0
- package/src/version/ContractVersionBase.sol +14 -0
- package/test/Comments.t.sol +482 -0
- package/test/CommentsTestBase.sol +86 -0
- package/test/Comments_mintAndComment.t.sol +101 -0
- package/test/Comments_permit.t.sol +397 -0
- package/test/mocks/Mock1155.sol +50 -0
- package/test/mocks/MockMinter.sol +29 -0
- package/test/mocks/ProtocolRewards.sol +1497 -0
- package/tsconfig.build.json +10 -0
- package/tsconfig.json +9 -0
- package/tsup.config.ts +11 -0
- package/wagmi.config.ts +14 -0
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zoralabs/comments-contracts",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"author": "oveddan",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"sideEffects": false,
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"default": "./dist/index.cjs"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@turnkey/api-key-stamper": "^0.3.1",
|
|
20
|
+
"@turnkey/http": "^2.5.1",
|
|
21
|
+
"@turnkey/viem": "^0.4.4",
|
|
22
|
+
"@types/node": "^20.1.2",
|
|
23
|
+
"@wagmi/cli": "^1.0.1",
|
|
24
|
+
"@zoralabs/chains": "^1.3.1",
|
|
25
|
+
"@openzeppelin/contracts": "5.0.2",
|
|
26
|
+
"@openzeppelin/contracts-upgradeable": "5.0.2",
|
|
27
|
+
"ds-test": "https://github.com/dapphub/ds-test#cd98eff28324bfac652e63a239a60632a761790b",
|
|
28
|
+
"forge-std": "https://github.com/foundry-rs/forge-std#v1.9.1",
|
|
29
|
+
"solady": "0.0.132",
|
|
30
|
+
"glob": "^10.2.2",
|
|
31
|
+
"pathe": "^1.1.2",
|
|
32
|
+
"prettier": "^3.0.3",
|
|
33
|
+
"prettier-plugin-solidity": "^1.3.1",
|
|
34
|
+
"tsup": "^7.2.0",
|
|
35
|
+
"tsx": "^3.13.0",
|
|
36
|
+
"typescript": "^5.2.2",
|
|
37
|
+
"viem": "^1.10.0",
|
|
38
|
+
"@zoralabs/tsconfig": "^0.0.1",
|
|
39
|
+
"@zoralabs/protocol-rewards": "^1.2.4",
|
|
40
|
+
"@zoralabs/shared-contracts": "^0.0.1",
|
|
41
|
+
"@zoralabs/sparks-contracts": "^0.2.2",
|
|
42
|
+
"@zoralabs/zora-1155-contracts": "^2.12.4"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"abitype": "^1.0.2"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"prettier:check": "prettier --check 'src/**/*.sol' 'test/**/*.sol' 'script/**/*.sol'",
|
|
49
|
+
"prettier:write": "prettier --write 'src/**/*.sol' 'test/**/*.sol' 'script/**/*.sol'",
|
|
50
|
+
"test": "forge test -vv",
|
|
51
|
+
"dev": "FOUNDRY_PROFILE=dev forge test --watch -vvv",
|
|
52
|
+
"test-gas": "forge test --gas-report",
|
|
53
|
+
"storage-inspect:check": "./script/storage-check.sh check ZoraTimedSaleStrategyImpl",
|
|
54
|
+
"storage-inspect:generate": "./script/storage-check.sh generate ZoraTimedSaleStrategyImpl",
|
|
55
|
+
"build:sizes": "forge build --sizes",
|
|
56
|
+
"copy-abis": "pnpm tsx script/bundle-abis.ts",
|
|
57
|
+
"coverage": "FOUNDRY_PROFILE=default forge coverage --report lcov",
|
|
58
|
+
"build": "pnpm run wagmi:generate && pnpm run copy-abis && pnpm run prettier:write && tsup",
|
|
59
|
+
"wagmi:generate": "FOUNDRY_PROFILE=dev forge build && wagmi generate",
|
|
60
|
+
"update-contract-version": "pnpm tsx script/update-contract-version.ts"
|
|
61
|
+
}
|
|
62
|
+
}
|
package/remappings.txt
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
ds-test/=node_modules/ds-test/src/
|
|
2
|
+
forge-std/=node_modules/forge-std/src/
|
|
3
|
+
@openzeppelin/=node_modules/@openzeppelin/
|
|
4
|
+
@zoralabs/protocol-rewards/=node_modules/@zoralabs/protocol-rewards/
|
|
5
|
+
@zoralabs/shared-contracts/=node_modules/@zoralabs/shared-contracts/src/
|
|
6
|
+
@zoralabs/sparks-contracts/=node_modules/@zoralabs/sparks-contracts/src/
|
|
7
|
+
@zoralabs/erc20z/=node_modules/@zoralabs/erc20z/src/
|
|
8
|
+
solady/=node_modules/solady/src/
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.23;
|
|
3
|
+
|
|
4
|
+
import "forge-std/Script.sol";
|
|
5
|
+
|
|
6
|
+
import {ProxyDeployerScript} from "@zoralabs/shared-contracts/deployment/ProxyDeployerScript.sol";
|
|
7
|
+
import {CommentsImpl} from "../src/CommentsImpl.sol";
|
|
8
|
+
import {IProtocolRewards} from "@zoralabs/protocol-rewards/src/interfaces/IProtocolRewards.sol";
|
|
9
|
+
|
|
10
|
+
// Temp script
|
|
11
|
+
contract CommentsDeployerBase is ProxyDeployerScript {
|
|
12
|
+
uint256 internal constant SPARK_VALUE = 0.000001 ether;
|
|
13
|
+
address internal constant PROTOCOL_REWARDS = 0x7777777F279eba3d3Ad8F4E708545291A6fDBA8B;
|
|
14
|
+
address internal constant ZORA_TIMED_SALE_STRATEGY = 0x777777722D078c97c6ad07d9f36801e653E356Ae;
|
|
15
|
+
using stdJson for string;
|
|
16
|
+
|
|
17
|
+
struct CommentsDeployment {
|
|
18
|
+
address comments;
|
|
19
|
+
address commentsImpl;
|
|
20
|
+
string commentsVersion;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function saveDeployment(CommentsDeployment memory deployment) internal {
|
|
24
|
+
string memory objectKey = "config";
|
|
25
|
+
|
|
26
|
+
vm.serializeAddress(objectKey, "COMMENTS", deployment.comments);
|
|
27
|
+
string memory result = vm.serializeAddress(objectKey, "COMMENTS_IMPL", deployment.commentsImpl);
|
|
28
|
+
|
|
29
|
+
vm.writeJson(result, string.concat("./addresses/", vm.toString(block.chainid), ".json"));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function readDeployment() internal view returns (CommentsDeployment memory) {
|
|
33
|
+
string memory json = vm.readFile(string.concat("./addresses/", vm.toString(block.chainid), ".json"));
|
|
34
|
+
|
|
35
|
+
return
|
|
36
|
+
CommentsDeployment({
|
|
37
|
+
comments: readAddressOrDefaultToZero(json, "COMMENTS"),
|
|
38
|
+
commentsImpl: readAddressOrDefaultToZero(json, "COMMENTS_IMPL"),
|
|
39
|
+
commentsVersion: readStringOrDefaultToEmpty(json, "COMMENTS_VERSION")
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function commentsImplCreationCode() internal pure returns (bytes memory) {
|
|
44
|
+
return abi.encodePacked(type(CommentsImpl).creationCode, abi.encode(SPARK_VALUE, PROTOCOL_REWARDS));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function getBackfillerAccount() internal pure returns (address) {
|
|
48
|
+
// todo: figure out backfiller. right now this is made from cast wallet new
|
|
49
|
+
return 0x9AfA68161f094DAEA62816b6264b3D777978a164;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function defaultDelegateCommenters() internal pure returns (address[] memory delegateCommenters) {
|
|
53
|
+
delegateCommenters = new address[](1);
|
|
54
|
+
delegateCommenters[0] = ZORA_TIMED_SALE_STRATEGY;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function deployCommentsImpl() internal returns (CommentsImpl) {
|
|
58
|
+
return new CommentsImpl(SPARK_VALUE, PROTOCOL_REWARDS);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// SPDX-License-Identifier: UNLICENSED
|
|
2
|
+
pragma solidity ^0.8.13;
|
|
3
|
+
|
|
4
|
+
import "forge-std/Script.sol";
|
|
5
|
+
|
|
6
|
+
import {ProxyDeployerScript} from "@zoralabs/shared-contracts/deployment/ProxyDeployerScript.sol";
|
|
7
|
+
import {ImmutableCreate2FactoryUtils} from "@zoralabs/shared-contracts/utils/ImmutableCreate2FactoryUtils.sol";
|
|
8
|
+
import {ProxyDeployerScript, DeterministicDeployerAndCaller, DeterministicContractConfig} from "@zoralabs/shared-contracts/deployment/ProxyDeployerScript.sol";
|
|
9
|
+
import {CommentsImpl} from "../src/CommentsImpl.sol";
|
|
10
|
+
import {CommentsDeployment} from "../src/deployments/CommentsDeployment.sol";
|
|
11
|
+
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
12
|
+
import {CommentsDeployerBase} from "./CommentsDeployerBase.sol";
|
|
13
|
+
|
|
14
|
+
// Temp script
|
|
15
|
+
contract DeployScript is CommentsDeployerBase {
|
|
16
|
+
function run() public {
|
|
17
|
+
CommentsDeployment memory deployment = readDeployment();
|
|
18
|
+
|
|
19
|
+
address owner = getProxyAdmin();
|
|
20
|
+
|
|
21
|
+
// todo: figure out backfiller. right now this is made from cast wallet new
|
|
22
|
+
address backfiller = 0x9AfA68161f094DAEA62816b6264b3D777978a164;
|
|
23
|
+
address zoraRecipient = getZoraRecipient();
|
|
24
|
+
|
|
25
|
+
// get deployed implementation address. it it's not deployed, revert
|
|
26
|
+
address implAddress = deployment.commentsImpl;
|
|
27
|
+
|
|
28
|
+
if (implAddress.code.length == 0) {
|
|
29
|
+
revert("Impl not yet deployed. Make sure to deploy it with DeployImpl.s.sol");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
vm.startBroadcast();
|
|
33
|
+
|
|
34
|
+
// get deployer contract
|
|
35
|
+
DeterministicDeployerAndCaller deployer = createOrGetDeployerAndCaller();
|
|
36
|
+
|
|
37
|
+
// read previously saved deterministic royalties config
|
|
38
|
+
DeterministicContractConfig memory commentsConfig = readDeterministicContractConfig("comments");
|
|
39
|
+
|
|
40
|
+
address[] memory delegateCommenters = defaultDelegateCommenters();
|
|
41
|
+
|
|
42
|
+
// build upgrade to and call for comments, with init call
|
|
43
|
+
bytes memory upgradeToAndCall = abi.encodeWithSelector(
|
|
44
|
+
UUPSUpgradeable.upgradeToAndCall.selector,
|
|
45
|
+
implAddress,
|
|
46
|
+
abi.encodeWithSelector(CommentsImpl.initialize.selector, zoraRecipient, owner, backfiller, delegateCommenters)
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// sign royalties deployment with turnkey account
|
|
50
|
+
bytes memory commentsSignature = signDeploymentWithTurnkey(commentsConfig, upgradeToAndCall, deployer);
|
|
51
|
+
|
|
52
|
+
// deterministically deploy royalties contract using the signature
|
|
53
|
+
deployment.comments = deployer.permitSafeCreate2AndCall(
|
|
54
|
+
commentsSignature,
|
|
55
|
+
commentsConfig.salt,
|
|
56
|
+
commentsConfig.creationCode,
|
|
57
|
+
upgradeToAndCall,
|
|
58
|
+
commentsConfig.deployedAddress
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
vm.stopBroadcast();
|
|
62
|
+
|
|
63
|
+
// save the deployment json
|
|
64
|
+
saveDeployment(deployment);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.13;
|
|
3
|
+
|
|
4
|
+
import "forge-std/console2.sol";
|
|
5
|
+
|
|
6
|
+
import {CommentsDeployerBase} from "./CommentsDeployerBase.sol";
|
|
7
|
+
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
8
|
+
|
|
9
|
+
contract DeployImpl is CommentsDeployerBase {
|
|
10
|
+
function run() public {
|
|
11
|
+
CommentsDeployment memory config = readDeployment();
|
|
12
|
+
vm.startBroadcast();
|
|
13
|
+
|
|
14
|
+
config.commentsImpl = address(deployCommentsImpl());
|
|
15
|
+
|
|
16
|
+
vm.stopBroadcast();
|
|
17
|
+
|
|
18
|
+
console2.log("CommentsImpl deployed, to upgrade:");
|
|
19
|
+
console2.log("target:", config.comments);
|
|
20
|
+
console2.log("calldata:");
|
|
21
|
+
console2.logBytes(abi.encodeWithSelector(UUPSUpgradeable.upgradeToAndCall.selector, config.commentsImpl, ""));
|
|
22
|
+
console2.log("multisig:", getProxyAdmin());
|
|
23
|
+
|
|
24
|
+
saveDeployment(config);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// SPDX-License-Identifier: UNLICENSED
|
|
2
|
+
pragma solidity ^0.8.13;
|
|
3
|
+
|
|
4
|
+
import "forge-std/Script.sol";
|
|
5
|
+
|
|
6
|
+
import {ProxyDeployerScript} from "@zoralabs/shared-contracts/deployment/ProxyDeployerScript.sol";
|
|
7
|
+
import {ImmutableCreate2FactoryUtils} from "@zoralabs/shared-contracts/utils/ImmutableCreate2FactoryUtils.sol";
|
|
8
|
+
import {ProxyDeployerScript, DeterministicDeployerAndCaller, DeterministicContractConfig} from "@zoralabs/shared-contracts/deployment/ProxyDeployerScript.sol";
|
|
9
|
+
import {Comments} from "../src/proxy/Comments.sol";
|
|
10
|
+
import {CommentsImpl} from "../src/CommentsImpl.sol";
|
|
11
|
+
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
12
|
+
import {CommentsDeployerBase} from "./CommentsDeployerBase.sol";
|
|
13
|
+
|
|
14
|
+
contract DeployNonDeterministic is CommentsDeployerBase {
|
|
15
|
+
function run() public {
|
|
16
|
+
CommentsDeployment memory deployment = readDeployment();
|
|
17
|
+
|
|
18
|
+
address owner = getProxyAdmin();
|
|
19
|
+
|
|
20
|
+
// todo: figure out backfiller. right now this is made from cast wallet new
|
|
21
|
+
address backfiller = 0x9AfA68161f094DAEA62816b6264b3D777978a164;
|
|
22
|
+
address zoraRecipient = getZoraRecipient();
|
|
23
|
+
|
|
24
|
+
vm.startBroadcast();
|
|
25
|
+
// deploy comments backfiller
|
|
26
|
+
|
|
27
|
+
address implAddress = address(deployCommentsImpl());
|
|
28
|
+
|
|
29
|
+
Comments comments = new Comments(implAddress);
|
|
30
|
+
|
|
31
|
+
address[] memory delegateCommenters = defaultDelegateCommenters();
|
|
32
|
+
|
|
33
|
+
CommentsImpl(payable(address(comments))).initialize(zoraRecipient, owner, backfiller, delegateCommenters);
|
|
34
|
+
|
|
35
|
+
vm.stopBroadcast();
|
|
36
|
+
|
|
37
|
+
deployment.comments = address(comments);
|
|
38
|
+
deployment.commentsImpl = implAddress;
|
|
39
|
+
|
|
40
|
+
// save the deployment json
|
|
41
|
+
saveDeployment(deployment);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// spdx-license-identifier: mit
|
|
2
|
+
pragma solidity ^0.8.20;
|
|
3
|
+
|
|
4
|
+
import "forge-std/Script.sol";
|
|
5
|
+
|
|
6
|
+
import {LibString} from "solady/utils/LibString.sol";
|
|
7
|
+
import {ImmutableCreate2FactoryUtils} from "@zoralabs/shared-contracts/utils/ImmutableCreate2FactoryUtils.sol";
|
|
8
|
+
import {ProxyDeployerScript, DeterministicDeployerAndCaller, DeterministicContractConfig} from "@zoralabs/shared-contracts/deployment/ProxyDeployerScript.sol";
|
|
9
|
+
import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";
|
|
10
|
+
import {Comments} from "../src/proxy/Comments.sol";
|
|
11
|
+
|
|
12
|
+
/// @dev This script saves the current bytecode, and initialization parameters for the Sparks proxy,
|
|
13
|
+
/// which then need to be populated with a salt and expected address, which can be achieved by
|
|
14
|
+
/// running the printed create2crunch command. The resulting config only needs to be generated once
|
|
15
|
+
/// and is reusable for all chains.
|
|
16
|
+
contract GenerateDeterministicParams is ProxyDeployerScript {
|
|
17
|
+
function mineForCommentsAddress(DeterministicDeployerAndCaller deployer, address caller) private returns (DeterministicContractConfig memory config) {
|
|
18
|
+
// get proxy creation code
|
|
19
|
+
// get the expected init code for the proxy from the uupsProxyDeployer
|
|
20
|
+
bytes memory initCode = deployer.proxyCreationCode(type(Comments).creationCode);
|
|
21
|
+
bytes32 initCodeHash = keccak256(initCode);
|
|
22
|
+
|
|
23
|
+
// uupsProxyDeployer is deployer
|
|
24
|
+
(bytes32 salt, address expectedAddress) = mineSalt(address(deployer), initCodeHash, "7777777", caller);
|
|
25
|
+
|
|
26
|
+
// test deployment
|
|
27
|
+
// Create2.deploy(0, salt, initCode);
|
|
28
|
+
|
|
29
|
+
console2.log("salt");
|
|
30
|
+
console2.log(vm.toString(salt));
|
|
31
|
+
|
|
32
|
+
config.salt = salt;
|
|
33
|
+
config.deployedAddress = expectedAddress;
|
|
34
|
+
config.creationCode = initCode;
|
|
35
|
+
config.constructorArgs = deployer.proxyConstructorArgs();
|
|
36
|
+
config.contractName = "Comments";
|
|
37
|
+
config.deploymentCaller = caller;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function run() public {
|
|
41
|
+
address caller = vm.envAddress("DEPLOYER");
|
|
42
|
+
|
|
43
|
+
vm.startBroadcast();
|
|
44
|
+
|
|
45
|
+
// create a proxy deployer, which we can use to generated determistic addresses and corresponding params.
|
|
46
|
+
// proxy deployer code is based on code saved to file from running the script SaveProxyDeployerConfig.s.sol
|
|
47
|
+
DeterministicDeployerAndCaller deployer = createOrGetDeployerAndCaller();
|
|
48
|
+
|
|
49
|
+
vm.stopBroadcast();
|
|
50
|
+
|
|
51
|
+
DeterministicContractConfig memory commentsConfig = mineForCommentsAddress(deployer, caller);
|
|
52
|
+
|
|
53
|
+
saveDeterministicContractConfig(commentsConfig, "comments");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { promises as fs } from "fs";
|
|
2
|
+
import { basename, extname, join, resolve } from "pathe";
|
|
3
|
+
import { glob } from "glob";
|
|
4
|
+
import { ContractConfig } from "@wagmi/cli";
|
|
5
|
+
|
|
6
|
+
const defaultExcludes = [
|
|
7
|
+
"Common.sol/**",
|
|
8
|
+
"Components.sol/**",
|
|
9
|
+
"Script.sol/**",
|
|
10
|
+
"StdAssertions.sol/**",
|
|
11
|
+
"StdInvariant.sol/**",
|
|
12
|
+
"StdError.sol/**",
|
|
13
|
+
"StdCheats.sol/**",
|
|
14
|
+
"StdMath.sol/**",
|
|
15
|
+
"StdJson.sol/**",
|
|
16
|
+
"StdStorage.sol/**",
|
|
17
|
+
"StdUtils.sol/**",
|
|
18
|
+
"Vm.sol/**",
|
|
19
|
+
"console.sol/**",
|
|
20
|
+
"console2.sol/**",
|
|
21
|
+
"test.sol/**",
|
|
22
|
+
"**.s.sol/*.json",
|
|
23
|
+
"**.t.sol/*.json",
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
// design inspired by https://github.com/wagmi-dev/wagmi/blob/main/packages/cli/src/plugins/foundry.ts
|
|
27
|
+
|
|
28
|
+
export const readContracts = async ({
|
|
29
|
+
deployments = {} as any,
|
|
30
|
+
exclude = defaultExcludes,
|
|
31
|
+
include = ["*.json"],
|
|
32
|
+
namePrefix = "",
|
|
33
|
+
project_ = "./",
|
|
34
|
+
}) => {
|
|
35
|
+
// get all the files in ./out
|
|
36
|
+
function getContractName(artifactPath: string, usePrefix = true) {
|
|
37
|
+
const filename = basename(artifactPath);
|
|
38
|
+
const extension = extname(artifactPath);
|
|
39
|
+
return `${usePrefix ? namePrefix : ""}${filename.replace(extension, "")}`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function getContract(artifactPath: string) {
|
|
43
|
+
const artifact = JSON.parse(await fs.readFile(artifactPath, "utf-8"));
|
|
44
|
+
return {
|
|
45
|
+
abi: artifact.abi,
|
|
46
|
+
address: (deployments as Record<string, ContractConfig["address"]>)[
|
|
47
|
+
getContractName(artifactPath, false)
|
|
48
|
+
],
|
|
49
|
+
name: getContractName(artifactPath),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function getArtifactPaths(artifactsDirectory: string) {
|
|
54
|
+
return await glob([
|
|
55
|
+
...include.map((x) => `${artifactsDirectory}/**/${x}`),
|
|
56
|
+
...exclude.map((x) => `!${artifactsDirectory}/**/${x}`),
|
|
57
|
+
]);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const project = resolve(process.cwd(), project_ ?? "");
|
|
61
|
+
|
|
62
|
+
const config = {
|
|
63
|
+
out: "out",
|
|
64
|
+
src: "src",
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const artifactsDirectory = join(project, config.out);
|
|
68
|
+
|
|
69
|
+
const artifactPaths = await getArtifactPaths(artifactsDirectory);
|
|
70
|
+
const contracts = [];
|
|
71
|
+
for (const artifactPath of artifactPaths) {
|
|
72
|
+
const contract = await getContract(artifactPath);
|
|
73
|
+
if (!contract.abi?.length) continue;
|
|
74
|
+
contracts.push(contract);
|
|
75
|
+
}
|
|
76
|
+
return contracts;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
async function saveContractsAbisJson(contracts: { abi: any; name: string }[]) {
|
|
80
|
+
// for each contract, write abi to ./abis/{contractName}.json
|
|
81
|
+
|
|
82
|
+
const abisFolder = "./abis";
|
|
83
|
+
|
|
84
|
+
// mkdir - p ./abis:
|
|
85
|
+
await fs.mkdir(abisFolder, { recursive: true });
|
|
86
|
+
// remove abis folder:
|
|
87
|
+
await fs.rm(abisFolder, { recursive: true });
|
|
88
|
+
// add it back
|
|
89
|
+
// mkdir - p ./abis:
|
|
90
|
+
await fs.mkdir(abisFolder, { recursive: true });
|
|
91
|
+
|
|
92
|
+
// now write abis:
|
|
93
|
+
await Promise.all(
|
|
94
|
+
contracts.map(async (contract) => {
|
|
95
|
+
const abiJson = JSON.stringify(contract.abi, null, 2);
|
|
96
|
+
const abiJsonPath = `${abisFolder}/${contract.name}.json`;
|
|
97
|
+
|
|
98
|
+
await fs.writeFile(abiJsonPath, abiJson);
|
|
99
|
+
}),
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function main() {
|
|
104
|
+
const contracts = await readContracts({});
|
|
105
|
+
|
|
106
|
+
await saveContractsAbisJson(contracts);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
main();
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
generate() {
|
|
6
|
+
file=$1
|
|
7
|
+
if [[ $func == "generate" ]]; then
|
|
8
|
+
echo "Creating storage layout diagrams for the following contracts: $contracts"
|
|
9
|
+
echo "..."
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
echo "=======================" > "$file"
|
|
13
|
+
echo "👁👁 STORAGE LAYOUT snapshot 👁👁" >"$file"
|
|
14
|
+
echo "=======================" >> "$file"
|
|
15
|
+
# shellcheck disable=SC2068
|
|
16
|
+
for contract in ${contracts[@]}
|
|
17
|
+
do
|
|
18
|
+
{ echo -e "\n======================="; echo "➡ $contract" ; echo -e "=======================\n"; } >> "$file"
|
|
19
|
+
FOUNDRY_PROFILE=dev forge inspect --pretty "$contract" storage-layout >> "$file"
|
|
20
|
+
done
|
|
21
|
+
if [[ $func == "generate" ]]; then
|
|
22
|
+
echo "Storage layout snapshot stored at $file"
|
|
23
|
+
fi
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if ! command -v forge &> /dev/null
|
|
27
|
+
then
|
|
28
|
+
echo "forge could not be found. Please install forge by running:"
|
|
29
|
+
echo "curl -L https://foundry.paradigm.xyz | bash"
|
|
30
|
+
exit
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# shellcheck disable=SC2124
|
|
34
|
+
contracts="${@:2}"
|
|
35
|
+
func=$1
|
|
36
|
+
filename=.storage-layout
|
|
37
|
+
new_filename=.storage-layout.temp
|
|
38
|
+
|
|
39
|
+
if [[ $func == "check" ]]; then
|
|
40
|
+
generate $new_filename
|
|
41
|
+
if ! cmp -s .storage-layout $new_filename ; then
|
|
42
|
+
echo "storage-layout test: fails ❌"
|
|
43
|
+
echo "The following lines are different:"
|
|
44
|
+
diff -a --suppress-common-lines "$filename" "$new_filename"
|
|
45
|
+
rm $new_filename
|
|
46
|
+
exit 1
|
|
47
|
+
else
|
|
48
|
+
echo "storage-layout test: passes ✅"
|
|
49
|
+
rm $new_filename
|
|
50
|
+
exit 0
|
|
51
|
+
fi
|
|
52
|
+
elif [[ $func == "generate" ]]; then
|
|
53
|
+
generate "$filename"
|
|
54
|
+
else
|
|
55
|
+
echo "unknown command. Use 'generate' or 'check' as the first argument."
|
|
56
|
+
exit 1
|
|
57
|
+
fi
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { promisify } from "util";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
|
|
6
|
+
const readFileAsync = promisify(fs.readFile);
|
|
7
|
+
const writeFileAsync = promisify(fs.writeFile);
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = path.dirname(__filename);
|
|
11
|
+
|
|
12
|
+
const makePackageVersionFile = async (version: string): Promise<void> => {
|
|
13
|
+
console.log("updating contract version to ", version);
|
|
14
|
+
// read the version from the root package.json:
|
|
15
|
+
|
|
16
|
+
const packageVersionCode = `// This file is automatically generated by code; do not manually update
|
|
17
|
+
// SPDX-License-Identifier: MIT
|
|
18
|
+
pragma solidity ^0.8.23;
|
|
19
|
+
|
|
20
|
+
import {IVersionedContract} from "@zoralabs/shared-contracts/interfaces/IVersionedContract.sol";
|
|
21
|
+
|
|
22
|
+
/// @title ContractVersionBase
|
|
23
|
+
/// @notice Base contract for versioning contracts
|
|
24
|
+
contract ContractVersionBase is IVersionedContract {
|
|
25
|
+
/// @notice The version of the contract
|
|
26
|
+
function contractVersion() external pure override returns (string memory) {
|
|
27
|
+
return "${version}";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
`;
|
|
31
|
+
|
|
32
|
+
// write the file to __dirname__/../src/version/ContractVersionBase.sol:
|
|
33
|
+
const filePath = path.join(
|
|
34
|
+
__dirname,
|
|
35
|
+
"..",
|
|
36
|
+
"src",
|
|
37
|
+
"version",
|
|
38
|
+
"ContractVersionBase.sol",
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
console.log("generated contract version code:", packageVersionCode);
|
|
42
|
+
console.log("writing file to", filePath);
|
|
43
|
+
|
|
44
|
+
await writeFileAsync(filePath, packageVersionCode);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const getVersion = async (): Promise<string> => {
|
|
48
|
+
// read package.json file, parse json, then get version:
|
|
49
|
+
const packageJson = JSON.parse(
|
|
50
|
+
await readFileAsync(path.join(__dirname, "..", "package.json"), "utf-8"),
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
return packageJson.version;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const main = async (): Promise<void> => {
|
|
57
|
+
const version = await getVersion();
|
|
58
|
+
await makePackageVersionFile(version);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
main().catch((error) => {
|
|
62
|
+
console.error("Error updating contract version:", error);
|
|
63
|
+
});
|
package/scripts/abis.ts
ADDED