Solidity Security – How NonReentrant Modifier Works

Securitysolidity

It's the source code from address 0x0d4535644fFeC908e39a711A01852Be40Bfe1C97, can the modifier nonReentrant prevent the re-entrance vulnerability?

contract ReentrancyGuard {
/// @dev counter to allow mutex lock with only one SSTORE operation
uint256 private _guardCounter;

constructor () internal {
    // The counter starts at one to prevent changing it from zero to a non-zero
    // value, which is a more expensive operation.
    _guardCounter = 1;
}

/**
 * @dev Prevents a contract from calling itself, directly or indirectly.
 * Calling a `nonReentrant` function from another `nonReentrant`
 * function is not supported. It is possible to prevent this from happening
 * by making the `nonReentrant` function external, and make it call a
 * `private` function that does the actual work.
 */
modifier nonReentrant() {
    _guardCounter += 1;
    uint256 localCounter = _guardCounter;
    _;
    require(localCounter == _guardCounter);
}

}

Best Answer

It basically checks that the value of localCounter has increased only by one. That means the function has been called only once (within the transaction).

The actual function is executed at _;. Before that it increases the counter by one and assigns the value to a local variable (opposed to the global variable _guardCounter). If the function calls itself, the code comes again to this phase and the counter is again increased by one (both the global and the local).

After the function has finished executing, it makes sure that the local counter is the same as the global counter. The local value will be the same only if the function was called only once - otherwise the global counter has been increased multiple times. If it was called multiple times, the execution will revert.

Related Topic