Skip to content

Commit

Permalink
Update the Aragon OSx docs by commit f607746
Browse files Browse the repository at this point in the history
  • Loading branch information
clauBv23 authored and arabot-1 committed May 15, 2024
1 parent 4be0881 commit c54d58d
Show file tree
Hide file tree
Showing 31 changed files with 49 additions and 70 deletions.
10 changes: 0 additions & 10 deletions docs/osx/01-get-started.mdx

This file was deleted.

4 changes: 2 additions & 2 deletions docs/osx/01-how-it-works/01-core/03-plugins/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Whenever a DAO installs a plugin, an instance of that plugin's base template is
Each instance of a plugin is installed to a DAO through the granting of permissions.

:::info
Learn more about the different [plugin types](../../../02-how-to-guides/02-plugin-development/02-plugin-types.md) in our How-to guide.
Lern more about the different [plugin types](../../../02-how-to-guides/02-plugin-development/02-plugin-types.md) in our How-to guide.
:::

This raises questions on how the DAO manages plugins and who actually owns plugins.
Expand All @@ -42,7 +42,7 @@ A DAO manages plugins and interactions between them. In more detail, its permiss
![Schematic depiction of the interaction between the DAO, the PermissionManager, and a Plugin contract.](../dao-plugin.drawio.svg)

<p class="caption">
An exemplary DAO setup showing interactions between the three core contract pieces triggered by different user groups: The <code>DAO</code> contract in blue containing the <code>PermissionManager</code> in red, respectively, as well as two <code>Plugin</code> contracts in green.
An examplary DAO setup showing interactions between the three core contract pieces triggered by different user groups: The <code>DAO</code> contract in blue containing the <code>PermissionManager</code> in red, respectively, as well as two <code>Plugin</code> contracts in green.
Function calls are visualized as black arrows and require permission checks (red, dashed arrow). In this example, the permission manager determines whether the token voting plugin can execute actions on the DAO, a member can change its settings, or if a DeFi-related plugin is allowed to invest in a certain, external contract.
</p>

Expand Down
3 changes: 1 addition & 2 deletions docs/osx/01-how-it-works/01-core/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
title: The Smart Contracts behind DAOs
sidebar_label: Smart Contracts
---

## The Contracts Constituting Your DAO
Expand Down Expand Up @@ -32,7 +31,7 @@ The underlying smart contracts constitute **the core contracts** of the Aragon O
![Schematic depiction of the interaction between the DAO, the PermissionManager, and a Plugin contract.](dao-plugin.drawio.svg)

<p class="caption">
An exemplary DAO setup showing interactions between the three core contract pieces triggered by different user groups: The <code>DAO</code> contract in blue containing the <code>PermissionManager</code> in red, respectively, as well as two <code>Plugin</code> contracts in green.
An examplary DAO setup showing interactions between the three core contract pieces triggered by different user groups: The <code>DAO</code> contract in blue containing the <code>PermissionManager</code> in red, respectively, as well as two <code>Plugin</code> contracts in green.
Function calls are visualized as black arrows and require permission checks (red, dashed arrow). In this example, the permission manager determines whether the token voting plugin can execute actions on the DAO, a member can change its settings, or if a DeFi-related plugin is allowed to invest in a certain, external contract.
</p>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ as well as an array of `PluginSettings` containing `PluginSetup` contract refere

The `DAOFactory` create the `DAO` in four steps and interacts with the `DAORegistry` and being also part of the Aragon OSx framework:

