Skip to content

An extension to OpenZeppelin's Governor protocol that restricts access to proposals along external role restricted functions.

License

Notifications You must be signed in to change notification settings

7Cedars/governor-restricted-powers

Repository files navigation

Issues MIT License LinkedIn


Logo

Governor Separated Powers: Introducing separation of powers to OpenZeppelin's Governor Contract

An extension that introduces OpenZeppelin's AccessControl restrictions to the governance processes of Governor derived contracts.
Explore the docs »

View an example contract on sepolia.etherscan.io. · Report Bug · Request Feature

Table of Contents
  1. About
  2. Getting Started
  3. Usage
  4. Roadmap
  5. Contributing
  6. License
  7. Contact
  8. Acknowledgments

About

The extension restricts access to governance processes along restricted roles.

It does this by relating the AccessControl to the Governor contract by restricting who can propose, vote on and execute proposals along the access control of an external function.

Why do this?

  • It enables the separation of powers in a DAO along access roles.
  • This in turn enables the creation of checks and balances between these roles.
  • This is a tried and true approach to safeguarding decentralisation of (social, political and economic) assets in light of their tendency to centralise around informal elites.

How does it work?

  • It has to be used with an additional contract that consists of functions that are set as restricted and, optionally, set as onlyGovernance.
  • Proposing, voting and executing proposals always happen in relation to calling these external restricted function.
  • The governance process is restricted along the role restrictions of these external functions.
  • For example: When an external function is restricted to JUDGE_ROLE, then it is only possible for those holding the JUDGE_ROLE to propose, vote on and execute proposals related to this fucntion.

See the following diagram:

Schema Protocol

Important files and folders

All solidity contracts can be found in the src folder. The folder consists of the following subfolders and files.

governor-extensions

  • GovernorDividedPowers.sol: the extension to OpenZeppelin's governor contract. Overrides the _propose, _countVote and _executeOperations functions. It aims to keep breaking changes to other extensions to a minimum. It incorporates a simple vote counting system based on the GovernorCountingVoteSimple.sol contract.

example-laws

  • LawTemplate.sol: A base contract for functions to use with GovernorDividedPowers.sol. Needs to be inherited by contracts that will be called by the Governor contract.
  • LawsAdministrative.sol: Example function that regulate checks and balances between roles. These all take proposalId from other roles as input variables, to allow their decisions to be checked by a secondary role. IRL, these are called administrative laws.
  • LawsElectoral.sol: Example functions for the selection and deselection of accounts to specific roles. Although often not involving a democratic election, these are laws that 'elect' accounts to particular roles.
  • LawsPublic.sol: These are any kind of function that does not fall into the electoral or administratice bracket. They are usually functions that guide the functioning of the DAO and related smart contracts.

example-governance-system

  • GovernedIdentity.sol: An example implementation of the GovernorDividedPowers.sol extension. It builds on the contracts from the governor-extension and example-laws folders.

(back to top)

Built With

  • Solidity 0.8.24
  • Foundry 0.2.0
  • OpenZeppelin 5.0.2

(back to top)

Getting Started

To get a local copy up and running do the following.

Prerequisites

  • Install git
    • You'll know you did it right if you can run git --version and you see a response like git version x.x.x
  • Install foundry
    • You'll know you did it right if you can run forge --version and you see a response like forge 0.2.0 (816e00b 2023-03-16T00:05:26.396218Z)

Clone the repository

  1. Clone the repo

    git clone https://github.com/7Cedars/governor-restricted-powers
  2. Run make

    cd governor-restricted-powers
    make

Run the test and build the contracts

  1. Run tests

    forge test
  2. Build contracts

    forge build

(back to top)

Known and Open Issues

  • This protocol is under active development. Basic functionality is incomplete.

  • Combining the AccessControl and Governor contracts results in several inconsistencies. Both contracts have their own governance logics and protocol infrastructure. The former revolves around designating and revoking roles that give access to functions; while the latter revolves around proposing and voting for proposals that give access to function execution. As a result

    • Role restrictions of external functions are set from the governance contract, which is a workflow that invites for setting role restrictions incorrectly. They should be set within the functions themselves.
    • There are three different execute functions. One relates to the execution of a proposal (inherited from Governor) while the other two relate to executing an external function (inherited from AccessManager).
    • There are 89 public functions in total. It is excessive and invites for bugs and security risks.
    • The only way to solve these issues is to create an entirely new governance protocol.
  • The GovernorDividedPowers implies two different levels at which votes are cast: A first in which individual members are selected for roles and a second in which role holders vote on proposals. These two levels have different voting logics.

    • The first can be done on the basis of delegated token voting - similar to the default method in the current Governor protocol. For example, the 20 members with most delegated votes are automatically given a councillor role in a DAO.
    • The second cannot have delegated voting and should not (in my opinion) work with weighted votes. It works best with N out of M logics that are similar to multisig wallets. For example, at least 5 judges need to vote yes from a total of 9 to revert a previous decision made by councillors.
    • Implementing two different voting logics in a single governance regime is currently too complex. A solution is to further abstract away voting systems from the governance system. For example linking an external functions to a particular voting mechanism; and collecting several default voting mechanisms in a separate protocol.
  • A few more specific issues:

    • Adding members to roles during a vote can alter quorum and votes needed to pass proposals. Traditionally a similar issue when it comes to ERC20 tokens is handled by the GovernorVotesQuorumFaction extension. I did not implement a similar check yet.
    • The use of PUBLIC_ROLE has not been implemented yet.
    • OpenZeppelin's AccessManager does not fully support multiple roles restricting a single function. If you call getTargetFunctionRole you only receive a single role restriction for a particular function. A function that checks if a particular function is restricted by a particular role (as in hasRole for accounts) does not yet exist.

See the open issues for a full list of proposed features (and known issues).

(back to top)

Contributing

Contributions make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Thank you!

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

(back to top)

License

Distributed under the MIT License. See LICENSE.txt for more information.

(back to top)

Contact

Seven Cedars - @7__Cedars - [email protected]

GitHub profile https://github.com/7Cedars

(back to top)

Acknowledgments

  • Patrick Collins
  • OpenZeppelin.
  • ...

(back to top)

About

An extension to OpenZeppelin's Governor protocol that restricts access to proposals along external role restricted functions.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published