OpenZeppelin ReentrancyGuard

OpenZeppelin Doc

Contract module that helps prevent reentrant calls to a function.

Inheriting from ReentrancyGuard will make the 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

State Variables and Constants

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():

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.

Note The nonReentrant() modifier only prevents reentrancy attack inside the current contract. It does not prevent cross-contract reentrancy attacks such as read only reentrancy.

Last updated