GovernorProposalGuardian.sol 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.20;
  3. import {Governor} from "../Governor.sol";
  4. /**
  5. * @dev Extension of {Governor} which adds a proposal guardian that can cancel proposals at any stage in the proposal's lifecycle.
  6. *
  7. * NOTE: if the proposal guardian is not configured, then proposers take this role for their proposals.
  8. */
  9. abstract contract GovernorProposalGuardian is Governor {
  10. address private _proposalGuardian;
  11. event ProposalGuardianSet(address oldProposalGuardian, address newProposalGuardian);
  12. /**
  13. * @dev Getter that returns the address of the proposal guardian.
  14. */
  15. function proposalGuardian() public view virtual returns (address) {
  16. return _proposalGuardian;
  17. }
  18. /**
  19. * @dev Update the proposal guardian's address. This operation can only be performed through a governance proposal.
  20. *
  21. * Emits a {ProposalGuardianSet} event.
  22. */
  23. function setProposalGuardian(address newProposalGuardian) public virtual onlyGovernance {
  24. _setProposalGuardian(newProposalGuardian);
  25. }
  26. /**
  27. * @dev Internal setter for the proposal guardian.
  28. *
  29. * Emits a {ProposalGuardianSet} event.
  30. */
  31. function _setProposalGuardian(address newProposalGuardian) internal virtual {
  32. emit ProposalGuardianSet(_proposalGuardian, newProposalGuardian);
  33. _proposalGuardian = newProposalGuardian;
  34. }
  35. /**
  36. * @dev Override {Governor-_validateCancel} to implement the extended cancellation logic.
  37. *
  38. * * The {proposalGuardian} can cancel any proposal at any point.
  39. * * If no proposal guardian is set, the {IGovernor-proposalProposer} can cancel their proposals at any point.
  40. * * In any case, permissions defined in {Governor-_validateCancel} (or another override) remains valid.
  41. */
  42. function _validateCancel(uint256 proposalId, address caller) internal view virtual override returns (bool) {
  43. address guardian = proposalGuardian();
  44. return
  45. guardian == caller ||
  46. (guardian == address(0) && caller == proposalProposer(proposalId)) ||
  47. super._validateCancel(proposalId, caller);
  48. }
  49. }