Skip to content

Commit 5c21639

Browse files
Transpile 85c278b
1 parent 0168fde commit 5c21639

File tree

6 files changed

+43
-7
lines changed

6 files changed

+43
-7
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 4.3.2 (2021-09-14)
4+
5+
* `UUPSUpgradeable`: Add modifiers to prevent `upgradeTo` and `upgradeToAndCall` being executed on any contract that is not the active ERC1967 proxy. This prevents these functions being called on implementation contracts or minimal ERC1167 clones, in particular.
6+
37
## 4.3.1 (2021-08-26)
48

59
* `TimelockController`: Add additional isOperationReady check.

contracts/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@openzeppelin/contracts-upgradeable",
33
"description": "Secure Smart Contract library for Solidity",
4-
"version": "4.3.1",
4+
"version": "4.3.2",
55
"files": [
66
"**/*.sol",
77
"/build/contracts/*.json",

contracts/proxy/utils/UUPSUpgradeable.sol

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,32 @@ abstract contract UUPSUpgradeable is Initializable, ERC1967UpgradeUpgradeable {
2525

2626
function __UUPSUpgradeable_init_unchained() internal initializer {
2727
}
28+
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
29+
address private immutable __self = address(this);
30+
31+
/**
32+
* @dev Check that the execution is being performed through a delegatecall call and that the execution context is
33+
* a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
34+
* for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
35+
* function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
36+
* fail.
37+
*/
38+
modifier onlyProxy() {
39+
require(address(this) != __self, "Function must be called through delegatecall");
40+
require(_getImplementation() == __self, "Function must be called through active proxy");
41+
_;
42+
}
43+
2844
/**
2945
* @dev Upgrade the implementation of the proxy to `newImplementation`.
3046
*
3147
* Calls {_authorizeUpgrade}.
3248
*
3349
* Emits an {Upgraded} event.
3450
*/
35-
function upgradeTo(address newImplementation) external virtual {
51+
function upgradeTo(address newImplementation) external virtual onlyProxy {
3652
_authorizeUpgrade(newImplementation);
37-
_upgradeToAndCallSecure(newImplementation, bytes(""), false);
53+
_upgradeToAndCallSecure(newImplementation, new bytes(0), false);
3854
}
3955

4056
/**
@@ -45,7 +61,7 @@ abstract contract UUPSUpgradeable is Initializable, ERC1967UpgradeUpgradeable {
4561
*
4662
* Emits an {Upgraded} event.
4763
*/
48-
function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual {
64+
function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {
4965
_authorizeUpgrade(newImplementation);
5066
_upgradeToAndCallSecure(newImplementation, data, true);
5167
}

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"private": true,
33
"name": "openzeppelin-solidity",
44
"description": "Secure Smart Contract library for Solidity",
5-
"version": "4.3.1",
5+
"version": "4.3.2",
66
"files": [
77
"/contracts/**/*.sol",
88
"/build/contracts/*.json",
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
diff --git a/contracts/proxy/utils/UUPSUpgradeable.sol b/contracts/proxy/utils/UUPSUpgradeable.sol
2+
index a9568729..860e66d7 100644
3+
--- a/contracts/proxy/utils/UUPSUpgradeable.sol
4+
+++ b/contracts/proxy/utils/UUPSUpgradeable.sol
5+
@@ -24,10 +24,9 @@ abstract contract UUPSUpgradeable is Initializable, ERC1967UpgradeUpgradeable {
6+
}
7+
8+
function __UUPSUpgradeable_init_unchained() internal initializer {
9+
- __self = address(this);
10+
}
11+
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
12+
- address private __self;
13+
+ address private immutable __self = address(this);
14+
15+
/**
16+
* @dev Check that the execution is being performed through a delegatecall call and that the execution context is

0 commit comments

Comments
 (0)