This guide focuses on showcasing battle-tested practices and recommended patterns to implement safer and more robust on-chain governance smart contracts. This content was originally part of a workshop recorded on the 16th of September 2021 and led by Martin Abbatemarco, Security Researcher at OpenZeppelin. It is the fourth workshop in a series that covers multiple topics around secure development of smart contracts.
Click here to watch the original workshop recording and here to view the slides
In these guidelines, we cover the following:
In the journey towards unstoppable decentralized applications, more projects are looking to integrate governance modules into their smart contract systems. Security is paramount for this type of contracts as you do not want governance powers falling in the wrong hands.
In general, governance modules are a set of smart contracts that allow a community to influence an on-chain governance system. Some initial questions a smart contract auditor may ask to better understand a governance module could include:
It is likely that each mainnet project would have different answers to these questions. Governance comes in multiple flavors, and each implementation can have particular value propositions worth exploring. At the end of the day, a system should be free to self-determine how it wants to be governed.
Still, if we consider the matter from a more neutral security standpoint, there are relevant practices worth following to mitigate security risks and learnings to integrate from past mistakes.
The reality today is that most projects are just starting to figure out how to do on-chain governance. You can find an overview of the governance features that the community is currently experimenting with in Balancer’s documentation.
Features and practices in on-chain governance modules are rapidly evolving and mutating as projects figure out their community’s needs. This is not only true for specific technicalities of smart contract implementations, but also for more high-level matters around tooling, processes, and risks. Hence it’s not straightforward to provide fundamental and evergreen security guidelines that will apply to all projects in the space.
Nonetheless, a recurring idea throughout this series is “learning from others”. Of course, in governance too we can learn from others by taking a look at some of the most popular and battle-tested projects in Ethereum and extracting insights, learnings, and recommendations from their practices. Note that our analysis does not aim to be exhaustive, we will not cover every single feature of each governance module. On top of that, some features or security-related practices are repeated across projects – in those cases we won’t highlight the practice multiple times.
Moreover, the article will not teach you the specific mechanics to participate in these governance systems. You can refer to the official docs for that. Instead, we are going to cover topics that from a security standpoint make sense to highlight. We want the guidelines to be agnostistic to implementation details so we will approach ideas from a high-level view referring to off-chain processes, documentation, roles and threats. Still, some specific implementations will be linked when necessary.
As a final remark, remember that these systems tend to evolve and change quickly over time. In fact, probably none of the examples we will showcase here started out as we will show them. They have evolved, matured, and learned over multiple iterations and will continue doing so. Therefore, many of the details we are about to describe might become outdated some time after the date of publication. Make sure to always check each protocol’s documentation for the latest information on this topic.
COMP is the governance token of the Compound Protocol. At high-level view, the set of contracts that made up the governance module are as following:
The mechanics for governance are implemented in a handful of contracts: the COMP token, Governor Bravo (with its proxy and implementation), and the Timelock. If you are interested in the specifics of the implementation, you can refer to the open-source code available at https://github.com/compound-finance/compound-protocol. Here, we will highlight some aspects of this architecture:
There are two additional features worth highlighting. For that, let us introduce two new components into the previous diagram: the community multisig (deployed here) and whitelisted proposers.
For more information on the Compound Protocol’s governance, please refer to the official documentation.
UNI is the governance token behind the Uniswap protocol. At the moment of writing, Uniswap’s governance architecture may resemble that of the Compound Protocol. It was recently migrated from the Governor Alpha contract to the Bravo version, following in the Compound Protocol’s footsteps. Several of the previous points (use of timelocks, delegation of voting power, flash-loan protection, upgrades) apply here as well, so we will not repeat them. Do note that in this case, there are no community multisigs nor whitelisted proposers (at the time of publication).
One interesting point that we should highlight about Uniswap is their use of external documentation to present “adversarial circumstances”. In the documentation, the community can find different scenarios that could potentially put Uniswap’s governance at risk and how the team understands mitigation of the stated risks. If you are curious to know more about how a governance module can react to proposals with exploitable vulnerabilities and attempts of governance takeover attacks, give their documentation a careful read and think about whether any of these scenarios could apply to your system. This is a great example of how projects can be honest and transparent with their community, sharing concerns, and laying out scenarios related to security risks that are highly relevant to everyone.
For more information on Uniswap’s governance, please refer to the official documentation.
SNX is the governance token behind the Synthetix protocol. Synthetix is today a fairly complex protocol. For this brief analysis we won’t dive into the details of its inner workings. However, we certainly encourage you to go read more about it in their thorough and extensive documentation linked at the end of this section.
Synthetix’s governance can be seen from at least two angles: the artifacts and the governing bodies. Already these simple ideas mark a fundamental difference with the protocols we’ve just covered. As your governance system matures, they will become more and more relevant to better define responsibilities and have clear separation of concerns within your formalized processes.
Additional practices in Synthetix governance that stand out and can serve as guidelines:
For more information on Synthetix’s governance, please refer to the official documentation.
BAL is the governance token of the Balancer protocol. At first glance, the architecture of the governance module is fairly straightforward although there are some key aspects that we can highlight as guidelines.
At the moment of writing, the main account controlling the governed contracts in Balancer is a multisig wallet (specifically, an implementation of a Gnosis Safe multisig). The owners of this multisig wallet are expected to enact the results from off-chain voting events happening at Balancer’s space in snapshot.org. One could argue that there is a good amount of trust deposited into these owners, and to some extent this might be true. Yet as one dives deeper into Balancer’s documentation, there are some interesting points that must be stressed to paint the whole picture.
Balancer’s approach to governance can serve as an example for those that want to start out with simpler and more straightforward governance mechanisms. It is likely that smaller communities that might not want to (or not be ready to) implement full-featured Governor-like contracts such as Compound or Uniswap, or structured and multi-layered governance hierarchies such as in Synthetix.
For more information on Balancer’s governance, please refer to the official documentation.
AAVE is the governance token of the AAVE protocol. Let us start by taking a look at a simplified version of AAVE’s components from a high-level view.
At the center of governance lives a contract with similar features to those usually seen in Governor-like contracts. Despite it not being upgradeable, it includes a key mechanism that can be used to change some of its internal mechanics. More specifically, the governance contract uses a “strategy” contract. This contract encapsulates the logic related to voting power for proposing changes and casting votes. By changing the strategy, AAVE’s governance can effectively change how voting power is used within governance, without having to implement a proxy pattern for upgradeability (and thus avoiding some complexity and related security risks).
Another key point to highlight for AAVE is the use of multiple timelocks. This pattern allows for different delays for different actions, depending on their type (protocol or governance changes). This is a pattern that further stresses the importance of considering governance actions depending on their potential impact in the protocol. Not all governance actions are the same, and they might require different processes to be reviewed and enacted – an idea that we have surfaced several times already throughout these guidelines. Nonetheless, if you are considering following this path, bear in mind that using multiple timelocks and delays might add overhead to management and maintenance. Discuss with your team whether the benefits of the added complexity outweigh the costs.
Finally, we must also mention an important role in AAVE’s governance: the guardian. Implemented using a multisig, this role has the power to cancel proposals that make it into the governance process (before they’re executed). The guardian can be seen as a safeguard to prevent malicious proposals that may negatively impact the protocol. Its powers are well documented and highlighted in AAVE’s documentation, which favors transparency, and serves to raise awareness in the community about powerful roles in the system.
For more information on AAVE’s governance, please refer to the official documentation.
Now’s the turn to talk about one of the most well known governance systems in the Ethereum ecosystem: MakerDAO. MKR is its governance token. Before jumping into some key practices implemented in this system, let’s first do an overview of its architecture and mechanics.
First and foremost, it should be noted that the voting process is quite different from other systems we’ve seen so far. Because MakerDAO implements an approval voting scheme.
One of their most important contracts is the Chief. In short, this is where users lock their governance tokens and vote for proposals. That is why you will see that the Chief usually has lots of MKR in balance.
Changes to the protocol come via governance proposals, also known as Spells (such as this one). Spells are smart contracts that include a set of well defined encapsulated actions that can affect how the protocol works. This approach can be helpful to better understand and review governance actions if you are more used to reading Solidity code than transactions’ calldata (as in the case of Governor-like contracts).
Once a proposal gathers enough support in the Chief, it can be enacted. At this point the proposal is chosen as “the hat” of the Chief, and therefore can be queued and later executed via the Pause (a timelock essentially).
Even though this is a simplified version of the mechanics of this governance system, with these basic explanations we can take some interesting learnings:
We encourage readers to specifically take a look at the sources of user error and failure modes of the Chief, the Pause, the Spells, and the Emergency Shutdown module to learn more about specific best practices and risks when using these contracts. It is likely that some of these can serve as examples for you to follow in your own governance system.
For more information on MakerDAO’s governance, please refer to the official documentation.
Beyond these example practices implemented in the wild for quite some time already, there are additional security recommendations we can make. These come from security issues that we have spotted during audits and actual vulnerabilities disclosed or exploited in mainnet.
Therefore, following secure development practices of thorough testing, peer-reviews, and security assessments to ensure your code is safe and sound are always a must.
In the same line of thought, depending on the level of decentralization you are aiming for, having guardians with powers to veto proposals or the ability to trigger sensitive actions on governance might be a sensible decision.
You must pay special attention to these kinds of changes. Even if your contracts are considered battle-tested (or even audited), issues can arise during migrations and initialization stages. Always require security assessments from peer developers, bug hunters and security auditors. Moreover, document processes, include checklists and have off-chain validations. Testing and post-deployment scripts should greatly contribute in this area. Not everyone in your community will be technically proficient to understand all risks and impact of a simple change in your governance module. Therefore, you want to have processes in place to ensure all steps to a safe upgrade are closely followed, and the right stakeholders are involved.
As a final thought on governance risks, there’s an insightful article from Vitalik Buterin on coin voting governance that clarifies the pitfalls of some current governance schemes, and potential future mitigations. There are also additional articles referenced in the blog relevant to the guidelines discussed above.
If you’re involved in the development of any of the governance modules mentioned in this guide and would like to provide feedback, further clarify, or improve the accuracy of the statements and information provided in this workshop, please reach out to tincho <at> openzeppelin <dot> com. I’d be happy to chat and continue improving our understanding of governance systems together.
Click here to view the slides from the workshop.