Skip to content

Conversation

borj404
Copy link

@borj404 borj404 commented Aug 19, 2025

Description

Eliminates redundant type casting in ReentrancyGuardTransient by pre-computing the BooleanSlot wrapper at compile-time.

Edit: Updated to support the new nonReentrantView modifier introduced in the latest version.

Current implementation

Performs asBoolean()BooleanSlot.wrap() three times per nonReentrant execution.

Optimization

Pre-computed constant:

TransientSlot.BooleanSlot private constant REENTRANCY_SLOT =
    TransientSlot.BooleanSlot.wrap(REENTRANCY_GUARD_STORAGE);

Gas savings

19 gas per nonReentrant call (verified via test suite).

Method Original gas Optimized gas Savings Improvement
callback() 44,007 43,988 19 gas 0.04%
guardedCheckEntered() 21,952 21,933 19 gas 0.09%

Eliminates 30 gas in wrapping operations, reduced to 19 gas net due to function call overhead from the refactored architecture.
Deployment overhead: 1,728 gas (amortized after ~91 transactions).

Testing

Impact

  • Zero security trade-offs.
  • Full backward compatibility.
  • Supports both nonReentrant and nonReentrantView modifiers.

@borj404 borj404 requested a review from a team as a code owner August 19, 2025 17:26
Copy link

changeset-bot bot commented Aug 19, 2025

🦋 Changeset detected

Latest commit: 2f1f537

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

@borj404 borj404 force-pushed the perf/reentrancy-guard-precompute-booleanslot branch from 5b77380 to c07b8d2 Compare August 22, 2025 18:31
Copy link

coderabbitai bot commented Sep 13, 2025

Walkthrough

Adds a pre-computed TransientSlot.BooleanSlot constant (REENTRANCY_SLOT) in ReentrancyGuardTransient.sol to wrap REENTRANCY_GUARD_STORAGE. Replaces repeated _reentrancyGuardStorageSlot().asBoolean().tload()/tstore(...) calls with REENTRANCY_SLOT.tload()/tstore(...) in _nonReentrantBefore, _nonReentrantAfter, and _reentrancyGuardEntered. Updates related inline comments. Retains _reentrancyGuardStorageSlot() unchanged. Functional behavior remains unchanged. Also adds a changeset entry marking an openzeppelin-solidity patch release documenting this optimization.

Possibly related issues

Possibly related PRs

  • Add _reentrancyGuardStorageSlot()  #5892: Modifies the same ReentrancyGuardTransient internal slot access to use a pre-computed wrapper across _nonReentrantBefore/_nonReentrantAfter/_reentrancyGuardEntered.
✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The current title succinctly and accurately identifies the primary change—precomputing a BooleanSlot to optimize ReentrancyGuardTransient—and clearly communicates the performance focus and affected contract to reviewers. It is concise, specific, and free of irrelevant details or emojis. This makes it appropriate for commit history and team review.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
Description Check ✅ Passed The pull request description directly corresponds to the changeset: it explains precomputing the TransientSlot.BooleanSlot wrapper in ReentrancyGuardTransient, includes the implementation snippet, reports measured gas savings and deployment overhead, and notes that tests pass, so it is related and informative for this lenient check.

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

🧹 Nitpick comments (1)
.changeset/thick-goats-travel.md (1)

5-5: Minor discrepancy in gas savings documentation.

The changeset mentions "30 gas per call" while the PR objectives specify "19 gas saved per nonReentrant call." Consider aligning these numbers for consistency across documentation.

-Optimize ReentrancyGuardTransient by pre-computing BooleanSlot wrapper to save 30 gas per call
+Optimize ReentrancyGuardTransient by pre-computing BooleanSlot wrapper to save 19 gas per call
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8f8d61c and 2f1f537.

📒 Files selected for processing (2)
  • .changeset/thick-goats-travel.md (1 hunks)
  • contracts/utils/ReentrancyGuardTransient.sol (2 hunks)
⏰ 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: slither
  • GitHub Check: coverage
  • GitHub Check: tests-foundry
  • GitHub Check: tests
  • GitHub Check: halmos
  • GitHub Check: tests-upgradeable
🔇 Additional comments (5)
contracts/utils/ReentrancyGuardTransient.sol (5)

22-30: Excellent gas optimization with clear documentation.

The pre-computed BooleanSlot constant is a smart optimization that eliminates redundant type casting operations. The comprehensive comment clearly explains the rationale and quantifies the gas savings, making it easy for future maintainers to understand the purpose.


70-70: LGTM! Clean replacement of redundant operations.

The direct usage of REENTRANCY_SLOT.tstore(true) eliminates the need for the previous _reentrancyGuardStorageSlot().asBoolean().tstore(true) pattern, reducing gas consumption while maintaining identical functionality.

Also applies to: 74-74


78-78: LGTM! Consistent optimization applied.

The direct usage of REENTRANCY_SLOT.tstore(false) follows the same optimization pattern as in _nonReentrantBefore(), maintaining consistency across the codebase.


86-86: LGTM! Optimization maintains function semantics.

The direct usage of REENTRANCY_SLOT.tload() eliminates the redundant _reentrancyGuardStorageSlot().asBoolean().tload() pattern while preserving the exact same return value and behavior.


89-91: Good design choice preserving backward compatibility.

Maintaining the _reentrancyGuardStorageSlot() function unchanged ensures that any external contracts or libraries that depend on this function for storage slot access continue to work without modification. This demonstrates excellent backward compatibility considerations.

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