Merge branch 'master' into next-v5.0
This commit is contained in:
@ -1,9 +1,10 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)
|
||||
// OpenZeppelin Contracts (last updated v4.8.3) (proxy/ERC1967/ERC1967Upgrade.sol)
|
||||
|
||||
pragma solidity ^0.8.2;
|
||||
|
||||
import "../beacon/IBeacon.sol";
|
||||
import "../../interfaces/IERC1967.sol";
|
||||
import "../../interfaces/draft-IERC1822.sol";
|
||||
import "../../utils/Address.sol";
|
||||
import "../../utils/StorageSlot.sol";
|
||||
@ -13,10 +14,8 @@ import "../../utils/StorageSlot.sol";
|
||||
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
|
||||
*
|
||||
* _Available since v4.1._
|
||||
*
|
||||
* @custom:oz-upgrades-unsafe-allow delegatecall
|
||||
*/
|
||||
abstract contract ERC1967Upgrade {
|
||||
abstract contract ERC1967Upgrade is IERC1967 {
|
||||
// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
|
||||
bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;
|
||||
|
||||
@ -27,11 +26,6 @@ abstract contract ERC1967Upgrade {
|
||||
*/
|
||||
bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
|
||||
|
||||
/**
|
||||
* @dev Emitted when the implementation is upgraded.
|
||||
*/
|
||||
event Upgraded(address indexed implementation);
|
||||
|
||||
/**
|
||||
* @dev Returns the current implementation address.
|
||||
*/
|
||||
@ -97,11 +91,6 @@ abstract contract ERC1967Upgrade {
|
||||
*/
|
||||
bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
|
||||
|
||||
/**
|
||||
* @dev Emitted when the admin account has changed.
|
||||
*/
|
||||
event AdminChanged(address previousAdmin, address newAdmin);
|
||||
|
||||
/**
|
||||
* @dev Returns the current admin.
|
||||
*
|
||||
@ -137,11 +126,6 @@ abstract contract ERC1967Upgrade {
|
||||
*/
|
||||
bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
|
||||
|
||||
/**
|
||||
* @dev Emitted when the beacon is upgraded.
|
||||
*/
|
||||
event BeaconUpgraded(address indexed beacon);
|
||||
|
||||
/**
|
||||
* @dev Returns the current beacon.
|
||||
*/
|
||||
|
||||
@ -56,6 +56,8 @@ The current implementation of this security mechanism uses https://eips.ethereum
|
||||
|
||||
== ERC1967
|
||||
|
||||
{{IERC1967}}
|
||||
|
||||
{{ERC1967Proxy}}
|
||||
|
||||
{{ERC1967Upgrade}}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)
|
||||
// OpenZeppelin Contracts (last updated v4.8.3) (proxy/transparent/ProxyAdmin.sol)
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
@ -18,7 +18,7 @@ contract ProxyAdmin is Ownable {
|
||||
*
|
||||
* - This contract must be the current admin of `proxy`.
|
||||
*/
|
||||
function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {
|
||||
function changeProxyAdmin(ITransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {
|
||||
proxy.changeAdmin(newAdmin);
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ contract ProxyAdmin is Ownable {
|
||||
*
|
||||
* - This contract must be the admin of `proxy`.
|
||||
*/
|
||||
function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {
|
||||
function upgrade(ITransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {
|
||||
proxy.upgradeTo(implementation);
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ contract ProxyAdmin is Ownable {
|
||||
* - This contract must be the admin of `proxy`.
|
||||
*/
|
||||
function upgradeAndCall(
|
||||
TransparentUpgradeableProxy proxy,
|
||||
ITransparentUpgradeableProxy proxy,
|
||||
address implementation,
|
||||
bytes memory data
|
||||
) public payable virtual onlyOwner {
|
||||
|
||||
@ -1,10 +1,24 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.7.0) (proxy/transparent/TransparentUpgradeableProxy.sol)
|
||||
// OpenZeppelin Contracts (last updated v4.8.3) (proxy/transparent/TransparentUpgradeableProxy.sol)
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "../ERC1967/ERC1967Proxy.sol";
|
||||
|
||||
/**
|
||||
* @dev Interface for {TransparentUpgradeableProxy}. In order to implement transparency, {TransparentUpgradeableProxy}
|
||||
* does not implement this interface directly, and some of its functions are implemented by an internal dispatch
|
||||
* mechanism. The compiler is unaware that these functions are implemented by {TransparentUpgradeableProxy} and will not
|
||||
* include them in the ABI so this interface must be used to interact with it.
|
||||
*/
|
||||
interface ITransparentUpgradeableProxy is IERC1967 {
|
||||
function changeAdmin(address) external;
|
||||
|
||||
function upgradeTo(address) external;
|
||||
|
||||
function upgradeToAndCall(address, bytes memory) external payable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev This contract implements a proxy that is upgradeable by an admin.
|
||||
*
|
||||
@ -25,6 +39,17 @@ import "../ERC1967/ERC1967Proxy.sol";
|
||||
*
|
||||
* Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,
|
||||
* you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.
|
||||
*
|
||||
* NOTE: The real interface of this proxy is that defined in `ITransparentUpgradeableProxy`. This contract does not
|
||||
* inherit from that interface, and instead the admin functions are implicitly implemented using a custom dispatch
|
||||
* mechanism in `_fallback`. Consequently, the compiler will not produce an ABI for this contract. This is necessary to
|
||||
* fully implement transparency without decoding reverts caused by selector clashes between the proxy and the
|
||||
* implementation.
|
||||
*
|
||||
* WARNING: It is not recommended to extend this contract to add additional external functions. If you do so, the compiler
|
||||
* will not check that there are no selector conflicts, due to the note above. A selector clash between any new function
|
||||
* and the functions declared in {ITransparentUpgradeableProxy} will be resolved in favor of the new one. This could
|
||||
* render the admin operations inaccessible, which could prevent upgradeability. Transparency may also be compromised.
|
||||
*/
|
||||
contract TransparentUpgradeableProxy is ERC1967Proxy {
|
||||
/**
|
||||
@ -37,6 +62,9 @@ contract TransparentUpgradeableProxy is ERC1967Proxy {
|
||||
|
||||
/**
|
||||
* @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.
|
||||
*
|
||||
* CAUTION: This modifier is deprecated, as it could cause issues if the modified function has arguments, and the
|
||||
* implementation provides a function with the same selector.
|
||||
*/
|
||||
modifier ifAdmin() {
|
||||
if (msg.sender == _getAdmin()) {
|
||||
@ -46,49 +74,82 @@ contract TransparentUpgradeableProxy is ERC1967Proxy {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev If caller is the admin process the call internally, otherwise transparently fallback to the proxy behavior
|
||||
*/
|
||||
function _fallback() internal virtual override {
|
||||
if (msg.sender == _getAdmin()) {
|
||||
bytes memory ret;
|
||||
bytes4 selector = msg.sig;
|
||||
if (selector == ITransparentUpgradeableProxy.upgradeTo.selector) {
|
||||
ret = _dispatchUpgradeTo();
|
||||
} else if (selector == ITransparentUpgradeableProxy.upgradeToAndCall.selector) {
|
||||
ret = _dispatchUpgradeToAndCall();
|
||||
} else if (selector == ITransparentUpgradeableProxy.changeAdmin.selector) {
|
||||
ret = _dispatchChangeAdmin();
|
||||
} else {
|
||||
revert("TransparentUpgradeableProxy: admin cannot fallback to proxy target");
|
||||
}
|
||||
assembly {
|
||||
return(add(ret, 0x20), mload(ret))
|
||||
}
|
||||
} else {
|
||||
super._fallback();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Changes the admin of the proxy.
|
||||
*
|
||||
* Emits an {AdminChanged} event.
|
||||
*
|
||||
* NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.
|
||||
*/
|
||||
function changeAdmin(address newAdmin) external virtual ifAdmin {
|
||||
function _dispatchChangeAdmin() private returns (bytes memory) {
|
||||
_requireZeroValue();
|
||||
|
||||
address newAdmin = abi.decode(msg.data[4:], (address));
|
||||
_changeAdmin(newAdmin);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Upgrade the implementation of the proxy.
|
||||
*
|
||||
* NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.
|
||||
*/
|
||||
function upgradeTo(address newImplementation) external ifAdmin {
|
||||
function _dispatchUpgradeTo() private returns (bytes memory) {
|
||||
_requireZeroValue();
|
||||
|
||||
address newImplementation = abi.decode(msg.data[4:], (address));
|
||||
_upgradeToAndCall(newImplementation, bytes(""), false);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified
|
||||
* by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the
|
||||
* proxied contract.
|
||||
*
|
||||
* NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.
|
||||
*/
|
||||
function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {
|
||||
function _dispatchUpgradeToAndCall() private returns (bytes memory) {
|
||||
(address newImplementation, bytes memory data) = abi.decode(msg.data[4:], (address, bytes));
|
||||
_upgradeToAndCall(newImplementation, data, true);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the current admin.
|
||||
*
|
||||
* CAUTION: This function is deprecated. Use {ERC1967Upgrade-_getAdmin} instead.
|
||||
*/
|
||||
function _admin() internal view virtual returns (address) {
|
||||
return _getAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.
|
||||
* @dev To keep this contract fully transparent, all `ifAdmin` functions must be payable. This helper is here to
|
||||
* emulate some proxy functions being non-payable while still allowing value to pass through.
|
||||
*/
|
||||
function _beforeFallback() internal virtual override {
|
||||
require(msg.sender != _getAdmin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target");
|
||||
super._beforeFallback();
|
||||
function _requireZeroValue() private {
|
||||
require(msg.value == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)
|
||||
// OpenZeppelin Contracts (last updated v4.8.1) (proxy/utils/Initializable.sol)
|
||||
|
||||
pragma solidity ^0.8.2;
|
||||
|
||||
@ -18,12 +18,13 @@ import "../../utils/Address.sol";
|
||||
* For example:
|
||||
*
|
||||
* [.hljs-theme-light.nopadding]
|
||||
* ```
|
||||
* ```solidity
|
||||
* contract MyToken is ERC20Upgradeable {
|
||||
* function initialize() initializer public {
|
||||
* __ERC20_init("MyToken", "MTK");
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
|
||||
* function initializeV2() reinitializer(2) public {
|
||||
* __ERC20Permit_init("MyToken");
|
||||
|
||||
@ -62,8 +62,10 @@ abstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {
|
||||
* Calls {_authorizeUpgrade}.
|
||||
*
|
||||
* Emits an {Upgraded} event.
|
||||
*
|
||||
* @custom:oz-upgrades-unsafe-allow-reachable delegatecall
|
||||
*/
|
||||
function upgradeTo(address newImplementation) external virtual onlyProxy {
|
||||
function upgradeTo(address newImplementation) public virtual onlyProxy {
|
||||
_authorizeUpgrade(newImplementation);
|
||||
_upgradeToAndCallUUPS(newImplementation, new bytes(0), false);
|
||||
}
|
||||
@ -75,8 +77,10 @@ abstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {
|
||||
* Calls {_authorizeUpgrade}.
|
||||
*
|
||||
* Emits an {Upgraded} event.
|
||||
*
|
||||
* @custom:oz-upgrades-unsafe-allow-reachable delegatecall
|
||||
*/
|
||||
function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {
|
||||
function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {
|
||||
_authorizeUpgrade(newImplementation);
|
||||
_upgradeToAndCallUUPS(newImplementation, data, true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user