ERC1967Upgrade.sol 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.2;
  3. import "./ERC1967Storage.sol";
  4. /**
  5. * @dev This abstract contract provides event emitting update functions for
  6. * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
  7. *
  8. * @custom:oz-upgrades-unsafe-allow delegatecall
  9. */
  10. abstract contract ERC1967Upgrade is ERC1967Storage {
  11. // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
  12. bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;
  13. /**
  14. * @dev Emitted when the implementation is upgraded.
  15. */
  16. event Upgraded(address indexed implementation);
  17. /**
  18. * @dev Emitted when the beacon is upgraded.
  19. */
  20. event BeaconUpgraded(address indexed beacon);
  21. /**
  22. * @dev Emitted when the admin account has changed.
  23. */
  24. event AdminChanged(address previousAdmin, address newAdmin);
  25. /**
  26. * @dev Perform implementation upgrade
  27. *
  28. * Emits an {Upgraded} event.
  29. */
  30. function _upgradeTo(address newImplementation) internal {
  31. _setImplementation(newImplementation);
  32. emit Upgraded(newImplementation);
  33. }
  34. /**
  35. * @dev Perform implementation upgrade with additional setup call.
  36. *
  37. * Emits an {Upgraded} event.
  38. */
  39. function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {
  40. _setImplementation(newImplementation);
  41. emit Upgraded(newImplementation);
  42. if (data.length > 0 || forceCall) {
  43. Address.functionDelegateCall(newImplementation, data);
  44. }
  45. }
  46. /**
  47. * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
  48. *
  49. * Emits an {Upgraded} event.
  50. */
  51. function _upgradeToAndCallSecure(address newImplementation, bytes memory data, bool forceCall) internal {
  52. address oldImplementation = _getImplementation();
  53. // do inital upgrade
  54. _setImplementation(newImplementation);
  55. // do setup call
  56. if (data.length > 0 || forceCall) {
  57. Address.functionDelegateCall(newImplementation, data);
  58. }
  59. // check if nested in an upgrade check
  60. StorageSlot.BooleanSlot storage rollbackTesting = StorageSlot.getBooleanSlot(_ROLLBACK_SLOT);
  61. if (!rollbackTesting.value) {
  62. // trigger upgrade check with flag set to true
  63. rollbackTesting.value = true;
  64. Address.functionDelegateCall(
  65. newImplementation,
  66. abi.encodeWithSignature(
  67. "upgradeTo(address)",
  68. oldImplementation
  69. )
  70. );
  71. rollbackTesting.value = false;
  72. // check upgrade was effective
  73. require(oldImplementation == _getImplementation(), "ERC1967Upgrade: upgrade breaks further upgrades");
  74. // reset upgrade
  75. _setImplementation(newImplementation);
  76. // emit event
  77. emit Upgraded(newImplementation);
  78. }
  79. }
  80. /**
  81. * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
  82. * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
  83. *
  84. * Emits a {BeaconUpgraded} event.
  85. */
  86. function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {
  87. _setBeacon(newBeacon);
  88. emit BeaconUpgraded(newBeacon);
  89. if (data.length > 0 || forceCall) {
  90. Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
  91. }
  92. }
  93. /**
  94. * @dev Changes the admin of the proxy.
  95. *
  96. * Emits an {AdminChanged} event.
  97. */
  98. function _changeAdmin(address newAdmin) internal {
  99. emit AdminChanged(_getAdmin(), newAdmin);
  100. _setAdmin(newAdmin);
  101. }
  102. }