|
@@ -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;
|
|
|
}
|
|
|
}
|