> For the complete documentation index, see [llms.txt](https://ret2basic.gitbook.io/ctfnote/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ret2basic.gitbook.io/ctfnote/web3-security-research/secureum/epoch-0/slot-2-solidity-101/openzeppelin-reentrancyguard.md).

# OpenZeppelin ReentrancyGuard

## OpenZeppelin Doc

{% embed url="<https://docs.openzeppelin.com/contracts/4.x/api/security#ReentrancyGuard>" %}
ReentrancyGuard
{% endembed %}

Contract module that helps prevent reentrant calls to a function.

Inheriting from `ReentrancyGuard` will make the [`nonReentrant`](https://docs.openzeppelin.com/contracts/4.x/api/security#ReentrancyGuard-nonReentrant--) modifier available, which can be applied to functions to make sure there are no nested (reentrant) calls to them.

Note that because there is a single `nonReentrant` guard, functions marked as `nonReentrant` may not call one another. This can be worked around by making those functions `private`, and then adding `external` `nonReentrant` entry points to them.

## OpenZeppelin ReentrancyGuard

{% embed url="<https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.8.3/contracts/security/ReentrancyGuard.sol>" %}
ReentrancyGuard.sol
{% endembed %}

### State Variables and Constants

```solidity
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;

uint256 private _status;
```

Note that `_status` will be stored in storage slot 0 if a contract inherits ReentrancyGuard.

### Main Logic

The "reentrancy guard" is a modifier named `nonReentrant()`:

```solidity
modifier nonReentrant() {
    _nonReentrantBefore();
    _;
    _nonReentrantAfter();
}

function _nonReentrantBefore() private {
    // On the first call to nonReentrant, _status will be _NOT_ENTERED
    require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

    // Any calls to nonReentrant after this point will fail
    _status = _ENTERED;
}

function _nonReentrantAfter() private {
    // By storing the original value once again, a refund is triggered (see
    // https://eips.ethereum.org/EIPS/eip-2200)
    _status = _NOT_ENTERED;
}
```

This is just a simple mutex lock that prevents the current function from re-entering.

{% hint style="info" %}
**Note**\
The `nonReentrant()` modifier only prevents reentrancy attack inside the current contract. It does not prevent cross-contract reentrancy attacks such as <mark style="color:red;">**read only reentrancy**</mark>.
{% endhint %}
