ReentrancyGuard vs ReentrancyGuardTransient gas saving

So I tried to check how much gas I can save if I use ReentrancyGuardTransient instead of ReentrancyGuard and for most of the tests it seems like it's around ~2000 gas or less. Based on my understanding this should be a little more, considering the fact that ReentrancyGuard is writing into an already existing storage slot, so I would assume it should be around ~5000 gas saved.

In theory gas usage should be something like this:

ReentrancyGuard.nonReentrant gas usage:

  1. SLOAD 2100 gas (status == 2)
  2. SSTORE 2900 gas (status 2)
  3. SSTORE 100 gas (status 1)

ReentrancyGuardTransient.nonReentrant gas usage:

  1. TLOAD 100 gas (status == 2)
  2. TSTORE 100 gas (status 2)
  3. TSTORE 100 gas (status 1)

May I ask what is the reason for this? Is it because of TransientSlot is being used?

:1234: Code to reproduce

I created a small repo where this can be reproduced and here are the actual gas snapshots.

:laptop: Environment

forge version: 1.0.0-stable
openzeppelin-solidity: 5.2.0

Thanks in advance

I think I found the answer here: What is the gas overhead of ReentrancyGuard? - #6 by frangio

It is because of the 2800 refund at the second SSTORE.

So the correct breakdown is this:

ReentrancyGuard.nonReentrant gas usage:

  1. SLOAD 2100 gas (status == 2)
  2. SSTORE 2900 gas (status 2)
  3. SSTORE 100 gas and refunds 2800 (status 1)

ReentrancyGuardTransient.nonReentrant gas usage:

  1. TLOAD 100 gas (status == 2)
  2. TSTORE 100 gas (status 2)
  3. TSTORE 100 gas (status 1)

it's 2300 vs 300 gas so the 2000 gas saving checks out

What is the fundamental difference between the ReentrancyGuardTransient contract and the classic ReentrancyGuard contract?

ReentrancyGuardTransient utilises transient storage.

Check the official docs: https://docs.soliditylang.org/en/v0.8.28/contracts.html#transient-storage

As far as I can see it is simply to use this kind of transient
variable with cheaper storage cost. But the saving is significant? we are talking about a variable of type value.

Check my previous answer: ReentrancyGuard vs ReentrancyGuardTransient gas saving - #3 by gabkov

It saves around ~2000 gas/call in this case. Depending on the implementation you can save more.