Skip to content

update deps and add check bytecode hash#13

Merged
thedavidmeister merged 6 commits intomainfrom
2026-01-23-check-cbor
Jan 25, 2026
Merged

update deps and add check bytecode hash#13
thedavidmeister merged 6 commits intomainfrom
2026-01-23-check-cbor

Conversation

@thedavidmeister
Copy link
Contributor

@thedavidmeister thedavidmeister commented Jan 23, 2026

Motivation

Solution

Checks

By submitting this for review, I'm confirming I've done the following:

  • made this PR as small as possible
  • unit-tested any new functionality
  • linked any relevant issues or PRs
  • included screenshots (if this involves a front-end change)

Summary by CodeRabbit

  • New Features

    • Improved error reporting for bytecode validation and a CBOR-trimmed bytecode hash verification routine.
  • Behavior Changes

    • Interpreter opcode classifications updated: expanded non-static allowances and tightened disallowed ops.
  • Tests

    • New and updated tests for bytecode hash checks, fork helper addition, several test renames and assertion adjustments.
  • Chores

    • Updated submodule pointers, .gitignore entry adjusted, benchmark gas snapshots refreshed, minor formatting tweaks, and CI env var added.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 23, 2026

Walkthrough

Updates two git submodule pointers, expands interpreter opcode allow/disallow sets, adds bytecode-validation errors and an internal bytecode-check, introduces a Forge Arbitrum fork helper and tests, and applies assorted test, formatting, .gitignore, and .gas-snapshot edits. (50 words)

Changes

Cohort / File(s) Summary
Submodule updates
lib/forge-std, lib/rain.solmem
Bumped tracked commits for two git submodules; pointer-only changes (no functional edits).
Bytecode validation
src/lib/LibExtrospectBytecode.sol
Added errors MetadataNotTrimmed() and BytecodeHashMismatch(bytes32 expected, bytes32 actual); changed trimSolidityCBORMetadata(bytes memory) to return bool didTrim; added internal view checkCBORTrimmedBytecodeHash(address, bytes32) that trims metadata, enforces trimming, and verifies keccak256 hash (reverts on failure).
Interpreter opcode sets
src/interface/IExtrospectInterpreterV1.sol
Expanded NON_STATIC_OPS to include LOG0LOG4, SSTORE, SELFDESTRUCT, CALL; expanded INTERPRETER_DISALLOWED_OPS to add SLOAD, DELEGATECALL, CALLCODE, CALL.
Tests & test helpers
test/lib/LibExtrospectTestProd.sol, test/src/lib/LibExtrospectBytecode.checkCBORTrimmedBytecodeHash.t.sol, test/src/lib/LibExtrospectBytecode.scanEVMOpcodesPresentInBytecode.t.sol, test/src/lib/LibExtrospectBytecode.scanEVMOpcodesReachableInBytecode.t.sol, test/src/lib/LibExtrospectBytecode.trimSolidityCBORMetadata.t.sol
Added Forge Arbitrum fork helper and new tests for checkCBORTrimmedBytecodeHash; renamed a test contract; replaced an assertEq with vm.assume; whitespace/formatting tweaks in tests.
Misc / formatting / config
src/lib/EVMOpcodes.sol, src/lib/LibExtrospectERC1167Proxy.sol, .gitignore, .gas-snapshot, test/src/concrete/Extrospection.ERC1167Proxy.t.sol, .github/workflows/rainix.yaml
Minor formatting/assembly whitespace edits; .gitignore updated (removed out, ensured cache, added .env); .gas-snapshot entries rebased/updated; concrete test adjusted preconditions (tighter proxy bound and proxy.code.length == 0 assume); CI workflow env var RPC_URL_ARBITRUM_FORK added.

Sequence Diagram(s)

