-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Successful compilation but docs not yet generating
- Loading branch information
Showing
15 changed files
with
751 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
= VEGOVERNANCE API | ||
|
||
== Core | ||
|
||
{{VotingEscrowIncreasing}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
name: ve-governance | ||
title: "@aragon/ve-governance" | ||
version: 1.x | ||
prerelease: false | ||
nav: | ||
- modules/ROOT/nav.adoc | ||
- modules/api/nav.adoc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* xref:index.adoc[Overview] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
= VE Governance | ||
|
||
== Description | ||
|
||
**StagedProposalProcessor** is a governance plugin developed and maintained by the Aragon core team. It orchestrates proposals through | ||
a series of configurable stages, enabling complex decision-making processes where proposals progress through predefined stages with | ||
multiple “bodies” (other governance plugins or contracts) that report results such as approvals or vetoes. By chaining these bodies and | ||
applying thresholds, durations, and conditions, the plugin guides proposals from creation to execution in a flexible, modular manner, | ||
addressing the link:https://blog.aragon.org/the-future-of-governance-is-modular-2/[problems facing large monolithic DAOs] stuck with one-size-fits-all governance processes. | ||
|
||
== Key Concepts | ||
|
||
=== Staged Governance Processes | ||
|
||
Rather than deciding proposals in a single step, **StagedProposalProcessor** breaks the decision-making process into sequential stages. Bodies within a stage | ||
approve or veto the proposal. Stages can impose timing constraints, thresholds for required number of approvals or vetoes, and rules for | ||
editing or canceling the proposal. | ||
|
||
Depending on how a stage is configured, it can support different use cases. For example: | ||
|
||
1. **Normal Stages:** A stage can allow bodies to approve the proposal before advancing | ||
2. **Optimistic Stages:** A stage can allow any body to act as a vetoer rather than approver, effectively allowing any stage to | ||
act as an optimistic stage as desired, only passing if not vetoed. | ||
3. **Time-Locked Stages**: If no bodies are added to a stage, it effectively acts as a timelock delay period, preventing a proposal | ||
from advancing until the period has passed. | ||
4. **Cancelable or Editable Stages**: These allow addresses with permission to do so to either cancel a proposal or modify proposals’ | ||
metadata and list of actions prior to advancing to the next stage. | ||
|
||
=== Bodies and Results | ||
|
||
A “body” represents an external governance component—such as another plugin or any other address—that evaluates the proposal at a given stage. | ||
Bodies call `reportProposalResult` to indicate if they are approving or vetoing a proposal. Stages can have any number of bodies, | ||
each reporting their own results. Stages have configurable thresholds to determine if it can be advanced to the next stage, based on | ||
the governance results from the bodies. | ||
|
||
=== Sub-proposals | ||
|
||
When a stage starts, including upon when a proposal is initially created, the **StagedProposalProcessor** attempts to create a | ||
sub-proposal on each body in that stage. For example, if someone is voting within a body, they are voting whether or not they want | ||
to advance or veto the parent proposal, but not voting directly on the proposal itself. | ||
|
||
Sub-proposals creation can only be “automatic” if both of the following are true: | ||
|
||
* body supports IERC165 and `IProposal` interface, thus supporting `createProposal` and other necessary functions. | ||
* body is added in a stage with `isManual` setting set to false. | ||
|
||
If a body does not meet these criteria, it is “manual,” and the external body (an EOA or other smart contract) must report results explicitly. | ||
|
||
=== Advanceability Criteria | ||
|
||
For each stage, you must define the following in the configuration: | ||
|
||
* **Approval Threshold:** How many bodies must approve for the proposal to proceed. | ||
* **Veto Threshold:** How many vetoes are necessary to prevent the proposal from being advanced, regardless of the number of approvals. | ||
Vetoes always trump approvals. | ||
* **minAdvance & maxAdvance:** Minimum and maximum time windows controlling when the proposal can be advanced to the next stage. | ||
* **voteDuration:** Has two different effects: | ||
- Used to calculate the `endTime` for sub-proposals created on automatic bodies | ||
- If and only if there are any vetoing bodies, used to extend the advance time window (potentially overriding `minAdvance`), | ||
ensuring they have enough time to veto it before it is advanced. | ||
|
||
If all the above conditions are met before `maxAdvance`, the proposal becomes `Advanceable`. After `maxAdvance`, it becomes `Expired` and | ||
can no longer be advanced. | ||
|
||
[NOTE] | ||
==== | ||
When a proposal reaches its final stage and meets that stage’s advanceability criteria, the proposal’s actions can be executed. | ||
==== | ||
|
||
=== Configurations | ||
|
||
**StagedProposalProcessor** supports updating stage configurations, allowing the DAO to evolve its governance rules over time. | ||
|
||
## Proposal Lifecycle | ||
|
||
1. **Creation:** | ||
|
||
* A user with `CREATE_PROPOSAL_PERMISSION_ID` calls `createProposal` providing metadata, actions, and start times. The proposal | ||
references the active configuration index and starts at stage 0, where sub-proposals are created on its automatic bodies. | ||
|
||
2. **Evaluation at Each Stage:** | ||
|
||
* Bodies at the current stage report `Approval` or `Veto` results via `reportProposalResult`. If the required advanceability criteria | ||
are met (see above), the proposal state becomes `Advanceable`. | ||
|
||
3. **Advancing to Next Stages:** | ||
|
||
* Proposal can be advanced by calling `advanceProposal` function, requiring the caller to have `ADVANCE_PERMISSION_ID`. This moves the | ||
proposal to the next stage, triggering sub-proposals on the new stage’s automatic bodies. | ||
|
||
4. **Execution:** | ||
|
||
* Once the proposal reaches the last stage and becomes `Advanceable`, it can be executed. A user with `EXECUTE_PROPOSAL_PERMISSION_ID` | ||
calls `execute`. | ||
|
||
|
||
[NOTE] | ||
==== | ||
If allowed by the stage configuration, a user with `EDIT_PERMISSION_ID` can modify the proposal’s metadata and actions prior to being advanced. | ||
A user with `CANCEL_PERMISSION_ID` can cancel the proposal if the stage permits it. | ||
==== | ||
|
||
## Plugin Setup | ||
|
||
=== **Deployed Contracts** | ||
|
||
During the plugin’s installation process, the setup contract deploys and configures the following contracts: | ||
|
||
- **StagedProposalProcessor Proxy** | ||
- A UUPS proxy instance of the main `StagedProposalProcessor` contract. This proxy is initialized with the chosen stages, metadata, | ||
and target configuration. It is the primary contract that users interact with to create, advance, and execute proposals through multiple | ||
stages. | ||
- **StagedProposalProcessor Implementation Contract** | ||
- The underlying implementation referenced by the UUPS proxy. While you typically won’t interact with this contract directly, it provides | ||
the upgradable logic that the proxy delegates all calls to. As the DAO evolves, addresses with permission to do so can upgrade this logic. | ||
- **SPPRuleCondition** | ||
- A condition contract deployed to enforce rules for determining whether callers meet the necessary criteria to create proposals on | ||
the StagedProposalProcessor. The condition’s logic modularly inherits conditional logic from other conditions. For example, | ||
the condition can be configured to return true if the `msg.sender` is a member of a multisig plugin and/or tokenvoting plugin, | ||
using boolean operators. | ||
|
||
|
||
|
||
**Permissions**: The following permissions are set up by default by the **StagedProposalProcessorSetup**: | ||
|
||
|=== | ||
| Permission ID | Where (Granted By) | Who (Granted To) | Condition | Functions | ||
|
||
| UPDATE_STAGES_PERMISSION_ID | ||
| Plugin | ||
| DAO | ||
| None | ||
| updateStages | ||
|
||
| CREATE_PROPOSAL_PERMISSION_ID | ||
| Plugin | ||
| Any Address | ||
| SPPRuleCondition | ||
| createProposal | ||
|
||
| SET_TRUSTED_FORWARDER_PERMISSION_ID | ||
| Plugin | ||
| DAO | ||
| None | ||
| setTrustedForwarder | ||
|
||
| SET_TARGET_CONFIG_PERMISSION_ID | ||
| Plugin | ||
| DAO | ||
| None | ||
| setTargetConfig | ||
|
||
| SET_METADATA_PERMISSION_ID | ||
| Plugin | ||
| DAO | ||
| None | ||
| setMetadata | ||
|
||
| EXECUTE_PROPOSAL_PERMISSION_ID | ||
| Plugin | ||
| Any Address | ||
| None | ||
| execute | ||
|
||
| CANCEL_PERMISSION_ID | ||
| Plugin | ||
| Any Address | ||
| None | ||
| cancel | ||
|
||
| ADVANCE_PERMISSION_ID | ||
| Plugin | ||
| Any Address | ||
| None | ||
| advanceProposal | ||
|
||
| EXECUTE_PERMISSION_ID | ||
| DAO | ||
| Plugin | ||
| None | ||
| execute | ||
|
||
| UPDATE_RULES_PERMISSION_ID | ||
| SPPRuleCondition | ||
| DAO | ||
| None | ||
| updateRules | ||
|=== |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.API |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
{{#each items}} | ||
:{{name}}: pass:normal[xref:#{{anchor}}[`++{{name}}++`]] | ||
{{/each}} | ||
|
||
[.contract] | ||
[[{{anchor}}]] | ||
=== `++{{name}}++` link:{{githubURI}}/blob/v{{version}}/{{__item_context.file.absolutePath}}[{github-icon},role=heading-link] | ||
|
||
|
||
{{{natspec.dev}}} | ||
|
||
{{#if modifiers}} | ||
[.contract-index] | ||
.Modifiers | ||
-- | ||
{{#each modifiers}} | ||
{{#if (isLocalContract __item_context.contract.name)}} | ||
* {xref-{{anchor~}} }[`++{{name}}({{names params}})++`] | ||
{{else if (isAragonInherittedContract __item_context.file.absolutePath) }} | ||
* link:{{getExternalLink __item_context.file.absolutePath}}[{{name}}] | ||
{{/if}} | ||
{{/each}} | ||
|
||
-- | ||
{{/if}} | ||
|
||
{{#if has-functions}} | ||
[.contract-index] | ||
.Functions | ||
-- | ||
{{#each inherited-functions}} | ||
{{#unless @first}} | ||
[.contract-subindex-inherited] | ||
.{{contract.name}} | ||
{{/unless}} | ||
{{#each functions}} | ||
{{#if (isLocalContract __item_context.contract.name)}} | ||
* {xref-{{anchor~}} }[`++{{name}}({{names params}})++`] | ||
{{else if (isAragonInherittedContract __item_context.file.absolutePath) }} | ||
* link:{{getExternalLink __item_context.file.absolutePath}}[{{name}}] | ||
{{/if}} | ||
{{/each}} | ||
|
||
{{/each}} | ||
-- | ||
{{/if}} | ||
|
||
|
||
{{#if has-events}} | ||
[.contract-index] | ||
.Events | ||
-- | ||
{{#each inheritance}} | ||
{{#unless @first}} | ||
[.contract-subindex-inherited] | ||
.{{name}} | ||
{{/unless}} | ||
{{#each events}} | ||
{{#if (isLocalContract __item_context.contract.name)}} | ||
* {xref-{{anchor~}} }[`++{{name}}({{names params}})++`] | ||
{{else if (isAragonInherittedContract __item_context.file.absolutePath) }} | ||
* link:{{getExternalLink __item_context.file.absolutePath}}[{{name}}] | ||
{{/if}} | ||
{{/each}} | ||
|
||
{{/each}} | ||
-- | ||
{{/if}} | ||
|
||
{{#if has-errors}} | ||
[.contract-index] | ||
.Errors | ||
-- | ||
{{#each inheritance}} | ||
{{#unless @first}} | ||
[.contract-subindex-inherited] | ||
.{{name}} | ||
{{/unless}} | ||
{{#each errors}} | ||
{{#if (isLocalContract __item_context.contract.name)}} | ||
* {xref-{{anchor~}} }[`++{{name}}({{names params}})++`] | ||
{{else if (isAragonInherittedContract __item_context.file.absolutePath) }} | ||
* link:{{getExternalLink __item_context.file.absolutePath}}[{{name}}] | ||
{{/if}} | ||
{{/each}} | ||
|
||
{{/each}} | ||
-- | ||
{{/if}} | ||
|
||
{{#if has-internal-variables}} | ||
[.contract-index] | ||
.Internal Variables | ||
-- | ||
{{#each inheritance}} | ||
{{#unless @first}} | ||
[.contract-subindex-inherited] | ||
.{{name}} | ||
{{/unless}} | ||
{{#each internal-variables}} | ||
{{#if (isLocalContract __item_context.contract.name)}} | ||
* {xref-{{anchor~}} }[`++{{{typeDescriptions.typeString}}} {{#if constant}}constant{{/if}} {{name}}++`] | ||
{{else if (isAragonInherittedContract __item_context.file.absolutePath) }} | ||
* link:{{getExternalLink __item_context.file.absolutePath}}[{{name}}] | ||
{{/if}} | ||
{{/each}} | ||
|
||
{{/each}} | ||
-- | ||
{{/if}} | ||
|
||
{{#each modifiers}} | ||
[.contract-item] | ||
[[{{anchor}}]] | ||
==== `[.contract-item-name]#++{{name}}++#++({{typed-params params}})++` [.item-kind]#modifier# | ||
|
||
{{{natspec.notice}}} | ||
|
||
{{{natspec.dev}}} | ||
|
||
{{/each}} | ||
|
||
{{#each functions}} | ||
[.contract-item] | ||
[[{{anchor}}]] | ||
==== `[.contract-item-name]#++{{name}}++#++({{typed-params params}}){{#if returns2}} → {{typed-params returns2}}{{/if}}++` [.item-kind]#{{visibility}}# | ||
|
||
{{{natspec.notice}}} | ||
|
||
{{{natspec.dev}}} | ||
|
||
{{/each}} | ||
|
||
{{#each events}} | ||
[.contract-item] | ||
[[{{anchor}}]] | ||
==== `[.contract-item-name]#++{{name}}++#++({{typed-params params}})++` [.item-kind]#event# | ||
|
||
{{{natspec.notice}}} | ||
|
||
{{{natspec.dev}}} | ||
|
||
{{/each}} | ||
|
||
{{#each errors}} | ||
[.contract-item] | ||
[[{{anchor}}]] | ||
==== `[.contract-item-name]#++{{name}}++#++({{typed-params params}})++` [.item-kind]#error# | ||
|
||
{{{natspec.notice}}} | ||
|
||
{{{natspec.dev}}} | ||
|
||
{{/each}} | ||
|
||
{{#each internal-variables}} | ||
[.contract-item] | ||
[[{{anchor}}]] | ||
==== `{{typeDescriptions.typeString}} [.contract-item-name]#++{{name}}++#` [.item-kind]#internal{{#if constant}} constant{{/if}}# | ||
|
||
{{{natspec.notice}}} | ||
|
||
{{{natspec.dev}}} | ||
|
||
{{/each}} |
Oops, something went wrong.