Skip to content

Conversation

Amxx
Copy link
Collaborator

@Amxx Amxx commented Aug 27, 2025

Fixes #5681
Replaces #5688

PR Checklist

  • Tests
  • Documentation
  • Changeset entry (run npx changeset add)

Summary by Sourcery

Refactor ReentrancyGuard and its transient variant to store state in a configurable StorageSlot and provide a virtual hook for customizing the storage slot

Enhancements:

  • Switch ReentrancyGuard to use StorageSlot storage slots for its status instead of a contract field
  • Introduce a pure virtual _reentrancyGuardStorageSlot() in both ReentrancyGuard and ReentrancyGuardTransient for slot customization
  • Update ReentrancyGuardTransient to delegate its transient storage operations to the new slot getter

Documentation:

  • Add changeset entry for ReentrancyGuard storage slot customization

Summary by CodeRabbit

  • New Features

    • Added an internal hook letting derived contracts customize the storage slot used for reentrancy protection; external behavior remains the same.
    • Introduced upgradeable package layout and related upgradeable storage support.
  • Refactor

    • Reworked reentrancy state to use a dedicated storage-slot mechanism and updated upgradeable EIP‑712 handling to derive domain data dynamically.
  • Documentation

    • Deprecation note: storage-based guard deprecated; transient variant slated for removal in v6.0.

@Amxx Amxx requested a review from a team as a code owner August 27, 2025 20:33
Copy link

changeset-bot bot commented Aug 27, 2025

🦋 Changeset detected

Latest commit: bf835e9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
openzeppelin-solidity Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Contributor

sourcery-ai bot commented Aug 27, 2025

Reviewer's Guide

Implements a storage-slot-based reentrancy guard by replacing the internal status variable with StorageSlot-based reads and writes via a new overrideable accessor, updates the transient guard accordingly, and adds a changeset entry for slot customization.

Class diagram for updated ReentrancyGuard and ReentrancyGuardTransient

classDiagram
    class ReentrancyGuard {
        <<abstract>>
        +constructor()
        +_reentrancyGuardEntered() bool
        +_reentrancyGuardStorageSlot() bytes32
        -REENTRANCY_GUARD_STORAGE bytes32
        -NOT_ENTERED uint256
        -ENTERED uint256
        -_nonReentrantBefore() void
        -_nonReentrantAfter() void
        error ReentrancyGuardReentrantCall
    }
    class ReentrancyGuardTransient {
        <<abstract>>
        +_reentrancyGuardEntered() bool
        +_reentrancyGuardStorageSlot() bytes32
        -REENTRANCY_GUARD_STORAGE bytes32
        -_nonReentrantBefore() void
        -_nonReentrantAfter() void
    }
    ReentrancyGuard <|-- ReentrancyGuardTransient
    ReentrancyGuard o-- StorageSlot
    ReentrancyGuardTransient o-- StorageSlot
Loading

Class diagram for StorageSlot usage in ReentrancyGuard

classDiagram
    class StorageSlot {
        +getUint256Slot() StorageSlot.Uint256Slot
        +asBoolean() StorageSlot.BooleanSlot
    }
    class StorageSlot.Uint256Slot {
        +value uint256
    }
    class StorageSlot.BooleanSlot {
        +tstore(bool)
        +tload() bool
    }
    ReentrancyGuard o-- StorageSlot.Uint256Slot
    ReentrancyGuardTransient o-- StorageSlot.BooleanSlot
Loading

File-Level Changes

Change Details Files
Implement storage-slot-based state in ReentrancyGuard
  • Import and use StorageSlot library for bytes32
  • Define REENTRANCY_GUARD_STORAGE constant
  • Replace _status variable with slot reads/writes in constructor, hooks, and entered check
  • Add overrideable _reentrancyGuardStorageSlot() accessor
contracts/utils/ReentrancyGuard.sol
Refactor transient guard to use storage-slot accessor
  • Replace direct constant accesses with _reentrancyGuardStorageSlot() in tstore/tload
  • Add overrideable _reentrancyGuardStorageSlot() accessor
