|
@@ -17,16 +17,24 @@ pragma solidity ^0.6.0;
|
|
|
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
|
|
|
*/
|
|
|
contract ReentrancyGuard {
|
|
|
- bool private _notEntered;
|
|
|
+ // Booleans are more expensive than uint256 or any type that takes up a full
|
|
|
+ // word because each write operation emits an extra SLOAD to first read the
|
|
|
+ // slot's contents, replace the bits taken up by the boolean, and then write
|
|
|
+ // back. This is the compiler's defense against contract upgrades and
|
|
|
+ // pointer aliasing, and it cannot be disabled.
|
|
|
+
|
|
|
+ // The values being 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 percentage 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.
|
|
|
+ uint256 private constant _NOT_ENTERED = 1;
|
|
|
+ uint256 private constant _ENTERED = 2;
|
|
|
+
|
|
|
+ uint256 private _status;
|
|
|
|
|
|
constructor () internal {
|
|
|
- // 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;
|
|
|
+ _status = _NOT_ENTERED;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -38,15 +46,15 @@ contract ReentrancyGuard {
|
|
|
*/
|
|
|
modifier nonReentrant() {
|
|
|
// On the first call to nonReentrant, _notEntered will be true
|
|
|
- require(_notEntered, "ReentrancyGuard: reentrant call");
|
|
|
+ require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
|
|
|
|
|
|
// Any calls to nonReentrant after this point will fail
|
|
|
- _notEntered = false;
|
|
|
+ _status = _ENTERED;
|
|
|
|
|
|
_;
|
|
|
|
|
|
// By storing the original value once again, a refund is triggered (see
|
|
|
// https://eips.ethereum.org/EIPS/eip-2200)
|
|
|
- _notEntered = true;
|
|
|
+ _status = _NOT_ENTERED;
|
|
|
}
|
|
|
}
|