Skip to content

Commit

Permalink
Adapting the tests (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
brickpop committed Nov 7, 2023
1 parent 153adb1 commit 31dfc2b
Show file tree
Hide file tree
Showing 13 changed files with 345 additions and 653 deletions.
94 changes: 89 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -422,26 +422,110 @@ This is taken care by the `DAOFactory`. The DAO creator calls `daoFactory.create
- The call contains:
- The DAO settings
- An array with the details and the settings of the desired plugins
- The method will deploy a new DAO and set itself as ROOT
- It will then call `prepareInstallation()` on all plugins and `applyInstallation()` right away
- It will finally drop `ROOT_PERMISSION` on itself
- The method will deploy a new DAO and grant `ROOT_PERMISSION` to the `DaoFactory`, temporarily
- Given the settings of the desired plugins, it will call the `PluginSetupProcessor`
- The PSP will then call `prepareInstallation()` on the given plugin set up contract
- Immedially after, `applyInstallation()` will be called by the `DaoFactory`
- The DaoFactory drops `ROOT_PERMISSION` on itself

[See a JS example of installing plugins during a DAO's deployment](https://devs.aragon.org/docs/sdk/examples/client/create-dao#create-a-dao)

### Installing plugins afterwards

Plugin changes need a proposal to be passed when the DAO already exists.

1. Calling `pluginSetup.prepareInstallation()`
1. Calling `pluginSetupProcessor.prepareInstallation()` which will call `prepareInstallation()` on the plugin's setup contract
- A new plugin instance is deployed with the desired settings
- The call requests a set of permissions to be applied by the DAO
- The call returns a set of requested permissions to be applied by the DAO
2. Editors pass a proposal to make the DAO call `applyInstallation()` on the [PluginSetupProcessor](https://devs.aragon.org/docs/osx/how-it-works/framework/plugin-management/plugin-setup/)
- This applies the requested permissions and the plugin becomes installed

See `SpacePluginSetup`, `PersonalSpaceAdminPluginSetup`, `MemberAccessPluginSetup` and `MainVotingPluginSetup`.

[Learn more about plugin setup's](https://devs.aragon.org/docs/osx/how-it-works/framework/plugin-management/plugin-setup/) and [preparing installations](https://devs.aragon.org/docs/sdk/examples/client/prepare-installation).

### Passing install parameters

In both of the cases described above, a call to `prepareInstallation()` will be made by the `PluginSetupProcessor` from OSx.

```solidity
function prepareInstallation(
address _dao,
bytes memory _data
) external returns (address plugin, PreparedSetupData memory preparedSetupData)
```

- The first parameter (dao address) will be provided by the PSP.
- The second parameter allows to pass an arbitrary array of bytes, encoding any set of custom settings that the plugin needs to receive.

The first step for `prepareInstallation()` is to decode them and use them on the deployment script as needed:

```solidity
// Decode incoming params
(
string memory _firstBlockContentUri,
address _predecessorAddress,
address _pluginUpgrader
) = abi.decode(_data, (string, address, address));
```

The JSON encoded ABI definition can be found at the corresponding `<name>-build-metadata.json` file:

```json
{
// ...
"pluginSetup": {
"prepareInstallation": {
// ...
"inputs": [
{
"name": "firstBlockContentUri",
"type": "string",
"internalType": "string",
"description": "The inital contents of the first block item."
},
{
"internalType": "address",
"name": "predecessorAddress",
"type": "address"
},
{
"internalType": "address",
"name": "pluginUpgrader",
"type": "address"
}
]
},
```

The same also applies to `prepareUpdate` (if present) and to `prepareUninstallation`.

### Available setup contracts

#### GovernancePluginsSetup

This contracts implements the deployment script for:

- `MainVotingPlugin`
- `MemberAccessPlugin`

The second plugin needs to know the address of the first one, therefore the contract deploys them together.

##### Note

When preparing the installation, an `InstallationPrepared` event is emitted. Using Typechain with Ethers:

- `event.args.preparedSetupData.plugin` contains the address of the Main Voting plugin
- `event.args.preparedSetupData.helpers` contains an array with the address of the Member Access plugin

#### SpacePluginSetup

This contract implements the deployment script for the `SpacePlugin` contract.

#### PersonalSpaceAdminPluginSetup

This contract implements the deployment script for the `PersonalSpaceAdminPlugin` contract.

## Deploying a DAO

The recommended way to create a DAO is by using `@aragon/sdk-client`. It uses the `DAOFactory` under the hood and it reduces the amount of low level interactions with the protocol.
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
"typescript": "5.0.4"
},
"scripts": {
"build": "cd ./packages/contracts && yarn build && cd ../contracts-ethers && yarn build && cd ../subgraph && yarn build",
"test": "cd ./packages/contracts && yarn test && cd ../subgraph && yarn test",
"clean": "cd ./packages/contracts && yarn clean && cd ../contracts-ethers && yarn clean && yarn clean && cd ../subgraph && yarn clean",
"build": "cd ./packages/contracts && yarn build && cd ../contracts-ethers && yarn build",
"test": "cd ./packages/contracts && yarn test",
"clean": "cd ./packages/contracts && yarn clean && cd ../contracts-ethers && yarn clean && yarn clean",
"prettier:check": "prettier --check \"**/*.{js,json,md,sol,ts,yml}\"",
"prettier:write": "prettier --write \"**/*.{js,json,md,sol,ts,yml}\""
}
Expand Down
8 changes: 2 additions & 6 deletions packages/contracts/deploy/01_repo/10_create_repo.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
MainVotingPluginSetupParams,
MemberAccessPluginSetupParams,
GovernancePluginsSetupParams,
PersonalSpaceAdminPluginSetupParams,
SpacePluginSetupParams,
} from "../../plugin-setup-params";
Expand All @@ -23,10 +22,7 @@ const func: DeployFunction = function (hre: HardhatRuntimeEnvironment) {
deployRepo(hre, PersonalSpaceAdminPluginSetupParams.PLUGIN_REPO_ENS_NAME)
)
.then(() =>
deployRepo(hre, MemberAccessPluginSetupParams.PLUGIN_REPO_ENS_NAME)
)
.then(() =>
deployRepo(hre, MainVotingPluginSetupParams.PLUGIN_REPO_ENS_NAME)
deployRepo(hre, GovernancePluginsSetupParams.PLUGIN_REPO_ENS_NAME)
);
};

Expand Down
25 changes: 6 additions & 19 deletions packages/contracts/deploy/02_setup/10_setup.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
MainVotingPluginSetupParams,
MemberAccessPluginSetupParams,
GovernancePluginsSetupParams,
PersonalSpaceAdminPluginSetupParams,
SpacePluginSetupParams,
} from "../../plugin-setup-params";
Expand All @@ -23,7 +22,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
log: true,
});

// Space
// Personal Space
console.log(
`\nDeploying ${PersonalSpaceAdminPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME}`,
);
Expand All @@ -37,23 +36,12 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
},
);

// Space
console.log(
`\nDeploying ${MemberAccessPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME}`,
);

await deploy(MemberAccessPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME, {
from: deployer,
args: [],
log: true,
});

// Space
// Governance
console.log(
`\nDeploying ${MainVotingPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME}`,
`\nDeploying ${GovernancePluginsSetupParams.PLUGIN_SETUP_CONTRACT_NAME}`,
);

await deploy(MainVotingPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME, {
await deploy(GovernancePluginsSetupParams.PLUGIN_SETUP_CONTRACT_NAME, {
from: deployer,
args: [],
log: true,
Expand All @@ -64,7 +52,6 @@ export default func;
func.tags = [
SpacePluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
PersonalSpaceAdminPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
MemberAccessPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
MainVotingPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
GovernancePluginsSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
"Deployment",
];
64 changes: 15 additions & 49 deletions packages/contracts/deploy/02_setup/11_setup_conclude.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import {
MainVotingPluginSetupParams,
MemberAccessPluginSetupParams,
GovernancePluginsSetupParams,
PersonalSpaceAdminPluginSetupParams,
SpacePluginSetupParams,
} from "../../plugin-setup-params";
import {
GovernancePluginsSetup__factory,
MainVotingPlugin__factory,
MainVotingPluginSetup__factory,
MemberAccessPlugin__factory,
MemberAccessPluginSetup__factory,
PersonalSpaceAdminPlugin__factory,
PersonalSpaceAdminPluginSetup__factory,
SpacePlugin__factory,
Expand All @@ -21,8 +19,7 @@ import { setTimeout } from "timers/promises";
const func: DeployFunction = function (hre: HardhatRuntimeEnvironment) {
return concludeSpaceSetup(hre)
.then(() => concludePersonalSpaceVotingSetup(hre))
.then(() => concludeMemberAccessVotingSetup(hre))
.then(() => concludeMainVotingSetup(hre));
.then(() => concludeGovernanceSetup(hre));
};

async function concludeSpaceSetup(hre: HardhatRuntimeEnvironment) {
Expand Down Expand Up @@ -99,27 +96,31 @@ async function concludePersonalSpaceVotingSetup(
});
}

async function concludeMemberAccessVotingSetup(
async function concludeGovernanceSetup(
hre: HardhatRuntimeEnvironment,
) {
const { deployments, network } = hre;
const [deployer] = await hre.ethers.getSigners();

console.log(
`Concluding ${MemberAccessPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME} deployment.\n`,
`Concluding ${GovernancePluginsSetupParams.PLUGIN_SETUP_CONTRACT_NAME} deployment.\n`,
);

const setupDeployment = await deployments.get(
MemberAccessPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
GovernancePluginsSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
);
const setup = MemberAccessPluginSetup__factory.connect(
const setup = GovernancePluginsSetup__factory.connect(
setupDeployment.address,
deployer,
);
const implementation = MemberAccessPlugin__factory.connect(
const mainVotingPluginImplementation = MainVotingPlugin__factory.connect(
await setup.implementation(),
deployer,
);
const memberAccessPluginImplementation = MemberAccessPlugin__factory.connect(
await setup.memberAccessPluginImplementation(),
deployer,
);

// Add a timeout for polygon because the call to `implementation()` can fail for newly deployed contracts in the first few seconds
if (network.name === "polygon") {
Expand All @@ -132,45 +133,11 @@ async function concludeMemberAccessVotingSetup(
args: setupDeployment.args,
});
hre.aragonToVerifyContracts.push({
address: implementation.address,
address: mainVotingPluginImplementation.address,
args: [],
});
}

async function concludeMainVotingSetup(
hre: HardhatRuntimeEnvironment,
) {
const { deployments, network } = hre;
const [deployer] = await hre.ethers.getSigners();

console.log(
`Concluding ${MainVotingPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME} deployment.\n`,
);

const setupDeployment = await deployments.get(
MainVotingPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
);
const setup = MainVotingPluginSetup__factory.connect(
setupDeployment.address,
deployer,
);
const implementation = MainVotingPlugin__factory.connect(
await setup.implementation(),
deployer,
);

// Add a timeout for polygon because the call to `implementation()` can fail for newly deployed contracts in the first few seconds
if (network.name === "polygon") {
console.log(`Waiting 30secs for ${network.name} to finish up...`);
await setTimeout(30000);
}

hre.aragonToVerifyContracts.push({
address: setupDeployment.address,
args: setupDeployment.args,
});
hre.aragonToVerifyContracts.push({
address: implementation.address,
address: memberAccessPluginImplementation.address,
args: [],
});
}
Expand All @@ -179,7 +146,6 @@ export default func;
func.tags = [
SpacePluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
PersonalSpaceAdminPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
MemberAccessPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
MainVotingPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
GovernancePluginsSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
"Verification",
];
9 changes: 3 additions & 6 deletions packages/contracts/deploy/02_setup/12_publish.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
MainVotingPluginSetupParams,
MemberAccessPluginSetupParams,
GovernancePluginsSetupParams,
PersonalSpaceAdminPluginSetupParams,
PluginSetupParams,
SpacePluginSetupParams,
Expand All @@ -19,8 +18,7 @@ import { HardhatRuntimeEnvironment } from "hardhat/types";
const func: DeployFunction = function (hre: HardhatRuntimeEnvironment) {
return publishPlugin(hre, SpacePluginSetupParams)
.then(() => publishPlugin(hre, PersonalSpaceAdminPluginSetupParams))
.then(() => publishPlugin(hre, MemberAccessPluginSetupParams))
.then(() => publishPlugin(hre, MainVotingPluginSetupParams));
.then(() => publishPlugin(hre, GovernancePluginsSetupParams));
};

async function publishPlugin(
Expand Down Expand Up @@ -150,7 +148,6 @@ export default func;
func.tags = [
SpacePluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
PersonalSpaceAdminPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
MemberAccessPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
MainVotingPluginSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
GovernancePluginsSetupParams.PLUGIN_SETUP_CONTRACT_NAME,
"Publication",
];
Loading

0 comments on commit 31dfc2b

Please sign in to comment.