contracts/utils/ReentrancyGuardTransient.sol
Add changeset for slot accessor customization
  • Introduce changeset file documenting the new overrideable function
.changeset/three-parents-argue.md

Assessment against linked issues

Issue Objective Addressed Explanation
#5681 Prevent storage slot collisions in modular delegatecall architectures (e.g., Diamond Standard) by enabling unique storage slot derivation per module for upgradeable contracts. The PR adds a virtual _reentrancyGuardStorageSlot() function to allow slot customization in ReentrancyGuard and ReentrancyGuardTransient, but it does not implement per-module slot derivation based on deployed address as proposed in the issue. The default slot remains a fixed constant, and no mechanism for unique slot calculation per module is provided.
#5681 Introduce a new base contract or modifier (e.g., DiamondCompatibleInitializable) that mirrors Initializable but uses per-module slot derivation, placed in an experimental or diamond subdirectory. The PR does not introduce a new base contract or modifier for Initializable, nor does it add anything to an experimental or diamond subdirectory. The changes are limited to ReentrancyGuard and ReentrancyGuardTransient.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

coderabbitai bot commented Aug 27, 2025

Walkthrough

Adds an internal hook _reentrancyGuardStorageSlot() and refactors ReentrancyGuard and ReentrancyGuardTransient to use a StorageSlot-backed reentrancy flag accessed via that hook; preserves public API and documents the storage-based guard as deprecated.

Changes

Cohort / File(s) Summary
Reentrancy guard (storage-slot refactor and hook)
contracts/utils/ReentrancyGuard.sol
Replaces private _status with a StorageSlot-backed value (imports StorageSlot, using StorageSlot for bytes32, REENTRANCY_GUARD_STORAGE constant); updates constructor and _nonReentrantBefore/_nonReentrantAfter/_reentrancyGuardEntered to read/write the slot; adds internal pure virtual _reentrancyGuardStorageSlot() and a deprecation note for storage-based guard.
Reentrancy guard (transient variant hook integration)
contracts/utils/ReentrancyGuardTransient.sol
Routes transient guard reads/writes through _reentrancyGuardStorageSlot() in _nonReentrantBefore, _nonReentrantAfter, and _reentrancyGuardEntered; adds internal pure virtual _reentrancyGuardStorageSlot() returning the existing slot by default.
Changeset metadata
.changeset/three-parents-argue.md
Notes addition of _reentrancyGuardStorageSlot() in both guard variants and slot customization capability; includes review estimate.
Upgradeable scaffolding & packaging
scripts/upgradeable/upgradeable.patch, contracts/package.json, remappings.txt, ...
Various upgradeable-specific changes (package rename/version bump, remappings, EIP-712 upgradeable adjustments, and an added ReentrancyGuardStorage struct for upgradeable layout) included in the patch bundle.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant Contract as Contract (inherits ReentrancyGuard)
  participant Slot as ReentrancyGuard Storage Slot

  Caller->>Contract: call nonReentrant function
  Contract->>Contract: _nonReentrantBefore()
  Contract->>Contract: _reentrancyGuardStorageSlot()
  Contract->>Slot: read slot (entered?)
  alt not entered
    Contract->>Slot: write ENTERED
    Contract->>Contract: execute function body
    Contract->>Slot: write NOT_ENTERED (_nonReentrantAfter)
    Contract-->>Caller: return
  else already entered
    Contract-->>Caller: revert ReentrancyGuardReentrantCall
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Assessment against linked issues

