Browse Source

Add internal functions `_getInitializedVersion` and `_isInitializing` (#3598)

Shatabarto "Rik" Bhattacharya 3 years ago
parent
commit
26cf47a2be

+ 1 - 0
CHANGELOG.md

@@ -2,6 +2,7 @@
 
 ## Unreleased
 
+ * `Initializable`: add internal functions `_getInitializedVersion` and `_isInitializing` ([#3598](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3598))
  * `ERC165Checker`: add `supportsERC165InterfaceUnchecked` for consulting individual interfaces without the full ERC165 protocol. ([#3339](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3339))
  * `Address`: optimize `functionCall` by calling `functionCallWithValue` directly. ([#3468](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3468))
  * `Address`: optimize `functionCall` functions by checking contract size only if there is no returned data. ([#3469](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3469))

+ 8 - 0
contracts/mocks/InitializableMock.sol

@@ -13,6 +13,10 @@ contract InitializableMock is Initializable {
     bool public onlyInitializingRan;
     uint256 public x;
 
+    function isInitializing() public view returns (bool) {
+        return _isInitializing();
+    }
+
     function initialize() public initializer {
         initializerRan = true;
     }
@@ -75,6 +79,10 @@ contract ChildConstructorInitializableMock is ConstructorInitializableMock {
 contract ReinitializerMock is Initializable {
     uint256 public counter;
 
+    function getInitializedVersion() public view returns (uint8) {
+        return _getInitializedVersion();
+    }
+
     function initialize() public initializer {
         doStuff();
     }

+ 14 - 0
contracts/proxy/utils/Initializable.sol

@@ -135,4 +135,18 @@ abstract contract Initializable {
             emit Initialized(type(uint8).max);
         }
     }
+
+    /**
+     * @dev Internal function that returns the initialized version. Returns `_initialized`
+     */
+    function _getInitializedVersion() internal view returns (uint8) {
+        return _initialized;
+    }
+
+    /**
+     * @dev Internal function that returns the initialized version. Returns `_initializing`
+     */
+    function _isInitializing() internal view returns (bool) {
+        return _initializing;
+    }
 }

+ 15 - 0
test/proxy/utils/Initializable.test.js

@@ -20,6 +20,10 @@ contract('Initializable', function (accounts) {
       it('initializer has not run', async function () {
         expect(await this.contract.initializerRan()).to.equal(false);
       });
+
+      it('_initializing returns false before initialization', async function () {
+        expect(await this.contract.isInitializing()).to.equal(false);
+      });
     });
 
     describe('after initialize', function () {
@@ -31,6 +35,10 @@ contract('Initializable', function (accounts) {
         expect(await this.contract.initializerRan()).to.equal(true);
       });
 
+      it('_initializing returns false after initialization', async function () {
+        expect(await this.contract.isInitializing()).to.equal(false);
+      });
+
       it('initializer does not run again', async function () {
         await expectRevert(this.contract.initialize(), 'Initializable: contract is already initialized');
       });
@@ -101,6 +109,13 @@ contract('Initializable', function (accounts) {
       expect(await this.contract.counter()).to.be.bignumber.equal('2');
     });
 
+    it('_getInitializedVersion returns right version', async function () {
+      await this.contract.initialize();
+      expect(await this.contract.getInitializedVersion()).to.be.bignumber.equal('1');
+      await this.contract.reinitialize(12);
+      expect(await this.contract.getInitializedVersion()).to.be.bignumber.equal('12');
+    });
+
     describe('contract locking', function () {
       it('prevents initialization', async function () {
         await this.contract.disableInitializers();