How to limit canceller role so that it cannot cancel every proposal?

In openzeppelin governance contracts, a proposal can be cancelled by a wallet that has the canceller role. As the deployer of the DAO, I want to ensure the security of my DAO, hence I want to be able to cancel some proposals, but not all of them. If I have the canceller role, I can cancel all proposals which is not something that I want and is completely centralized. Is there a way to limit the role so that I cannot cancel some proposals? Maybe with an additional requirement statement in setter functions (functions that timelock calls to set variables after a successful proposals)?

An example provided below

Example
Say that someone created a proposal which is not feasible (or harmful) to implement. I want to be able to cancel that proposal. On the other hand, someone created a proposal to change the reward given to the governance members. I shouldn't have the power to cancel it. How can I achieve that? Below is how I grant the CANCELLER_ROLE. I'm using time lock controller in governance and admin is me:

const CANCELLER_ROLE = await contractTimelockController.CANCELLER_ROLE();
  await contractTimelockController.grantRole(
    CANCELLER_ROLE,
    admin.address
  );

Hey @DoDzilla,

Indeed, the Timelock offers a way of canceling operations restricted to the CANCELLER_ROLE, so in order to customize its behavior of the cancel function I'd recommend assigning the CANCELLER_ROLE to a multi-sig or a controlled account.

A good option can be using OpenZeppelin Defender to setup a Relayer that can execute a cancellation. The reason to recommend an automation like this is because you can keep an auditability track of who's using the Relayer while also restricting access for your organization (maybe DAO members).

Other than that you can also assign the CANCELLER_ROLE to a multisig account (can recommend Safe Multisig) but that may add friction to the response speed, which you may consider if that speed is critical.

Best!

1 Like