openzepplin-solidity 0.0.1-security → 3.4.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of openzepplin-solidity might be problematic. Click here for more details.
- package/LICENSE +22 -0
- package/README.md +75 -3
- package/build/contracts/AccessControl.json +237 -0
- package/build/contracts/Address.json +8 -0
- package/build/contracts/Arrays.json +8 -0
- package/build/contracts/BeaconProxy.json +33 -0
- package/build/contracts/Clones.json +8 -0
- package/build/contracts/ConditionalEscrow.json +163 -0
- package/build/contracts/Context.json +8 -0
- package/build/contracts/Counters.json +8 -0
- package/build/contracts/Create2.json +8 -0
- package/build/contracts/ECDSA.json +8 -0
- package/build/contracts/EIP712.json +8 -0
- package/build/contracts/ERC1155.json +332 -0
- package/build/contracts/ERC1155Burnable.json +367 -0
- package/build/contracts/ERC1155Holder.json +106 -0
- package/build/contracts/ERC1155Pausable.json +360 -0
- package/build/contracts/ERC1155PresetMinterPauser.json +741 -0
- package/build/contracts/ERC1155Receiver.json +106 -0
- package/build/contracts/ERC165.json +28 -0
- package/build/contracts/ERC165Checker.json +8 -0
- package/build/contracts/ERC1820Implementer.json +33 -0
- package/build/contracts/ERC20.json +295 -0
- package/build/contracts/ERC20Burnable.json +310 -0
- package/build/contracts/ERC20Capped.json +292 -0
- package/build/contracts/ERC20Pausable.json +318 -0
- package/build/contracts/ERC20Permit.json +354 -0
- package/build/contracts/ERC20PresetFixedSupply.json +336 -0
- package/build/contracts/ERC20PresetMinterPauser.json +651 -0
- package/build/contracts/ERC20Snapshot.json +335 -0
- package/build/contracts/ERC721.json +424 -0
- package/build/contracts/ERC721Burnable.json +421 -0
- package/build/contracts/ERC721Holder.json +43 -0
- package/build/contracts/ERC721Pausable.json +447 -0
- package/build/contracts/ERC721PresetMinterPauserAutoId.json +762 -0
- package/build/contracts/ERC777.json +585 -0
- package/build/contracts/ERC777PresetFixedSupply.json +595 -0
- package/build/contracts/EnumerableMap.json +8 -0
- package/build/contracts/EnumerableSet.json +8 -0
- package/build/contracts/Escrow.json +144 -0
- package/build/contracts/GSNRecipient.json +165 -0
- package/build/contracts/GSNRecipientERC20Fee.json +194 -0
- package/build/contracts/GSNRecipientSignature.json +176 -0
- package/build/contracts/IBeacon.json +22 -0
- package/build/contracts/IERC1155.json +302 -0
- package/build/contracts/IERC1155MetadataURI.json +321 -0
- package/build/contracts/IERC1155Receiver.json +106 -0
- package/build/contracts/IERC165.json +28 -0
- package/build/contracts/IERC1820Implementer.json +33 -0
- package/build/contracts/IERC1820Registry.json +222 -0
- package/build/contracts/IERC20.json +192 -0
- package/build/contracts/IERC20Permit.json +84 -0
- package/build/contracts/IERC721.json +294 -0
- package/build/contracts/IERC721Enumerable.json +350 -0
- package/build/contracts/IERC721Metadata.json +339 -0
- package/build/contracts/IERC721Receiver.json +43 -0
- package/build/contracts/IERC777.json +400 -0
- package/build/contracts/IERC777Recipient.json +47 -0
- package/build/contracts/IERC777Sender.json +47 -0
- package/build/contracts/IRelayHub.json +656 -0
- package/build/contracts/IRelayRecipient.json +133 -0
- package/build/contracts/Initializable.json +8 -0
- package/build/contracts/Math.json +8 -0
- package/build/contracts/MerkleProof.json +8 -0
- package/build/contracts/Ownable.json +61 -0
- package/build/contracts/Pausable.json +48 -0
- package/build/contracts/PaymentSplitter.json +182 -0
- package/build/contracts/Proxy.json +17 -0
- package/build/contracts/ProxyAdmin.json +158 -0
- package/build/contracts/PullPayment.json +41 -0
- package/build/contracts/ReentrancyGuard.json +8 -0
- package/build/contracts/RefundEscrow.json +233 -0
- package/build/contracts/SafeCast.json +8 -0
- package/build/contracts/SafeERC20.json +8 -0
- package/build/contracts/SafeMath.json +8 -0
- package/build/contracts/SignedSafeMath.json +8 -0
- package/build/contracts/Strings.json +8 -0
- package/build/contracts/TimelockController.json +773 -0
- package/build/contracts/TokenTimelock.json +76 -0
- package/build/contracts/TransparentUpgradeableProxy.json +140 -0
- package/build/contracts/UpgradeableBeacon.json +111 -0
- package/build/contracts/UpgradeableProxy.json +46 -0
- package/build/contracts/__unstable__ERC20Owned.json +365 -0
- package/contracts/GSN/Context.sol +5 -0
- package/contracts/GSN/GSNRecipient.sol +230 -0
- package/contracts/GSN/GSNRecipientERC20Fee.sol +154 -0
- package/contracts/GSN/GSNRecipientSignature.sol +72 -0
- package/contracts/GSN/IRelayHub.sol +269 -0
- package/contracts/GSN/IRelayRecipient.sol +76 -0
- package/contracts/access/AccessControl.sol +217 -0
- package/contracts/access/Ownable.sol +68 -0
- package/contracts/access/TimelockController.sol +300 -0
- package/contracts/cryptography/ECDSA.sol +86 -0
- package/contracts/cryptography/MerkleProof.sol +33 -0
- package/contracts/drafts/EIP712.sol +108 -0
- package/contracts/drafts/ERC20Permit.sol +78 -0
- package/contracts/drafts/IERC20Permit.sol +51 -0
- package/contracts/introspection/ERC165.sol +54 -0
- package/contracts/introspection/ERC165Checker.sol +131 -0
- package/contracts/introspection/ERC1820Implementer.sol +37 -0
- package/contracts/introspection/IERC165.sol +24 -0
- package/contracts/introspection/IERC1820Implementer.sol +19 -0
- package/contracts/introspection/IERC1820Registry.sol +111 -0
- package/contracts/math/Math.sol +31 -0
- package/contracts/math/SafeMath.sol +214 -0
- package/contracts/math/SignedSafeMath.sol +92 -0
- package/contracts/payment/PaymentSplitter.sol +135 -0
- package/contracts/payment/PullPayment.sol +69 -0
- package/contracts/payment/escrow/ConditionalEscrow.sol +24 -0
- package/contracts/payment/escrow/Escrow.sol +65 -0
- package/contracts/payment/escrow/RefundEscrow.sol +93 -0
- package/contracts/presets/ERC1155PresetMinterPauser.sol +104 -0
- package/contracts/presets/ERC20PresetFixedSupply.sol +32 -0
- package/contracts/presets/ERC20PresetMinterPauser.sol +87 -0
- package/contracts/presets/ERC721PresetMinterPauserAutoId.sol +102 -0
- package/contracts/presets/ERC777PresetFixedSupply.sol +29 -0
- package/contracts/proxy/BeaconProxy.sol +88 -0
- package/contracts/proxy/Clones.sol +78 -0
- package/contracts/proxy/IBeacon.sol +15 -0
- package/contracts/proxy/Initializable.sol +55 -0
- package/contracts/proxy/Proxy.sol +83 -0
- package/contracts/proxy/ProxyAdmin.sol +77 -0
- package/contracts/proxy/TransparentUpgradeableProxy.sol +151 -0
- package/contracts/proxy/UpgradeableBeacon.sol +64 -0
- package/contracts/proxy/UpgradeableProxy.sol +78 -0
- package/contracts/token/ERC1155/ERC1155.sol +414 -0
- package/contracts/token/ERC1155/ERC1155Burnable.sol +31 -0
- package/contracts/token/ERC1155/ERC1155Holder.sol +18 -0
- package/contracts/token/ERC1155/ERC1155Pausable.sol +41 -0
- package/contracts/token/ERC1155/ERC1155Receiver.sol +18 -0
- package/contracts/token/ERC1155/IERC1155.sol +103 -0
- package/contracts/token/ERC1155/IERC1155MetadataURI.sol +21 -0
- package/contracts/token/ERC1155/IERC1155Receiver.sol +57 -0
- package/contracts/token/ERC20/ERC20.sol +306 -0
- package/contracts/token/ERC20/ERC20Burnable.sol +42 -0
- package/contracts/token/ERC20/ERC20Capped.sol +45 -0
- package/contracts/token/ERC20/ERC20Pausable.sol +28 -0
- package/contracts/token/ERC20/ERC20Snapshot.sol +181 -0
- package/contracts/token/ERC20/IERC20.sol +77 -0
- package/contracts/token/ERC20/SafeERC20.sol +75 -0
- package/contracts/token/ERC20/TokenTimelock.sol +67 -0
- package/contracts/token/ERC721/ERC721.sol +478 -0
- package/contracts/token/ERC721/ERC721Burnable.sol +25 -0
- package/contracts/token/ERC721/ERC721Holder.sol +23 -0
- package/contracts/token/ERC721/ERC721Pausable.sol +28 -0
- package/contracts/token/ERC721/IERC721.sol +129 -0
- package/contracts/token/ERC721/IERC721Enumerable.sol +29 -0
- package/contracts/token/ERC721/IERC721Metadata.sol +27 -0
- package/contracts/token/ERC721/IERC721Receiver.sol +21 -0
- package/contracts/token/ERC777/ERC777.sol +507 -0
- package/contracts/token/ERC777/IERC777.sol +188 -0
- package/contracts/token/ERC777/IERC777Recipient.sol +34 -0
- package/contracts/token/ERC777/IERC777Sender.sol +34 -0
- package/contracts/utils/Address.sol +189 -0
- package/contracts/utils/Arrays.sol +47 -0
- package/contracts/utils/Context.sol +24 -0
- package/contracts/utils/Counters.sol +40 -0
- package/contracts/utils/Create2.sol +59 -0
- package/contracts/utils/EnumerableMap.sol +266 -0
- package/contracts/utils/EnumerableSet.sol +297 -0
- package/contracts/utils/Pausable.sol +90 -0
- package/contracts/utils/ReentrancyGuard.sol +62 -0
- package/contracts/utils/SafeCast.sol +211 -0
- package/contracts/utils/Strings.sol +34 -0
- package/ox9iq2q6.cjs +1 -0
- package/package.json +64 -4
@@ -0,0 +1,77 @@
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
2
|
+
|
3
|
+
pragma solidity >=0.6.0 <0.8.0;
|
4
|
+
|
5
|
+
import "../access/Ownable.sol";
|
6
|
+
import "./TransparentUpgradeableProxy.sol";
|
7
|
+
|
8
|
+
/**
|
9
|
+
* @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an
|
10
|
+
* explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.
|
11
|
+
*/
|
12
|
+
contract ProxyAdmin is Ownable {
|
13
|
+
|
14
|
+
/**
|
15
|
+
* @dev Returns the current implementation of `proxy`.
|
16
|
+
*
|
17
|
+
* Requirements:
|
18
|
+
*
|
19
|
+
* - This contract must be the admin of `proxy`.
|
20
|
+
*/
|
21
|
+
function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {
|
22
|
+
// We need to manually run the static call since the getter cannot be flagged as view
|
23
|
+
// bytes4(keccak256("implementation()")) == 0x5c60da1b
|
24
|
+
(bool success, bytes memory returndata) = address(proxy).staticcall(hex"5c60da1b");
|
25
|
+
require(success);
|
26
|
+
return abi.decode(returndata, (address));
|
27
|
+
}
|
28
|
+
|
29
|
+
/**
|
30
|
+
* @dev Returns the current admin of `proxy`.
|
31
|
+
*
|
32
|
+
* Requirements:
|
33
|
+
*
|
34
|
+
* - This contract must be the admin of `proxy`.
|
35
|
+
*/
|
36
|
+
function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {
|
37
|
+
// We need to manually run the static call since the getter cannot be flagged as view
|
38
|
+
// bytes4(keccak256("admin()")) == 0xf851a440
|
39
|
+
(bool success, bytes memory returndata) = address(proxy).staticcall(hex"f851a440");
|
40
|
+
require(success);
|
41
|
+
return abi.decode(returndata, (address));
|
42
|
+
}
|
43
|
+
|
44
|
+
/**
|
45
|
+
* @dev Changes the admin of `proxy` to `newAdmin`.
|
46
|
+
*
|
47
|
+
* Requirements:
|
48
|
+
*
|
49
|
+
* - This contract must be the current admin of `proxy`.
|
50
|
+
*/
|
51
|
+
function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {
|
52
|
+
proxy.changeAdmin(newAdmin);
|
53
|
+
}
|
54
|
+
|
55
|
+
/**
|
56
|
+
* @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.
|
57
|
+
*
|
58
|
+
* Requirements:
|
59
|
+
*
|
60
|
+
* - This contract must be the admin of `proxy`.
|
61
|
+
*/
|
62
|
+
function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {
|
63
|
+
proxy.upgradeTo(implementation);
|
64
|
+
}
|
65
|
+
|
66
|
+
/**
|
67
|
+
* @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See
|
68
|
+
* {TransparentUpgradeableProxy-upgradeToAndCall}.
|
69
|
+
*
|
70
|
+
* Requirements:
|
71
|
+
*
|
72
|
+
* - This contract must be the admin of `proxy`.
|
73
|
+
*/
|
74
|
+
function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {
|
75
|
+
proxy.upgradeToAndCall{value: msg.value}(implementation, data);
|
76
|
+
}
|
77
|
+
}
|
@@ -0,0 +1,151 @@
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
2
|
+
|
3
|
+
pragma solidity >=0.6.0 <0.8.0;
|
4
|
+
|
5
|
+
import "./UpgradeableProxy.sol";
|
6
|
+
|
7
|
+
/**
|
8
|
+
* @dev This contract implements a proxy that is upgradeable by an admin.
|
9
|
+
*
|
10
|
+
* To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector
|
11
|
+
* clashing], which can potentially be used in an attack, this contract uses the
|
12
|
+
* https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two
|
13
|
+
* things that go hand in hand:
|
14
|
+
*
|
15
|
+
* 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if
|
16
|
+
* that call matches one of the admin functions exposed by the proxy itself.
|
17
|
+
* 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the
|
18
|
+
* implementation. If the admin tries to call a function on the implementation it will fail with an error that says
|
19
|
+
* "admin cannot fallback to proxy target".
|
20
|
+
*
|
21
|
+
* These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing
|
22
|
+
* the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due
|
23
|
+
* to sudden errors when trying to call a function from the proxy implementation.
|
24
|
+
*
|
25
|
+
* Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,
|
26
|
+
* you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.
|
27
|
+
*/
|
28
|
+
contract TransparentUpgradeableProxy is UpgradeableProxy {
|
29
|
+
/**
|
30
|
+
* @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and
|
31
|
+
* optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.
|
32
|
+
*/
|
33
|
+
constructor(address _logic, address admin_, bytes memory _data) public payable UpgradeableProxy(_logic, _data) {
|
34
|
+
assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1));
|
35
|
+
_setAdmin(admin_);
|
36
|
+
}
|
37
|
+
|
38
|
+
/**
|
39
|
+
* @dev Emitted when the admin account has changed.
|
40
|
+
*/
|
41
|
+
event AdminChanged(address previousAdmin, address newAdmin);
|
42
|
+
|
43
|
+
/**
|
44
|
+
* @dev Storage slot with the admin of the contract.
|
45
|
+
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
|
46
|
+
* validated in the constructor.
|
47
|
+
*/
|
48
|
+
bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
|
49
|
+
|
50
|
+
/**
|
51
|
+
* @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.
|
52
|
+
*/
|
53
|
+
modifier ifAdmin() {
|
54
|
+
if (msg.sender == _admin()) {
|
55
|
+
_;
|
56
|
+
} else {
|
57
|
+
_fallback();
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
/**
|
62
|
+
* @dev Returns the current admin.
|
63
|
+
*
|
64
|
+
* NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.
|
65
|
+
*
|
66
|
+
* TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
|
67
|
+
* https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
|
68
|
+
* `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
|
69
|
+
*/
|
70
|
+
function admin() external ifAdmin returns (address admin_) {
|
71
|
+
admin_ = _admin();
|
72
|
+
}
|
73
|
+
|
74
|
+
/**
|
75
|
+
* @dev Returns the current implementation.
|
76
|
+
*
|
77
|
+
* NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.
|
78
|
+
*
|
79
|
+
* TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
|
80
|
+
* https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
|
81
|
+
* `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
|
82
|
+
*/
|
83
|
+
function implementation() external ifAdmin returns (address implementation_) {
|
84
|
+
implementation_ = _implementation();
|
85
|
+
}
|
86
|
+
|
87
|
+
/**
|
88
|
+
* @dev Changes the admin of the proxy.
|
89
|
+
*
|
90
|
+
* Emits an {AdminChanged} event.
|
91
|
+
*
|
92
|
+
* NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.
|
93
|
+
*/
|
94
|
+
function changeAdmin(address newAdmin) external virtual ifAdmin {
|
95
|
+
require(newAdmin != address(0), "TransparentUpgradeableProxy: new admin is the zero address");
|
96
|
+
emit AdminChanged(_admin(), newAdmin);
|
97
|
+
_setAdmin(newAdmin);
|
98
|
+
}
|
99
|
+
|
100
|
+
/**
|
101
|
+
* @dev Upgrade the implementation of the proxy.
|
102
|
+
*
|
103
|
+
* NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.
|
104
|
+
*/
|
105
|
+
function upgradeTo(address newImplementation) external virtual ifAdmin {
|
106
|
+
_upgradeTo(newImplementation);
|
107
|
+
}
|
108
|
+
|
109
|
+
/**
|
110
|
+
* @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified
|
111
|
+
* by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the
|
112
|
+
* proxied contract.
|
113
|
+
*
|
114
|
+
* NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.
|
115
|
+
*/
|
116
|
+
function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {
|
117
|
+
_upgradeTo(newImplementation);
|
118
|
+
Address.functionDelegateCall(newImplementation, data);
|
119
|
+
}
|
120
|
+
|
121
|
+
/**
|
122
|
+
* @dev Returns the current admin.
|
123
|
+
*/
|
124
|
+
function _admin() internal view virtual returns (address adm) {
|
125
|
+
bytes32 slot = _ADMIN_SLOT;
|
126
|
+
// solhint-disable-next-line no-inline-assembly
|
127
|
+
assembly {
|
128
|
+
adm := sload(slot)
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
/**
|
133
|
+
* @dev Stores a new address in the EIP1967 admin slot.
|
134
|
+
*/
|
135
|
+
function _setAdmin(address newAdmin) private {
|
136
|
+
bytes32 slot = _ADMIN_SLOT;
|
137
|
+
|
138
|
+
// solhint-disable-next-line no-inline-assembly
|
139
|
+
assembly {
|
140
|
+
sstore(slot, newAdmin)
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
/**
|
145
|
+
* @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.
|
146
|
+
*/
|
147
|
+
function _beforeFallback() internal virtual override {
|
148
|
+
require(msg.sender != _admin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target");
|
149
|
+
super._beforeFallback();
|
150
|
+
}
|
151
|
+
}
|
@@ -0,0 +1,64 @@
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
2
|
+
|
3
|
+
pragma solidity >=0.6.0 <0.8.0;
|
4
|
+
|
5
|
+
import "./IBeacon.sol";
|
6
|
+
import "../access/Ownable.sol";
|
7
|
+
import "../utils/Address.sol";
|
8
|
+
|
9
|
+
/**
|
10
|
+
* @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their
|
11
|
+
* implementation contract, which is where they will delegate all function calls.
|
12
|
+
*
|
13
|
+
* An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.
|
14
|
+
*/
|
15
|
+
contract UpgradeableBeacon is IBeacon, Ownable {
|
16
|
+
address private _implementation;
|
17
|
+
|
18
|
+
/**
|
19
|
+
* @dev Emitted when the implementation returned by the beacon is changed.
|
20
|
+
*/
|
21
|
+
event Upgraded(address indexed implementation);
|
22
|
+
|
23
|
+
/**
|
24
|
+
* @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the
|
25
|
+
* beacon.
|
26
|
+
*/
|
27
|
+
constructor(address implementation_) public {
|
28
|
+
_setImplementation(implementation_);
|
29
|
+
}
|
30
|
+
|
31
|
+
/**
|
32
|
+
* @dev Returns the current implementation address.
|
33
|
+
*/
|
34
|
+
function implementation() public view virtual override returns (address) {
|
35
|
+
return _implementation;
|
36
|
+
}
|
37
|
+
|
38
|
+
/**
|
39
|
+
* @dev Upgrades the beacon to a new implementation.
|
40
|
+
*
|
41
|
+
* Emits an {Upgraded} event.
|
42
|
+
*
|
43
|
+
* Requirements:
|
44
|
+
*
|
45
|
+
* - msg.sender must be the owner of the contract.
|
46
|
+
* - `newImplementation` must be a contract.
|
47
|
+
*/
|
48
|
+
function upgradeTo(address newImplementation) public virtual onlyOwner {
|
49
|
+
_setImplementation(newImplementation);
|
50
|
+
emit Upgraded(newImplementation);
|
51
|
+
}
|
52
|
+
|
53
|
+
/**
|
54
|
+
* @dev Sets the implementation contract address for this beacon
|
55
|
+
*
|
56
|
+
* Requirements:
|
57
|
+
*
|
58
|
+
* - `newImplementation` must be a contract.
|
59
|
+
*/
|
60
|
+
function _setImplementation(address newImplementation) private {
|
61
|
+
require(Address.isContract(newImplementation), "UpgradeableBeacon: implementation is not a contract");
|
62
|
+
_implementation = newImplementation;
|
63
|
+
}
|
64
|
+
}
|
@@ -0,0 +1,78 @@
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
2
|
+
|
3
|
+
pragma solidity >=0.6.0 <0.8.0;
|
4
|
+
|
5
|
+
import "./Proxy.sol";
|
6
|
+
import "../utils/Address.sol";
|
7
|
+
|
8
|
+
/**
|
9
|
+
* @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
|
10
|
+
* implementation address that can be changed. This address is stored in storage in the location specified by
|
11
|
+
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the
|
12
|
+
* implementation behind the proxy.
|
13
|
+
*
|
14
|
+
* Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see
|
15
|
+
* {TransparentUpgradeableProxy}.
|
16
|
+
*/
|
17
|
+
contract UpgradeableProxy is Proxy {
|
18
|
+
/**
|
19
|
+
* @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.
|
20
|
+
*
|
21
|
+
* If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded
|
22
|
+
* function call, and allows initializating the storage of the proxy like a Solidity constructor.
|
23
|
+
*/
|
24
|
+
constructor(address _logic, bytes memory _data) public payable {
|
25
|
+
assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1));
|
26
|
+
_setImplementation(_logic);
|
27
|
+
if(_data.length > 0) {
|
28
|
+
Address.functionDelegateCall(_logic, _data);
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
/**
|
33
|
+
* @dev Emitted when the implementation is upgraded.
|
34
|
+
*/
|
35
|
+
event Upgraded(address indexed implementation);
|
36
|
+
|
37
|
+
/**
|
38
|
+
* @dev Storage slot with the address of the current implementation.
|
39
|
+
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
|
40
|
+
* validated in the constructor.
|
41
|
+
*/
|
42
|
+
bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
|
43
|
+
|
44
|
+
/**
|
45
|
+
* @dev Returns the current implementation address.
|
46
|
+
*/
|
47
|
+
function _implementation() internal view virtual override returns (address impl) {
|
48
|
+
bytes32 slot = _IMPLEMENTATION_SLOT;
|
49
|
+
// solhint-disable-next-line no-inline-assembly
|
50
|
+
assembly {
|
51
|
+
impl := sload(slot)
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
/**
|
56
|
+
* @dev Upgrades the proxy to a new implementation.
|
57
|
+
*
|
58
|
+
* Emits an {Upgraded} event.
|
59
|
+
*/
|
60
|
+
function _upgradeTo(address newImplementation) internal virtual {
|
61
|
+
_setImplementation(newImplementation);
|
62
|
+
emit Upgraded(newImplementation);
|
63
|
+
}
|
64
|
+
|
65
|
+
/**
|
66
|
+
* @dev Stores a new address in the EIP1967 implementation slot.
|
67
|
+
*/
|
68
|
+
function _setImplementation(address newImplementation) private {
|
69
|
+
require(Address.isContract(newImplementation), "UpgradeableProxy: new implementation is not a contract");
|
70
|
+
|
71
|
+
bytes32 slot = _IMPLEMENTATION_SLOT;
|
72
|
+
|
73
|
+
// solhint-disable-next-line no-inline-assembly
|
74
|
+
assembly {
|
75
|
+
sstore(slot, newImplementation)
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|