Skip to content

Commit

Permalink
Adapting the docs and diagrams
Browse files Browse the repository at this point in the history
  • Loading branch information
brickpop committed Jan 31, 2024
1 parent 04732ab commit e204d38
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 56 deletions.
90 changes: 59 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ yarn test

## Overview

A Space is composed by a DAO and several plugins installed on it. The [DAO](https://github.com/aragon/osx/blob/develop/packages/contracts/src/core/dao/DAO.sol) contract holds all the assets and rights, while plugins are custom, opt-in pieces of logic that can perform certain actions governed by the DAO's permission database.
A Space is composed by a DAO and several plugins installed on it. The [DAO](https://github.com/aragon/osx/blob/develop/packages/contracts/src/core/dao/DAO.sol) contract holds all the assets and rights to act on external components, while plugins are custom, composable, opt-in pieces of logic that can perform certain actions governed by the DAO's permission database.

The DAO contract can be deployed by using Aragon's DAOFactory contract. This will deploy a new DAO with the desired plugins and settings.
The DAO contract can be deployed by using Aragon's DAOFactory contract. This will deploy a new DAO with the desired plugins and their respective settings.

The current repository provides the plugins necessary to cover two use cases:

Expand All @@ -35,17 +35,17 @@ The current repository provides the plugins necessary to cover two use cases:

### Standard Space

In standard spaces, _members_ can create proposals while _editors_ can vote whether they should pass. Proposals eventually approved can be executed by anyone and this will make the DAO call the predefined proposal actions.
In standard spaces, _members_ can create proposals while _editors_ can vote on them. Approved proposals can be executed by anyone and this will make the DAO call the predefined proposal actions.

The most typical case will be telling the Space Plugin to emit the event of a proposal being processed.
The most typical case will be telling the Space Plugin to emit the event of a proposal being processed. It can include emitting a new hash for the contents or accepting a subspace.

<img src="./img/std-1.svg">

The Main Voting Plugin can also pass proposals that change its own settings.

<img src="./img/std-2.svg">

To add new members, the Member Access Plugin allows anyone to request the permission. Editors can approve or reject it.
To manage who can create proposals, the Member Access Plugin allows anyone to request becoming a member. Editors can approve or reject incoming proposals.

<img src="./img/std-3.svg">

Expand All @@ -55,9 +55,13 @@ Personal spaces are a simplified version, where anyone defined as editor can imm

<img src="./img/personal-1.svg">

Editors may also execute proposals who define new editors.

<img src="./img/personal-2.svg">

### Plugin Upgrader

There's an optional case, where a predefined address can execute the actions to upgrade a plugin to the latest published version.
There's an optional feature, where a predefined address can execute the actions to upgrade a plugin to the latest published version.

<img src="./img/upgrader-1.svg">

Expand All @@ -69,17 +73,17 @@ There's an optional case, where a predefined address can execute the actions to

### Joining a space

1. An address calls `proposeNewMember()` on the `MemberAccessPlugin`
- If the wallet is the only editor, the proposal succeeds immediately
1. Someone calls `proposeNewMember()` on the `MemberAccessPlugin`
- If the caller is the only editor, the proposal succeeds immediately
2. One of the editors calls `approve()` or `reject()`
- Calling `approve()` makes the proposal succeed
- Calling `reject()` cancels the proposal
3. A succeeded proposal is executed automatically
- This makes the DAO call `grant()` on itself to grant the `MEMBER_PERMISSION_ID` to the intended address
- This makes the DAO call `addMember()` on the main voting plugin

### Creating proposals for a space

1. An editor or a wallet with the `MEMBER_PERMISSION_ID` granted, creates a proposal
1. An editor or a member creates a proposal
2. Editors can vote on it for a predefined amount of time
3. If the proposal exceeds the required quorum and support, the proposal succeeds
4. Succeeded proposals can be executed by anyone
Expand All @@ -93,21 +97,21 @@ There's an optional case, where a predefined address can execute the actions to

## General notice

The implementation of the four plugins is built on top of existing and thoroughly autited plugins from Aragon OSx. The base contracts used highly align with the requirements of Geo. However, there is some cases in which certain parameters may not be relevant or may need to be kept for compatibility.
The implementation of the four plugins is built on top of existing and thoroughly autited plugins from Aragon OSx. In order to fully accomodate to Geo's design, some functions and interfaces needed a few tweaks, which made it necessary to fork and adapt these contracts in-place.

The alternative would be to fork these base contracts and include them as part of this repository. Given the pro's of getting OSx updates from Aragon for free vs the con's of keeping a few redundant parameters, we have decided to avoid forking any base contract.
They can be found on `packages/contracts/src/governance/base`

[Learn more about Aragon OSx](https://devs.aragon.org/docs/osx/how-it-works/framework/)

## How permissions work

For each Space, an Aragon DAO is going to be created to act as the entry point. It will hold any assets and most importantly, manage the permission database which will govern all plugin interactions.
Each Space created is an Aragon DAO. It holds any assets and most importantly, it manages the permission database that governs all plugin interactions.

A permission looks like:

- An address `who` holds `MY_PERMISSION_ID` on a target contract `where`

New DAO's are deployed with a `ROOT_PERMISSION` assigned to its creator, but the DAO will typically deployed by the DAO factory, which will install all the requested plugins and drop the ROOT permission after the set up is done.
New DAO's deployed manyally will grant `ROOT_PERMISSION` to its creator. However, most DAO's are typically deployed via Aragon's DAO factory, which will deploy a new contract with safe defaults, install all the requested plugins and drop the ROOT permission when the set up is done.

Managing permissions is made via two functions that are called on the DAO:

Expand Down Expand Up @@ -144,26 +148,43 @@ See the `MemberAccessExecuteCondition` contract. It restricts what the [MemberAc

Below are all the permissions that a [PluginSetup](#plugin-setup-contracts) contract may want to request:

- `MEMBER_PERMISSION` is required to create proposals on the [MainVotingPlugin](#main-voting-plugin)
Proposal:

- `EDITOR_PERMISSION` is required to execute proposals on the [PersonalSpaceAdminPlugin](#personal-space-admin-plugin)
- `EXECUTE_PERMISSION` is required to make the DAO `execute` a set of actions
- Only plugins should have this permission
- Some plugins should restrict it with a condition
- `ROOT_PERMISSION` is required to make the DAO `grant` or `revoke` permissions
- The DAO needs to be ROOT on itself (it is by default)
- Nobody else should be ROOT on the DAO
- `UPGRADE_PLUGIN_PERMISSION` is required for an address to be able to upgrade a plugin to a newer version published by the developer
- Typically called by the DAO via proposal
- Optionally granted to an additional address for convenience

Spaces:

- `CONTENT_PERMISSION_ID` is required to call the function that emits new content events on the [SpacePlugin](#space-plugin)
- Typically called by the DAO via proposal
- `SUBSPACE_PERMISSION_ID` is required to call the functions that emit new subspace accept/reject events on the [SpacePlugin](#space-plugin)
- Typically called by the DAO via proposal
- `UPDATE_MULTISIG_SETTINGS_PERMISSION_ID` is required to change the settings of the [MemberAccessPlugin](#member-access-plugin)

Governance settings:

- `UPDATE_VOTING_SETTINGS_PERMISSION_ID` is required to change the settings of the [MainVotingPlugin](#main-voting-plugin)
- `UPDATE_ADDRESSES_PERMISSION_ID` is required to add or remove members or editors on the [MainVotingPlugin](#main-voting-plugin)
- Typically called by the DAO via proposal
- `UPDATE_ADDRESSES_PERMISSION_ID` is required to add or remove editors on the [MainVotingPlugin](#main-voting-plugin)
- `UPDATE_MULTISIG_SETTINGS_PERMISSION_ID` is required to change the settings of the [MemberAccessPlugin](#member-access-plugin)
- Typically called by the DAO via proposal

Permission management:

- `ROOT_PERMISSION` is required to make the DAO `grant` or `revoke` permissions
- If the DAO is executing a set of actions, it needs to be ROOT on itself (it is by default)
- The PluginSetupProcessor may be granted ROOT permission temporarily
- Nobody else should be ROOT on a DAO

Plugin versioning:

- `UPGRADE_PLUGIN_PERMISSION` is required to be able to call `upgradeTo()` or `upgradeToAndCall()` on a plugin
- Called by the PSP via proposal on the DAO
- `APPLY_UPDATE_PERMISSION` is needed to call `applyUpdate()` on the PluginSetupProcessor
- Optionally granted to an additional address, for convenience
- Correspondingly, `APPLY_INSTALLATION_PERMISSION` and `APPLY_UNINSTALLATION_PERMISSION` allow to call `applyInstallation()` or `applyUninstallation()`

Other DAO permissions:

- `EXECUTE_PERMISSION`
Expand All @@ -183,7 +204,7 @@ See `packages/contracts/typechain` for all the generated JS/TS wrappers to inter

## Encoding and decoding actions

Making calls to the DAO is straightforward, however making execute arbitrary actions requires them to be encoded, stored on chain and be approved before they can be executed.
Making calls to the DAO is straightforward, however executing arbitrary actions requires them to be encoded, stored on chain and be approved before they can be executed.

To this end, the DAO has a struct called `Action { to, value, data }`, which will make the DAO call the `to` address, with `value` ether and call the given calldata (if any).

Expand All @@ -197,17 +218,19 @@ On Spaces with the standard governance, a [MemberAccessPlugin](#member-access-pl

- Send a transaction to call `proposeNewMember()`
- Have an editor (different to the proposer) calling `approve()` for this proposal
- This will grant `MEMBER_PERMISSION` to the requested address on the main voting contract
- This will add the requested address to the members list on the main voting contract

The same applies to remove members with `proposeRemoveMember()`

### Editors

- A member or editor creates a proposal
- The proposal should have an action to make the DAO `execute()` a call to `addAddresses()` on the plugin
- The proposal should have an action to make the DAO `execute()` a call to `addEditor()` on the plugin
- A majority of editors call `vote()` and approve it
- Someone calls `plugin.execute()` so that the DAO executes the requested action on the plugin
- The new editor will be able to vote on proposals created from then on

The same procedure applies to removing members and editors.
The same procedure applies to removing editors with `removeEditor()`

## Adding editors (personal spaces)

Expand All @@ -228,10 +251,15 @@ This plugin is upgradeable.

#### Methods

- `function initialize(IDAO _dao, string _firstBlockContentUri, address predecessorSpace)`
- `function processGeoProposal(uint32 _blockIndex, uint32 _itemIndex, string _contentUri)`
- `function acceptSubspace(address _dao)`
- `function removeSubspace(address _dao)`
```solidity
function initialize(IDAO _dao, string _firstBlockContentUri, address predecessorSpace);
function processGeoProposal(uint32 _blockIndex, uint32 _itemIndex, string _contentUri);
function acceptSubspace(address _dao);
function removeSubspace(address _dao);
```

Inherited:

Expand Down
44 changes: 38 additions & 6 deletions img/Geo Diagrams.drawio
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<mxfile host="Electron" modified="2024-01-24T14:36:08.538Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/22.1.21 Chrome/120.0.6099.109 Electron/28.1.0 Safari/537.36" etag="gi4xnPyI-KSXU6QCMxEl" version="22.1.21" type="device" pages="5">
<diagram name="Personal" id="thjhlSlWM23S0B1YojXH">
<mxfile host="Electron" modified="2024-01-31T15:04:42.370Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/23.0.2 Chrome/120.0.6099.109 Electron/28.1.0 Safari/537.36" etag="BaBtiGP05E-8qSi2kVgj" version="23.0.2" type="device" pages="6">
<diagram name="Personal 1" id="thjhlSlWM23S0B1YojXH">
<mxGraphModel dx="1114" dy="999" grid="0" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" background="#ffffff" math="0" shadow="0">
<root>
<mxCell id="0" />
Expand Down Expand Up @@ -40,6 +40,38 @@
</root>
</mxGraphModel>
</diagram>
<diagram name="Personal 2" id="QbmbZwpN9fCBtF1i5erl">
<mxGraphModel dx="1114" dy="999" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" background="#ffffff" math="0" shadow="0">
<root>
<mxCell id="ZMF03YjosN-jic-8k9ZM-0" />
<mxCell id="ZMF03YjosN-jic-8k9ZM-1" parent="ZMF03YjosN-jic-8k9ZM-0" />
<mxCell id="ZMF03YjosN-jic-8k9ZM-2" value="&lt;font style=&quot;font-size: 20px;&quot;&gt;&lt;b&gt;DAO&lt;/b&gt;&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;fontColor=#333333;strokeColor=#666666;" vertex="1" parent="ZMF03YjosN-jic-8k9ZM-1">
<mxGeometry x="420" y="110" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="ZMF03YjosN-jic-8k9ZM-3" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="ZMF03YjosN-jic-8k9ZM-1" source="ZMF03YjosN-jic-8k9ZM-5" target="ZMF03YjosN-jic-8k9ZM-2">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ZMF03YjosN-jic-8k9ZM-5" value="&lt;b style=&quot;border-color: var(--border-color); font-size: 17px;&quot;&gt;Personal Space&lt;br style=&quot;border-color: var(--border-color);&quot;&gt;Admin Plugin&lt;/b&gt;&lt;font size=&quot;1&quot; style=&quot;&quot;&gt;&lt;b style=&quot;font-size: 17px;&quot;&gt;&lt;br&gt;&lt;/b&gt;&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;fontColor=#333333;strokeColor=#666666;" vertex="1" parent="ZMF03YjosN-jic-8k9ZM-1">
<mxGeometry x="200" y="220" width="160" height="90" as="geometry" />
</mxCell>
<mxCell id="ZMF03YjosN-jic-8k9ZM-7" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="ZMF03YjosN-jic-8k9ZM-1" source="ZMF03YjosN-jic-8k9ZM-8" target="ZMF03YjosN-jic-8k9ZM-5">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ZMF03YjosN-jic-8k9ZM-8" value="Execute proposal" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#4d4d4d;" vertex="1" parent="ZMF03YjosN-jic-8k9ZM-1">
<mxGeometry x="220" y="350" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="ZMF03YjosN-jic-8k9ZM-9" value="Execute actions" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#4d4d4d;" vertex="1" parent="ZMF03YjosN-jic-8k9ZM-1">
<mxGeometry x="280" y="148" width="110" height="30" as="geometry" />
</mxCell>
<mxCell id="ZMF03YjosN-jic-8k9ZM-11" value="Grant / Revoke" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#4d4d4d;" vertex="1" parent="ZMF03YjosN-jic-8k9ZM-1">
<mxGeometry x="570" y="160" width="100" height="30" as="geometry" />
</mxCell>
<mxCell id="ZMF03YjosN-jic-8k9ZM-12" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;curved=0;" edge="1" parent="ZMF03YjosN-jic-8k9ZM-1" source="ZMF03YjosN-jic-8k9ZM-2" target="ZMF03YjosN-jic-8k9ZM-2">
<mxGeometry relative="1" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram name="Standard 1" id="P21WclOAyHeW8eECvL_4">
<mxGraphModel dx="1114" dy="999" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" background="#ffffff" math="0" shadow="0">
<root>
Expand Down Expand Up @@ -126,7 +158,7 @@
<mxCell id="YLZ5xhDpQ7pldwhZ7Gaj-4" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="YLZ5xhDpQ7pldwhZ7Gaj-1" source="YLZ5xhDpQ7pldwhZ7Gaj-5" target="YLZ5xhDpQ7pldwhZ7Gaj-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="eN2QFOQ7j5IP7RqDKuwH-0" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="YLZ5xhDpQ7pldwhZ7Gaj-1" source="YLZ5xhDpQ7pldwhZ7Gaj-5" target="YLZ5xhDpQ7pldwhZ7Gaj-7" edge="1">
<mxCell id="eN2QFOQ7j5IP7RqDKuwH-0" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;startArrow=classic;startFill=1;dashed=1;" parent="YLZ5xhDpQ7pldwhZ7Gaj-1" source="YLZ5xhDpQ7pldwhZ7Gaj-5" target="YLZ5xhDpQ7pldwhZ7Gaj-7" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="YLZ5xhDpQ7pldwhZ7Gaj-5" value="&lt;font size=&quot;1&quot; style=&quot;&quot;&gt;&lt;b style=&quot;font-size: 17px;&quot;&gt;Member Access Plugin&lt;br&gt;&lt;/b&gt;&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;fontColor=#333333;strokeColor=#666666;" parent="YLZ5xhDpQ7pldwhZ7Gaj-1" vertex="1">
Expand All @@ -147,10 +179,10 @@
<mxCell id="eN2QFOQ7j5IP7RqDKuwH-2" value="Is editor?&lt;br&gt;Editor count?" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#4d4d4d;" parent="YLZ5xhDpQ7pldwhZ7Gaj-1" vertex="1">
<mxGeometry x="380" y="220" width="90" height="40" as="geometry" />
</mxCell>
<mxCell id="_tGiztMdJlxGEjcx_7y3-1" value="Grant / Revoke" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#4d4d4d;" parent="YLZ5xhDpQ7pldwhZ7Gaj-1" vertex="1">
<mxGeometry x="570" y="160" width="100" height="30" as="geometry" />
<mxCell id="_tGiztMdJlxGEjcx_7y3-1" value="Add member&lt;br&gt;Remove member" style="text;html=1;align=right;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#4d4d4d;" parent="YLZ5xhDpQ7pldwhZ7Gaj-1" vertex="1">
<mxGeometry x="551" y="145" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="_tGiztMdJlxGEjcx_7y3-2" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;curved=0;" parent="YLZ5xhDpQ7pldwhZ7Gaj-1" source="YLZ5xhDpQ7pldwhZ7Gaj-3" target="YLZ5xhDpQ7pldwhZ7Gaj-3" edge="1">
<mxCell id="_tGiztMdJlxGEjcx_7y3-2" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;curved=0;" parent="YLZ5xhDpQ7pldwhZ7Gaj-1" source="YLZ5xhDpQ7pldwhZ7Gaj-3" target="YLZ5xhDpQ7pldwhZ7Gaj-7" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
</root>
Expand Down
Loading

0 comments on commit e204d38

Please sign in to comment.