Skip to content

ci/fix: add lint rule to detect non-alphabetical struct field ordering in TOML/JSON parsing#1335

Merged
maurelian merged 4 commits intomainfrom
fix/struct-order
Jan 9, 2026
Merged

ci/fix: add lint rule to detect non-alphabetical struct field ordering in TOML/JSON parsing#1335
maurelian merged 4 commits intomainfrom
fix/struct-order

Conversation

@mds1
Copy link
Copy Markdown
Contributor

@mds1 mds1 commented Jan 9, 2026

Foundry's parseRaw()/parseToml()/parseJson() orders struct fields alphabetically when converting to ABI-encoded bytes. If Solidity struct fields aren't in alphabetical order, abi.decode() assigns values to wrong fields. This caused cannonPrestate and cannonKonaPrestate to be swapped in OPCMUpgradeV600.sol.

See: https://getfoundry.sh/reference/cheatcodes/parse-toml/#decoding-toml-tables-into-solidity-structs

This PR therefore adds a CI lint rule (check-struct-order.sh) that detects this issue. CI for the first commit on this PR should fail because the bug is currently on main. Then I will push the fix and CI should pass at which point we fully validated everything works and we can merge.

This PR also moves an existing shell test script to test/script/ for better organization, but the file was unchanged

@mds1 mds1 requested review from a team as code owners January 9, 2026 18:14
@mds1 mds1 requested a review from AmadiMichael January 9, 2026 18:14
@mds1
Copy link
Copy Markdown
Contributor Author

mds1 commented Jan 9, 2026

As expected, the new check_struct_order failed in the first commit, and passed in the second commit (a regression test failed, and was fixed in the last commit, but the new check did pass). Here is what the first commit failed with

Checking TOML/JSON struct field ordering...

OK L2Chain (in src/libraries/MultisigTypes.sol)
OK AddGameInputWithChainId (in src/template/AddGameTypeTemplate.sol)
OK BlacklistGamesTaskConfig (in src/template/BlacklistGamesV140.sol)
OK BlacklistGamesTaskConfig (in src/template/BlacklistGamesV400.sol)
OK OPCMUpgrade (in src/template/OPCMUpdatePrestateV300.sol)
OK OPCMUpgrade (in src/template/OPCMUpdatePrestateV410.sol)
OK OPCMUpgrade (in src/template/OPCMUpgradeV200.sol)
OK OPCMUpgrade (in src/template/OPCMUpgradeV220toV410.sol)
OK OPCMUpgrade (in src/template/OPCMUpgradeV300.sol)
OK OPCMUpgrade (in src/template/OPCMUpgradeV400.sol)
OK OPCMUpgrade (in src/template/OPCMUpgradeV410.sol)
OK OPCMUpgrade (in src/template/OPCMUpgradeV500.sol)
FAIL OPCMUpgrade (in src/template/OPCMUpgradeV600.sol)
  Fields are not in alphabetical order!
  Current order:  cannonPrestate cannonKonaPrestate chainId expectedValidationErrors 
  Expected order: cannonKonaPrestate cannonPrestate chainId expectedValidationErrors 

OK GameImplConfig (in src/template/SetDisputeGameImpl.sol)
OK SetRespectedGameTypeTaskConfig (in src/template/SetRespectedGameTypeTemplate.sol)
OK OPCMUpgrade (in src/template/boilerplate/OPCMTaskBase.template.sol)

[FAIL] Some structs have incorrectly ordered fields! See above for details.

To fix: Reorder the struct fields to be in alphabetical order.
This is required because Foundry's parseRaw()/parseToml()/parseJson()
orders keys alphabetically when converting to ABI-encoded bytes.

See: https://getfoundry.sh/reference/cheatcodes/parse-toml/#decoding-toml-tables-into-solidity-structs

Exited with code exit status 1