sequenceDiagram
    participant Test as Test (caller)
    participant Lib as LibExtrospectBytecode
    participant EVM as EVM / Account

    Test->>Lib: checkCBORTrimmedBytecodeHash(account, expectedHash)
    Lib->>EVM: retrieve account bytecode
    EVM-->>Lib: bytecode
    Lib->>Lib: trimSolidityCBORMetadata(bytecode) -> (trimmed, didTrim)
    alt didTrim == false
        Lib-->>Test: revert MetadataNotTrimmed()
    else didTrim == true
        Lib->>Lib: compute keccak256(trimmed) -> actualHash
        alt actualHash != expectedHash
            Lib-->>Test: revert BytecodeHashMismatch(expectedHash, actualHash)
        else actualHash == expectedHash
            Lib-->>Test: return success
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

  • 2025 10 18 extrospection #11 — overlaps changes to src/lib/LibExtrospectBytecode.sol and opcode/constants; likely related to bytecode logic and interpreter opcode adjustments.
  • 2025 12 06 deps #12 — updates the lib/rain.solmem submodule pointer; related at the submodule tracking level.
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'update deps and add check bytecode hash' directly matches the main changes: submodule updates (deps) and new bytecode hash checking functionality (checkCBORTrimmedBytecodeHash).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@test/lib/LibExtrospectTestProd.sol`:
- Line 3: Update the Solidity pragma in this file to match the project's exact
version pinning: replace the caret-style pragma declaration (^0.8.25) with the
exact version (=0.8.25) in the top-level pragma statement so it is consistent
with other tests and avoids accidental compiler version drift.
- Around line 10-12: The helper function createSelectForkArbitrum currently
calls vm.envString("RPC_URL_ARBITRUM_FORK") which will revert with a generic
error if the env var is missing; update createSelectForkArbitrum to either use
vm.envOr("RPC_URL_ARBITRUM_FORK", "<placeholder_or_default>") or explicitly
check the result and revert with a clear message like "missing
RPC_URL_ARBITRUM_FORK environment variable" so test failures give a descriptive
error; refer to the createSelectForkArbitrum function and vm.envString/vm.envOr
when making the change.

@@ -0,0 +1,13 @@
// SPDX-License-Identifier: LicenseRef-DCL-1.0
// SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd
pragma solidity ^0.8.25;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Minor: Pragma version inconsistency.

This file uses ^0.8.25 (caret) while other test files in this PR use =0.8.25 (exact version pinning). Consider aligning for consistency.

♻️ Suggested fix
-pragma solidity ^0.8.25;
+pragma solidity =0.8.25;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pragma solidity ^0.8.25;
pragma solidity =0.8.25;
🤖 Prompt for AI Agents
In `@test/lib/LibExtrospectTestProd.sol` at line 3, Update the Solidity pragma in
this file to match the project's exact version pinning: replace the caret-style
pragma declaration (^0.8.25) with the exact version (=0.8.25) in the top-level
pragma statement so it is consistent with other tests and avoids accidental
compiler version drift.

Comment on lines +10 to +12
function createSelectForkArbitrum(Vm vm) internal {
vm.createSelectFork(vm.envString("RPC_URL_ARBITRUM_FORK"), PROD_TEST_BLOCK_NUMBER_ARBITRUM);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider adding a descriptive error message if the environment variable is missing.

If RPC_URL_ARBITRUM_FORK is not set, vm.envString will revert with a generic error. This could confuse developers who run tests without the proper environment setup.

♻️ Suggested improvement
 function createSelectForkArbitrum(Vm vm) internal {
+    // Will revert if RPC_URL_ARBITRUM_FORK is not set
     vm.createSelectFork(vm.envString("RPC_URL_ARBITRUM_FORK"), PROD_TEST_BLOCK_NUMBER_ARBITRUM);
 }

Alternatively, you could use vm.envOr with a fallback or add a custom revert message, but a simple comment may suffice for test helper code.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function createSelectForkArbitrum(Vm vm) internal {
vm.createSelectFork(vm.envString("RPC_URL_ARBITRUM_FORK"), PROD_TEST_BLOCK_NUMBER_ARBITRUM);
}
function createSelectForkArbitrum(Vm vm) internal {
// Will revert if RPC_URL_ARBITRUM_FORK is not set
vm.createSelectFork(vm.envString("RPC_URL_ARBITRUM_FORK"), PROD_TEST_BLOCK_NUMBER_ARBITRUM);
}
🤖 Prompt for AI Agents
In `@test/lib/LibExtrospectTestProd.sol` around lines 10 - 12, The helper function
createSelectForkArbitrum currently calls vm.envString("RPC_URL_ARBITRUM_FORK")
which will revert with a generic error if the env var is missing; update
createSelectForkArbitrum to either use vm.envOr("RPC_URL_ARBITRUM_FORK",
"<placeholder_or_default>") or explicitly check the result and revert with a
clear message like "missing RPC_URL_ARBITRUM_FORK environment variable" so test
failures give a descriptive error; refer to the createSelectForkArbitrum
function and vm.envString/vm.envOr when making the change.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@test/src/concrete/Extrospection.ERC1167Proxy.t.sol`:
- Around line 26-30: The test tightens the precompile exclusion by assuming
vm.assume(uint160(proxy) > type(uint160).max / 2) which reduces fuzz coverage
and diverges from the success test’s check; change the exclusion to match the
success test (e.g., vm.assume(uint160(proxy) > 10)) or introduce and reuse a
shared constant like PRECOMPILE_BOUND used by both tests so both extrospection
checks (the vm.assume for proxy and any corresponding checks in Extrospection
tests) consistently avoid only low precompile addresses while preserving fuzz
coverage.

