UpgradeableBeacon.sol 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.0;
  3. import "./IBeacon.sol";
  4. import "../access/Ownable.sol";
  5. import "../utils/Address.sol";
  6. /**
  7. * @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their
  8. * implementation contract, which is where they will delegate all function calls.
  9. *
  10. * An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.
  11. */
  12. contract UpgradeableBeacon is IBeacon, Ownable {
  13. address private _implementation;
  14. /**
  15. * @dev Emitted when the implementation returned by the beacon is changed.
  16. */
  17. event Upgraded(address indexed implementation);
  18. /**
  19. * @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the
  20. * beacon.
  21. */
  22. constructor(address implementation_) {
  23. _setImplementation(implementation_);
  24. }
  25. /**
  26. * @dev Returns the current implementation address.
  27. */
  28. function implementation() public view virtual override returns (address) {
  29. return _implementation;
  30. }
  31. /**
  32. * @dev Upgrades the beacon to a new implementation.
  33. *
  34. * Emits an {Upgraded} event.
  35. *
  36. * Requirements:
  37. *
  38. * - msg.sender must be the owner of the contract.
  39. * - `newImplementation` must be a contract.
  40. */
  41. function upgradeTo(address newImplementation) public virtual onlyOwner {
  42. _setImplementation(newImplementation);
  43. emit Upgraded(newImplementation);
  44. }
  45. /**
  46. * @dev Sets the implementation contract address for this beacon
  47. *
  48. * Requirements:
  49. *
  50. * - `newImplementation` must be a contract.
  51. */
  52. function _setImplementation(address newImplementation) private {
  53. require(Address.isContract(newImplementation), "UpgradeableBeacon: implementation is not a contract");
  54. _implementation = newImplementation;
  55. }
  56. }