Branch data Line data Source code
1 : : // SPDX-License-Identifier: MIT
2 : : pragma solidity ^0.8.10;
3 : :
4 : : /**
5 : : * @title VersionedInitializable
6 : : * @author Aave, inspired by the OpenZeppelin Initializable contract
7 : : * @notice Helper contract to implement initializer functions. To use it, replace
8 : : * the constructor with a function that has the `initializer` modifier.
9 : : * @dev WARNING: Unlike constructors, initializer functions must be manually
10 : : * invoked. This applies both to deploying an Initializable contract, as well
11 : : * as extending an Initializable contract via inheritance.
12 : : * WARNING: When used with inheritance, manual care must be taken to not invoke
13 : : * a parent initializer twice, or ensure that all initializers are idempotent,
14 : : * because this is not dealt with automatically as with constructors.
15 : : */
16 : : abstract contract VersionedInitializable {
17 : : /**
18 : : * @dev Indicates that the contract has been initialized.
19 : : */
20 : : uint256 private lastInitializedRevision = 0;
21 : :
22 : : /**
23 : : * @dev Indicates that the contract is in the process of being initialized.
24 : : */
25 : : bool private initializing;
26 : :
27 : : /**
28 : : * @dev Modifier to use in the initializer function of a contract.
29 : : */
30 : : modifier initializer() {
31 : 346987 : uint256 revision = getRevision();
32 : 346987 : require(
33 : : initializing || isConstructor() || revision > lastInitializedRevision,
34 : : 'Contract instance has already been initialized'
35 : : );
36 : :
37 : 345986 : bool isTopLevelCall = !initializing;
38 : 345986 : if (isTopLevelCall) {
39 : 345986 : initializing = true;
40 : 345986 : lastInitializedRevision = revision;
41 : : }
42 : :
43 : : _;
44 : :
45 : 344984 : if (isTopLevelCall) {
46 : 344984 : initializing = false;
47 : : }
48 : : }
49 : :
50 : : /**
51 : : * @notice Returns the revision number of the contract
52 : : * @dev Needs to be defined in the inherited class as a constant.
53 : : * @return The revision number
54 : : */
55 : : function getRevision() internal pure virtual returns (uint256);
56 : :
57 : : /**
58 : : * @notice Returns true if and only if the function is running in the constructor
59 : : * @return True if the function is running in the constructor
60 : : */
61 : : function isConstructor() private view returns (bool) {
62 : : // extcodesize checks the size of the code stored in an address, and
63 : : // address returns the current address. Since the code is still not
64 : : // deployed when running a constructor, any checks on its code size will
65 : : // yield zero, making it an effective way to detect if a contract is
66 : : // under construction or not.
67 : 346987 : uint256 cs;
68 : : //solium-disable-next-line
69 : : assembly {
70 : 346987 : cs := extcodesize(address())
71 : : }
72 : 346987 : return cs == 0;
73 : : }
74 : :
75 : : // Reserved storage space to allow for layout changes in the future.
76 : : uint256[50] private ______gap;
77 : : }
|