From eee2ed30b5672ca9d6c125460c3fa47f7e24d02a Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Mon, 5 Jan 2026 07:49:58 -0800 Subject: [PATCH 1/4] ci: update mention from evm-safety-team to security-oncall (#1328) --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 80554e53d1..b1feb16c51 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -67,7 +67,7 @@ jobs: just install (cd src/ && just --justfile ci.just check-superchain-registry-latest) - notify-failures-on-main: - mentions: "@evm-safety-team" + mentions: "@security-oncall" stacked_simulation: description: "Runs a stacked simulation" @@ -93,7 +93,7 @@ jobs: - store_artifacts: path: src/stack-simulation-output.txt - notify-failures-on-main: - mentions: "@evm-safety-team" + mentions: "@security-oncall" forge_build: docker: @@ -141,7 +141,7 @@ jobs: # Run manually with: forge test --match-contract Integration forge test --skip Integration -vvv - notify-failures-on-main: - mentions: "@evm-safety-team" + mentions: "@security-oncall" template_regression_tests: circleci_ip_ranges: true @@ -158,7 +158,7 @@ jobs: command: | (cd src/ && just --justfile ci.just simulate-all-templates) - notify-failures-on-main: - mentions: "@evm-safety-team" + mentions: "@security-oncall" just_new_recipe_tests: circleci_ip_ranges: true From 8db9bf9fcc4a03d5d65f56dade667e2bd2e491a7 Mon Sep 17 00:00:00 2001 From: Wazabie <48911235+Wazabie@users.noreply.github.com> Date: Mon, 5 Jan 2026 19:35:39 +0100 Subject: [PATCH 2/4] Update U18 betanet tasks addresses (#1329) * Update U18 betanet tasks addresses * Update addresses and hashes --- .../050-op-betanet-add-game-type/README.md | 2 +- .../VALIDATION.md | 7 ++- .../addresses.json | 22 ++++----- .../050-op-betanet-add-game-type/config.toml | 12 ++--- .../README.md | 4 +- .../VALIDATION.md | 9 ++-- .../addresses.json | 22 ++++----- src/tasks/sep/052-U18-op-betanets/README.md | 2 +- .../sep/052-U18-op-betanets/VALIDATION.md | 9 ++-- .../sep/052-U18-op-betanets/addresses.json | 48 +++++++++---------- src/tasks/sep/052-U18-op-betanets/config.toml | 14 +++--- 11 files changed, 74 insertions(+), 77 deletions(-) diff --git a/src/tasks/sep/050-op-betanet-add-game-type/README.md b/src/tasks/sep/050-op-betanet-add-game-type/README.md index cf636e07a2..cf4c8e6ef9 100644 --- a/src/tasks/sep/050-op-betanet-add-game-type/README.md +++ b/src/tasks/sep/050-op-betanet-add-game-type/README.md @@ -11,7 +11,7 @@ This task adds the dispute game type 0 (Permissionless) to the Dispute Game Fact Simulation commands for each safe: ```bash cd src/tasks/sep/050-op-betanet-add-game-type -SIMULATE_WITHOUT_LEDGER=1 SKIP_DECODE_AND_PRINT=1 just --dotenv-path $(pwd)/.env simulate +just simulate-stack sep 050-op-betanet-add-game-type ``` Signing commands for each safe: diff --git a/src/tasks/sep/050-op-betanet-add-game-type/VALIDATION.md b/src/tasks/sep/050-op-betanet-add-game-type/VALIDATION.md index 70e3b51eec..9f36a58e56 100644 --- a/src/tasks/sep/050-op-betanet-add-game-type/VALIDATION.md +++ b/src/tasks/sep/050-op-betanet-add-game-type/VALIDATION.md @@ -17,15 +17,14 @@ the values printed to the terminal when you run the task. > [!CAUTION] > > -> ### Betanet EOA (`0xe934Dc97E347C6aCef74364B50125bb8689c40ff`) +> ### Betanet 1/1 Safe (`0xe934Dc97E347C6aCef74364B50125bb8689c40ff`) > > - Domain Hash: `0x07e03428d7125835eca12b6dd1a02903029b456da3a091ecd66fda859fbce61e` -> - Message Hash: `0x9c5cbe23181c28d77aa0eaf6d190d60500c2f58387134deb2249ffd0545d97c6` +> - Message Hash: `0x8bc5b68c47ac7fe4fb44f3e16267580dea43c4d22b5eeac990d840337232b6c6` > - ## Task Calldata Calldata: ``` -0x82ad56cb000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c69e4c24db479191676611a25d977203c3bdca620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002441661a2e900000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000005babf93ac7affeae25dc1a7ad4587fdeebba44c2000000000000000000000000cd18a0c04286eba52bb168fa1d79133da4856bef00000000000000000000000062841f5e03a56f818bc8818c5130757aca2541a7000000000000000000000000000000000000000000000000000000000000000003ccb5619628eeba89d58b204aadeb2ed9f51d18ff938069dd298b9e19fb2d310000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000002a300000000000000000000000000000000000000000000000000000000000049d40000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000006463dee3828677f6270d83d45408044fc5edb908000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147468697320697320612073616c74206d6978657200000000000000000000000000000000000000000000000000000000000000000000000000000000 +0x82ad56cb000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c69e4c24db479191676611a25d977203c3bdca620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002441661a2e900000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000004e0528a9dc40fedf1c2cfc0eaa04e70e7d3d591b000000000000000000000000905c82c09b8e6f9b8a89e4840d390ea966b5e6110000000000000000000000007c85a789cc0cf7b4161d4dafc6e22bbecfc8ae3f000000000000000000000000000000000000000000000000000000000000000003f2146db42fdcf336a6980af7899a365054527e75f5d5aa33638b318a5632a20000000000000000000000000000000000000000000000000000000000000049000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000002a300000000000000000000000000000000000000000000000000000000000049d40000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000006463dee3828677f6270d83d45408044fc5edb908000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147468697320697320612073616c74206d6978657200000000000000000000000000000000000000000000000000000000000000000000000000000000 ``` \ No newline at end of file diff --git a/src/tasks/sep/050-op-betanet-add-game-type/addresses.json b/src/tasks/sep/050-op-betanet-add-game-type/addresses.json index 6d2d54929e..4d6fbfb365 100644 --- a/src/tasks/sep/050-op-betanet-add-game-type/addresses.json +++ b/src/tasks/sep/050-op-betanet-add-game-type/addresses.json @@ -1,16 +1,16 @@ { "420110022": { - "ProxyAdmin": "0xcd18a0C04286Eba52Bb168Fa1D79133Da4856bEf", + "ProxyAdmin": "0x905C82c09B8e6f9B8a89E4840D390ea966B5e611", "ProxyAdminOwner": "0xe934Dc97E347C6aCef74364B50125bb8689c40ff", - "SystemConfigProxy": "0x5babF93aC7AFfeaE25dc1a7ad4587fDeEbba44C2", - "L1CrossDomainMessengerProxy": "0xF0e4aAcC6D039C05B827994C3FfBBBcf00085D11", - "L1StandardBridgeProxy": "0x3756BF0380E7fdABcB81f2cFb1d8022e8B798a8F", - "OptimismPortalProxy": "0xbd36ac8fB65F192dAEbCB2Dca819CB7ea7D60417", - "DisputeGameFactoryProxy": "0x298038f9E37b370d20E58706E8Ac78475b089FB2", - "DelayedWETHProxy": "0x62841F5E03a56f818BC8818c5130757acA2541A7", - "PermissionedDelayedWETHProxy": "0x62841F5E03a56f818BC8818c5130757acA2541A7", - "AnchorStateRegistryProxy": "0x333f8D607B81E880315716A815A9369B33ea6A77", - "AddressManager": "0x82D735Cc1e04fcFef24d0190F11b5253e05562AF", - "L1ERC721BridgeProxy": "0xe081aD91D049e9999d1e7006dbF025b38198B518" + "SystemConfigProxy": "0x4E0528A9dc40FEdf1C2cFc0eAA04e70E7d3d591B", + "L1CrossDomainMessengerProxy": "0x111f33844009aFA470426f21c889ebFb60730816", + "L1StandardBridgeProxy": "0x29df21707B827b026477F38233A1d9B1913e3595", + "OptimismPortalProxy": "0x94b5917bF2666E8ACe48850490B2eA86FABbEa48", + "DisputeGameFactoryProxy": "0xE1526620245355BE132E29C581c9166F85b5f243", + "DelayedWETHProxy": "0x7c85A789cc0CF7b4161d4DAFc6E22bbecFC8aE3f", + "PermissionedDelayedWETHProxy": "0x7c85A789cc0CF7b4161d4DAFc6E22bbecFC8aE3f", + "AnchorStateRegistryProxy": "0x80B0660CBFcF338b9eCb5cD0A0C0086759B05FaB", + "AddressManager": "0xcFf6C52f3E3AC2D58FC450A45AB94C2bE90bd6fa", + "L1ERC721BridgeProxy": "0xeF0a87a2FB3e1c1Aba3E4d1749B383576c780240" } } \ No newline at end of file diff --git a/src/tasks/sep/050-op-betanet-add-game-type/config.toml b/src/tasks/sep/050-op-betanet-add-game-type/config.toml index 7f66bc6861..069a318522 100644 --- a/src/tasks/sep/050-op-betanet-add-game-type/config.toml +++ b/src/tasks/sep/050-op-betanet-add-game-type/config.toml @@ -9,21 +9,21 @@ l2chains = [ # The below addresses can be found here https://github.com/ethereum-optimism/devnets/blob/main/betanets/u18-beta/u18-beta-1/chain.yaml chainId = 420110022 saltMixer = "this is a salt mixer" -systemConfig = "0x5babF93aC7AFfeaE25dc1a7ad4587fDeEbba44C2" -proxyAdmin = "0xcd18a0C04286Eba52Bb168Fa1D79133Da4856bEf" -delayedWETH = "0x62841F5E03a56f818BC8818c5130757acA2541A7" +systemConfig = "0x4E0528A9dc40FEdf1C2cFc0eAA04e70E7d3d591B" +proxyAdmin = "0x905C82c09B8e6f9B8a89E4840D390ea966B5e611" +delayedWETH = "0x7c85A789cc0CF7b4161d4DAFc6E22bbecFC8aE3f" disputeGameType = 0 -disputeAbsolutePrestate = "0x03ccb5619628eeba89d58b204aadeb2ed9f51d18ff938069dd298b9e19fb2d31" # Source: https://www.notion.so/oplabs/Betanet-2a9f153ee16280859261e3000d866ee9?source=copy_link#2c5f153ee1628012bc4dfbeaae710c70 +disputeAbsolutePrestate = "0x03f2146db42fdcf336a6980af7899a365054527e75f5d5aa33638b318a5632a2" # This is a custom prestate, as the betanets are not in the SCR. Source: https://www.notion.so/oplabs/Betanet-2a9f153ee16280859261e3000d866ee9?source=copy_link#2c5f153ee1628012bc4dfbeaae710c70 disputeMaxGameDepth = 73 disputeSplitDepth = 30 disputeClockExtension = 10800 disputeMaxClockDuration = 302400 initialBond = 80000000000000000 -vm = "0x6463dEE3828677F6270d83d45408044fc5eDB908" # Source: https://github.com/ethereum-optimism/superchain-registry/blob/ad5becd08007b80988679b8f0c08d415e1294066/validation/standard/standard-versions-sepolia.toml#L11 +vm = "0x6463dEE3828677F6270d83d45408044fc5eDB908" # Standard VM version for contracts v5.0.0. Source: https://github.com/ethereum-optimism/superchain-registry/blob/ad5becd08007b80988679b8f0c08d415e1294066/validation/standard/standard-versions-sepolia.toml#L11 permissioned = false [addresses] -OPCM = "0xc69e4c24db479191676611a25d977203c3bdca62" # https://github.com/ethereum-optimism/superchain-registry/blob/74d9bb4ad4cd8d6fd453f2e9dfe5380d97c07ca9/validation/standard/standard-versions-sepolia.toml#L23C56-L23C98 +OPCM = "0xc69e4c24db479191676611a25d977203c3bdca62" # Standard OPCM for contracts v5.0.0. Source: https://github.com/ethereum-optimism/superchain-registry/blob/74d9bb4ad4cd8d6fd453f2e9dfe5380d97c07ca9/validation/standard/standard-versions-sepolia.toml#L23C56-L23C98 [stateOverrides] 0xe934Dc97E347C6aCef74364B50125bb8689c40ff = [ diff --git a/src/tasks/sep/051-op-betanet-set-respected-game-type/README.md b/src/tasks/sep/051-op-betanet-set-respected-game-type/README.md index 7cfabcfb75..c3a5027633 100644 --- a/src/tasks/sep/051-op-betanet-set-respected-game-type/README.md +++ b/src/tasks/sep/051-op-betanet-set-respected-game-type/README.md @@ -11,11 +11,11 @@ This task sets the respected dispute game type to game type 0 (Permissionless) o Simulation commands for each safe: ```bash cd src/tasks/sep/051-op-betanet-set-respected-game-type -SIMULATE_WITHOUT_LEDGER=1 SKIP_DECODE_AND_PRINT=1 just --dotenv-path $(pwd)/.env simulate +just simulate-stack sep 051-op-betanet-set-respected-game-type ``` Signing commands for each safe: ```bash cd src/tasks/sep/051-op-betanet-set-respected-game-type SKIP_DECODE_AND_PRINT=1 just --dotenv-path $(pwd)/.env sign -``` +``` \ No newline at end of file diff --git a/src/tasks/sep/051-op-betanet-set-respected-game-type/VALIDATION.md b/src/tasks/sep/051-op-betanet-set-respected-game-type/VALIDATION.md index f2ab7625b3..1f9fde6cb5 100644 --- a/src/tasks/sep/051-op-betanet-set-respected-game-type/VALIDATION.md +++ b/src/tasks/sep/051-op-betanet-set-respected-game-type/VALIDATION.md @@ -17,15 +17,14 @@ the values printed to the terminal when you run the task. > [!CAUTION] > > -> ### Betanet EOA (`0xe934Dc97E347C6aCef74364B50125bb8689c40ff`) +> ### Betanet 1/1 Safe (`0xe934Dc97E347C6aCef74364B50125bb8689c40ff`) > > - Domain Hash: `0x07e03428d7125835eca12b6dd1a02903029b456da3a091ecd66fda859fbce61e` -> - Message Hash: `0x9e8127525f1f0fdfe412df910c50c9cd81d2a926147240dfcc9aaf20c0994e03` +> - Message Hash: `0x02ebce4af54c04ec4a2c2f1b11781266418f1cfbd38b55c867d67ce5767f9ef3` > - ## Task Calldata Calldata: ``` -0x174dea71000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000333f8d607b81e880315716a815a9369b33ea6a7700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000247fc48504000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -``` +0x174dea7100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000080b0660cbfcf338b9ecb5cd0a0c0086759b05fab00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000247fc48504000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +``` \ No newline at end of file diff --git a/src/tasks/sep/051-op-betanet-set-respected-game-type/addresses.json b/src/tasks/sep/051-op-betanet-set-respected-game-type/addresses.json index 6d2d54929e..4d6fbfb365 100644 --- a/src/tasks/sep/051-op-betanet-set-respected-game-type/addresses.json +++ b/src/tasks/sep/051-op-betanet-set-respected-game-type/addresses.json @@ -1,16 +1,16 @@ { "420110022": { - "ProxyAdmin": "0xcd18a0C04286Eba52Bb168Fa1D79133Da4856bEf", + "ProxyAdmin": "0x905C82c09B8e6f9B8a89E4840D390ea966B5e611", "ProxyAdminOwner": "0xe934Dc97E347C6aCef74364B50125bb8689c40ff", - "SystemConfigProxy": "0x5babF93aC7AFfeaE25dc1a7ad4587fDeEbba44C2", - "L1CrossDomainMessengerProxy": "0xF0e4aAcC6D039C05B827994C3FfBBBcf00085D11", - "L1StandardBridgeProxy": "0x3756BF0380E7fdABcB81f2cFb1d8022e8B798a8F", - "OptimismPortalProxy": "0xbd36ac8fB65F192dAEbCB2Dca819CB7ea7D60417", - "DisputeGameFactoryProxy": "0x298038f9E37b370d20E58706E8Ac78475b089FB2", - "DelayedWETHProxy": "0x62841F5E03a56f818BC8818c5130757acA2541A7", - "PermissionedDelayedWETHProxy": "0x62841F5E03a56f818BC8818c5130757acA2541A7", - "AnchorStateRegistryProxy": "0x333f8D607B81E880315716A815A9369B33ea6A77", - "AddressManager": "0x82D735Cc1e04fcFef24d0190F11b5253e05562AF", - "L1ERC721BridgeProxy": "0xe081aD91D049e9999d1e7006dbF025b38198B518" + "SystemConfigProxy": "0x4E0528A9dc40FEdf1C2cFc0eAA04e70E7d3d591B", + "L1CrossDomainMessengerProxy": "0x111f33844009aFA470426f21c889ebFb60730816", + "L1StandardBridgeProxy": "0x29df21707B827b026477F38233A1d9B1913e3595", + "OptimismPortalProxy": "0x94b5917bF2666E8ACe48850490B2eA86FABbEa48", + "DisputeGameFactoryProxy": "0xE1526620245355BE132E29C581c9166F85b5f243", + "DelayedWETHProxy": "0x7c85A789cc0CF7b4161d4DAFc6E22bbecFC8aE3f", + "PermissionedDelayedWETHProxy": "0x7c85A789cc0CF7b4161d4DAFc6E22bbecFC8aE3f", + "AnchorStateRegistryProxy": "0x80B0660CBFcF338b9eCb5cD0A0C0086759B05FaB", + "AddressManager": "0xcFf6C52f3E3AC2D58FC450A45AB94C2bE90bd6fa", + "L1ERC721BridgeProxy": "0xeF0a87a2FB3e1c1Aba3E4d1749B383576c780240" } } \ No newline at end of file diff --git a/src/tasks/sep/052-U18-op-betanets/README.md b/src/tasks/sep/052-U18-op-betanets/README.md index d2f22bd988..1e94e8b02f 100644 --- a/src/tasks/sep/052-U18-op-betanets/README.md +++ b/src/tasks/sep/052-U18-op-betanets/README.md @@ -19,4 +19,4 @@ just --dotenv-path $(pwd)/.env simulate USE_KEYSTORE=1 just --dotenv-path $(pwd)/.env sign # or USE_KEYSTORE=1 just sign-stack sep 052-U18-op-betanets SIGNATURES=0x just execute -``` +``` \ No newline at end of file diff --git a/src/tasks/sep/052-U18-op-betanets/VALIDATION.md b/src/tasks/sep/052-U18-op-betanets/VALIDATION.md index f737401080..a0b06b2b71 100644 --- a/src/tasks/sep/052-U18-op-betanets/VALIDATION.md +++ b/src/tasks/sep/052-U18-op-betanets/VALIDATION.md @@ -7,13 +7,12 @@ the values printed to the terminal when you run the task. > > Before signing, ensure the below hashes match what is on your ledger. > -> ### Betanet Proxy Admin Owner (`0xe934Dc97E347C6aCef74364B50125bb8689c40ff`) +> ### Betanet 1/1 Safe (`0xe934Dc97E347C6aCef74364B50125bb8689c40ff`) > > - Domain Hash: `0x07e03428d7125835eca12b6dd1a02903029b456da3a091ecd66fda859fbce61e` -> - Message Hash: `0xea39832549b35e6ff015f3138f1216b7dd1bfea74d4192ebbf5de3d9451114e7` - +> - Message Hash: `0xb68f6205d8b418ecc98bc9c282da194412afb73217d13c6a9839312b033efacc` ## Task Calldata ``` -0x82ad56cb000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000f0a2e224519e876979ea6b2cd15ef5cc3d6703bd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000104cbeda5a700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000571d97509f51d7911ca51092f51c0a57d591a8f303845751c66672c0b09e68ba7c3024a7543a1a22edaa90d7c2c90ebc8cecee6803f833cc2a644a9f7bba9718c13f622b867c513f3c43f3eb5a0cad17784bd4080000000000000000000000005babf93ac7affeae25dc1a7ad4587fdeebba44c203845751c66672c0b09e68ba7c3024a7543a1a22edaa90d7c2c90ebc8cecee6803f833cc2a644a9f7bba9718c13f622b867c513f3c43f3eb5a0cad17784bd40800000000000000000000000000000000000000000000000000000000 -``` +0x82ad56cb000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000f0a2e224519e876979ea6b2cd15ef5cc3d6703bd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000104cbeda5a700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c9f4bce265966df2591d580b6b1461f67bbebb990305724f88c14328429fa82f36637347b4e7a7dc0eb2e2aaf4ba8e87ada246ae03783ce7584a957a1f11a831f8dd735a54cdc54e9ad94ac78a20714e131eebc50000000000000000000000004e0528a9dc40fedf1c2cfc0eaa04e70e7d3d591b0305724f88c14328429fa82f36637347b4e7a7dc0eb2e2aaf4ba8e87ada246ae03783ce7584a957a1f11a831f8dd735a54cdc54e9ad94ac78a20714e131eebc500000000000000000000000000000000000000000000000000000000 +``` \ No newline at end of file diff --git a/src/tasks/sep/052-U18-op-betanets/addresses.json b/src/tasks/sep/052-U18-op-betanets/addresses.json index a30a8be617..f10f874d5c 100644 --- a/src/tasks/sep/052-U18-op-betanets/addresses.json +++ b/src/tasks/sep/052-U18-op-betanets/addresses.json @@ -1,36 +1,36 @@ { "420110021": { - "ProxyAdmin": "0x5402a671527d2Bbde2C271862FC02B3f39531059", + "ProxyAdmin": "0x7bF1bbaEfeF23cD67eC8223c28f5ae6F864eD200", "ProxyAdminOwner": "0xe934Dc97E347C6aCef74364B50125bb8689c40ff", - "SystemConfigProxy": "0x571d97509f51d7911cA51092F51c0A57d591a8F3", - "L1CrossDomainMessengerProxy": "0xe3FCcA78f39948eD8170fE04698F1e26a2551466", - "L1StandardBridgeProxy": "0x0Bfe4ccb44bd4591BD106345eec8473B4036A976", - "OptimismPortalProxy": "0x03E9Cbd5742D2462C3b6FAD5de0b0F599444d16a", - "DisputeGameFactoryProxy": "0xF97985C58B7E520Bd0215C11BB51Ac46475F0F87", - "DelayedWETHProxy": "0xd2254B347c4A9ce6eF4C245FC83b4F2285e8b212", - "PermissionedDelayedWETHProxy": "0xd2254B347c4A9ce6eF4C245FC83b4F2285e8b212", - "AnchorStateRegistryProxy": "0x3805CB4B2b3f7edBaA2A788b50Dd5264AB0756e3", - "AddressManager": "0xF52FA3816db753E3BF7Db8cd6134258592F0bF51", - "L1ERC721BridgeProxy": "0x7Be332D7b7F7c28dE79cE28b36F17F3C0ad31ce2", + "SystemConfigProxy": "0xC9F4Bce265966dF2591D580B6B1461f67BBeBB99", + "L1CrossDomainMessengerProxy": "0xc46fB4d2A818F78E64c189450903205C4e5af863", + "L1StandardBridgeProxy": "0x7F20fd209C196ff90B5f72523B192e887C958010", + "OptimismPortalProxy": "0x6Dc2424C452e40C3589A9b7D3C91458665a1f9Fb", + "DisputeGameFactoryProxy": "0x2737a7dE033A6489d59C4ef3f71F4ee456064B72", + "DelayedWETHProxy": "0x7d83cDc6c3D97d12F8f845c86614C3ABC90B7bFB", + "PermissionedDelayedWETHProxy": "0x7d83cDc6c3D97d12F8f845c86614C3ABC90B7bFB", + "AnchorStateRegistryProxy": "0x7caC1cab307f4513C1234d3a5cdF096F713d4A40", + "AddressManager": "0x29E19ccc5047659bA4C2D25cd4cF0E9c874eAa2F", + "L1ERC721BridgeProxy": "0x2bE8f56C704b93959e1c356d72BDe0685F7CB1Db", "Proposer": "0x87af2830e8A39a76261f7ed515EE4a3451105561", "Challenger": "0x839057B2F150b4720d47771B9D9e51D79f3E4B38", - "OptimismMintableERC20FactoryProxy": "0xC09189bC7A60248b625Eca79d4f3446Ca1Bbc64f" + "OptimismMintableERC20FactoryProxy": "0xCf5029Ff58Be52b840a6B5a7890F5671Ddd7577F" }, "420110022": { - "ProxyAdmin": "0xcd18a0C04286Eba52Bb168Fa1D79133Da4856bEf", + "ProxyAdmin": "0x905C82c09B8e6f9B8a89E4840D390ea966B5e611", "ProxyAdminOwner": "0xe934Dc97E347C6aCef74364B50125bb8689c40ff", - "SystemConfigProxy": "0x5babF93aC7AFfeaE25dc1a7ad4587fDeEbba44C2", - "L1CrossDomainMessengerProxy": "0xF0e4aAcC6D039C05B827994C3FfBBBcf00085D11", - "L1StandardBridgeProxy": "0x3756BF0380E7fdABcB81f2cFb1d8022e8B798a8F", - "OptimismPortalProxy": "0xbd36ac8fB65F192dAEbCB2Dca819CB7ea7D60417", - "DisputeGameFactoryProxy": "0x298038f9E37b370d20E58706E8Ac78475b089FB2", - "DelayedWETHProxy": "0x62841F5E03a56f818BC8818c5130757acA2541A7", - "PermissionedDelayedWETHProxy": "0x62841F5E03a56f818BC8818c5130757acA2541A7", - "AnchorStateRegistryProxy": "0x333f8D607B81E880315716A815A9369B33ea6A77", - "AddressManager": "0x82D735Cc1e04fcFef24d0190F11b5253e05562AF", - "L1ERC721BridgeProxy": "0xe081aD91D049e9999d1e7006dbF025b38198B518", + "SystemConfigProxy": "0x4E0528A9dc40FEdf1C2cFc0eAA04e70E7d3d591B", + "L1CrossDomainMessengerProxy": "0x111f33844009aFA470426f21c889ebFb60730816", + "L1StandardBridgeProxy": "0x29df21707B827b026477F38233A1d9B1913e3595", + "OptimismPortalProxy": "0x94b5917bF2666E8ACe48850490B2eA86FABbEa48", + "DisputeGameFactoryProxy": "0xE1526620245355BE132E29C581c9166F85b5f243", + "DelayedWETHProxy": "0x7c85A789cc0CF7b4161d4DAFc6E22bbecFC8aE3f", + "PermissionedDelayedWETHProxy": "0x7c85A789cc0CF7b4161d4DAFc6E22bbecFC8aE3f", + "AnchorStateRegistryProxy": "0x80B0660CBFcF338b9eCb5cD0A0C0086759B05FaB", + "AddressManager": "0xcFf6C52f3E3AC2D58FC450A45AB94C2bE90bd6fa", + "L1ERC721BridgeProxy": "0xeF0a87a2FB3e1c1Aba3E4d1749B383576c780240", "Proposer": "0x39Ff903Ca8a3d759dE9A7502D9C3B5Ef8A8e6670", "Challenger": "0xd9f48B7D3e1Ff4A1d4877834aaCAC9d1d6230d8E", - "OptimismMintableERC20FactoryProxy": "0xB1453F648E22c4DEB2FdEDA840E5Af42Ef9ea49a" + "OptimismMintableERC20FactoryProxy": "0xC4a0Cc8b2E99B8048b5d5D473EBbAe54E15A7355" } } \ No newline at end of file diff --git a/src/tasks/sep/052-U18-op-betanets/config.toml b/src/tasks/sep/052-U18-op-betanets/config.toml index a27186727d..f913ff0f28 100644 --- a/src/tasks/sep/052-U18-op-betanets/config.toml +++ b/src/tasks/sep/052-U18-op-betanets/config.toml @@ -13,9 +13,9 @@ templateName = "OPCMUpgradeV600" [[opcmUpgrades]] chainId = 420110021 -# U18 prestates from betanet: https://www.notion.so/oplabs/Betanet-2a9f153ee16280859261e3000d866ee9?source=copy_link#2c5f153ee162805abcc3e949ab6c837e -cannonPrestate = "0x03f833cc2a644a9f7bba9718c13f622b867c513f3c43f3eb5a0cad17784bd408" -cannonKonaPrestate = "0x03845751c66672c0b09e68ba7c3024a7543a1a22edaa90d7c2c90ebc8cecee68" +# U18 prestates for betanet: https://www.notion.so/oplabs/Betanet-2a9f153ee16280859261e3000d866ee9?source=copy_link#2c5f153ee162805abcc3e949ab6c837e +cannonPrestate = "0x03783ce7584a957a1f11a831f8dd735a54cdc54e9ad94ac78a20714e131eebc5" +cannonKonaPrestate = "0x0305724f88c14328429fa82f36637347b4e7a7dc0eb2e2aaf4ba8e87ada246ae" expectedValidationErrors = "OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER,SYSCON-130,PLDG-10,CKDG-10" # OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER: these are expected as they are not the standard OP Sepolia ones # SYSCON-130: this is expected as the SystemConfig proxyAdmin on betanets is not the standard OP Sepolia one @@ -24,15 +24,15 @@ expectedValidationErrors = "OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER,SYSCON- [[opcmUpgrades]] chainId = 420110022 -# U18 prestates from betanet: https://www.notion.so/oplabs/Betanet-2a9f153ee16280859261e3000d866ee9?source=copy_link#2c5f153ee162805abcc3e949ab6c837e -cannonPrestate = "0x03f833cc2a644a9f7bba9718c13f622b867c513f3c43f3eb5a0cad17784bd408" -cannonKonaPrestate = "0x03845751c66672c0b09e68ba7c3024a7543a1a22edaa90d7c2c90ebc8cecee68" +# U18 prestates for betanet: https://www.notion.so/oplabs/Betanet-2a9f153ee16280859261e3000d866ee9?source=copy_link#2c5f153ee162805abcc3e949ab6c837e +cannonPrestate = "0x03783ce7584a957a1f11a831f8dd735a54cdc54e9ad94ac78a20714e131eebc5" +cannonKonaPrestate = "0x0305724f88c14328429fa82f36637347b4e7a7dc0eb2e2aaf4ba8e87ada246ae" expectedValidationErrors = "OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER,SYSCON-130" # OVERRIDES-L1PAOMULTISIG,OVERRIDES-CHALLENGER: these are expected as they are not the standard OP Sepolia ones # SYSCON-130: this is expected as the SystemConfig proxyAdmin on betanets is not the standard OP Sepolia one [addresses] -OPCM = "0xf0a2e224519e876979ea6b2cd15ef5cc3d6703bd" # v600 OPCM source: https://www.notion.so/oplabs/Upgrade-18-Hub-2a3f153ee1628173bfe4f732657e4f01?source=copy_link#2cef153ee162806482fceb958964651e +OPCM = "0xf0a2e224519e876979ea6b2cd15ef5cc3d6703bd" # v600 OPCM source: https://github.com/ethereum-optimism/superchain-registry/blob/c84ed822ae5a65500d8c0e323460fa688cfcca22/validation/standard/standard-versions-sepolia.toml#L23C56-L23C98 [stateOverrides] From 80c275d028ed7a33a1fdd1a074f6d554336734cf Mon Sep 17 00:00:00 2001 From: Wazabie <48911235+Wazabie@users.noreply.github.com> Date: Wed, 7 Jan 2026 18:58:41 +0100 Subject: [PATCH 3/4] Update U18 beta task status (#1331) Update U18 beta task status --- src/tasks/sep/050-op-betanet-add-game-type/README.md | 2 +- src/tasks/sep/051-op-betanet-set-respected-game-type/README.md | 2 +- src/tasks/sep/052-U18-op-betanets/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tasks/sep/050-op-betanet-add-game-type/README.md b/src/tasks/sep/050-op-betanet-add-game-type/README.md index cf4c8e6ef9..bb051f29b9 100644 --- a/src/tasks/sep/050-op-betanet-add-game-type/README.md +++ b/src/tasks/sep/050-op-betanet-add-game-type/README.md @@ -1,6 +1,6 @@ # 050-op-betanet-add-game-type -Status: [READY TO SIGN] +Status: [EXECUTED](https://sepolia.etherscan.io/tx/0xe9d6af9325d78cbb17e8cc6f054d66f38f26b09059b979dd076b97a87ec6dd52) ## Objective diff --git a/src/tasks/sep/051-op-betanet-set-respected-game-type/README.md b/src/tasks/sep/051-op-betanet-set-respected-game-type/README.md index c3a5027633..ac2f48b376 100644 --- a/src/tasks/sep/051-op-betanet-set-respected-game-type/README.md +++ b/src/tasks/sep/051-op-betanet-set-respected-game-type/README.md @@ -1,6 +1,6 @@ # 051-op-betanet-set-respected-game-type -Status: [READY TO SIGN] +Status: [EXECUTED](https://sepolia.etherscan.io/tx/0x17db07eb40cd403162359e1575a773691553bfc8529f1bd773e3cfa56c04833e) ## Objective diff --git a/src/tasks/sep/052-U18-op-betanets/README.md b/src/tasks/sep/052-U18-op-betanets/README.md index 1e94e8b02f..ec57ce56d9 100644 --- a/src/tasks/sep/052-U18-op-betanets/README.md +++ b/src/tasks/sep/052-U18-op-betanets/README.md @@ -1,6 +1,6 @@ # 052-U18-op-betanets -Status: [READY TO SIGN] +Status: [EXECUTED](https://sepolia.etherscan.io/tx/0x53e6a4664fc3f33ddfa4fc1fee610ba86d8eb55198701371796d420f66b1ce50) ## Objective From 78b72c881692a00a6b5f59a3ba2fdc8b9009e6da Mon Sep 17 00:00:00 2001 From: Matt Solomon Date: Fri, 9 Jan 2026 13:31:37 -0800 Subject: [PATCH 4/4] ci/fix: add lint rule to detect non-alphabetical struct field ordering in TOML/JSON parsing (#1335) * ci: add script and check for proper struct ordering * fix: struct field ordering in OPCMUpgradeV600 * test: fix regression test, calldata changed * chore: revert chmod change --- .circleci/config.yml | 16 +- src/script/check-struct-order.sh | 209 +++++++++++++++++ src/template/OPCMUpgradeV600.sol | 2 +- test/script/test-check-struct-order.sh | 296 +++++++++++++++++++++++++ {src => test}/script/test-just-new.sh | 0 test/tasks/Regression.t.sol | 6 +- 6 files changed, 523 insertions(+), 6 deletions(-) create mode 100755 src/script/check-struct-order.sh create mode 100755 test/script/test-check-struct-order.sh rename {src => test}/script/test-just-new.sh (100%) diff --git a/.circleci/config.yml b/.circleci/config.yml index b1feb16c51..68e6f8de62 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -168,8 +168,7 @@ jobs: - utils/checkout-with-mise - run: name: just new recipe tests - command: | - (cd src/ && bash script/test-just-new.sh) + command: (cd src/ && bash ../test/script/test-just-new.sh) print_versions: docker: @@ -202,6 +201,18 @@ jobs: - run: name: check task names command: (cd src/script && ./check-task-names.sh) + # Check that structs used with JSON/TOML parseRaw have alphabetically ordered fields. + # This prevents a subtle bug where Foundry's parseRaw orders keys alphabetically, + # causing abi.decode to assign values to wrong fields if struct fields aren't sorted. See: + # https://getfoundry.sh/reference/cheatcodes/parse-toml/#decoding-toml-tables-into-solidity-structs + check_struct_order: + docker: + - image: <> + steps: + - utils/checkout-with-mise + - run: + name: check struct field ordering + command: (cd src/script && ./check-struct-order.sh) close-issue: machine: image: ubuntu-2204:2024.08.1 @@ -256,6 +267,7 @@ workflows: context: - circleci-repo-readonly-authenticated-github-token - check_task_names + - check_struct_order # Verify that all tasks have a valid status in their README. - check_task_statuses: context: diff --git a/src/script/check-struct-order.sh b/src/script/check-struct-order.sh new file mode 100755 index 0000000000..d441464959 --- /dev/null +++ b/src/script/check-struct-order.sh @@ -0,0 +1,209 @@ +#!/bin/bash +set -eo pipefail + +# --------------------------------------------- +# Script to detect structs used with TOML/JSON parseRaw that have +# non-alphabetically ordered fields. +# +# When Foundry's parseRaw() converts TOML/JSON to ABI-encoded bytes, +# it orders struct fields ALPHABETICALLY by key name. If the Solidity +# struct fields are not in alphabetical order, abi.decode() will +# assign values to the wrong fields. See: +# https://getfoundry.sh/reference/cheatcodes/parse-toml/#decoding-toml-tables-into-solidity-structs +# +# This script: +# 1. Finds all abi.decode() calls with parseRaw/parseToml/parseJson +# 2. Extracts the struct type being decoded into +# 3. Finds the struct definition +# 4. Verifies fields are in alphabetical order +# +# Usage: Run from any directory inside the git repo. +# --------------------------------------------- + +# Get the root directory of the git repo +root_dir=$(git rev-parse --show-toplevel) +src_dir="$root_dir/src" +exit_code=0 + +# Colors for output (disabled if not a terminal) +if [ -t 1 ]; then + RED='\033[0;31m' + GREEN='\033[0;32m' + YELLOW='\033[0;33m' + NC='\033[0m' # No Color +else + RED='' + GREEN='' + YELLOW='' + NC='' +fi + +# Primitive types to skip - these don't have named fields, so alphabetical +# ordering doesn't apply. Only structs with named fields can have the bug. +# Example: abi.decode(..., (address[])) is safe, but abi.decode(..., (MyStruct[])) needs checking. +# Pattern matches: address, bool, string, bytes, uint8-uint256, int8-int256, bytes1-bytes32 +PRIMITIVE_TYPES="address|bool|string|bytes|uint[0-9]+|int[0-9]+|bytes[0-9]+" + +# Function to extract struct field names from a file +# Args: $1 = file path, $2 = struct name +# Returns: newline-separated field names +extract_struct_fields() { + local file=$1 + local struct_name=$2 + + # Use awk to extract the struct body (handles indented closing brace) + # Then grep for field declarations: ; or [] ; + awk "/struct ${struct_name} \\{/,/^[[:space:]]*\\}/" "$file" 2>/dev/null | \ + grep -E '^[[:space:]]+[A-Za-z][A-Za-z0-9_]*(\[\])?[[:space:]]+[a-z][A-Za-z0-9_]*;' | \ + awk '{print $2}' | \ + sed 's/;//g' +} + +# Function to find struct definition file +# Args: $1 = struct name, $2 = starting file (to check first) +# Returns: file path containing the struct, or empty if not found +find_struct_file() { + local struct_name=$1 + local start_file=$2 + + # First check the starting file + if grep -q "struct ${struct_name} {" "$start_file" 2>/dev/null; then + echo "$start_file" + return + fi + + # Search in common locations + local found_file + found_file=$(grep -rl "struct ${struct_name} {" "$src_dir" 2>/dev/null | head -1) + + if [ -n "$found_file" ]; then + echo "$found_file" + fi +} + +# Function to check if fields are alphabetically ordered +# Args: field names via stdin (newline-separated) +# Returns: 0 if ordered, 1 if not +check_alphabetical_order() { + local fields + fields=$(cat) + + if [ -z "$fields" ]; then + return 0 # Empty is considered ordered + fi + + local sorted + sorted=$(echo "$fields" | sort) + + if [ "$fields" = "$sorted" ]; then + return 0 + else + return 1 + fi +} + +# Function to extract struct type from abi.decode line +# Args: $1 = line containing abi.decode +# Returns: struct type name or empty if primitive/not found +extract_struct_type() { + local line=$1 + + # Extract the type from patterns like: + # abi.decode(..., (StructName[])) + # abi.decode(..., (StructName)) + local type_match + + # Try to match (TypeName[]) or (TypeName) at the end + type_match=$(echo "$line" | sed -E 's/.*\(([A-Z][A-Za-z0-9_]+)(\[\])?\)\s*\)\s*;.*/\1/' 2>/dev/null) + + # Check if we got a valid type (starts with uppercase, not a primitive) + if [ -n "$type_match" ] && [ "$type_match" != "$line" ]; then + # Skip primitive types + if echo "$type_match" | grep -qE "^(${PRIMITIVE_TYPES})$"; then + return + fi + echo "$type_match" + fi +} + +echo "Checking TOML/JSON struct field ordering..." +echo "" + +# Find all files with abi.decode + parseRaw/parseToml/parseJson patterns +# Using a temp file for portability (process substitution behavior varies) +temp_file=$(mktemp) +checked_file=$(mktemp) +trap 'rm -f "$temp_file" "$checked_file"' EXIT + +grep -rn "abi\.decode.*\(parseRaw\|\.parseRaw\|vm\.parseToml\|vm\.parseJson\)" \ + --include="*.sol" "$src_dir" 2>/dev/null > "$temp_file" || true + +if [ ! -s "$temp_file" ]; then + echo "No TOML/JSON struct parsing patterns found." + exit 0 +fi + +while IFS= read -r match; do + # Parse the grep output: file:line:content + file=$(echo "$match" | cut -d: -f1) + line_num=$(echo "$match" | cut -d: -f2) + line_content=$(echo "$match" | cut -d: -f3-) + + # Extract struct type + struct_type=$(extract_struct_type "$line_content") + + if [ -z "$struct_type" ]; then + continue # Skip primitives or unparseable lines + fi + + # Find the struct definition file + struct_file=$(find_struct_file "$struct_type" "$file") + + if [ -z "$struct_file" ]; then + echo -e "${YELLOW}Warning: Could not find struct '$struct_type' (used in $file:$line_num)${NC}" + continue + fi + + # Create a unique key for this struct+file combination + check_key="${struct_type}:${struct_file}" + + # Skip if we've already checked this combination (use grep on temp file) + if grep -qF "$check_key" "$checked_file" 2>/dev/null; then + continue + fi + echo "$check_key" >> "$checked_file" + + # Extract and check field ordering + fields=$(extract_struct_fields "$struct_file" "$struct_type") + + if [ -z "$fields" ]; then + echo -e "${YELLOW}Warning: Could not extract fields from struct '$struct_type' in $struct_file${NC}" + continue + fi + + if echo "$fields" | check_alphabetical_order; then + echo -e "${GREEN}OK${NC} $struct_type (in ${struct_file#"$root_dir"/})" + else + echo -e "${RED}FAIL${NC} $struct_type (in ${struct_file#"$root_dir"/})" + echo " Fields are not in alphabetical order!" + echo " Current order: $(echo "$fields" | tr '\n' ' ')" + echo " Expected order: $(echo "$fields" | sort | tr '\n' ' ')" + echo "" + exit_code=1 + fi +done < "$temp_file" + +echo "" +if [ $exit_code -eq 0 ]; then + echo -e "${GREEN}All TOML/JSON-parsed structs have correctly ordered fields.${NC}" +else + echo -e "${RED}[FAIL] Some structs have incorrectly ordered fields! See above for details.${NC}" + echo "" + echo "To fix: Reorder the struct fields to be in alphabetical order." + echo "This is required because Foundry's parseRaw()/parseToml()/parseJson()" + echo "orders keys alphabetically when converting to ABI-encoded bytes." + echo "" + echo "See: https://getfoundry.sh/reference/cheatcodes/parse-toml/#decoding-toml-tables-into-solidity-structs" +fi + +exit $exit_code diff --git a/src/template/OPCMUpgradeV600.sol b/src/template/OPCMUpgradeV600.sol index 4feaef5971..e0715b43f3 100644 --- a/src/template/OPCMUpgradeV600.sol +++ b/src/template/OPCMUpgradeV600.sol @@ -18,8 +18,8 @@ contract OPCMUpgradeV600 is OPCMTaskBase { /// @notice Struct to store inputs data for each L2 chain. struct OPCMUpgrade { - Claim cannonPrestate; Claim cannonKonaPrestate; + Claim cannonPrestate; uint256 chainId; string expectedValidationErrors; } diff --git a/test/script/test-check-struct-order.sh b/test/script/test-check-struct-order.sh new file mode 100755 index 0000000000..7f4c1ed1f3 --- /dev/null +++ b/test/script/test-check-struct-order.sh @@ -0,0 +1,296 @@ +#!/bin/bash +set -eo pipefail + +# --------------------------------------------- +# Test script for check-struct-order.sh +# +# Creates temporary Solidity files with various struct patterns +# and verifies the check script correctly identifies: +# - Structs with alphabetically ordered fields (should pass) +# - Structs with non-alphabetically ordered fields (should fail) +# +# Usage: Run from any directory inside the git repo. +# --------------------------------------------- + +# Get the repo root and script directories +repo_root="$(git rev-parse --show-toplevel)" +src_script_dir="$repo_root/src/script" + +echo "Running check-struct-order.sh tests..." +echo "" + +# Track test results +tests_passed=0 +tests_failed=0 + +# Track temp directories for cleanup +temp_dirs="" + +# shellcheck disable=SC2317,SC2329 # cleanup is called via trap +cleanup() { + for dir in $temp_dirs; do + [ -d "$dir" ] && rm -rf "$dir" + done +} +trap cleanup EXIT + +# Helper function to run a test case +# Args: $1 = test name, $2 = expected result (pass|fail), $3 = file content +run_test() { + local test_name=$1 + local expected=$2 + local content=$3 + + # Create a fresh temp directory for this test + local test_dir + test_dir=$(mktemp -d) + temp_dirs="$temp_dirs $test_dir" + + # Create test file + local test_file="$test_dir/src/template/Test${test_name}.sol" + mkdir -p "$(dirname "$test_file")" + echo "$content" > "$test_file" + + # Initialize git repo + (cd "$test_dir" && git init -q) > /dev/null 2>&1 + + # Run the check script from the test directory + local result + if (cd "$test_dir" && "$src_script_dir/check-struct-order.sh") > /dev/null 2>&1; then + result="pass" + else + result="fail" + fi + + # Check result + if [ "$result" = "$expected" ]; then + echo " PASS: $test_name (expected $expected, got $result)" + tests_passed=$((tests_passed + 1)) + else + echo " FAIL: $test_name (expected $expected, got $result)" + tests_failed=$((tests_failed + 1)) + fi +} + +echo "=== Test Cases ===" +echo "" + +# Test 1: Alphabetically ordered struct (should pass) +run_test "AlphabeticalOrder" "pass" ' +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {stdToml} from "forge-std/StdToml.sol"; + +contract TestAlphabeticalOrder { + using stdToml for string; + + struct Config { + address addr; + uint256 chainId; + string name; + } + + function setup(string memory toml) internal { + Config[] memory configs = abi.decode(toml.parseRaw(".configs"), (Config[])); + } +} +' + +# Test 2: Non-alphabetically ordered struct (should fail) +run_test "NonAlphabeticalOrder" "fail" ' +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {stdToml} from "forge-std/StdToml.sol"; + +contract TestNonAlphabeticalOrder { + using stdToml for string; + + struct Config { + string name; + address addr; + uint256 chainId; + } + + function setup(string memory toml) internal { + Config[] memory configs = abi.decode(toml.parseRaw(".configs"), (Config[])); + } +} +' + +# Test 3: Primitive array (should pass - no struct to check) +run_test "PrimitiveArray" "pass" ' +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {stdToml} from "forge-std/StdToml.sol"; + +contract TestPrimitiveArray { + using stdToml for string; + + function setup(string memory toml) internal { + address[] memory addrs = abi.decode(toml.parseRaw(".addresses"), (address[])); + uint256[] memory ids = abi.decode(toml.parseRaw(".ids"), (uint256[])); + } +} +' + +# Test 4: Single struct (not array) - alphabetical (should pass) +run_test "SingleStructAlphabetical" "pass" ' +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {VmSafe} from "forge-std/Vm.sol"; + +contract TestSingleStructAlphabetical { + VmSafe internal constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + struct Settings { + bool enabled; + uint256 value; + } + + function setup(string memory toml) internal { + Settings memory s = abi.decode(vm.parseToml(toml, ".settings"), (Settings)); + } +} +' + +# Test 5: Similar field name prefixes - wrong order (should fail) +# This is the exact bug pattern from OPCMUpgradeV600 +run_test "SimilarPrefixes" "fail" ' +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {stdToml} from "forge-std/StdToml.sol"; + +contract TestSimilarPrefixes { + using stdToml for string; + + struct Prestate { + bytes32 cannonPrestate; + bytes32 cannonKonaPrestate; + } + + function setup(string memory toml) internal { + Prestate[] memory p = abi.decode(toml.parseRaw(".prestates"), (Prestate[])); + } +} +' + +# Test 6: Similar prefixes but correct order (should pass) +run_test "SimilarPrefixesCorrect" "pass" ' +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {stdToml} from "forge-std/StdToml.sol"; + +contract TestSimilarPrefixesCorrect { + using stdToml for string; + + struct Prestate { + bytes32 cannonKonaPrestate; + bytes32 cannonPrestate; + } + + function setup(string memory toml) internal { + Prestate[] memory p = abi.decode(toml.parseRaw(".prestates"), (Prestate[])); + } +} +' + +# Test 7: No parseRaw usage (should pass - nothing to check) +run_test "NoParseRaw" "pass" ' +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +contract TestNoParseRaw { + struct Config { + string name; + address addr; + } + + function doSomething() internal pure returns (uint256) { + return 42; + } +} +' + +# Test 8: Complex types in struct (should pass if alphabetical) +run_test "ComplexTypes" "pass" ' +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {stdToml} from "forge-std/StdToml.sol"; + +contract TestComplexTypes { + using stdToml for string; + + struct GameConfig { + address[] addresses; + bytes32 gameType; + uint256[] values; + } + + function setup(string memory toml) internal { + GameConfig[] memory configs = abi.decode(toml.parseRaw(".games"), (GameConfig[])); + } +} +' + +# Test 9: JSON with stdJson.parseRaw - wrong order (should fail) +run_test "JsonWrongOrder" "fail" ' +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {stdJson} from "forge-std/StdJson.sol"; + +contract TestJsonWrongOrder { + using stdJson for string; + + struct JsonConfig { + string name; + address addr; + } + + function setup(string memory json) internal { + JsonConfig[] memory configs = abi.decode(json.parseRaw(".configs"), (JsonConfig[])); + } +} +' + +# Test 10: JSON with vm.parseJson - correct order (should pass) +run_test "JsonCorrectOrder" "pass" ' +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {VmSafe} from "forge-std/Vm.sol"; + +contract TestJsonCorrectOrder { + VmSafe internal constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + struct JsonConfig { + address addr; + string name; + } + + function setup(string memory json) internal { + JsonConfig memory config = abi.decode(vm.parseJson(json, ".config"), (JsonConfig)); + } +} +' + +echo "" +echo "=== Summary ===" +echo "Passed: $tests_passed" +echo "Failed: $tests_failed" +echo "" + +if [ $tests_failed -gt 0 ]; then + echo "Some tests failed!" + exit 1 +else + echo "All tests passed!" + exit 0 +fi diff --git a/src/script/test-just-new.sh b/test/script/test-just-new.sh similarity index 100% rename from src/script/test-just-new.sh rename to test/script/test-just-new.sh diff --git a/test/tasks/Regression.t.sol b/test/tasks/Regression.t.sol index 4a55357601..fd3831416d 100644 --- a/test/tasks/Regression.t.sol +++ b/test/tasks/Regression.t.sol @@ -878,7 +878,7 @@ contract RegressionTest is Test { function testRegressionCallDataMatches_OPCMUpgradeV600Template() public { string memory taskConfigFilePath = "test/tasks/example/sep/033-opcm-upgrade-v600/config.toml"; string memory expectedCallData = - "0x82ad56cb000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000f0a2e224519e876979ea6b2cd15ef5cc3d6703bd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a4cbeda5a700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000034edd2a225f7f429a63e0f1d2084b9e0a93b53803845751c66672c0b09e68ba7c3024a7543a1a22edaa90d7c2c90ebc8cecee6803f833cc2a644a9f7bba9718c13f622b867c513f3c43f3eb5a0cad17784bd40800000000000000000000000000000000000000000000000000000000"; + "0x82ad56cb000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000f0a2e224519e876979ea6b2cd15ef5cc3d6703bd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a4cbeda5a700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000034edd2a225f7f429a63e0f1d2084b9e0a93b53803f833cc2a644a9f7bba9718c13f622b867c513f3c43f3eb5a0cad17784bd40803845751c66672c0b09e68ba7c3024a7543a1a22edaa90d7c2c90ebc8cecee6800000000000000000000000000000000000000000000000000000000"; MultisigTask multisigTask = new OPCMUpgradeV600(); address rootSafe = address(0x1Eb2fFc903729a0F03966B917003800b145F56E2); address nestedSafe = address(0xDEe57160aAfCF04c34C887B5962D0a69676d3C8B); // sepolia @@ -891,10 +891,10 @@ contract RegressionTest is Test { string[] memory expectedDataToSign = new string[](2); // Foundation expectedDataToSign[0] = - "0x190137e1f5dd3b92a004a23589b741196c8a214629d4ea3a690ec8e41ae45c689cbbdebb61a012c61cc79de4251db4172889f9c2bea3593fdb3cf79b7016d90b88d8"; + "0x190137e1f5dd3b92a004a23589b741196c8a214629d4ea3a690ec8e41ae45c689cbb0e99c9006e46153badc324f7b1c50824fa5afe34e8b2a22b33ce602d2d3d5d8a"; // Security Council expectedDataToSign[1] = - "0x1901be081970e9fc104bd1ea27e375cd21ec7bb1eec56bfe43347c3e36c5d27b85338af46bfe0ef8d4c4dcd740b727f664c01b5d0ee612f67383466fdebaff9ae1fb"; + "0x1901be081970e9fc104bd1ea27e375cd21ec7bb1eec56bfe43347c3e36c5d27b8533f37689cf5b2227f8ba807d4618c41f8dac247be9429d1c5339241e2a9938c16e"; _assertDataToSignNestedMultisig(multisigTask, actions, expectedDataToSign, MULTICALL3_ADDRESS, rootSafe); }