123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- // SPDX-License-Identifier: MIT
- pragma solidity ^0.8.3;
- import "./ERC1967Storage.sol";
- /**
- * @dev This abstract contract provides event emitting update functions for
- * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
- *
- * @custom:oz-upgrades-unsafe-allow delegatecall
- */
- abstract contract ERC1967Upgrade is ERC1967Storage {
- // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
- bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;
- /**
- * @dev Emitted when the implementation is upgraded.
- */
- event Upgraded(address indexed implementation);
- /**
- * @dev Emitted when the beacon is upgraded.
- */
- event BeaconUpgraded(address indexed beacon);
- /**
- * @dev Emitted when the admin account has changed.
- */
- event AdminChanged(address previousAdmin, address newAdmin);
- /**
- * @dev Perform implementation upgrade
- *
- * Emits an {Upgraded} event.
- */
- function _upgradeTo(address newImplementation) internal {
- _setImplementation(newImplementation);
- emit Upgraded(newImplementation);
- }
- /**
- * @dev Perform implementation upgrade with additional setup call.
- *
- * Emits an {Upgraded} event.
- */
- function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {
- _setImplementation(newImplementation);
- emit Upgraded(newImplementation);
- if (data.length > 0 || forceCall) {
- Address.functionDelegateCall(newImplementation, data);
- }
- }
- /**
- * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
- *
- * Emits an {Upgraded} event.
- */
- function _upgradeToAndCallSecure(address newImplementation, bytes memory data, bool forceCall) internal {
- address oldImplementation = _getImplementation();
- // do inital upgrade
- _setImplementation(newImplementation);
- // do setup call
- if (data.length > 0 || forceCall) {
- Address.functionDelegateCall(newImplementation, data);
- }
- // check if nested in an upgrade check
- StorageSlot.BooleanSlot storage rollbackTesting = StorageSlot.getBooleanSlot(_ROLLBACK_SLOT);
- if (!rollbackTesting.value) {
- // trigger upgrade check with flag set to true
- rollbackTesting.value = true;
- Address.functionDelegateCall(
- newImplementation,
- abi.encodeWithSignature(
- "upgradeTo(address)",
- oldImplementation
- )
- );
- rollbackTesting.value = false;
- // check upgrade was effective
- require(oldImplementation == _getImplementation(), "ERC1967Upgrade: upgrade breaks further upgrades");
- // reset upgrade
- _setImplementation(newImplementation);
- // emit event
- emit Upgraded(newImplementation);
- }
- }
- /**
- * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
- * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
- *
- * Emits a {BeaconUpgraded} event.
- */
- function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {
- _setBeacon(newBeacon);
- emit BeaconUpgraded(newBeacon);
- if (data.length > 0 || forceCall) {
- Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
- }
- }
- /**
- * @dev Changes the admin of the proxy.
- *
- * Emits an {AdminChanged} event.
- */
- function _changeAdmin(address newAdmin) internal {
- emit AdminChanged(_getAdmin(), newAdmin);
- _setAdmin(newAdmin);
- }
- }
|