Comment thread test/script/test-just-new.sh
@maurelian maurelian enabled auto-merge January 9, 2026 21:25
@maurelian maurelian added this pull request to the merge queue Jan 9, 2026
Merged via the queue into main with commit 78b72c8 Jan 9, 2026
21 checks passed
@maurelian maurelian deleted the fix/struct-order branch January 9, 2026 21:39
0xChin added a commit to defi-wonderland/superchain-ops that referenced this pull request Jan 12, 2026
* ci: update mention from evm-safety-team to security-oncall (ethereum-optimism#1328)

* Update U18 betanet tasks addresses (ethereum-optimism#1329)

* Update U18 betanet tasks addresses

* Update addresses and hashes

* Update U18 beta task status (ethereum-optimism#1331)

Update U18 beta task status

* ci/fix: add lint rule to detect non-alphabetical struct field ordering in TOML/JSON parsing (ethereum-optimism#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

---------

Co-authored-by: Matt Solomon <matt@mattsolomon.dev>
Co-authored-by: Wazabie <48911235+Wazabie@users.noreply.github.com>
0xChin added a commit to defi-wonderland/superchain-ops that referenced this pull request Jan 12, 2026
* ci: update mention from evm-safety-team to security-oncall (ethereum-optimism#1328)

* Update U18 betanet tasks addresses (ethereum-optimism#1329)

* Update U18 betanet tasks addresses

* Update addresses and hashes

* Update U18 beta task status (ethereum-optimism#1331)

Update U18 beta task status

* ci/fix: add lint rule to detect non-alphabetical struct field ordering in TOML/JSON parsing (ethereum-optimism#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

---------

Co-authored-by: Matt Solomon <matt@mattsolomon.dev>
Co-authored-by: Wazabie <48911235+Wazabie@users.noreply.github.com>
github-merge-queue Bot pushed a commit that referenced this pull request Jan 16, 2026
* test: add post task assertions (#111)

* test: update configs with soneium (#81)

* fix: forge fmt (#84)

* test: add post task assertions

* style: formatting

* test: receive assertions vars from env

* refactor: remove trycatch usage

* fix: build error (#88)

* fix: warning

* chore: sync prod configs (#94)

* feat: base as executed (#1312)

* feat:add worldchain sepolia key handback over task (#1284)

* feat:add worldchain sepolia key handback over task

* clean up worldchain key handback over task

* changed worldchain task number

* fix:delete task 39

replaced by task 46

* fix:update nonces

* Update src/tasks/sep/046-worldchain-l2pao-key-handback-over/README.md

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>

* fix:updated message hashes

changed after adding new nonces

* Update README.md

* fix:clean up text in sepolia validation.md

* Update src/tasks/sep/046-worldchain-l2pao-key-handback-over/VALIDATION.md

Co-authored-by: Alberto Cuesta Cañada <38806121+alcueca@users.noreply.github.com>

* ci: bump timeout because stacked sims are slow

* ci: this really shouldn’t take 90m, testing…

* Update config.toml

* Update config.yml

* feat: nonce bump

* fix: remove noGasMetering modifier which causes stacked sims to hang

I am unsure exactly why it hangs. This did not used to hang, but now it does.
Still need to better understand the root cause here

---------

Co-authored-by: Wazabie <48911235+Wazabie@users.noreply.github.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: Alberto Cuesta Cañada <38806121+alcueca@users.noreply.github.com>
Co-authored-by: Matt Solomon <matt@mattsolomon.dev>
Co-authored-by: JosepBove <josep@oplabs.co>

* Safer safes migrate to LivenessModule2 template (#1298)

* WIP on jb/safer-safes

* fix: typos

* feat: regression tests and finish template

* fmt

* fix: block

* adding solutions to sepolia task dir (#1306)

* feat: set worldchain l2pao key handback as executed on sepolia (#1315)

* test: update configs with soneium (#81) (#1309)

* test: update configs with soneium (#81)

* fix: forge fmt (#84)

* fix: build error (#88)

* fix: warning

* fix: wrong sepolia examples tasks numeration

---------

Co-authored-by: Disco <131301107+0xDiscotech@users.noreply.github.com>

---------

Co-authored-by: JosepBove <josep@oplabs.co>
Co-authored-by: Zak Ayesh <44901995+ZakAyesh@users.noreply.github.com>
Co-authored-by: Wazabie <48911235+Wazabie@users.noreply.github.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: Alberto Cuesta Cañada <38806121+alcueca@users.noreply.github.com>
Co-authored-by: Matt Solomon <matt@mattsolomon.dev>
Co-authored-by: soyboy <85043086+sbvegan@users.noreply.github.com>
Co-authored-by: Disco <131301107+0xDiscotech@users.noreply.github.com>

* refactor: consistency in integration tests structure

* test: remove min withdrawal check

* test: add post task assertions example command

* test: expect l1withdrawer address on expect emit

* refactor: change hardcoded variables to environment

* refactor: move reused code to internal integration base functions

* chore: update tasks config values

* fix: remove wrong config

* feat: add production task (#98)

* test: add L2ToL1 message relaying

* test: use fusaka block numbers and update regression tests

* fix: sep task order on name

* fix: integration and stack simulate tests (#100)

* test: update tests

* test: use deployed contracts upgrader

* chore: remove unused vars

* chore: remove unused vars

* fix: update message hashes

* fix: reduce upgrade gas limit (#102)

* chore: update gas limit on examples as well

* chore: improve L1 RPC example

* test: add L1ToL2 message relaying

* fix: sep council msg hash based on stacked simulation (#103)

* fix: recipient in OP after FeesDepositor deposit

* fix: add nonce overrides in sepolia task, fix hash in eth task (#106)

* fix: remove pao nonce update on 048 and msg hashes (#107)

* chore: increase gas cost on message relaying

* fix: wrong address for TransactionDeposited event

---------

Co-authored-by: Disco <131301107+0xDiscotech@users.noreply.github.com>
Co-authored-by: JosepBove <josep@oplabs.co>
Co-authored-by: Zak Ayesh <44901995+ZakAyesh@users.noreply.github.com>
Co-authored-by: Wazabie <48911235+Wazabie@users.noreply.github.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: Alberto Cuesta Cañada <38806121+alcueca@users.noreply.github.com>
Co-authored-by: Matt Solomon <matt@mattsolomon.dev>
Co-authored-by: soyboy <85043086+sbvegan@users.noreply.github.com>

* fix: op fork id

* refactor: improve assertions (#119)

* fix: query l1 withdrawer instead of calculating it

* fix: remove mainnet from op url name since it can be testnet as well

* refactor: improve withdrawal assertions using below and above threshold

* fix: receive op cdm as input instead of hardcoding mainnet

* fix: rounding error on assertion

* chore: replace mainnet hardcoded values for env inputs

* chore: create strcuts to organize inputs and remove some mainnet defaults

* chore: polish

* chore: sync assertions (#120)

* ci: update mention from evm-safety-team to security-oncall (#1328)

* Update U18 betanet tasks addresses (#1329)

* Update U18 betanet tasks addresses

* Update addresses and hashes

* Update U18 beta task status (#1331)

Update U18 beta task status

* 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

---------

Co-authored-by: Matt Solomon <matt@mattsolomon.dev>
Co-authored-by: Wazabie <48911235+Wazabie@users.noreply.github.com>

* Revert "chore: sync assertions (#120)"

This reverts commit db61257.

* Merge pull request #124 from defi-wonderland/chore/improve-example-args

chore: improve example args

* Merge pull request #129 from defi-wonderland/fix/address-comments

fix: address comments

---------

Co-authored-by: Disco <131301107+0xDiscotech@users.noreply.github.com>
Co-authored-by: JosepBove <josep@oplabs.co>
Co-authored-by: Zak Ayesh <44901995+ZakAyesh@users.noreply.github.com>
Co-authored-by: Wazabie <48911235+Wazabie@users.noreply.github.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: Alberto Cuesta Cañada <38806121+alcueca@users.noreply.github.com>
Co-authored-by: Matt Solomon <matt@mattsolomon.dev>
Co-authored-by: soyboy <85043086+sbvegan@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants