ReentrancyGuard gas optimization (#1996)
* Improve gas efficiency of reentrancyGuard * Add changelog entry * Fix ReentrancyGuard test
This commit is contained in:
@ -12,17 +12,20 @@ pragma solidity ^0.5.0;
|
||||
* those functions `private`, and then adding `external` `nonReentrant` entry
|
||||
* points to them.
|
||||
*
|
||||
* _Since v2.5.0:_ this module is now much more gas efficient, given net gas
|
||||
* _Since v2.5.0:_ this module is now much more gas efficient, given net gas
|
||||
* metering changes introduced in the Istanbul hardfork.
|
||||
*/
|
||||
contract ReentrancyGuard {
|
||||
// counter to allow mutex lock with only one SSTORE operation
|
||||
uint256 private _guardCounter;
|
||||
bool private _notEntered;
|
||||
|
||||
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;
|
||||
// Storing an initial non-zero value makes deployment a bit more
|
||||
// expensive, but in exchange the refund on every call to nonReentrant
|
||||
// will be lower in amount. Since refunds are capped to a percetange of
|
||||
// the total transaction's gas, it is best to keep them low in cases
|
||||
// like this one, to increase the likelihood of the full refund coming
|
||||
// into effect.
|
||||
_notEntered = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -33,10 +36,16 @@ contract ReentrancyGuard {
|
||||
* `private` function that does the actual work.
|
||||
*/
|
||||
modifier nonReentrant() {
|
||||
_guardCounter += 1;
|
||||
uint256 localCounter = _guardCounter;
|
||||
// On the first call to nonReentrant, _notEntered will be true
|
||||
require(_notEntered, "ReentrancyGuard: reentrant call");
|
||||
|
||||
// Any calls to nonReentrant after this point will fail
|
||||
_notEntered = false;
|
||||
|
||||
_;
|
||||
require(localCounter == _guardCounter, "ReentrancyGuard: reentrant call");
|
||||
_guardCounter = 1;
|
||||
|
||||
// By storing the original value once again, a refund is triggered (see
|
||||
// https://eips.ethereum.org/EIPS/eip-2200)
|
||||
_notEntered = true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user