Comment on lines 26 to 30
// Proxy can't be extrospection, otherwise we'll etch over it.
vm.assume(proxy != address(extrospection));
// Proxy can't be a precompile either.
vm.assume(uint160(proxy) > 10);
vm.assume(uint160(proxy) > type(uint160).max / 2);
// Force incorrect proxy implementation into the proxy address.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Align the precompile exclusion criteria between tests.

Line 29 now filters to the upper half of the address space, which sharply narrows fuzz coverage and diverges from the success test’s > 10 check. If the goal is only to avoid precompiles, keep the same explicit boundary (or a shared constant) so low-address edge cases are still exercised consistently.

♻️ Suggested tweak
-        vm.assume(uint160(proxy) > type(uint160).max / 2);
+        vm.assume(uint160(proxy) > 10);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Proxy can't be extrospection, otherwise we'll etch over it.
vm.assume(proxy != address(extrospection));
// Proxy can't be a precompile either.
vm.assume(uint160(proxy) > 10);
vm.assume(uint160(proxy) > type(uint160).max / 2);
// Force incorrect proxy implementation into the proxy address.
// Proxy can't be extrospection, otherwise we'll etch over it.
vm.assume(proxy != address(extrospection));
// Proxy can't be a precompile either.
vm.assume(uint160(proxy) > 10);
// Force incorrect proxy implementation into the proxy address.
🤖 Prompt for AI Agents
In `@test/src/concrete/Extrospection.ERC1167Proxy.t.sol` around lines 26 - 30, The
test tightens the precompile exclusion by assuming vm.assume(uint160(proxy) >
type(uint160).max / 2) which reduces fuzz coverage and diverges from the success
test’s check; change the exclusion to match the success test (e.g.,
vm.assume(uint160(proxy) > 10)) or introduce and reuse a shared constant like
PRECOMPILE_BOUND used by both tests so both extrospection checks (the vm.assume
for proxy and any corresponding checks in Extrospection tests) consistently
avoid only low precompile addresses while preserving fuzz coverage.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@test/src/concrete/Extrospection.ERC1167Proxy.t.sol`:
- Line 36: Remove the leftover debug call console2.logBytes(bytecode) from the
test (Extrospection.ERC1167Proxy.t.sol) so test output stays clean; locate the
call to console2.logBytes(bytecode) and delete it (or replace it with an
appropriate assertion if you intended to validate bytecode), and scan for any
other console2.* debug calls to remove before merging.
♻️ Duplicate comments (3)
test/src/concrete/Extrospection.ERC1167Proxy.t.sol (1)

29-30: Precompile exclusion bound differs from success test.

The failure test now uses uint160(proxy) > type(uint160).max / 2, dramatically limiting fuzz coverage to just the upper half of the address space, while the success test at line 52 uses > 10. If both tests are intended to avoid precompiles, consider using a consistent bound or a shared constant.

test/lib/LibExtrospectTestProd.sol (2)

3-3: Pragma version inconsistency.

This file uses ^0.8.25 while other test files use =0.8.25. Consider aligning for consistency.


10-12: Consider adding clarity for missing environment variable.

If RPC_URL_ARBITRUM_FORK is not set, vm.envString reverts with a generic error. A comment or vm.envOr with a descriptive fallback would help developers understand the setup requirement.

@thedavidmeister thedavidmeister merged commit 60f35a0 into main Jan 25, 2026
4 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Feb 4, 2026
4 tasks
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.

1 participant