From 8965047d744ec2539f8f9366072ddcfde6b4e0d5 Mon Sep 17 00:00:00 2001 From: Stanislav Breadless Date: Thu, 16 Jan 2025 10:18:44 +0100 Subject: [PATCH 01/14] display more addresses --- l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol b/l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol index f6a89b402..432aa7265 100644 --- a/l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol +++ b/l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol @@ -1673,6 +1673,8 @@ contract EcosystemUpgrade is Script { ); vm.serializeAddress("deployed_addresses", "l1_gateway_upgrade", addresses.gatewayUpgrade); vm.serializeAddress("deployed_addresses", "l1_transitionary_owner", addresses.transitionaryOwner); + vm.serializeAddress("deployed_addresses", "l1_rollup_da_manager", daAddresses.rollupDAManager); + vm.serializeAddress("deployed_addresses", "l1_governance_upgrade_timer", daAddresses.upgradeTimer); string memory deployedAddresses = vm.serializeAddress( "deployed_addresses", From 56dc377a5fe490c277330b9fe3267be588edc112 Mon Sep 17 00:00:00 2001 From: Stanislav Breadless Date: Thu, 16 Jan 2025 10:19:42 +0100 Subject: [PATCH 02/14] display more contracts + correct constructor params for validator timelock --- l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol b/l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol index 432aa7265..a59e79a6a 100644 --- a/l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol +++ b/l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol @@ -961,13 +961,13 @@ contract EcosystemUpgrade is Script { uint32 executionDelay = uint32(config.contracts.validatorTimelockExecutionDelay); bytes memory bytecode = abi.encodePacked( type(ValidatorTimelock).creationCode, - abi.encode(config.deployerAddress, executionDelay, config.eraChainId) + abi.encode(config.deployerAddress, executionDelay) ); address contractAddress = deployViaCreate2(bytecode); notifyAboutDeployment( contractAddress, "ValidatorTimelock", - abi.encode(config.deployerAddress, executionDelay, config.eraChainId) + abi.encode(config.deployerAddress, executionDelay) ); addresses.validatorTimelock = contractAddress; } From 572cd0c766a2f0aed2811c1afa93599b47304e3a Mon Sep 17 00:00:00 2001 From: Stanislav Breadless Date: Thu, 16 Jan 2025 15:57:09 +0100 Subject: [PATCH 03/14] include the script for security council approval --- .../SecurityCouncilApproveStageUpgrade.s.sol | 28 +++++++++ l1-contracts/deploy-scripts/Utils.sol | 58 +++++++++++++++++++ .../interfaces/ISecurityCouncil.sol | 23 ++++++++ .../upgrade/EcosystemUpgrade.s.sol | 4 +- 4 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 l1-contracts/deploy-scripts/SecurityCouncilApproveStageUpgrade.s.sol create mode 100644 l1-contracts/deploy-scripts/interfaces/ISecurityCouncil.sol diff --git a/l1-contracts/deploy-scripts/SecurityCouncilApproveStageUpgrade.s.sol b/l1-contracts/deploy-scripts/SecurityCouncilApproveStageUpgrade.s.sol new file mode 100644 index 000000000..5a5aa09cc --- /dev/null +++ b/l1-contracts/deploy-scripts/SecurityCouncilApproveStageUpgrade.s.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.21; + +import {Utils} from "./Utils.sol"; +import {IGovernance} from "contracts/governance/IGovernance.sol"; +import {stdToml} from "forge-std/StdToml.sol"; +import {IProtocolUpgradeHandler} from "./interfaces/IProtocolUpgradeHandler.sol"; +import {Script} from "forge-std/Script.sol"; +import {Vm} from "forge-std/Vm.sol"; + +contract SecurityCouncilApproveStageUpgrade is Script { + using stdToml for string; + + function run() external { + // Insert the address of the protocol upgrade handler here. + IProtocolUpgradeHandler protocolUpgradeHandler = IProtocolUpgradeHandler(address(0)); + // Insert the private key of the stage governance + Vm.Wallet memory wallet = vm.createWallet(uint256(0)); + + bytes32 upgradeId = bytes32(0); + + Utils.securityCouncilApproveUpgrade( + protocolUpgradeHandler, + wallet, + upgradeId + ); + } +} diff --git a/l1-contracts/deploy-scripts/Utils.sol b/l1-contracts/deploy-scripts/Utils.sol index d19bafb08..720a19a8f 100644 --- a/l1-contracts/deploy-scripts/Utils.sol +++ b/l1-contracts/deploy-scripts/Utils.sol @@ -19,6 +19,7 @@ import {IChainAdmin} from "contracts/governance/IChainAdmin.sol"; import {EIP712Utils} from "./EIP712Utils.sol"; import {IProtocolUpgradeHandler} from "./interfaces/IProtocolUpgradeHandler.sol"; import {IEmergencyUpgrageBoard} from "./interfaces/IEmergencyUpgrageBoard.sol"; +import {ISecurityCouncil} from "./interfaces/ISecurityCouncil.sol"; import {IMultisig} from "./interfaces/IMultisig.sol"; import {ISafe} from "./interfaces/ISafe.sol"; import {AccessControlRestriction} from "contracts/governance/AccessControlRestriction.sol"; @@ -38,6 +39,11 @@ bytes32 constant EXECUTE_EMERGENCY_UPGRADE_ZK_FOUNDATION_TYPEHASH = keccak256( "ExecuteEmergencyUpgradeZKFoundation(bytes32 id)" ); +/// @dev EIP-712 TypeHash for protocol upgrades approval by the Security Council. +bytes32 constant APPROVE_UPGRADE_SECURITY_COUNCIL_TYPEHASH = + keccak256("ApproveUpgradeSecurityCouncil(bytes32 id)"); + + /// @dev The offset from which the built-in, but user space contracts are located. uint160 constant USER_CONTRACTS_OFFSET = 0x10000; // 2^16 @@ -1002,6 +1008,58 @@ library Utils { } } + function securityCouncilApproveUpgrade( + IProtocolUpgradeHandler _protocolUpgradeHandler, + Vm.Wallet memory _governorWallet, + bytes32 upgradeId + ) internal returns (bytes memory) { + address securityCouncilAddr = _protocolUpgradeHandler.securityCouncil(); + bytes32 securityCouncilDigest; + { + securityCouncilDigest = EIP712Utils.buildDomainHash( + securityCouncilAddr, + "SecurityCouncil", + "1" + ); + } + + bytes[] memory securityCouncilRawSignatures = new bytes[](12); + address[] memory securityCouncilMembers = new address[](12); + { + { + IMultisig securityCouncil = IMultisig(_protocolUpgradeHandler.securityCouncil()); + for (uint256 i = 0; i < 12; i++) { + securityCouncilMembers[i] = securityCouncil.members(i); + } + } + for (uint256 i = 0; i < securityCouncilMembers.length; i++) { + bytes32 safeDigest; + { + bytes32 digest = EIP712Utils.buildDigest( + securityCouncilDigest, + keccak256(abi.encode(APPROVE_UPGRADE_SECURITY_COUNCIL_TYPEHASH, upgradeId)) + ); + safeDigest = ISafe(securityCouncilMembers[i]).getMessageHash(abi.encode(digest)); + } + { + (uint8 v, bytes32 r, bytes32 s) = vm.sign(_governorWallet, safeDigest); + securityCouncilRawSignatures[i] = abi.encodePacked(r, s, v); + } + } + } + + { + vm.startBroadcast(msg.sender); + ISecurityCouncil(securityCouncilAddr).approveUpgradeSecurityCouncil( + upgradeId, + securityCouncilMembers, + securityCouncilRawSignatures + ); + vm.stopBroadcast(); + } + } + + function adminExecute( address _admin, address _accessControlRestriction, diff --git a/l1-contracts/deploy-scripts/interfaces/ISecurityCouncil.sol b/l1-contracts/deploy-scripts/interfaces/ISecurityCouncil.sol new file mode 100644 index 000000000..070f17682 --- /dev/null +++ b/l1-contracts/deploy-scripts/interfaces/ISecurityCouncil.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +/// @author Matter Labs +/// @custom:security-contact security@matterlabs.dev +interface ISecurityCouncil { + function approveUpgradeSecurityCouncil(bytes32 _id, address[] calldata _signers, bytes[] calldata _signatures) + external; + + function softFreeze(uint256 _validUntil, address[] calldata _signers, bytes[] calldata _signatures) external; + + function hardFreeze(uint256 _validUntil, address[] calldata _signers, bytes[] calldata _signatures) external; + + function unfreeze(uint256 _validUntil, address[] calldata _signers, bytes[] calldata _signatures) external; + + function setSoftFreezeThreshold( + uint256 _threshold, + uint256 _validUntil, + address[] calldata _signers, + bytes[] calldata _signatures + ) external; +} diff --git a/l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol b/l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol index a59e79a6a..9b05121ce 100644 --- a/l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol +++ b/l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol @@ -1673,8 +1673,8 @@ contract EcosystemUpgrade is Script { ); vm.serializeAddress("deployed_addresses", "l1_gateway_upgrade", addresses.gatewayUpgrade); vm.serializeAddress("deployed_addresses", "l1_transitionary_owner", addresses.transitionaryOwner); - vm.serializeAddress("deployed_addresses", "l1_rollup_da_manager", daAddresses.rollupDAManager); - vm.serializeAddress("deployed_addresses", "l1_governance_upgrade_timer", daAddresses.upgradeTimer); + vm.serializeAddress("deployed_addresses", "l1_rollup_da_manager", addresses.daAddresses.rollupDAManager); + vm.serializeAddress("deployed_addresses", "l1_governance_upgrade_timer", addresses.upgradeTimer); string memory deployedAddresses = vm.serializeAddress( "deployed_addresses", From 3cd71593061367da65b63dd43099fa20715c986e Mon Sep 17 00:00:00 2001 From: Stanislav Breadless Date: Thu, 16 Jan 2025 16:00:36 +0100 Subject: [PATCH 04/14] fmt --- .../SecurityCouncilApproveStageUpgrade.s.sol | 8 ++------ l1-contracts/deploy-scripts/Utils.sol | 13 +++---------- .../deploy-scripts/interfaces/ISecurityCouncil.sol | 7 +++++-- .../deploy-scripts/upgrade/EcosystemUpgrade.s.sol | 6 +----- 4 files changed, 11 insertions(+), 23 deletions(-) diff --git a/l1-contracts/deploy-scripts/SecurityCouncilApproveStageUpgrade.s.sol b/l1-contracts/deploy-scripts/SecurityCouncilApproveStageUpgrade.s.sol index 5a5aa09cc..258efe663 100644 --- a/l1-contracts/deploy-scripts/SecurityCouncilApproveStageUpgrade.s.sol +++ b/l1-contracts/deploy-scripts/SecurityCouncilApproveStageUpgrade.s.sol @@ -14,15 +14,11 @@ contract SecurityCouncilApproveStageUpgrade is Script { function run() external { // Insert the address of the protocol upgrade handler here. IProtocolUpgradeHandler protocolUpgradeHandler = IProtocolUpgradeHandler(address(0)); - // Insert the private key of the stage governance + // Insert the private key of the stage governance Vm.Wallet memory wallet = vm.createWallet(uint256(0)); bytes32 upgradeId = bytes32(0); - Utils.securityCouncilApproveUpgrade( - protocolUpgradeHandler, - wallet, - upgradeId - ); + Utils.securityCouncilApproveUpgrade(protocolUpgradeHandler, wallet, upgradeId); } } diff --git a/l1-contracts/deploy-scripts/Utils.sol b/l1-contracts/deploy-scripts/Utils.sol index 720a19a8f..0bed8f226 100644 --- a/l1-contracts/deploy-scripts/Utils.sol +++ b/l1-contracts/deploy-scripts/Utils.sol @@ -19,7 +19,7 @@ import {IChainAdmin} from "contracts/governance/IChainAdmin.sol"; import {EIP712Utils} from "./EIP712Utils.sol"; import {IProtocolUpgradeHandler} from "./interfaces/IProtocolUpgradeHandler.sol"; import {IEmergencyUpgrageBoard} from "./interfaces/IEmergencyUpgrageBoard.sol"; -import {ISecurityCouncil} from "./interfaces/ISecurityCouncil.sol"; +import {ISecurityCouncil} from "./interfaces/ISecurityCouncil.sol"; import {IMultisig} from "./interfaces/IMultisig.sol"; import {ISafe} from "./interfaces/ISafe.sol"; import {AccessControlRestriction} from "contracts/governance/AccessControlRestriction.sol"; @@ -40,9 +40,7 @@ bytes32 constant EXECUTE_EMERGENCY_UPGRADE_ZK_FOUNDATION_TYPEHASH = keccak256( ); /// @dev EIP-712 TypeHash for protocol upgrades approval by the Security Council. -bytes32 constant APPROVE_UPGRADE_SECURITY_COUNCIL_TYPEHASH = - keccak256("ApproveUpgradeSecurityCouncil(bytes32 id)"); - +bytes32 constant APPROVE_UPGRADE_SECURITY_COUNCIL_TYPEHASH = keccak256("ApproveUpgradeSecurityCouncil(bytes32 id)"); /// @dev The offset from which the built-in, but user space contracts are located. uint160 constant USER_CONTRACTS_OFFSET = 0x10000; // 2^16 @@ -1016,11 +1014,7 @@ library Utils { address securityCouncilAddr = _protocolUpgradeHandler.securityCouncil(); bytes32 securityCouncilDigest; { - securityCouncilDigest = EIP712Utils.buildDomainHash( - securityCouncilAddr, - "SecurityCouncil", - "1" - ); + securityCouncilDigest = EIP712Utils.buildDomainHash(securityCouncilAddr, "SecurityCouncil", "1"); } bytes[] memory securityCouncilRawSignatures = new bytes[](12); @@ -1059,7 +1053,6 @@ library Utils { } } - function adminExecute( address _admin, address _accessControlRestriction, diff --git a/l1-contracts/deploy-scripts/interfaces/ISecurityCouncil.sol b/l1-contracts/deploy-scripts/interfaces/ISecurityCouncil.sol index 070f17682..8d5bfab5b 100644 --- a/l1-contracts/deploy-scripts/interfaces/ISecurityCouncil.sol +++ b/l1-contracts/deploy-scripts/interfaces/ISecurityCouncil.sol @@ -5,8 +5,11 @@ pragma solidity 0.8.24; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev interface ISecurityCouncil { - function approveUpgradeSecurityCouncil(bytes32 _id, address[] calldata _signers, bytes[] calldata _signatures) - external; + function approveUpgradeSecurityCouncil( + bytes32 _id, + address[] calldata _signers, + bytes[] calldata _signatures + ) external; function softFreeze(uint256 _validUntil, address[] calldata _signers, bytes[] calldata _signatures) external; diff --git a/l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol b/l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol index 9b05121ce..36d113961 100644 --- a/l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol +++ b/l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol @@ -964,11 +964,7 @@ contract EcosystemUpgrade is Script { abi.encode(config.deployerAddress, executionDelay) ); address contractAddress = deployViaCreate2(bytecode); - notifyAboutDeployment( - contractAddress, - "ValidatorTimelock", - abi.encode(config.deployerAddress, executionDelay) - ); + notifyAboutDeployment(contractAddress, "ValidatorTimelock", abi.encode(config.deployerAddress, executionDelay)); addresses.validatorTimelock = contractAddress; } From e7f91634fa254c1eb99b1a6bbca6a2723d7473ce Mon Sep 17 00:00:00 2001 From: Stanislav Breadless Date: Fri, 17 Jan 2025 10:56:41 +0100 Subject: [PATCH 05/14] update hashes of scripts --- AllContractsHashes.json | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/AllContractsHashes.json b/AllContractsHashes.json index 8e8d52dac..a0b847609 100644 --- a/AllContractsHashes.json +++ b/AllContractsHashes.json @@ -1579,9 +1579,9 @@ "contractName": "l1-contracts/Utils", "zkBytecodeHash": "0x010000077b86e41703f8195fd86398efb4004f1486c2b86130fc0667603ab5d2", "zkBytecodePath": "/l1-contracts/zkout/SystemContractsCaller.sol/Utils.json", - "evmBytecodeHash": "0x534bc5e7432735c8808d91708e9eab901f55a7ec6f7c0f878bb562757b6a99d9", + "evmBytecodeHash": "0x33535ce5e17ea5ccd2a8974681cd654f48af21ffaa04c69028fb9bf31d23d0ca", "evmBytecodePath": "/l1-contracts/out/Utils.sol/Utils.json", - "evmDeployedBytecodeHash": "0x43081c39edfbf9f44a8f1c1f0e5e00423e727da0da196eab876aed9949811e77" + "evmDeployedBytecodeHash": "0xa14ce7f64000373414d8e0abf1fcf85394c7bb265dd76626644bfe67f0bc407a" }, { "contractName": "l1-contracts/TestCalldataDA", @@ -1729,9 +1729,9 @@ }, { "contractName": "l1-contracts/GatewayCTMDeployerHelper", - "evmBytecodeHash": "0xc2f943354c6081cfeb4d6e14bcc4206286b432c8b798c26d1238a9e1f7f2ebe5", + "evmBytecodeHash": "0x6b830ff91e30f1df0250ac885915d84c853caa35237be5bf62fab2a9231e3009", "evmBytecodePath": "/l1-contracts/out/GatewayCTMDeployerHelper.sol/GatewayCTMDeployerHelper.json", - "evmDeployedBytecodeHash": "0x2f0d5740387eecfd06e5bb2c5a813e3d76bdab3bd9fea5bb80cf0a25e9bd58bf", + "evmDeployedBytecodeHash": "0xd9019924e302314f4b9eb5499ffb2a899f734ee30918c60fde58baf085efdcaf", "zkBytecodeHash": null, "zkBytecodePath": null }, @@ -1753,25 +1753,25 @@ }, { "contractName": "l1-contracts/L2ContractsBytecodesLib", - "evmBytecodeHash": "0xf529991a2409549048691f228460421fc7abeadf0a850c77e045be9f1e03d84f", + "evmBytecodeHash": "0x4c0c576a69474356edd527c91c7a5c94a3226e85d3f1def4d1f724146f14b6e4", "evmBytecodePath": "/l1-contracts/out/L2ContractsBytecodesLib.sol/L2ContractsBytecodesLib.json", - "evmDeployedBytecodeHash": "0x926b5cbdd4380fcee8ce08c83e7a1537ff552d732ea3a9a67a55acbed2486ba2", + "evmDeployedBytecodeHash": "0xeaa80ab78d57d9c107225bb125a48ff5491880102f28fce3d3e097b6f1aac273", "zkBytecodeHash": null, "zkBytecodePath": null }, { "contractName": "l1-contracts/L2LegacySharedBridgeTestHelper", - "evmBytecodeHash": "0xa5764f4d2186631b2e510944ed57f76d95c03e18853e75b870da6ff52d7ec866", + "evmBytecodeHash": "0x7947bc809c5e7cb7a1f46fe388214b196feb0813c4d677576b3a80ece028a3d1", "evmBytecodePath": "/l1-contracts/out/L2LegacySharedBridgeTestHelper.sol/L2LegacySharedBridgeTestHelper.json", - "evmDeployedBytecodeHash": "0xd549dd56c79a7dbb77c2b5985212a9dcf3833436258f972cacf3f553776b224e", + "evmDeployedBytecodeHash": "0xdb1c2965093fb98d39a7f4d29af44e41163b3b7c86bff637ed48a495b5e5ee34", "zkBytecodeHash": null, "zkBytecodePath": null }, { "contractName": "l1-contracts/L2Utils", - "evmBytecodeHash": "0x58ad7d621b09034d87f85956b99800fc81e883d80cf3e08927b5ebac506043af", + "evmBytecodeHash": "0xc4afd9848eb1ae6eba3cde34b8616cccbf529b66420b52a1991e5f99959caa91", "evmBytecodePath": "/l1-contracts/out/L2Utils.sol/L2Utils.json", - "evmDeployedBytecodeHash": "0x524ad674b4b7d42ab8813b36cae3e37019aecaad15b4c1769334c68da6c7429c", + "evmDeployedBytecodeHash": "0x9e9e616f311730f8ea60ea80afec8ff4de70b1eee6c4725afbf03ffb1f7e46d3", "zkBytecodeHash": null, "zkBytecodePath": null }, @@ -1897,25 +1897,25 @@ }, { "contractName": "l1-contracts/GatewayPreparationForTests", - "evmBytecodeHash": "0xa49ad09b7277cd40223b0b8c78382552b9a96f23933414e0ebc045167f5f9681", + "evmBytecodeHash": "0xce8f153b1d144148e9b0e64bbc57a172bd2958f6c4f654b743e57e6d3617a412", "evmBytecodePath": "/l1-contracts/out/_GatewayPreparationForTests.sol/GatewayPreparationForTests.json", - "evmDeployedBytecodeHash": "0x260a2a1e256a6d70ec9e66c6e5acf67c64caa05e13d40336b095bb8ab64cfaf1", + "evmDeployedBytecodeHash": "0xcf545604cd7d8fa00d738d89a77a9c885ab0422075a396a25aacf287e4a5e252", "zkBytecodeHash": null, "zkBytecodePath": null }, { "contractName": "l1-contracts/SharedL2ContractL1DeployerUtils", - "evmBytecodeHash": "0x5903f68e6896e719cd87d0c5c08af2b5646ef035a34d7d3d2508ab3ce0c1a754", + "evmBytecodeHash": "0xaf0ef6dce4a9862e9abfae30d3d4368cf5c68994192c0092b5013f03ffb2ad69", "evmBytecodePath": "/l1-contracts/out/_SharedL2ContractL1DeployerUtils.sol/SharedL2ContractL1DeployerUtils.json", - "evmDeployedBytecodeHash": "0xeb3b8144c3b690055f33a8ce4a80d8a50badff0a775e175f3cee6860892312d8", + "evmDeployedBytecodeHash": "0xad076c1d3639629cbe09f4a4b8f7b5a245d0c3f13747e0ee59825e0bced6f071", "zkBytecodeHash": null, "zkBytecodePath": null }, { "contractName": "l1-contracts/SharedL2ContractL2DeployerUtils", - "evmBytecodeHash": "0xd892435640a5c4beb9cbda5af0e5374f677d7fb3ad07cfda77bf7e1a1887f266", + "evmBytecodeHash": "0x54894f52956c7b260f17d3d6a273e7a8f96fe752fe54853e0d7ffa7bfb701e2d", "evmBytecodePath": "/l1-contracts/out/_SharedL2ContractL2DeployerUtils.sol/SharedL2ContractL2DeployerUtils.json", - "evmDeployedBytecodeHash": "0x6266ca830309305eacd21db8a215dbb4c5f2bae84e77ed7c571689ec63a78710", + "evmDeployedBytecodeHash": "0xbafd36f7e9ffaec48694bbaced45979a67e6105dd64b2de5922b55d75da06c23", "zkBytecodeHash": null, "zkBytecodePath": null }, From e1b50e8971c8304526d4f4759b2148c8930a5e12 Mon Sep 17 00:00:00 2001 From: Stanislav Breadless Date: Fri, 17 Jan 2025 11:47:10 +0100 Subject: [PATCH 06/14] dont include scripts --- AllContractsHashes.json | 38 +----------- scripts/calculate-hashes.ts | 111 ++++++++++++++++++++++++++++++++---- 2 files changed, 104 insertions(+), 45 deletions(-) diff --git a/AllContractsHashes.json b/AllContractsHashes.json index a0b847609..60d3ed9c4 100644 --- a/AllContractsHashes.json +++ b/AllContractsHashes.json @@ -1579,9 +1579,9 @@ "contractName": "l1-contracts/Utils", "zkBytecodeHash": "0x010000077b86e41703f8195fd86398efb4004f1486c2b86130fc0667603ab5d2", "zkBytecodePath": "/l1-contracts/zkout/SystemContractsCaller.sol/Utils.json", - "evmBytecodeHash": "0x33535ce5e17ea5ccd2a8974681cd654f48af21ffaa04c69028fb9bf31d23d0ca", - "evmBytecodePath": "/l1-contracts/out/Utils.sol/Utils.json", - "evmDeployedBytecodeHash": "0xa14ce7f64000373414d8e0abf1fcf85394c7bb265dd76626644bfe67f0bc407a" + "evmBytecodeHash": "0x4c9033aa9f834d00d4110549c502fecc1028b31b071c5d4833f1e23a59c941bf", + "evmBytecodePath": "/l1-contracts/out/SystemContractsCaller.sol/Utils.json", + "evmDeployedBytecodeHash": "0x749f6171fd58e7fd6742e379d8685bbd605fc439382a9a5cee2c02e68f0b7df7" }, { "contractName": "l1-contracts/TestCalldataDA", @@ -1719,22 +1719,6 @@ "zkBytecodeHash": null, "zkBytecodePath": null }, - { - "contractName": "l1-contracts/EIP712Utils", - "evmBytecodeHash": "0x2c6e37222391b17574f82ea60648ff76570857c09850e19cb439484ceea9f5ce", - "evmBytecodePath": "/l1-contracts/out/EIP712Utils.sol/EIP712Utils.json", - "evmDeployedBytecodeHash": "0xf878f1f72fdb3a0a08c4d8ca7d74a2389f84707c06c94dd6189786ef03bed7fd", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, - { - "contractName": "l1-contracts/GatewayCTMDeployerHelper", - "evmBytecodeHash": "0x6b830ff91e30f1df0250ac885915d84c853caa35237be5bf62fab2a9231e3009", - "evmBytecodePath": "/l1-contracts/out/GatewayCTMDeployerHelper.sol/GatewayCTMDeployerHelper.json", - "evmDeployedBytecodeHash": "0xd9019924e302314f4b9eb5499ffb2a899f734ee30918c60fde58baf085efdcaf", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, { "contractName": "l1-contracts/L1NativeTokenVaultTest", "evmBytecodeHash": "0x250162173ef74292e1cc80aab84aa7bd7b4add7c3dabcb37c2214f991eb8c4f3", @@ -1751,22 +1735,6 @@ "zkBytecodeHash": null, "zkBytecodePath": null }, - { - "contractName": "l1-contracts/L2ContractsBytecodesLib", - "evmBytecodeHash": "0x4c0c576a69474356edd527c91c7a5c94a3226e85d3f1def4d1f724146f14b6e4", - "evmBytecodePath": "/l1-contracts/out/L2ContractsBytecodesLib.sol/L2ContractsBytecodesLib.json", - "evmDeployedBytecodeHash": "0xeaa80ab78d57d9c107225bb125a48ff5491880102f28fce3d3e097b6f1aac273", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, - { - "contractName": "l1-contracts/L2LegacySharedBridgeTestHelper", - "evmBytecodeHash": "0x7947bc809c5e7cb7a1f46fe388214b196feb0813c4d677576b3a80ece028a3d1", - "evmBytecodePath": "/l1-contracts/out/L2LegacySharedBridgeTestHelper.sol/L2LegacySharedBridgeTestHelper.json", - "evmDeployedBytecodeHash": "0xdb1c2965093fb98d39a7f4d29af44e41163b3b7c86bff637ed48a495b5e5ee34", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, { "contractName": "l1-contracts/L2Utils", "evmBytecodeHash": "0xc4afd9848eb1ae6eba3cde34b8616cccbf529b66420b52a1991e5f99959caa91", diff --git a/scripts/calculate-hashes.ts b/scripts/calculate-hashes.ts index 075414455..c4d4e7091 100644 --- a/scripts/calculate-hashes.ts +++ b/scripts/calculate-hashes.ts @@ -5,6 +5,94 @@ import os from "os"; import { join } from "path"; import { hashBytecode } from "zksync-ethers/build/utils"; +const SOLIDITY_SOURCE_CODE_PATHS = ["system-contracts/", "l2-contracts/", "l1-contracts/", "da-contracts/"]; +const YUL_SOURCE_CODE_PATHS = ["system-contracts/"]; +const OUTPUT_FILE_PATH = "AllContractsHashes.json"; + +const SKIPPED_FOLDERS = ["l1-contracts/deploy-scripts"]; +const FORCE_INCLUDE = ["Create2AndTransfer.sol"]; + +function getCanonicalNameFromFile(directory: string, fileName: string) { + const folderName = SOLIDITY_SOURCE_CODE_PATHS.find(x => directory.startsWith(x)); + if(!folderName) { + throw new Error('Unknown directory'); + } + + return `${folderName}${fileName}`; +} + +// A path to the file in zkout/out folder, e.g. `/l1-contracts/zkout/ERC20.sol/ERC20.json` +function getCanonicalNameFromFoundryPath(foundryPath: string) { + const folderName = SOLIDITY_SOURCE_CODE_PATHS.find(x => foundryPath.startsWith('/' + x)); + if(!folderName) { + throw new Error('Unknown directory'); + } + + const fileName = foundryPath.split('/').find(x => x.endsWith('.sol')); + if(!fileName) { + // It may be a yul file, so we return null + return null; + } + + return `${folderName}${fileName}`; +} + +function listSolFiles(directory: string): string[] { + const solFiles: string[] = []; + + function searchDir(dir: string) { + const entries = fs.readdirSync(dir, { withFileTypes: true }); + for (const entry of entries) { + const fullPath = join(dir, entry.name); + if (entry.isDirectory()) { + searchDir(fullPath); + } else if (entry.isFile() && fullPath.endsWith('.sol')) { + solFiles.push(getCanonicalNameFromFile(directory, entry.name)); + } + } + } + + searchDir(directory); + return solFiles; +} + +let cachedIgnoredFiles: any = null; + +function shouldForceIncludeFile(filePath: string) { + return FORCE_INCLUDE.some(x => filePath.includes(x)); +} + +function getIgnoredFiles() { + if (cachedIgnoredFiles) { + return cachedIgnoredFiles; + } + + let res: any = {}; + + for (const dir of SKIPPED_FOLDERS) { + const files = listSolFiles(dir); + for (const f of files) { + if (!shouldForceIncludeFile(f)) { + res[f] = true; + } + } + } + + cachedIgnoredFiles = res; + + return res; +} + +function shouldSkipFolderOrFile(filePath: string): boolean { + const canonicalPath = getCanonicalNameFromFoundryPath(filePath); + + if(!canonicalPath) { + return false; + } + + return !!getIgnoredFiles()[canonicalPath] +} + type SourceContractDetails = { contractName: string; }; @@ -106,9 +194,11 @@ const getZkSolidityContractsDetailsWithArtifactsDir = (workDir: string): SourceA zkBytecodePath, zkBytecodeHash, }; - // Filter out the interfaces (that don't have any bytecode). }) - .filter((c) => c.zkBytecodeHash != "0x"); + // --------------------------------------------------------------------- + // Filter out empty bytecode + check skipping logic + // --------------------------------------------------------------------- + .filter((c) => c.zkBytecodeHash != "0x" && !shouldSkipFolderOrFile(c.zkBytecodePath)); }; const getEVMSolidityContractsDetailsWithArtifactsDir = (workDir: string): SourceAndEvmCompilationDetails[] => { @@ -148,9 +238,11 @@ const getEVMSolidityContractsDetailsWithArtifactsDir = (workDir: string): Source evmBytecodeHash: hashes[0], evmDeployedBytecodeHash: hashes[1], }; - // Filter out the interfaces (that don't have any bytecode). }) - .filter((c) => c.evmBytecodeHash != "0x"); + // --------------------------------------------------------------------- + // Filter out empty bytecode + check skipping logic + // --------------------------------------------------------------------- + .filter((c) => c.evmBytecodeHash != "0x" && !shouldSkipFolderOrFile(c.evmBytecodePath)); }; const getSolidityContractsDetails = (dir: string): ContractsInfo[] => { @@ -231,9 +323,11 @@ const getYulContractsDetails = (dir: string): ContractsInfo[] => { evmBytecodeHash: null, evmDeployedBytecodeHash: null, }; - // Filter out the interfaces (that don't have any bytecode). }) - .filter((c) => c.zkBytecodeHash != "0x"); + // --------------------------------------------------------------------- + // Filter out empty bytecode + check skipping logic + // --------------------------------------------------------------------- + .filter((c) => c.zkBytecodeHash != "0x" && !shouldSkipFolderOrFile(c.zkBytecodePath)); }; const makePathAbsolute = (path: string): string => { @@ -291,9 +385,6 @@ const findDifferences = (newHashes: ContractsInfo[], oldHashes: ContractsInfo[]) return differencesList; }; -const SOLIDITY_SOURCE_CODE_PATHS = ["system-contracts/", "l2-contracts/", "l1-contracts/", "da-contracts/"]; -const YUL_SOURCE_CODE_PATHS = ["system-contracts/"]; -const OUTPUT_FILE_PATH = "AllContractsHashes.json"; const main = async () => { const args = process.argv; @@ -322,7 +413,7 @@ const main = async () => { console.log("Calculated hashes differ from the hashes in the SystemContractsHashes.json file. Differences:"); console.log(differences); if (checkOnly) { - console.log("You can use the `yarn calculate-hashes:fix` command to update the AllContractHashes.json file."); + console.log("You can use the `yarn calculate-hashes:fix` command to update the AllContractsHashes.json file."); console.log("Exiting..."); process.exit(1); } else { From 661266439e8964c225925a074a307e8204087555 Mon Sep 17 00:00:00 2001 From: Stanislav Breadless Date: Fri, 17 Jan 2025 11:48:42 +0100 Subject: [PATCH 07/14] remove test files --- AllContractsHashes.json | 112 ------------------------------------ scripts/calculate-hashes.ts | 2 +- 2 files changed, 1 insertion(+), 113 deletions(-) diff --git a/AllContractsHashes.json b/AllContractsHashes.json index 60d3ed9c4..48a4678c8 100644 --- a/AllContractsHashes.json +++ b/AllContractsHashes.json @@ -1207,14 +1207,6 @@ "evmBytecodePath": "/l1-contracts/out/L1GenesisUpgrade.sol/L1GenesisUpgrade.json", "evmDeployedBytecodeHash": "0x67a0e7432c8aa8dcb820dc298d756363904aac944b13eea945ab3f6ee740411d" }, - { - "contractName": "l1-contracts/L1NativeTokenVault", - "zkBytecodeHash": "0x010008e544b9c10bcab94701ebaa8a1d5de071a74466acff4fb97e159c01004d", - "zkBytecodePath": "/l1-contracts/zkout/L1NativeTokenVault.sol/L1NativeTokenVault.json", - "evmBytecodeHash": "0xf7062da19f0995aecd070cd191cbc7cb37182fedf142877922fbcb4cfbc92b44", - "evmBytecodePath": "/l1-contracts/out/L1NativeTokenVault.sol/L1NativeTokenVault.json", - "evmDeployedBytecodeHash": "0x940ff770725d3bcdfc18998067f0c834b2cda892e02ec87763ad4f30bc700f75" - }, { "contractName": "l1-contracts/L1Nullifier", "zkBytecodeHash": "0x010005c5bc10a16f1653966b6dbf6364a5e2b0ea3fee3aaeb21f9552b01c5886", @@ -1703,14 +1695,6 @@ "evmBytecodePath": "/l1-contracts/out/ZKChainBase.sol/ZKChainBase.json", "evmDeployedBytecodeHash": "0x1438f2c1614cf88694e270d8290e51050d8444e5fac7f6332ec21cda59d2c530" }, - { - "contractName": "l1-contracts/CheckTransactionTest", - "evmBytecodeHash": "0x1078337564b75370b1751bdc7e685add3695cbc2099f98681df8a9e7b70f45ae", - "evmBytecodePath": "/l1-contracts/out/CheckTransaction.sol/CheckTransactionTest.json", - "evmDeployedBytecodeHash": "0x695ef1be463fb461939d9d5e4e2e1692e03a046ff3e6ba372995e0f3d7b3e46a", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, { "contractName": "l1-contracts/Create2AndTransfer", "evmBytecodeHash": "0x95d7ded2a7e878aa82674a330a2b3638b0efa6168a4e0af9b30afdf68384cabb", @@ -1719,46 +1703,6 @@ "zkBytecodeHash": null, "zkBytecodePath": null }, - { - "contractName": "l1-contracts/L1NativeTokenVaultTest", - "evmBytecodeHash": "0x250162173ef74292e1cc80aab84aa7bd7b4add7c3dabcb37c2214f991eb8c4f3", - "evmBytecodePath": "/l1-contracts/out/L1NativeTokenVault.sol/L1NativeTokenVaultTest.json", - "evmDeployedBytecodeHash": "0xf85d7935c4ffd77f30bcdc04d4bbf6fe3e4bd06d5406b76d6294df41c03fb4fb", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, - { - "contractName": "l1-contracts/SomeToken", - "evmBytecodeHash": "0x4f2715fe887d9a1644ad9bef9a4a054544e30528211f05695e3cbd444931592b", - "evmBytecodePath": "/l1-contracts/out/L1NativeTokenVault.sol/SomeToken.json", - "evmDeployedBytecodeHash": "0x37318c04e7520ac15d36f987bd0c9e357d51f6d8089302ca90bf8b476accc026", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, - { - "contractName": "l1-contracts/L2Utils", - "evmBytecodeHash": "0xc4afd9848eb1ae6eba3cde34b8616cccbf529b66420b52a1991e5f99959caa91", - "evmBytecodePath": "/l1-contracts/out/L2Utils.sol/L2Utils.json", - "evmDeployedBytecodeHash": "0x9e9e616f311730f8ea60ea80afec8ff4de70b1eee6c4725afbf03ffb1f7e46d3", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, - { - "contractName": "l1-contracts/ManageWhitelistTest", - "evmBytecodeHash": "0x57dfede110d42a9360e7d4385231e587e7c5e6c08aeb765a31200af1412f2667", - "evmBytecodePath": "/l1-contracts/out/ManageWhitelist.sol/ManageWhitelistTest.json", - "evmDeployedBytecodeHash": "0x206074c8d6d3d36cb603a59393b45bcdcb4d0ca53031990483c96ba57eb778c3", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, - { - "contractName": "l1-contracts/MerkleTreeNoSort", - "evmBytecodeHash": "0x298afb6ae89c746384e124b97a782984cb928083426359b655ec3e65c2ba56b1", - "evmBytecodePath": "/l1-contracts/out/MerkleTreeNoSort.sol/MerkleTreeNoSort.json", - "evmDeployedBytecodeHash": "0xe437113971789c010b68580bbcfa06d0a4e6b14355d2aa1d1191659e5d2ea8e9", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, { "contractName": "l1-contracts/MockERC20", "evmBytecodeHash": "0x4979cc2df2ac7d0cfe5400ea0fc00c1cce56248c3e87764eed7a1a3b260f1f93", @@ -1775,30 +1719,6 @@ "zkBytecodeHash": null, "zkBytecodePath": null }, - { - "contractName": "l1-contracts/OnEmptyQueueTest", - "evmBytecodeHash": "0x66e63a393c6021e132b95f9ce91931a97e3617cef18b308b78834bef125ef700", - "evmBytecodePath": "/l1-contracts/out/OnEmptyQueue.sol/OnEmptyQueueTest.json", - "evmDeployedBytecodeHash": "0x78e374d0568b46409ae77cea76379e420282220ecae5ac296433195d9e65d2ed", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, - { - "contractName": "l1-contracts/PopOperationsTest", - "evmBytecodeHash": "0x2fced6d25eb21c0a87aefb8338c35113e7d8fd0631a8319975baae270be3f083", - "evmBytecodePath": "/l1-contracts/out/PopOperations.sol/PopOperationsTest.json", - "evmDeployedBytecodeHash": "0xe161cbd8524ab40d2534a516ece7c844c40b132b6737240c090e898612b4ec8e", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, - { - "contractName": "l1-contracts/PushOperationsTest", - "evmBytecodeHash": "0x6cd55e5476461ec9cf2c04b03d564d413b7850809873655d0daf2c91bec48ab8", - "evmBytecodePath": "/l1-contracts/out/PushOperations.sol/PushOperationsTest.json", - "evmDeployedBytecodeHash": "0x18e0f4892bf49aef0dcc8d104858f52c86b3a33b8b0777ef748513b2536f86f2", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, { "contractName": "l1-contracts/stdError", "evmBytecodeHash": "0xa5cd965e5609ac02cc106708d5449c5a2e01d0d09a879e7c9bc1ca6ef6142f53", @@ -1855,38 +1775,6 @@ "zkBytecodeHash": null, "zkBytecodePath": null }, - { - "contractName": "l1-contracts/UtilsFacet", - "evmBytecodeHash": "0x1ea198587e47946d69110741303d7e44e15afdd7370e4b3497993a1d37f2b902", - "evmBytecodePath": "/l1-contracts/out/UtilsFacet.sol/UtilsFacet.json", - "evmDeployedBytecodeHash": "0x7bd18121543aad77e8a631ba7bf7967434a3fa805ab92220bad03d5b4d4b27b2", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, - { - "contractName": "l1-contracts/GatewayPreparationForTests", - "evmBytecodeHash": "0xce8f153b1d144148e9b0e64bbc57a172bd2958f6c4f654b743e57e6d3617a412", - "evmBytecodePath": "/l1-contracts/out/_GatewayPreparationForTests.sol/GatewayPreparationForTests.json", - "evmDeployedBytecodeHash": "0xcf545604cd7d8fa00d738d89a77a9c885ab0422075a396a25aacf287e4a5e252", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, - { - "contractName": "l1-contracts/SharedL2ContractL1DeployerUtils", - "evmBytecodeHash": "0xaf0ef6dce4a9862e9abfae30d3d4368cf5c68994192c0092b5013f03ffb2ad69", - "evmBytecodePath": "/l1-contracts/out/_SharedL2ContractL1DeployerUtils.sol/SharedL2ContractL1DeployerUtils.json", - "evmDeployedBytecodeHash": "0xad076c1d3639629cbe09f4a4b8f7b5a245d0c3f13747e0ee59825e0bced6f071", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, - { - "contractName": "l1-contracts/SharedL2ContractL2DeployerUtils", - "evmBytecodeHash": "0x54894f52956c7b260f17d3d6a273e7a8f96fe752fe54853e0d7ffa7bfb701e2d", - "evmBytecodePath": "/l1-contracts/out/_SharedL2ContractL2DeployerUtils.sol/SharedL2ContractL2DeployerUtils.json", - "evmDeployedBytecodeHash": "0xbafd36f7e9ffaec48694bbaced45979a67e6105dd64b2de5922b55d75da06c23", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, { "contractName": "l1-contracts/console", "evmBytecodeHash": "0x35348e9a92e75913ac4347c4748573128dc2422e67975566407ce365b30786b3", diff --git a/scripts/calculate-hashes.ts b/scripts/calculate-hashes.ts index c4d4e7091..4c9ab7417 100644 --- a/scripts/calculate-hashes.ts +++ b/scripts/calculate-hashes.ts @@ -9,7 +9,7 @@ const SOLIDITY_SOURCE_CODE_PATHS = ["system-contracts/", "l2-contracts/", "l1-co const YUL_SOURCE_CODE_PATHS = ["system-contracts/"]; const OUTPUT_FILE_PATH = "AllContractsHashes.json"; -const SKIPPED_FOLDERS = ["l1-contracts/deploy-scripts"]; +const SKIPPED_FOLDERS = ["l1-contracts/deploy-scripts", "l1-contracts/test"]; const FORCE_INCLUDE = ["Create2AndTransfer.sol"]; function getCanonicalNameFromFile(directory: string, fileName: string) { From f749f8a6333e42b6e1910888314785c8b2dffe29 Mon Sep 17 00:00:00 2001 From: Stanislav Breadless Date: Fri, 17 Jan 2025 12:09:29 +0100 Subject: [PATCH 08/14] wip --- scripts/calculate-hashes.ts | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/scripts/calculate-hashes.ts b/scripts/calculate-hashes.ts index 4c9ab7417..f8d9e0522 100644 --- a/scripts/calculate-hashes.ts +++ b/scripts/calculate-hashes.ts @@ -12,13 +12,37 @@ const OUTPUT_FILE_PATH = "AllContractsHashes.json"; const SKIPPED_FOLDERS = ["l1-contracts/deploy-scripts", "l1-contracts/test"]; const FORCE_INCLUDE = ["Create2AndTransfer.sol"]; -function getCanonicalNameFromFile(directory: string, fileName: string) { +// Opens a Solidity file and returns all the contracts/libraries created inside of it. +function parseSolFile(filePath: string): string[] { + const content = fs.readFileSync(filePath, 'utf-8'); + const regex = /(?:^|\s)(contract|library)\s+(\w+)/g; + const matches: string[] = []; + let match; + + while ((match = regex.exec(content)) !== null) { + matches.push(match[2]); + } + + return matches; +} + +function getCanonicalPathsFromFile( + directory: string, + fileName: string, + fullPath: string, +) { const folderName = SOLIDITY_SOURCE_CODE_PATHS.find(x => directory.startsWith(x)); if(!folderName) { throw new Error('Unknown directory'); } - return `${folderName}${fileName}`; + const res = []; + + const parsed = parseSolFile(fullPath); + + return [ + `${folderName}out/${fileName}/` + ]; } // A path to the file in zkout/out folder, e.g. `/l1-contracts/zkout/ERC20.sol/ERC20.json` From 30b471f12804b28658a33933e66164dfb6dbae80 Mon Sep 17 00:00:00 2001 From: Stanislav Breadless Date: Fri, 17 Jan 2025 14:50:09 +0100 Subject: [PATCH 09/14] upd script --- scripts/calculate-hashes.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/scripts/calculate-hashes.ts b/scripts/calculate-hashes.ts index f8d9e0522..eb51907fa 100644 --- a/scripts/calculate-hashes.ts +++ b/scripts/calculate-hashes.ts @@ -36,13 +36,16 @@ function getCanonicalPathsFromFile( throw new Error('Unknown directory'); } - const res = []; + const res: string[] = []; const parsed = parseSolFile(fullPath); - return [ - `${folderName}out/${fileName}/` - ]; + for(const item of parsed) { + res.push(`${folderName}out/${fileName}/${item}.json`); + res.push(`${folderName}zkout/${fileName}/${item}.json`); + } + + return res; } // A path to the file in zkout/out folder, e.g. `/l1-contracts/zkout/ERC20.sol/ERC20.json` @@ -71,7 +74,7 @@ function listSolFiles(directory: string): string[] { if (entry.isDirectory()) { searchDir(fullPath); } else if (entry.isFile() && fullPath.endsWith('.sol')) { - solFiles.push(getCanonicalNameFromFile(directory, entry.name)); + solFiles.push(...getCanonicalPathsFromFile(directory, entry.name, fullPath)); } } } From 91c675299186f39c524d7838968f14a3362d18ef Mon Sep 17 00:00:00 2001 From: Stanislav Breadless Date: Fri, 17 Jan 2025 15:04:28 +0100 Subject: [PATCH 10/14] fix script --- AllContractsHashes.json | 40 ++++++++----------------------------- scripts/calculate-hashes.ts | 28 +++----------------------- 2 files changed, 11 insertions(+), 57 deletions(-) diff --git a/AllContractsHashes.json b/AllContractsHashes.json index 48a4678c8..ea84504b3 100644 --- a/AllContractsHashes.json +++ b/AllContractsHashes.json @@ -1207,6 +1207,14 @@ "evmBytecodePath": "/l1-contracts/out/L1GenesisUpgrade.sol/L1GenesisUpgrade.json", "evmDeployedBytecodeHash": "0x67a0e7432c8aa8dcb820dc298d756363904aac944b13eea945ab3f6ee740411d" }, + { + "contractName": "l1-contracts/L1NativeTokenVault", + "zkBytecodeHash": "0x010008e544b9c10bcab94701ebaa8a1d5de071a74466acff4fb97e159c01004d", + "zkBytecodePath": "/l1-contracts/zkout/L1NativeTokenVault.sol/L1NativeTokenVault.json", + "evmBytecodeHash": "0xf7062da19f0995aecd070cd191cbc7cb37182fedf142877922fbcb4cfbc92b44", + "evmBytecodePath": "/l1-contracts/out/L1NativeTokenVault.sol/L1NativeTokenVault.json", + "evmDeployedBytecodeHash": "0x940ff770725d3bcdfc18998067f0c834b2cda892e02ec87763ad4f30bc700f75" + }, { "contractName": "l1-contracts/L1Nullifier", "zkBytecodeHash": "0x010005c5bc10a16f1653966b6dbf6364a5e2b0ea3fee3aaeb21f9552b01c5886", @@ -1791,38 +1799,6 @@ "zkBytecodeHash": null, "zkBytecodePath": null }, - { - "contractName": "da-contracts/AvailL1DAValidator", - "evmBytecodeHash": "0xa1e74a3af577978f617e1a236bd9cb08bd6ddb34cb8b22ffb8819447bb331c49", - "evmBytecodePath": "/da-contracts/out/AvailL1DAValidator.sol/AvailL1DAValidator.json", - "evmDeployedBytecodeHash": "0x2f5b45fa3176b3b9e64d62f9c718313b433efc7c5fbd45aed46b6368ee26fb5b", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, - { - "contractName": "da-contracts/DummyAvailBridge", - "evmBytecodeHash": "0x459a46eb9a76f387afeab9af9a69025ddea631dd8eec121ed1ec475ef8369539", - "evmBytecodePath": "/da-contracts/out/DummyAvailBridge.sol/DummyAvailBridge.json", - "evmDeployedBytecodeHash": "0xe2dec4376b1c4bfd622dda92f33df19d55789416ffd48befcf4832c00ffe4731", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, - { - "contractName": "da-contracts/DummyVectorX", - "evmBytecodeHash": "0xca21ed0f661a68947589de22cfe3f673f4932b37a0363ee3ca072d305d669efb", - "evmBytecodePath": "/da-contracts/out/DummyVectorX.sol/DummyVectorX.json", - "evmDeployedBytecodeHash": "0x8e32ea3e5937d6712e43153d41c320234a15584bc7927a9fb944a0a27979f90b", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, - { - "contractName": "da-contracts/RollupL1DAValidator", - "evmBytecodeHash": "0x70183f5c0d4c1294d0a512c1845a08d175e28d64bd4c565be4fb7fffdaa2f846", - "evmBytecodePath": "/da-contracts/out/RollupL1DAValidator.sol/RollupL1DAValidator.json", - "evmDeployedBytecodeHash": "0x21eeb1b38e4ea3a947d5cb4570022946c845be23cbdbf431094eaf406994ce56", - "zkBytecodeHash": null, - "zkBytecodePath": null - }, { "contractName": "CodeOracle.yul", "zkBytecodePath": "/system-contracts/zkout/CodeOracle.yul/contracts-preprocessed/precompiles/CodeOracle.yul.json", diff --git a/scripts/calculate-hashes.ts b/scripts/calculate-hashes.ts index eb51907fa..213c2563f 100644 --- a/scripts/calculate-hashes.ts +++ b/scripts/calculate-hashes.ts @@ -41,29 +41,13 @@ function getCanonicalPathsFromFile( const parsed = parseSolFile(fullPath); for(const item of parsed) { - res.push(`${folderName}out/${fileName}/${item}.json`); - res.push(`${folderName}zkout/${fileName}/${item}.json`); + res.push(`/${folderName}out/${fileName}/${item}.json`); + res.push(`/${folderName}zkout/${fileName}/${item}.json`); } return res; } -// A path to the file in zkout/out folder, e.g. `/l1-contracts/zkout/ERC20.sol/ERC20.json` -function getCanonicalNameFromFoundryPath(foundryPath: string) { - const folderName = SOLIDITY_SOURCE_CODE_PATHS.find(x => foundryPath.startsWith('/' + x)); - if(!folderName) { - throw new Error('Unknown directory'); - } - - const fileName = foundryPath.split('/').find(x => x.endsWith('.sol')); - if(!fileName) { - // It may be a yul file, so we return null - return null; - } - - return `${folderName}${fileName}`; -} - function listSolFiles(directory: string): string[] { const solFiles: string[] = []; @@ -111,13 +95,7 @@ function getIgnoredFiles() { } function shouldSkipFolderOrFile(filePath: string): boolean { - const canonicalPath = getCanonicalNameFromFoundryPath(filePath); - - if(!canonicalPath) { - return false; - } - - return !!getIgnoredFiles()[canonicalPath] + return !!getIgnoredFiles()[filePath] } type SourceContractDetails = { From 4338f5d7f0643f81fe83f25871d20708468b47ea Mon Sep 17 00:00:00 2001 From: Stanislav Breadless Date: Fri, 17 Jan 2025 15:09:06 +0100 Subject: [PATCH 11/14] restore da contracts --- AllContractsHashes.json | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/AllContractsHashes.json b/AllContractsHashes.json index ea84504b3..5fb98276c 100644 --- a/AllContractsHashes.json +++ b/AllContractsHashes.json @@ -1799,6 +1799,38 @@ "zkBytecodeHash": null, "zkBytecodePath": null }, + { + "contractName": "da-contracts/AvailL1DAValidator", + "evmBytecodeHash": "0xa1e74a3af577978f617e1a236bd9cb08bd6ddb34cb8b22ffb8819447bb331c49", + "evmBytecodePath": "/da-contracts/out/AvailL1DAValidator.sol/AvailL1DAValidator.json", + "evmDeployedBytecodeHash": "0x2f5b45fa3176b3b9e64d62f9c718313b433efc7c5fbd45aed46b6368ee26fb5b", + "zkBytecodeHash": null, + "zkBytecodePath": null + }, + { + "contractName": "da-contracts/DummyAvailBridge", + "evmBytecodeHash": "0x459a46eb9a76f387afeab9af9a69025ddea631dd8eec121ed1ec475ef8369539", + "evmBytecodePath": "/da-contracts/out/DummyAvailBridge.sol/DummyAvailBridge.json", + "evmDeployedBytecodeHash": "0xe2dec4376b1c4bfd622dda92f33df19d55789416ffd48befcf4832c00ffe4731", + "zkBytecodeHash": null, + "zkBytecodePath": null + }, + { + "contractName": "da-contracts/DummyVectorX", + "evmBytecodeHash": "0xca21ed0f661a68947589de22cfe3f673f4932b37a0363ee3ca072d305d669efb", + "evmBytecodePath": "/da-contracts/out/DummyVectorX.sol/DummyVectorX.json", + "evmDeployedBytecodeHash": "0x8e32ea3e5937d6712e43153d41c320234a15584bc7927a9fb944a0a27979f90b", + "zkBytecodeHash": null, + "zkBytecodePath": null + }, + { + "contractName": "da-contracts/RollupL1DAValidator", + "evmBytecodeHash": "0x70183f5c0d4c1294d0a512c1845a08d175e28d64bd4c565be4fb7fffdaa2f846", + "evmBytecodePath": "/da-contracts/out/RollupL1DAValidator.sol/RollupL1DAValidator.json", + "evmDeployedBytecodeHash": "0x21eeb1b38e4ea3a947d5cb4570022946c845be23cbdbf431094eaf406994ce56", + "zkBytecodeHash": null, + "zkBytecodePath": null + }, { "contractName": "CodeOracle.yul", "zkBytecodePath": "/system-contracts/zkout/CodeOracle.yul/contracts-preprocessed/precompiles/CodeOracle.yul.json", From c461207646586c15bae53d0bc4cbd4456024c375 Mon Sep 17 00:00:00 2001 From: Stanislav Breadless Date: Fri, 17 Jan 2025 15:13:23 +0100 Subject: [PATCH 12/14] add some comments --- scripts/calculate-hashes.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/calculate-hashes.ts b/scripts/calculate-hashes.ts index 213c2563f..5d8fcccf2 100644 --- a/scripts/calculate-hashes.ts +++ b/scripts/calculate-hashes.ts @@ -26,6 +26,7 @@ function parseSolFile(filePath: string): string[] { return matches; } +// Returns paths where all the foundry compiled artifacts related to the file can be stored function getCanonicalPathsFromFile( directory: string, fileName: string, @@ -70,6 +71,8 @@ function listSolFiles(directory: string): string[] { let cachedIgnoredFiles: any = null; function shouldForceIncludeFile(filePath: string) { + // This is a simple substring check. It is simple and fine in most cases. + // In the worst case, accidentally including a file is better than accidentally excluding. return FORCE_INCLUDE.some(x => filePath.includes(x)); } From 741d10d865629f64bf621b7058c23c50a47b3fd3 Mon Sep 17 00:00:00 2001 From: Stanislav Breadless Date: Fri, 17 Jan 2025 15:17:57 +0100 Subject: [PATCH 13/14] fmt --- scripts/calculate-hashes.ts | 183 ++++++++++++++++++------------------ 1 file changed, 93 insertions(+), 90 deletions(-) diff --git a/scripts/calculate-hashes.ts b/scripts/calculate-hashes.ts index 5d8fcccf2..c25be3f90 100644 --- a/scripts/calculate-hashes.ts +++ b/scripts/calculate-hashes.ts @@ -14,34 +14,30 @@ const FORCE_INCLUDE = ["Create2AndTransfer.sol"]; // Opens a Solidity file and returns all the contracts/libraries created inside of it. function parseSolFile(filePath: string): string[] { - const content = fs.readFileSync(filePath, 'utf-8'); + const content = fs.readFileSync(filePath, "utf-8"); const regex = /(?:^|\s)(contract|library)\s+(\w+)/g; const matches: string[] = []; let match; while ((match = regex.exec(content)) !== null) { - matches.push(match[2]); + matches.push(match[2]); } return matches; } // Returns paths where all the foundry compiled artifacts related to the file can be stored -function getCanonicalPathsFromFile( - directory: string, - fileName: string, - fullPath: string, -) { - const folderName = SOLIDITY_SOURCE_CODE_PATHS.find(x => directory.startsWith(x)); - if(!folderName) { - throw new Error('Unknown directory'); +function getCanonicalPathsFromFile(directory: string, fileName: string, fullPath: string) { + const folderName = SOLIDITY_SOURCE_CODE_PATHS.find((x) => directory.startsWith(x)); + if (!folderName) { + throw new Error("Unknown directory"); } const res: string[] = []; const parsed = parseSolFile(fullPath); - for(const item of parsed) { + for (const item of parsed) { res.push(`/${folderName}out/${fileName}/${item}.json`); res.push(`/${folderName}zkout/${fileName}/${item}.json`); } @@ -53,27 +49,28 @@ function listSolFiles(directory: string): string[] { const solFiles: string[] = []; function searchDir(dir: string) { - const entries = fs.readdirSync(dir, { withFileTypes: true }); - for (const entry of entries) { - const fullPath = join(dir, entry.name); - if (entry.isDirectory()) { - searchDir(fullPath); - } else if (entry.isFile() && fullPath.endsWith('.sol')) { - solFiles.push(...getCanonicalPathsFromFile(directory, entry.name, fullPath)); - } + const entries = fs.readdirSync(dir, { withFileTypes: true }); + for (const entry of entries) { + const fullPath = join(dir, entry.name); + if (entry.isDirectory()) { + searchDir(fullPath); + } else if (entry.isFile() && fullPath.endsWith(".sol")) { + solFiles.push(...getCanonicalPathsFromFile(directory, entry.name, fullPath)); } + } } searchDir(directory); return solFiles; } +// eslint-disable-next-line @typescript-eslint/no-explicit-any let cachedIgnoredFiles: any = null; function shouldForceIncludeFile(filePath: string) { // This is a simple substring check. It is simple and fine in most cases. // In the worst case, accidentally including a file is better than accidentally excluding. - return FORCE_INCLUDE.some(x => filePath.includes(x)); + return FORCE_INCLUDE.some((x) => filePath.includes(x)); } function getIgnoredFiles() { @@ -81,7 +78,8 @@ function getIgnoredFiles() { return cachedIgnoredFiles; } - let res: any = {}; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const res: any = {}; for (const dir of SKIPPED_FOLDERS) { const files = listSolFiles(dir); @@ -98,7 +96,7 @@ function getIgnoredFiles() { } function shouldSkipFolderOrFile(filePath: string): boolean { - return !!getIgnoredFiles()[filePath] + return !!getIgnoredFiles()[filePath]; } type SourceContractDetails = { @@ -186,27 +184,29 @@ const getZkSolidityContractsDetailsWithArtifactsDir = (workDir: string): SourceA }) .flat(); - return compiledFiles - .map((jsonFile) => { - const jsonFileContents = JSON.parse(fs.readFileSync(jsonFile, "utf8")); - const zkBytecodeHash = getBytecodeHashFromZkJson(jsonFileContents); - - const zkBytecodePath = jsonFile.startsWith(join(__dirname, "..")) - ? jsonFile.replace(join(__dirname, ".."), "") - : jsonFile; - - const contractName = (jsonFile.split("/").pop() || "").replace(".json", ""); - - return { - contractName: join(workDir, contractName), - zkBytecodePath, - zkBytecodeHash, - }; - }) - // --------------------------------------------------------------------- - // Filter out empty bytecode + check skipping logic - // --------------------------------------------------------------------- - .filter((c) => c.zkBytecodeHash != "0x" && !shouldSkipFolderOrFile(c.zkBytecodePath)); + return ( + compiledFiles + .map((jsonFile) => { + const jsonFileContents = JSON.parse(fs.readFileSync(jsonFile, "utf8")); + const zkBytecodeHash = getBytecodeHashFromZkJson(jsonFileContents); + + const zkBytecodePath = jsonFile.startsWith(join(__dirname, "..")) + ? jsonFile.replace(join(__dirname, ".."), "") + : jsonFile; + + const contractName = (jsonFile.split("/").pop() || "").replace(".json", ""); + + return { + contractName: join(workDir, contractName), + zkBytecodePath, + zkBytecodeHash, + }; + }) + // --------------------------------------------------------------------- + // Filter out empty bytecode + check skipping logic + // --------------------------------------------------------------------- + .filter((c) => c.zkBytecodeHash != "0x" && !shouldSkipFolderOrFile(c.zkBytecodePath)) + ); }; const getEVMSolidityContractsDetailsWithArtifactsDir = (workDir: string): SourceAndEvmCompilationDetails[] => { @@ -229,28 +229,30 @@ const getEVMSolidityContractsDetailsWithArtifactsDir = (workDir: string): Source }) .flat(); - return compiledFiles - .map((jsonFile) => { - const jsonFileContents = JSON.parse(fs.readFileSync(jsonFile, "utf8")); - const hashes = getBytecodeHashFromEvmJson(jsonFileContents); - - const evmBytecodePath = jsonFile.startsWith(join(__dirname, "..")) - ? jsonFile.replace(join(__dirname, ".."), "") - : jsonFile; - - const contractName = (jsonFile.split("/").pop() || "").replace(".json", ""); - - return { - contractName: join(workDir, contractName), - evmBytecodePath, - evmBytecodeHash: hashes[0], - evmDeployedBytecodeHash: hashes[1], - }; - }) - // --------------------------------------------------------------------- - // Filter out empty bytecode + check skipping logic - // --------------------------------------------------------------------- - .filter((c) => c.evmBytecodeHash != "0x" && !shouldSkipFolderOrFile(c.evmBytecodePath)); + return ( + compiledFiles + .map((jsonFile) => { + const jsonFileContents = JSON.parse(fs.readFileSync(jsonFile, "utf8")); + const hashes = getBytecodeHashFromEvmJson(jsonFileContents); + + const evmBytecodePath = jsonFile.startsWith(join(__dirname, "..")) + ? jsonFile.replace(join(__dirname, ".."), "") + : jsonFile; + + const contractName = (jsonFile.split("/").pop() || "").replace(".json", ""); + + return { + contractName: join(workDir, contractName), + evmBytecodePath, + evmBytecodeHash: hashes[0], + evmDeployedBytecodeHash: hashes[1], + }; + }) + // --------------------------------------------------------------------- + // Filter out empty bytecode + check skipping logic + // --------------------------------------------------------------------- + .filter((c) => c.evmBytecodeHash != "0x" && !shouldSkipFolderOrFile(c.evmBytecodePath)) + ); }; const getSolidityContractsDetails = (dir: string): ContractsInfo[] => { @@ -312,30 +314,32 @@ const getYulContractsDetails = (dir: string): ContractsInfo[] => { }) .flat(); - return compiledFiles - .map((jsonFile) => { - const jsonFileContents = JSON.parse(fs.readFileSync(jsonFile, "utf8")); - const zkBytecodeHash = getBytecodeHashFromZkJson(jsonFileContents); - - const zkBytecodePath = jsonFile.startsWith(join(__dirname, "..")) - ? jsonFile.replace(join(__dirname, ".."), "") - : jsonFile; - - const contractName = (jsonFile.split("/").pop() || "").replace(".json", ""); - - return { - contractName, - zkBytecodePath, - zkBytecodeHash, - evmBytecodePath: null, - evmBytecodeHash: null, - evmDeployedBytecodeHash: null, - }; - }) - // --------------------------------------------------------------------- - // Filter out empty bytecode + check skipping logic - // --------------------------------------------------------------------- - .filter((c) => c.zkBytecodeHash != "0x" && !shouldSkipFolderOrFile(c.zkBytecodePath)); + return ( + compiledFiles + .map((jsonFile) => { + const jsonFileContents = JSON.parse(fs.readFileSync(jsonFile, "utf8")); + const zkBytecodeHash = getBytecodeHashFromZkJson(jsonFileContents); + + const zkBytecodePath = jsonFile.startsWith(join(__dirname, "..")) + ? jsonFile.replace(join(__dirname, ".."), "") + : jsonFile; + + const contractName = (jsonFile.split("/").pop() || "").replace(".json", ""); + + return { + contractName, + zkBytecodePath, + zkBytecodeHash, + evmBytecodePath: null, + evmBytecodeHash: null, + evmDeployedBytecodeHash: null, + }; + }) + // --------------------------------------------------------------------- + // Filter out empty bytecode + check skipping logic + // --------------------------------------------------------------------- + .filter((c) => c.zkBytecodeHash != "0x" && !shouldSkipFolderOrFile(c.zkBytecodePath)) + ); }; const makePathAbsolute = (path: string): string => { @@ -393,7 +397,6 @@ const findDifferences = (newHashes: ContractsInfo[], oldHashes: ContractsInfo[]) return differencesList; }; - const main = async () => { const args = process.argv; if (args.length > 3 || (args.length == 3 && !args.includes("--check-only"))) { From 1cd5d6b9cdeb30f1dfe5a8cbd63a8654bc5413c6 Mon Sep 17 00:00:00 2001 From: Stanislav Breadless Date: Tue, 21 Jan 2025 12:15:47 +0100 Subject: [PATCH 14/14] respond to comments --- l1-contracts/deploy-scripts/Utils.sol | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/l1-contracts/deploy-scripts/Utils.sol b/l1-contracts/deploy-scripts/Utils.sol index 0bed8f226..531419692 100644 --- a/l1-contracts/deploy-scripts/Utils.sol +++ b/l1-contracts/deploy-scripts/Utils.sol @@ -54,6 +54,8 @@ address constant L2_WETH_IMPL_ADDRESS = address(USER_CONTRACTS_OFFSET + 0x07); address constant L2_CREATE2_FACTORY_ADDRESS = address(USER_CONTRACTS_OFFSET); +uint256 constant SECURITY_COUNCIL_SIZE = 12; + // solhint-disable-next-line gas-struct-packing struct StateTransitionDeployedAddresses { address chainTypeManagerProxy; @@ -944,14 +946,14 @@ library Utils { bytes memory securityCouncilSignatures; { - address[] memory securityCouncilMembers = new address[](12); + address[] memory securityCouncilMembers = new address[](SECURITY_COUNCIL_SIZE); { IMultisig securityCouncil = IMultisig(_protocolUpgradeHandler.securityCouncil()); for (uint256 i = 0; i < 12; i++) { securityCouncilMembers[i] = securityCouncil.members(i); } } - bytes[] memory securityCouncilRawSignatures = new bytes[](12); + bytes[] memory securityCouncilRawSignatures = new bytes[](SECURITY_COUNCIL_SIZE); for (uint256 i = 0; i < securityCouncilMembers.length; i++) { bytes32 safeDigest; { @@ -1006,18 +1008,21 @@ library Utils { } } + // Signs and approves the upgrade by the security council. + // It works only on staging env, since the `_governorWallet` must be the wallet + // that is the sole owner of the Gnosis wallets that constitute the security council. function securityCouncilApproveUpgrade( IProtocolUpgradeHandler _protocolUpgradeHandler, Vm.Wallet memory _governorWallet, bytes32 upgradeId - ) internal returns (bytes memory) { + ) internal { address securityCouncilAddr = _protocolUpgradeHandler.securityCouncil(); bytes32 securityCouncilDigest; { securityCouncilDigest = EIP712Utils.buildDomainHash(securityCouncilAddr, "SecurityCouncil", "1"); } - bytes[] memory securityCouncilRawSignatures = new bytes[](12); + bytes[] memory securityCouncilRawSignatures = new bytes[](SECURITY_COUNCIL_SIZE); address[] memory securityCouncilMembers = new address[](12); { {