Objective Addressed Explanation
Derive storage slots uniquely per module using deployed address; introduce diamond-compatible base (e.g., DiamondCompatibleInitializable) [#5681] Implements a hook but does not derive slots from contract address or add a diamond-compatible base.
Apply diamond-compatible approach to upgradeable components like Initializable [#5681] Initializable and upgradeable slot derivation were not modified to use per-module/address-derived slots.
Maintain EIP-1967-aligned slot computation with masking [#5681] Uses a fixed slot constant and does not apply masking or EIP-1967-style derivation.

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Added REENTRANCY_GUARD_STORAGE constant and StorageSlot-based reads/writes (contracts/utils/ReentrancyGuard.sol) Change refactors guard to a fixed storage slot and adds a hook, but does not implement address-derived, per-module slot computation required by #5681.
Added hook routing in transient variant (contracts/utils/ReentrancyGuardTransient.sol) Introduces _reentrancyGuardStorageSlot() but returns the same fixed slot by default; does not implement the diamond-compatible derivation requested.
Upgradeable packaging and EIP-712 changes (scripts/upgradeable/upgradeable.patch, contracts/package.json, contracts/utils/cryptography/EIP712.sol, ... ) Packaging/EIP-712 upgradeable adjustments are outside the scope of #5681 which targets per-module storage slot derivation; these changes do not address the linked issue objectives.

I twitch my whiskers, tap the chain,
A tiny slot to guard the lane.
A hook I left for those who dare,
To change the hole with care and flair.
Thump-thump — hop safe, beware the snare. 🐰✨

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • Add NatSpec documentation on _reentrancyGuardStorageSlot() to explain the override mechanism and how consumers should pick a unique storage slot.
  • Consider extracting the repeated getUint256Slot().value = ... patterns into private setter/getter helpers to reduce boilerplate and improve readability.
  • Double-check that the chosen REENTRANCY_GUARD_STORAGE constant is guaranteed to not collide with other storage slots and document how it was derived for audit clarity.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Add NatSpec documentation on `_reentrancyGuardStorageSlot()` to explain the override mechanism and how consumers should pick a unique storage slot.
- Consider extracting the repeated `getUint256Slot().value = ...` patterns into private setter/getter helpers to reduce boilerplate and improve readability.
- Double-check that the chosen `REENTRANCY_GUARD_STORAGE` constant is guaranteed to not collide with other storage slots and document how it was derived for audit clarity.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@Amxx Amxx added this to the 5.5 milestone Aug 27, 2025
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: 3

🧹 Nitpick comments (1)
contracts/utils/ReentrancyGuard.sol (1)

26-30: Clarify the deprecation note to avoid mixed signals.

Current wording reads as both “this is deprecated” and “Transient will be removed,” which can confuse readers. Tighten the phrasing.

- * As of v5.5, this storage-based version of the reentrancy guard is DEPRECATED. In the
- * next major release (v6.0), {ReentrancyGuardTransient} will be removed, and its logic
- * moved to this contract, making transient storage the standard storage option for
- * reentrancy guards.
+ * As of v5.5, this storage-backed implementation is DEPRECATED.
+ * In v6.0, this contract will adopt the transient-storage implementation and
+ * {ReentrancyGuardTransient} will be removed.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 53bb340 and f8a43dc.

📒 Files selected for processing (3)
  • .changeset/three-parents-argue.md (1 hunks)
  • contracts/utils/ReentrancyGuard.sol (4 hunks)
  • contracts/utils/ReentrancyGuardTransient.sol (1 hunks)
🧰 Additional context used
🪛 LanguageTool
.changeset/three-parents-argue.md

[grammar] ~5-~5: Ensure spelling is correct
Context: ... a pure virtual function, that can be overriden to allow slot customization.

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~5-~5: There might be a mistake here.
Context: ...e overriden to allow slot customization.

(QB_NEW_EN)

🔇 Additional comments (4)
contracts/utils/ReentrancyGuardTransient.sol (2)

47-52: Good refactor: writes go through the slot hook.

Switching to _reentrancyGuardStorageSlot() centralizes slot selection and enables customization in descendants.


59-60: Good refactor: read goes through the slot hook.

Keeps read/write symmetry and makes overrides effective everywhere.

contracts/utils/ReentrancyGuard.sol (2)

75-83: Good migration to StorageSlot-based guard.

Read/Write via getUint256Slot() is consistent and keeps semantics intact.


33-38: Confirmed: REENTRANCY_GUARD_STORAGE is identical in both variants

All occurrences of the REENTRANCY_GUARD_STORAGE constant share the same 32-byte value (0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00):

  • contracts/utils/ReentrancyGuard.sol (lines 36–37)
  • contracts/utils/ReentrancyGuardTransient.sol (lines 19–20)

No divergent defaults—no further changes needed.

'openzeppelin-solidity': patch
---

`ReentrancyGuard` and `ReentrancyGuardTransient`: Add `_reentrancyGuardStorageSlot()`, a `pure virtual` function, that can be overriden to allow slot customization.
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Make the hook view-virtual (to enable address-derived slots) and fix wording.

Declaring the hook as pure prevents overrides from using address(this) (required for per-module, diamond-safe slots). Also fix typo and comma splice.

-`ReentrancyGuard` and `ReentrancyGuardTransient`: Add `_reentrancyGuardStorageSlot()`, a `pure virtual` function, that can be overriden to allow slot customization.
+`ReentrancyGuard` and `ReentrancyGuardTransient`: Add `_reentrancyGuardStorageSlot()`, an `internal view virtual` function that can be overridden to allow slot customization.
📝 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
`ReentrancyGuard` and `ReentrancyGuardTransient`: Add `_reentrancyGuardStorageSlot()`, a `pure virtual` function, that can be overriden to allow slot customization.
`ReentrancyGuard` and `ReentrancyGuardTransient`: Add `_reentrancyGuardStorageSlot()`, an `internal view virtual` function that can be overridden to allow slot customization.
🧰 Tools
🪛 LanguageTool

[grammar] ~5-~5: Ensure spelling is correct
Context: ... a pure virtual function, that can be overriden to allow slot customization.

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~5-~5: There might be a mistake here.
Context: ...e overriden to allow slot customization.

(QB_NEW_EN)

🤖 Prompt for AI Agents
.changeset/three-parents-argue.md around line 5: the release note currently
states the hook as a `pure virtual` function which prevents overrides from
referencing `address(this)` (needed for per-module, diamond-safe,
address-derived storage slots) and contains a wording/typo/comma-splice; change
the description to say the hook is a `view virtual` function (so overrides can
use `address(this)`), and rewrite the sentence to fix the typo and comma splice
and clarify that the function can be overridden to customize the storage slot
(e.g., for per-module, diamond-safe slots derived from addresses).

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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/upgradeable/upgradeable.patch (1)

117-141: peerDependencies version placeholder will break installs.

"@openzeppelin/contracts": "" is not valid semver and will cause npm/yarn/pnpm to error. Use a concrete range aligned with this package’s major.

   "peerDependencies": {
-    "@openzeppelin/contracts": "<package-version>"
+    "@openzeppelin/contracts": "^5.4.0"
   }

If you need tighter coupling within a monorepo, consider "workspace:^" for pnpm/yarn workspaces.

🧹 Nitpick comments (7)
scripts/upgradeable/upgradeable.patch (7)

101-109: Usage example reads well for upgradeable flow.

initialize + __ERC721_init is the right pattern. Consider bumping the pragma in the snippet to ^0.8.24 to match current min version elsewhere.

-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;

185-188: Minor gas/readability: precompute empty-string hash.

keccak256("") appears multiple times; define a file-level constant to avoid recomputation and clarify intent.

     bytes32 private constant TYPE_HASH =
         keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
+    bytes32 private constant EMPTY_STRING_HASH = keccak256("");

Then use EMPTY_STRING_HASH below.


195-198: Immutables kept but set to zero — clarify intent or remove.

Keeping _hashedName/_hashedVersion as immutables and assigning zero in the constructor is unusual. If they only serve as a “legacy sentinel”, prefer constants and update comments to avoid implying these live in storage.

-    /// @custom:oz-renamed-from _HASHED_NAME
-    bytes32 private immutable _hashedName;
-    /// @custom:oz-renamed-from _HASHED_VERSION
-    bytes32 private immutable _hashedVersion;
+    // Legacy sentinels kept for upgrade-path detection (non-storage, code-embedded).
+    /// @custom:oz-renamed-from _HASHED_NAME
+    bytes32 private constant _LEGACY_HASHED_NAME = bytes32(0);
+    /// @custom:oz-renamed-from _HASHED_VERSION
+    bytes32 private constant _LEGACY_HASHED_VERSION = bytes32(0);

And adjust references accordingly (see lines 252–255, 302–305, 323–326). If you prefer to keep immutables, at least update the comments below to say “immutable” instead of “storage”.


214-228: Constructor assignments suggest “reset storage” but target immutables.

The comment says “Reset prior values in storage”, but the variables are immutables (code, not storage). This is misleading; fix the wording or switch to true storage fields if reset semantics are intended.

-        // Reset prior values in storage if upgrading
+        // Note: these are immutables; there is no storage to reset here.

Alternatively, replace immutables with constants as suggested above.


252-255: Condition/message mismatch: “Uninitialized” check reads as legacy-sentinel check.

The require currently reverts when legacy hashes are non-zero, which is not an “uninitialized” condition. Either drop this gate or reword to reflect what it guards.

-        // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized
-        // and the EIP712 domain is not reliable, as it will be missing name and version.
-        require(_hashedName == 0 && _hashedVersion == 0, "EIP712: Uninitialized");
+        // If legacy cached hashes are non-zero, this is a legacy/incorrect implementation for upgradeable usage.
+        require(_hashedName == 0 && _hashedVersion == 0, "EIP712: legacy-cached-values");

If the intent was to ensure initialization, consider checking bytes(_EIP712Name()).length and bytes(_EIP712Version()).length instead (but tests were adjusted to allow empty values).


295-309: Use EMPTY_STRING_HASH in fallback branch.

Slight gas/readability improvement; also avoids recomputing keccak256("").

-                return keccak256("");
+                return EMPTY_STRING_HASH;

Apply similarly in _EIP712VersionHash().


317-330: Same as above for version hash; also minor micro-optimization.

Reuse the EMPTY_STRING_HASH constant for the version empty case.

-                return keccak256("");
+                return EMPTY_STRING_HASH;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4b5ce78 and bf835e9.

📒 Files selected for processing (1)
  • scripts/upgradeable/upgradeable.patch (9 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-29T13:16:08.640Z
Learnt from: Amxx
PR: OpenZeppelin/openzeppelin-contracts#5904
File: contracts/mocks/crosschain/ERC7786RecipientMock.sol:12-14
Timestamp: 2025-08-29T13:16:08.640Z
Learning: In OpenZeppelin contracts, mock contracts (like ERC7786RecipientMock) don't require input validation such as zero-address checks in constructors, as they are only used for testing purposes in controlled environments.

Applied to files:

  • scripts/upgradeable/upgradeable.patch
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: coverage
  • GitHub Check: slither
  • GitHub Check: tests
  • GitHub Check: tests-foundry
  • GitHub Check: tests-upgradeable
  • GitHub Check: halmos
🔇 Additional comments (10)
scripts/upgradeable/upgradeable.patch (10)

69-71: Good addition: clear note about the upgradeable variant.

Helps steer users to the right docs.


80-81: npm install path updated correctly.

Switch to @openzeppelin/contracts-upgradeable is appropriate.


88-94: Foundry install and remapping look correct.

The remapping points to the upgradeable repo as expected.


243-245: LGTM: always rebuilding domain separator.

This matches the upgradeable-friendly approach and avoids stale caches.


333-342: Repository URL switch is correct for the upgradeable package.


349-353: remappings.txt aligns both upgradeable and non-upgradeable imports.

Looks good.


369-383: Same test adjustment for modules mock looks fine.

Mirror the verification above to cover overridden values too.


384-415: Removal of clone/proxy adjustment test is reasonable under the new no-cache model.

Given the separator is rebuilt each time, the legacy cache invalidation test is no longer applicable.


147-154: No direct constant usage observed: all reads and writes use _reentrancyGuardStorageSlot(), with REENTRANCY_GUARD_STORAGE confined to its declaration and the hook’s return.


357-367: (run-scripts block issued)

@Amxx Amxx merged commit 4e35b0b into OpenZeppelin:master Sep 3, 2025
21 checks passed
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.

Storage Slot Collisions in Diamond-Compatible Delegatecall Architecture (Upgradeable Contracts)
3 participants