1. Creates a new DAO by deploying an [ERC-1967](https://eips.ethereum.org/EIPS/eip-1967) proxy pointing to the latest Aragon OSx `DAO` implementation and becomes the initial owner.
1. Creates a new DAO by deploying an [ERC-1967](https://eips.ethereum.org/EIPS/eip-1967) proxy pointing to the latest Aragon OSx `DAO` impelementation and becomes the initial owner.

2. Registers the new contract in the [`DAORegistry`](#daoregistry).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: Plugin Repositories

## What are Plugin Repositories?

Each plugin has its own Plugin Repository, unique ENS name, and on-chain repository contract, the `PluginRepo`, in which different versions of the plugin are stored for reference using version tags constituted by a **release** and **build** number.
Each plugin has its own Plugin Repository, unique ENS name, and on-chain repository contract, the `PluginRepo`, in which different versions of the plugin are stored for reference using verstion tags constituted by a **release** and **build** number.

Different versions might contain:

Expand All @@ -19,7 +19,7 @@ Different versions might contain:
![Schematic depiction of the versioning taking place in the PluginRepoRegistry.](./plugin-repo-overview.drawio.svg)

<p class="caption">
Overview of the plugin versioning and registry in the Aragon OSx protocol. The `PluginRepoRegistry` contract, which is a curated list of ENS named `PluginRepo` contracts, is shown on the left. Each `PluginRepo` contract maintains a list of versions of the `PluginSetup` contract (internally referencing the `Plugin` implementation contract) and the associated UI building blocks as a URI, exemplarily shown on the right.
Overview of the plugin versioning and registry in the Aragon OSx protocol. The `PluginRepoRegistry` contract, which is a curated list of ENS named `PluginRepo` contracts, is shown on the left. Each `PluginRepo` contract maintains a list of versions of the `PluginSetup` contract (internally referencing the `Plugin` implementation contract) and the associated UI building blocks as a URI, examplarily shown on the right.
</p>

</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ that might be carelessly or intentionally caused, a malicious plugin can hide **

#### Backdoors

- [metamorphic contracts](https://a16zcrypto.com/metamorphic-smart-contract-detector-tool/) (contracts, that can be redeployed with new code to the same address)
- [metamorpic contracts](https://a16zcrypto.com/metamorphic-smart-contract-detector-tool/) (contracts, that can be redeployed with new code to the same address)
- malicious repurposing of storage in an update of an upgradeable plugin contract

<!-- Add statement that Aragon will provide / collaborate with 3rd parties to create tools to check for this-->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ How this works:

- Although a Plugin is composed by the `Plugin` and `PluginSetup` contracts, the Aragon OSx protocol only knows of the `PluginSetup` contract.
- Since the `PluginSetup` contract is the one containing the plugin installation instructions, it is the one in charge of deploying the Plugin instance. Each plugin instance is specific to that DAO, deployed with its own unique parameters. You can review how to build a `PluginSetup` contract [here](../../../../02-how-to-guides/02-plugin-development/index.md).
- The `PluginSetup` contract then interacts with the Aragon OSx framework's `PluginSetupProcessor` contract, which is in charge of applying the installation, update, or uninstallation of a plugin into a DAO.
- The `PluginSetup` contract then interacts with the Aragon OSx framework's `PluginSetupProcessor` contract, which is in charge of applying the installion, update, or uninstallation of a plugin into a DAO.
- Publishing a Plugin into the Aragon OSx protocol is done through creating the first version of the plugin's `PluginRepo`. The plugin's `PluginRepo` instance stores all plugin versions. You can read more about that [here](../../../../02-how-to-guides/02-plugin-development/07-publication/index.md).
- Except for the gas costs required, plugins are completely free to install, unless decided otherwise by the developer.

Expand Down Expand Up @@ -44,7 +44,7 @@ The preparation of a `PluginSetup` contract proceeds as follows:

- deployment of new contracts
- initialization of new storage variables
- deprecating/decommissioning outdated (helper) contracts
- deprecating/decomissioning outdated (helper) contracts
- governance settings or other attributes
- ...

Expand Down
1 change: 0 additions & 1 deletion docs/osx/01-how-it-works/02-framework/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
title: Framework - How Everything Connects
sidebar_label: Framework
---

## The Infrastructure Running the Aragon OSx Protocol
Expand Down
2 changes: 0 additions & 2 deletions docs/osx/01-how-it-works/_category_.yml

This file was deleted.

2 changes: 1 addition & 1 deletion docs/osx/02-how-to-guides/01-dao/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Operating a DAO
title: How to Operate a DAO
---

DAOs are decentralized autonomous organizations. They are a group of people managing on-chain assets through a set of smart contracts.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ Some key things to keep in mind:

The following table compares the different deployment methods with their benefits and drawbacks:

| | `new` Instantiation | Minimal Proxy (Clones) | Transparent Proxy | UUPS Proxy |
| -------------- | --------------------------------------------- | ------------------------------------------------- | ------------------------------------------------ | --------------------------------------------- |
| upgradeability | <span class="table-cell-negative">no</span> | <span class="table-cell-negative">no</span> | <span class="table-cell-positive">yes</span> | <span class="table-cell-positive">yes</span> |
| gas costs | <span class="table-cell-negative">high</span> | <span class="table-cell-positive">very low</span> | <span class="table-cell-neutral">moderate</span> | <span class="table-cell-positive">low</span> |
| difficulty | <span class="table-cell-positive">low</span> | <span class="table-cell-positive">low</span> | <span class="table-cell-negative">high</span> | <span class="table-cell-negative">high</span> |
| | `new` Instantiation | Minimal Proxy (Clones) | Transparent Proxy | UUPS Proxy |
| ------------- | --------------------------------------------- | ------------------------------------------------- | ------------------------------------------------ | --------------------------------------------- |
| upgradability | <span class="table-cell-negative">no</span> | <span class="table-cell-negative">no</span> | <span class="table-cell-positive">yes</span> | <span class="table-cell-positive">yes</span> |
| gas costs | <span class="table-cell-negative">high</span> | <span class="table-cell-positive">very low</span> | <span class="table-cell-neutral">moderate</span> | <span class="table-cell-positive">low</span> |
| difficulty | <span class="table-cell-positive">low</span> | <span class="table-cell-positive">low</span> | <span class="table-cell-negative">high</span> | <span class="table-cell-negative">high</span> |

Accordingly, we recommend to use [minimal proxies (ERC-1167)](https://eips.ethereum.org/EIPS/eip-1167) for non-upgradeable and [UUPS proxies (1822)](https://eips.ethereum.org/EIPS/eip-1822) for upgradeable plugin.
To help you with developing and deploying your plugin within the Aragon infrastructure, we provide the following implementation that you can inherit from:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ contract SimpleAdmin is PluginCloneable {
}
```

We must protect it from being called multiple times by using [OpenZeppelin's `initializer` modifier made available through `Initializable`](https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable) and call the internal function `__PluginCloneable_init(IDAO _dao)` available through the `PluginCloneable` base contract to store the `IDAO _dao` reference in the right place.
We must protect it from being called multiple times by using [OpenZeppelin's `initializer` modifier made available through `Initalizable`](https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable) and call the internal function `__PluginCloneable_init(IDAO _dao)` available through the `PluginCloneable` base contract to store the `IDAO _dao` reference in the right place.

:::caution
If you forget calling `__PluginCloneable_init(_dao)` inside your `initialize` function, your plugin won't be associated with a DAO and cannot use the DAO's `PermissionManager`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Setting this permission is key because it ensures only signers who have been gra

Now that we have created the permission, we will use it to protect the implementation. We want to make sure only the authorized callers holding the `ADMIN_EXECUTE_PERMISSION`, can use the function.

Because we have initialized the [`PluginCloneable` base contract](https://github.com/aragon/osx-commons/blob/develop/contracts/src/plugin/PluginCloneable.sol), we can now use its features, i.e., the [`auth` modifier](https://github.com/aragon/osx-commons/blob/1cf46ff15dbda8481f9ee37558e7ea8b257d51f2/contracts/src/permission/auth/DaoAuthorizable.sol#L30-L35) provided through the `DaoAuthorizable` base class. The `auth('ADMIN_EXECUTE_PERMISSION')` returns an error if the address calling on the function has not been granted that permission, effectively protecting from malicious use cases.
Because we have initialized the [`PluginClonable` base contract](https://github.com/aragon/osx-commons/blob/develop/contracts/src/plugin/PluginCloneable.sol), we can now use its features, i.e., the [`auth` modifier](https://github.com/aragon/osx-commons/blob/1cf46ff15dbda8481f9ee37558e7ea8b257d51f2/contracts/src/permission/auth/DaoAuthorizable.sol#L30-L35) provided through the `DaoAuthorizable` base class. The `auth('ADMIN_EXECUTE_PERMISSION')` returns an error if the address calling on the function has not been granted that permission, effectively protecting from malicious use cases.

Later, we will also use the [`dao()` getter function from the base contract](https://github.com/aragon/osx-commons/blob/1cf46ff15dbda8481f9ee37558e7ea8b257d51f2/contracts/src/permission/auth/DaoAuthorizable.sol#L24-L28), which returns the associated DAO for that plugin.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ title: Plugin Setup Contract

The Plugin Setup contract is the contract defining the instructions for installing, uninstalling, or upgrading plugins into DAOs. This contract prepares the permission granting or revoking that needs to happen in order for plugins to be able to perform actions on behalf of the DAO.

You need it for the plugin to be installed into the DAO.
You need it for the plugin to be installed intto the DAO.

### 1. Finish the Plugin contract

Expand Down Expand Up @@ -116,7 +116,7 @@ The `prepareInstallation()` function should take in two parameters:
1. the `DAO` it prepares the installation for, and
2. the `_data` parameter containing all the information needed for this function to work properly, in this case, the address we want to set as admin of our DAO.

Hence, the first thing we should do when working on the `prepareInstallation()` function is decode the information from the `_data` parameter. We also want to check that the address is not accidentally set to `address(0)`, which would freeze the DAO forever.
Hence, the first thing we should do when working on the `prepareInsallation()` function is decode the information from the `_data` parameter. We also want to check that the address is not accidentally set to `address(0)`, which would freeze the DAO forever.

```solidity
import {Clones} from '@openzeppelin/contracts/proxy/Clones.sol';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Some observations:

Before moving on with the Guide, make sure you've read our documentation on [Choosing the Best Type for Your Plugin](../02-plugin-types.md) to make sure you're selecting the right type of contract for your Plugin.

## Building a Non-Upgradable Plugin
## Building a Non-Upgradeble Plugin

We will build a plugin which returns "Hello world!" and the amount of times the function has been called.

Expand Down Expand Up @@ -43,7 +43,7 @@ sudo apt-get install -y nodejs

[Here's a tutorial](https://hardhat.org/tutorial/setting-up-the-environment) on installing this if you haven't done so already.

2. Next up, we want to create a Hardhat project in our terminal. This is the Solidity framework we'll use to get our project up and running.
2. Next up, we want to create a Hardhat project in our terminal. This is the Solidity framework we'll use to get our project up and runing.

```bash
npm init
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
title: Initialization
title: Intialization
---

## How to Initialize Upgradeable Plugins

To deploy your implementation contract via the [UUPS pattern (ERC-1822)](https://eips.ethereum.org/EIPS/eip-1822), you inherit from the `PluginUUPSUpgradeable` contract.

We must protect it from being set up multiple times by using [OpenZeppelin's `initializer` modifier made available through `Initializable`](https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable). In order to do this, we will call the internal function `__PluginUUPSUpgradeable_init(IDAO _dao)` function available through the `PluginUUPSUpgradeable` base contract to store the `IDAO _dao` reference in the right place.
We must protect it from being set up multiple times by using [OpenZeppelin's `initializer` modifier made available through `Initalizable`](https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable). In order to do this, we will call the internal function `__PluginUUPSUpgradeable_init(IDAO _dao)` function available through the `PluginUUPSUpgradeable` base contract to store the `IDAO _dao` reference in the right place.

:::note
This has to be called - otherwise, anyone else could call the plugin's initialization with whatever params they wanted.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ The `prepareInstallation()` function takes in two parameters:
1. the `DAO` it should prepare the installation for, and
2. the `_data` parameter containing all the information needed for this function to work properly, encoded as a `bytes memory`. In this case, we get the number we want to store.

Hence, the first thing we should do when working on the `prepareInstallation()` function is decode the information from the `_data` parameter.
Hence, the first thing we should do when working on the `prepareInsallation()` function is decode the information from the `_data` parameter.
Similarly, the `prepareUninstallation()` function takes in a `payload`.

```solidity
Expand Down Expand Up @@ -131,7 +131,7 @@ Firstly, we'll make sure our preferred network is well setup within our `hardhat
```js
import '@nomicfoundation/hardhat-toolbox';

// To find your Alchemy key, go to https://dashboard.alchemy.com/. Infura or any other provider would work here as well.
// To find your Alchemy key, go to https://dashboard.alchemy.com/. Infure or any other provider would work here as well.
const goerliAlchemyKey = 'add-your-own-alchemy-key';
// To find a private key, go to your wallet of choice and export a private key. Remember this must be kept secret at all times.
const privateKeyGoerli = 'add-your-account-private-key';
Expand Down Expand Up @@ -177,8 +177,7 @@ async function main() {
console.log('Deploying contracts with the account:', deployer.address);
console.log('Account balance:', (await deployer.getBalance()).toString());

const getSimpleStorageSetup =
await ethers.getContractFactory('SimpleStorageSetup');
const getSimpleStorageSetup = await ethers.getContractFactory('SimpleStorageSetup');
const SimpleStorageSetup = await SimpleStorageSetup.deploy();

await SimpleStorageSetup.deployed();
Expand Down
Loading

0 comments on commit c54d58d

Please sign in to comment.