Skip to content

Commit

Permalink
Successful compilation but docs not yet generating
Browse files Browse the repository at this point in the history
  • Loading branch information
jordaniza committed Feb 25, 2025
1 parent b90a7bf commit db88689
Show file tree
Hide file tree
Showing 15 changed files with 751 additions and 4 deletions.
5 changes: 5 additions & 0 deletions README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
= VEGOVERNANCE API

== Core

{{VotingEscrowIncreasing}}
Binary file added bun.lockb
Binary file not shown.
7 changes: 7 additions & 0 deletions docs/antora.yml
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
1 change: 1 addition & 0 deletions docs/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* xref:index.adoc[Overview]
188 changes: 188 additions & 0 deletions docs/modules/ROOT/pages/index.adoc
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
|===
1 change: 1 addition & 0 deletions docs/modules/api/nav.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.API
165 changes: 165 additions & 0 deletions docs/templates/contract.hbs
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}}
Loading

0 comments on commit db88689

Please sign in to comment.