Contract | Purpose |
---|---|
OrigamiMembershipToken |
A membership NFT issued to DAO members |
OrigamiGovernanceToken |
An ERC20 token appropriate for use in governance |
OrigamiGovernorDiamond |
The EIP-2535 Diamond interface to the governor facets |
OrigamiTimelockController |
Part of a given DAO's governor deploy |
AccessControl |
A re-implementation of OZ AccessControl using Diamond Storage |
A Governor instance is deployed as an EIP-2535 Diamond, with the facet deploys being reusable implementations. The facets and their supporting files can be found in src/governor
.
We power our solidity development with foundry
. The book is a great jumping off point. Awesome Foundry does a great job of showcasing common patterns implemented using foundry
. Run forge
from the project directory after installing the prerequisites to get an idea of the capabilities.
- Install
cargo
:curl https://sh.rustup.rs -sSf | sh
- Install
foundry
(instructions and details):curl -L https://foundry.paradigm.xyz | bash
foundryup
- Install
argc
:cargo install argc
- Install
solhint
:npm ci
- Install
lcov
andgenhtml
(in order to support running coverage viajib
)
NB: if you intend to run the scripts in ./script
directly or via ./bin/jib
, ensure you've created a .envrc
file (cp {example,}.envrc
), populated its values and exported them to your shell (direnv
is a convenient way of managing this).
All documentation is in NatSpec
format and available alongside the code. You can also generate the documentation for the project as HTML using the go-natspec
project. Here's a brief overview of usage on macOS:
$ brew install pygments
$ curl -O https://github.com/sambacha/go-natspec/releases/download/v0.0.1/dappspec
$ chmod +x dappspec
$ ./dappspec src/OrigamiGovernanceToken.sol
$ open docs/OrigamiGovernanceToken.sol
Tests are implemented in Solidity and use foundry
to power them. The documentation for writing tests using foundry
is thorough and there is an active community in their telegram.
The simplest test invocation is:
$ forge test
Running tests with 3 levels of verbosity provides extensive feedback on failures and gas usage estimates. Combining this with watch mode makes for a tight feedback loop:
$ forge test -vvv -w
Generate a coverage report:
$ ./bin/jib coverage
Run the linter manually:
$ npx solhint src/**/*.sol
This is handled via the jib
command (a jib is the arm that supports the load on a crane). The command self-documents by passing --help
to its commands, as in:
$ ./bin/jib --help
or
$ ./bin/jib cmt --help
Some commands require the address of a previously deployed contract (e.g. the clone commands). Team members can find these on the notion page for deployed contract addresses.
It may prove advantageous to deploy the entire suite of smart contracts locally for development purposes. To that end, we've created a local-deploy
script that will deploy everything to a local node (here we use anvil
, from the Foundry toolset).
The provided configuration file assumes that the account at index 19 from the test test test test test test test test test test test junk
mnemonic was used to deploy the contracts. Additionally, the example commands that follow assume that the account at index 20 is set as the contract admin. Both of these accounts will need to be funded in your local node. A simple way to do so with anvil
is:
$ anvil -a 21
The default behavior of anvil
is to fund all accounts generated from the specified mnemonic.
To deploy the membership token, governance token, timelock controller, governor facets and governor diamond to a local node:
$ ./bin/jib local-deploy <ADDRESS CONTRACT-ADMIN> -p <PRIV KEY DEPLOYER>
Provided you've used the specified account as the deployer, an example configuration file that uses the addresses that will have been generated by the above can be found at configs/local-config.json
. If you did not use those accounts, you should update configs/local-config.json
accordingly or use a different configuration file for the governor that specifies your generated contract addresses. Contract addresses are output during the local-deploy
run.
The governor must be configured to use the facets in order to be used. You can do so with this command:
$ ./bin/jib cg -p <PRIVATE KEY OF CONTRACT ADMIN> <ADDRESS DIAMOND INIT> <ADDRESS OF THE GOVERNOR (DIAMOND)> <ADDRESS OF THE TIMELOCKCONTROLLER> <PATH TO JSON CONFIG>