|
@@ -7,31 +7,48 @@ This directory includes primitives for on-chain governance.
|
|
|
|
|
|
== Governor
|
|
|
|
|
|
-The {Governor} contract provides primitive to set an on-chain voting system similar to https://compound.finance/docs/governance[Compound's Governor Alpha & Bravo].
|
|
|
+This modular system of Governor contracts allows the deployment on-chain voting protocols similar to https://compound.finance/docs/governance[Compound's Governor Alpha & Bravo] and beyond, through the ability to easily customize multiple aspects of the protocol.
|
|
|
|
|
|
-Similarly to our other contracts, it is customizable through inheritance and comes with extensions:
|
|
|
+[TIP]
|
|
|
+====
|
|
|
+For a guided experience, set up your Governor contract using https://wizard.openzeppelin.com/#governor[Contracts Wizard].
|
|
|
|
|
|
-* {GovernorTimelockControl}: A {Governor} extension that performs executions through a {TimelockController}. This requires a successful proposal to be queued before then can be executed. The {TimelockController} will enforce a delay between the queueing and the execution. With this module, proposals are executed by the external {TimelockController} contract, which would have to hold the assets that are being governed.
|
|
|
+For a written walkthrough, check out our guide on xref:ROOT:governance.adoc[How to set up on-chain governance].
|
|
|
+====
|
|
|
|
|
|
-* {GovernorTimelockCompound}: A {Governor} extension that performs executions through a compound https://github.com/compound-finance/compound-protocol/blob/master/contracts/Timelock.sol[`Timelock`]. This requires a successful proposal to be queued before then can be executed. The `Timelock` will enforce a delay between the queueing and the execution. With this module, proposals are executed by the external `Timelock` contract, which would have to hold the assets that are being governed.
|
|
|
+* {Governor}: The core contract that contains all the logic and primitives. It is abstract and requires choosing one of each of the modules below, or custom ones.
|
|
|
|
|
|
-* {GovernorCountingSimple}: A simple voting mechanism for {Governor} with support 3 vote options: Against, For and Abstain.
|
|
|
+Votes modules determine the source of voting power, and sometimes quorum number.
|
|
|
|
|
|
-* {GovernorVotes}: Binding to extract voting weight from an {ERC20Votes} token.
|
|
|
+* {GovernorVotes}: Extracts voting weight from an {ERC20Votes} token.
|
|
|
|
|
|
-* {GovernorVotesQuorumFraction}: Binding to extract voting weight from an {ERC20Votes} token and set the quorum as a fraction of the (snapshoted) total token supply.
|
|
|
+* {GovernorVotesComp}: Extracts voting weight from a COMP-like or {ERC20VotesComp} token.
|
|
|
|
|
|
-* {GovernorVotesComp}: Binding to extract voting weight from a Comp or {ERC20VotesComp} token.
|
|
|
+* {GovernorVotesQuorumFraction}: Combines with `GovernorVotes` to set the quorum as a fraction of the total token supply.
|
|
|
|
|
|
-In addition to modules, the {Governor} requires a few virtual functions to be implemented to your particular specifications:
|
|
|
+Counting modules determine valid voting options.
|
|
|
|
|
|
-* <<Governor-votingOffset-,`votingOffset()`>>: Delay (number of blocks), between the proposal, is submitted and the snapshot block used for voting. This can be used to enforce a delay after a proposal is published for users to buy tokens, or delegate their votes (default: 0).
|
|
|
-* <<Governor-votingDuration-,`votingDuration()`>>: Delay (in seconds), between the proposal, is submitted and the vote ends.
|
|
|
-* <<Governor-quorum-uint256-,`quorum(uint256 blockNumber)`>>: Quorum required for a proposal to be successful. This function includes a `blockNumber` argument so the quorum can adapt through time, for example, to follow a token's `totalSupply`.
|
|
|
+* {GovernorCountingSimple}: Simple voting mechanism with 3 voting options: Against, For and Abstain.
|
|
|
+
|
|
|
+Timelock extensions add a delay for governance decisions to be executed. The workflow is extended to require a `queue` step before execution. With these modules, proposals are executed by the external timelock contract, thus it is the timelock that has to hold the assets that are being governed.
|
|
|
+
|
|
|
+* {GovernorTimelockControl}: Connects with an instance of {TimelockController}. Allows multiple proposers and executors, in addition to the Governor itself.
|
|
|
+
|
|
|
+* {GovernorTimelockCompound}: Connects with an instance of Compound's https://github.com/compound-finance/compound-protocol/blob/master/contracts/Timelock.sol[`Timelock`] contract.
|
|
|
+
|
|
|
+Other extensions can customize the behavior or interface in multiple ways.
|
|
|
|
|
|
-Note: Function of the {Governor} contract does NOT include access control. If you want to restrict access (for example to require a minimum balance to submit a proposal), you should add these checks by overloading the particular functions. For security reasons, the {Governor-_cancel} method is internal, and you will have to expose it (which the right access control mechanism) yourself if this is a mechanism you need.
|
|
|
+* {GovernorCompatibilityBravo}: Extends the interface to be fully `GovernorBravo`-compatible. Note that events are compatible regardless of whether this extension is included or not.
|
|
|
|
|
|
-Events emitted by the {Governor} contract are compatible with Compound's `GovernorBravo`. Additionnaly, function compatibility can be added using the {GovernorCompatibilityBravo} compatibility layer. This layer includes a voting system but does not include token bindings. This layer also requiers a timelock module (either {GovernorTimelockControl} or {GovernorTimelockCompound}).
|
|
|
+* {GovernorProposalThreshold}: Restricts proposals to delegates with a minimum voting power.
|
|
|
+
|
|
|
+In addition to modules and extensions, the core contract requires a few virtual functions to be implemented to your particular specifications:
|
|
|
+
|
|
|
+* <<Governor-votingDelay-,`votingDelay()`>>: Delay (in number of blocks) since the proposal is submitted until voting power is fixed and voting starts. This can be used to enforce a delay after a proposal is published for users to buy tokens, or delegate their votes.
|
|
|
+* <<Governor-votingPeriod-,`votingPeriod()`>>: Delay (in number of blocks) since the proposal starts until voting ends.
|
|
|
+* <<Governor-quorum-uint256-,`quorum(uint256 blockNumber)`>>: Quorum required for a proposal to be successful. This function includes a `blockNumber` argument so the quorum can adapt through time, for example, to follow a token's `totalSupply`.
|
|
|
+
|
|
|
+NOTE: Functions of the `Governor` contract do not include access control. If you want to restrict access, you should add these checks by overloading the particular functions. Among these, {Governor-_cancel} is internal by default, and you will have to expose it (which the right access control mechanism) yourself if this function is needed.
|
|
|
|
|
|
=== Core
|
|
|
|
|
@@ -39,11 +56,7 @@ Events emitted by the {Governor} contract are compatible with Compound's `Govern
|
|
|
|
|
|
{{Governor}}
|
|
|
|
|
|
-=== Extensions
|
|
|
-
|
|
|
-{{GovernorTimelockControl}}
|
|
|
-
|
|
|
-{{GovernorTimelockCompound}}
|
|
|
+=== Modules
|
|
|
|
|
|
{{GovernorCountingSimple}}
|
|
|
|
|
@@ -53,7 +66,13 @@ Events emitted by the {Governor} contract are compatible with Compound's `Govern
|
|
|
|
|
|
{{GovernorVotesComp}}
|
|
|
|
|
|
-=== Compatibility
|
|
|
+=== Extensions
|
|
|
+
|
|
|
+{{GovernorTimelockControl}}
|
|
|
+
|
|
|
+{{GovernorTimelockCompound}}
|
|
|
+
|
|
|
+{{GovernorProposalThreshold}}
|
|
|
|
|
|
{{GovernorCompatibilityBravo}}
|
|
|
|