Skip to content

aragon/osx-plugin-template-hardhat

Repository files navigation

Aragon OSX Plugin Template Hardhat License: AGPL v3

Quickstart

After creating a new repository from this template, cloning, and opening it in your IDE, create an .env file from the .env.example file and put in the Alchemy API key. Feel free to add other API keys for the services that you want to use. Now run,

yarn install && cd packages/contracts && yarn install && yarn build && yarn typechain

You can now develop a plugin by changing the src/MyPlugin.sol and src/MyPluginSetup.sol files. You can directly import contracts from Aragon OSx as well as OpenZeppelin's openzeppelin-contracts and openzeppelin-contracts-upgradeable that are already set up for you.

// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.17;

import {IDAO, PluginUUPSUpgradeable} from "@aragon/osx/core/plugin/PluginUUPSUpgradeable.sol";
import {SafeCastUpgradeable} from '@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol';

contract MyPlugin is PluginUUPSUpgradeable {
    //...
};

The initial MyPlugin and MyPluginSetup example comes with unit test, integration test, and test helpers in the package/contracts/test folder that you can reuse.

To build and test your contracts, run

yarn clean && yarn build && yarn test

Project

The root folder of the repo includes two subfolders:

.
├── packages/contracts
│ ├── src
│ ├── deploy
│ ├── test
│ ├── utils
│ ├── ...
│ └── package.json
│
├── packages/subgraph
│ ├── src
│ ├── scripts
│ ├── manifest
│ ├── tests
│ ├── utils
│ ├── ...
│ └── package.json
│
├── ...
└── package.json

The root-level package.json file contains global dev-dependencies for formatting and linting. After installing the dependencies with

yarn install

you can run the associated formatting and linting commands.

Formatting

yarn prettier:check

all .sol, .js, .ts, .json, and .yml files will be format-checked according to the specifications in .prettierrc file.With

yarn prettier:write

the formatting is applied.

Linting

With

yarn lint

.sol, .js, and .ts files in the subfolders are analyzed with solhint and eslint, respectively.

Setting Environment Variables

To be able to work on the contracts, make sure that you have created an .env file from the .env.example file and put in the API keys for

  • Alchemy that we use as the web3 provider
  • Alchemy Subgraphs that we use as the subgraph provider
  • the block explorer that you want to use depending on the networks that you want to deploy to

Before deploying, you MUST also change the default hardhat private key (PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80").

Contracts

In packages/contracts, first run

yarn install

Building

First build the contracts and

yarn build

and generate the typechain TypeScript bindings with

yarn typechain

During development of your smart contracts, changes can result in altered typechain bindings. You can remove the outdated build- and typechain-related files with

yarn clean

which will execute yarn typechain again. For convenience, use yarn clean && yarn build.

Testing

To test your contracts, run

yarn test

Linting

Lint the Solidity and TypeScript code all together with

yarn lint

or separately with

yarn lint:sol

and

yarn lint:ts

Coverage

Generate the code coverage report with

yarn coverage

Gas Report

See the gas usage per test and average gas per method call with

REPORT_GAS=true yarn test

you can permanently enable the gas reporting by putting the REPORT_GAS=true into the .env file.

Deployment

The deploy scripts provided inside ./packages/contracts/deploy take care of

  1. Creating an on-chain Plugin Repository for you through Aragon's factories with an unique ENS name.
  2. Publishing the first version of your Plugin and associated PluginSetup contract in your repo from step 1.
  3. Upgrade your plugin repository to the latest Aragon OSx protocol version.

Finally, it verifies all contracts on the block explorer of the chosen network.

You don't need to make changes to the deploy script. You only have to update the entries in packages/contracts/plugin-settings.ts as explained in the template usage guide.

Creating a Plugin Repository & Publishing Your Plugin

Deploy the contracts to the local Hardhat Network (being forked from the network specified in NETWORK_NAME in your .env file ) with

yarn deploy --tags CreateRepo,NewVersion

This will create a plugin repo and publish the first version (v1.1) of your plugin.

Deploy the contracts to sepolia with

yarn deploy --network sepolia --tags CreateRepo,NewVersion,Verification

This will create a plugin repo, publish the first version (v1.1) of your plugin, and verfiy the contracts on sepolia.

If you want to deploy a new version of your plugin afterwards (e.g., 1.2), simply change the VERSION entry in the packages/contracts/plugin-settings.ts file and use

yarn deploy --network sepolia --tags NewVersion,Verification

Note, that if you include the CreateRepo tag after you've created your plugin repo already, this part of the script will be skipped.

Upgrading Your Plugin Repository

Upgrade your plugin repo on the local Hardhat Network (being forked from the network specified in NETWORK_NAME in your .env file ) with

yarn deploy --tags UpgradeRepo

Upgrade your plugin repo on sepolia with

yarn deploy --network sepolia --tags UpgradeRepo

This will upgrade your plugin repo to the latest Aragon OSx protocol version implementation, which might include new features and security updates. For this to work, make sure that you are using the latest version of this repository in your fork.

Subgraph

Installing

In packages/subgraph, first run

yarn install

which will also run

yarn postinstall

subsequently, to build the ABI in the imported folder.

Building

Build the subgraph and

yarn build

which will first build the contracts (see Contracts / Building) with

yarn build:contracts

second the subgraph manifest with

yarn build:manifest

and finally the subgraph itself with

yarn build:subgraph

When running yarn build, it requires a plugin address, which is obtained from the configuration file located at subgraph/manifest/data/<network>.json, based on the network specified in your .env file under the SUBGRAPH_NETWORK_NAME variable. You do not need to provide a plugin address for building or testing purposes, but it becomes necessary when deploying the subgraph.

During development of the subgraph, you might want to clean outdated files that were build, imported, and generated. To do this, run

yarn clean

Testing

Test the subgraph with

yarn test

Linting

Lint the TypeScript code with

yarn lint

Coverage

Generate the code coverage with

yarn coverage

Deployment

To deploy the subgraph to the subgraph provider, write your intended subgraph name and version into the SUBGRAPH_NAME and SUBGRAPH_VERSION variables in the .env file that you created in the beginning and pick a network name SUBGRAPH_NETWORK_NAME being supported by the subgraph provider. Remember to place correctly the Plugin address on the network you are going to deploy to, you can do that by adding it on subgraph/manifest/data/<network>.json. Then run

yarn deploy

to deploy the subgraph and check your Alchemy subgraph dashboard for completion and possible errors.

License

This project is licensed under AGPL-3.0-or-later.