I am trying to implement the following governance pattern but facing issues so wanted to check if this is supported
We have a GovernorA with TimelockX and GovernorB with TimelockY and would like to have GovernorA with TimelockX be the governance mechanism for the GovernorSettings of GovernorB.
Following the contracts, I can override the _executor() in GovernorB and set it to TimelockX. However when I execute a successful proposal via this route, I get a TimelockController: underlying transaction reverted error back from the TimelockX.execute call. Sample foundry trace below:
In the above example I am trying to GovernorB::setVotingPeriod and I know for a fact this call is successful because if I read the return data of TimelockController._execute()target.call I get the event back for a successful new VotingPeriod set.
I suspect this scenario is not supported but wanted to double check with you. Thanks
to relate this code to the original example, GovernorA with TimelockX = ZeroExProtocolGovernor with ZeroExTimelock instance for protocol
and GovernorB with TimelockY = ZeroExTreasuryGovernor with ZeroExTimelock instance for treasury.
You can see how the tests for updating the GovernanceSettings in ZeroExTreasuryGovernor fail.
It seems like you add a new variable protocolTimelock in ZeroExTreasuryGovernor.sol, so there are two timelock variables in your ZeroExTreasuryGovernor.sol contract, they are protocolTimelock and _timelock, I do not think it can work as well as you expect, in your description, GovernorA with TimelockX and GovernorB with TimelockY, I think you can call TimelockY. updateTimelock(TimelockX), so then TimelockX can control GovernorA and GovernorB at the same time.
The reason that this is failing is that the "Settings" module uses the onlyGovernance modifier. This modifier doesn't just check that the sender is _executor, it also has a mechanism to make sure the transactions actually go through the Governor's own governance protocol. This mechanism is what's failing in your transaction trace.
I think your best option is to fork the GovernorSettings contract and use a modifier other than onlyGovernance.