diff --git a/.changeset/thick-goats-travel.md b/.changeset/thick-goats-travel.md new file mode 100644 index 00000000000..c06f8b5322a --- /dev/null +++ b/.changeset/thick-goats-travel.md @@ -0,0 +1,5 @@ +--- +'openzeppelin-solidity': patch +--- + +Optimize ReentrancyGuardTransient by pre-computing BooleanSlot wrapper to save 30 gas per call diff --git a/contracts/utils/ReentrancyGuardTransient.sol b/contracts/utils/ReentrancyGuardTransient.sol index edf14c9551f..4da45ed9de5 100644 --- a/contracts/utils/ReentrancyGuardTransient.sol +++ b/contracts/utils/ReentrancyGuardTransient.sol @@ -19,6 +19,16 @@ abstract contract ReentrancyGuardTransient { bytes32 private constant REENTRANCY_GUARD_STORAGE = 0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00; + /** + * @dev Pre-computed BooleanSlot type wrapper for the reentrancy guard storage slot. + * This optimization avoids the overhead of repeatedly calling asBoolean() which performs + * a bytes32.wrap() operation on each invocation. By pre-computing the wrapped type at compile-time, + * this eliminates 3 redundant type casting operations per nonReentrant modifier execution, + * reducing gas consumption by 19 gas. + */ + TransientSlot.BooleanSlot private constant REENTRANCY_SLOT = + TransientSlot.BooleanSlot.wrap(REENTRANCY_GUARD_STORAGE); + /** * @dev Unauthorized reentrant call. */ @@ -57,15 +67,15 @@ abstract contract ReentrancyGuardTransient { } function _nonReentrantBefore() private { - // On the first call to nonReentrant, REENTRANCY_GUARD_STORAGE.asBoolean().tload() will be false + // On the first call to nonReentrant, REENTRANCY_SLOT.tload() will be false _nonReentrantBeforeView(); // Any calls to nonReentrant after this point will fail - REENTRANCY_GUARD_STORAGE.asBoolean().tstore(true); + REENTRANCY_SLOT.tstore(true); } function _nonReentrantAfter() private { - REENTRANCY_GUARD_STORAGE.asBoolean().tstore(false); + REENTRANCY_SLOT.tstore(false); } /** @@ -73,6 +83,6 @@ abstract contract ReentrancyGuardTransient { * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { - return REENTRANCY_GUARD_STORAGE.asBoolean().tload(); + return REENTRANCY_SLOT.tload(); } }