From d681a212722475125973db757839930d47324419 Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 13 Oct 2020 10:28:52 +0200 Subject: [PATCH] Added immutable proxies --- .../BaseImmutableAdminUpgradeabilityProxy.sol | 80 +++++++++++++++++++ .../ImmutableAdminUpgradeabilityProxy.sol | 35 ++++++++ 2 files changed, 115 insertions(+) create mode 100644 contracts/libraries/aave-upgradeability/BaseImmutableAdminUpgradeabilityProxy.sol create mode 100644 contracts/libraries/aave-upgradeability/ImmutableAdminUpgradeabilityProxy.sol diff --git a/contracts/libraries/aave-upgradeability/BaseImmutableAdminUpgradeabilityProxy.sol b/contracts/libraries/aave-upgradeability/BaseImmutableAdminUpgradeabilityProxy.sol new file mode 100644 index 00000000..23a5f2eb --- /dev/null +++ b/contracts/libraries/aave-upgradeability/BaseImmutableAdminUpgradeabilityProxy.sol @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: agpl-3.0 +pragma solidity ^0.6.8; + +import '../openzeppelin-upgradeability/BaseUpgradeabilityProxy.sol'; + +/** + * @title BaseAdminUpgradeabilityProxy + * @dev This contract combines an upgradeability proxy with an authorization + * mechanism for administrative tasks. + * All external functions in this contract must be guarded by the + * `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity + * feature proposal that would enable this to be done automatically. + */ +contract BaseImmutableAdminUpgradeabilityProxy is BaseUpgradeabilityProxy { + + address immutable ADMIN; + + constructor(address admin) public { + ADMIN = admin; + } + + modifier ifAdmin() { + if (msg.sender == ADMIN) { + _; + } else { + _fallback(); + } + } + + /** + * @return The address of the proxy admin. + */ + function admin() external ifAdmin returns (address) { + return ADMIN; + } + + /** + * @return The address of the implementation. + */ + function implementation() external ifAdmin returns (address) { + return _implementation(); + } + + /** + * @dev Upgrade the backing implementation of the proxy. + * Only the admin can call this function. + * @param newImplementation Address of the new implementation. + */ + function upgradeTo(address newImplementation) external ifAdmin { + _upgradeTo(newImplementation); + } + + /** + * @dev Upgrade the backing implementation of the proxy and call a function + * on the new implementation. + * This is useful to initialize the proxied contract. + * @param newImplementation Address of the new implementation. + * @param data Data to send as msg.data in the low level call. + * It should include the signature and the parameters of the function to be called, as described in + * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. + */ + function upgradeToAndCall(address newImplementation, bytes calldata data) + external + payable + ifAdmin + { + _upgradeTo(newImplementation); + (bool success, ) = newImplementation.delegatecall(data); + require(success); + } + + + /** + * @dev Only fall back when the sender is not the admin. + */ + function _willFallback() internal virtual override { + require(msg.sender != ADMIN, 'Cannot call fallback function from the proxy admin'); + super._willFallback(); + } +} diff --git a/contracts/libraries/aave-upgradeability/ImmutableAdminUpgradeabilityProxy.sol b/contracts/libraries/aave-upgradeability/ImmutableAdminUpgradeabilityProxy.sol new file mode 100644 index 00000000..5ee8f914 --- /dev/null +++ b/contracts/libraries/aave-upgradeability/ImmutableAdminUpgradeabilityProxy.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: agpl-3.0 +pragma solidity ^0.6.8; + +import './BaseImmutableAdminUpgradeabilityProxy.sol'; +import '../openzeppelin-upgradeability/UpgradeabilityProxy.sol'; + +/** + * @title AdminUpgradeabilityProxy + * @dev Extends from BaseAdminUpgradeabilityProxy with a constructor for + * initializing the implementation, admin, and init data. + */ +contract ImmutableAdminUpgradeabilityProxy is BaseImmutableAdminUpgradeabilityProxy, UpgradeabilityProxy { + /** + * Contract constructor. + * @param _logic address of the initial implementation. + * @param _admin Address of the proxy administrator. + * @param _data Data to send as msg.data to the implementation to initialize the proxied contract. + * It should include the signature and the parameters of the function to be called, as described in + * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. + * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. + */ + constructor( + address _logic, + address _admin, + bytes memory _data + ) public payable UpgradeabilityProxy(_logic, _data) BaseImmutableAdminUpgradeabilityProxy(_admin) { + } + + /** + * @dev Only fall back when the sender is not the admin. + */ + function _willFallback() internal override(BaseImmutableAdminUpgradeabilityProxy, Proxy) { + BaseImmutableAdminUpgradeabilityProxy._willFallback(); + } +}