2020-05-29 16:45:37 +00:00
|
|
|
// SPDX-License-Identifier: agpl-3.0
|
2020-11-20 10:45:20 +00:00
|
|
|
pragma solidity 0.6.12;
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
import './Proxy.sol';
|
2020-10-15 13:41:56 +00:00
|
|
|
import '../contracts/Address.sol';
|
2020-05-29 16:45:37 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @title BaseUpgradeabilityProxy
|
|
|
|
* @dev This contract implements a proxy that allows to change the
|
|
|
|
* implementation address to which it will delegate.
|
|
|
|
* Such a change is called an implementation upgrade.
|
|
|
|
*/
|
|
|
|
contract BaseUpgradeabilityProxy is Proxy {
|
2020-07-13 08:54:08 +00:00
|
|
|
/**
|
2020-05-29 16:45:37 +00:00
|
|
|
* @dev Emitted when the implementation is upgraded.
|
|
|
|
* @param implementation Address of the new implementation.
|
|
|
|
*/
|
2020-07-13 08:54:08 +00:00
|
|
|
event Upgraded(address indexed implementation);
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
/**
|
2020-05-29 16:45:37 +00:00
|
|
|
* @dev Storage slot with the address of the current implementation.
|
|
|
|
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
|
|
|
|
* validated in the constructor.
|
|
|
|
*/
|
2021-01-27 14:43:34 +00:00
|
|
|
bytes32 internal constant IMPLEMENTATION_SLOT =
|
|
|
|
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
/**
|
2020-05-29 16:45:37 +00:00
|
|
|
* @dev Returns the current implementation.
|
|
|
|
* @return impl Address of the current implementation
|
|
|
|
*/
|
2021-01-27 14:43:34 +00:00
|
|
|
function _implementation() internal view override returns (address impl) {
|
2020-07-13 08:54:08 +00:00
|
|
|
bytes32 slot = IMPLEMENTATION_SLOT;
|
|
|
|
//solium-disable-next-line
|
|
|
|
assembly {
|
|
|
|
impl := sload(slot)
|
2020-05-29 16:45:37 +00:00
|
|
|
}
|
2020-07-13 08:54:08 +00:00
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
/**
|
2020-05-29 16:45:37 +00:00
|
|
|
* @dev Upgrades the proxy to a new implementation.
|
|
|
|
* @param newImplementation Address of the new implementation.
|
|
|
|
*/
|
2020-07-13 08:54:08 +00:00
|
|
|
function _upgradeTo(address newImplementation) internal {
|
|
|
|
_setImplementation(newImplementation);
|
|
|
|
emit Upgraded(newImplementation);
|
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
/**
|
2020-05-29 16:45:37 +00:00
|
|
|
* @dev Sets the implementation address of the proxy.
|
|
|
|
* @param newImplementation Address of the new implementation.
|
|
|
|
*/
|
2020-07-13 08:54:08 +00:00
|
|
|
function _setImplementation(address newImplementation) internal {
|
|
|
|
require(
|
|
|
|
Address.isContract(newImplementation),
|
|
|
|
'Cannot set a proxy implementation to a non-contract address'
|
|
|
|
);
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
bytes32 slot = IMPLEMENTATION_SLOT;
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
//solium-disable-next-line
|
|
|
|
assembly {
|
|
|
|
sstore(slot, newImplementation)
|
2020-05-29 16:45:37 +00:00
|
|
|
}
|
2020-07-13 08:54:08 +00:00
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
}
|