This repository contains test suites for building proposals for CompoundGovernor / OpenZeppelin GovernorBravo. The repository is designed with foundry.
Want to demonstrate setting up a vote and executing a swap of 500 wstETH to rETH
- Approve the required amount of
stETHto wrap intowstETH. - Wrap
stETHintowstETH - Approve the to-be-created
Safe(in pt. 4) to use the DAO'swstETH - Create the
ComposableCoWcompatibleSafecontract with:thresholdof 1ownerset to theNounsDAOExecutoraddress (ie. all executions on theSafeare bound by timelock)
- Execute post-Safe creation configuration and create conditional order:
a. Set
ComposableCoWas the domain verifier forGPv2Settlementb. Set an allowance forGPv2VaultRelayerto use thewstETHfrom theSafecontract c. DotransferFromof the wstETH to theSafecontract d. Create the TWAP order onComposableCoWvia theSafecontractsellTokenset to the wstETH addressbuyTokenset to the rETH addresssellAmountset to 500 wstETHbuyAmountTBDreceiverset to theNounsDAOExecutoraddress (all funds on swap move to the timelock)
- Enforce that the allowance for
wstETHto be spent from the timelock controller is set back to zero
- Any
Safethat is created that holdsNounsDAOfunds, must be subject to the timelock controller nature ofNounsDAOExecutor. - The sole owner of the
Safeshall be theNounsDAOExecutor. - NO funds are sent to the to-be-created
Safein the atomic transaction bundle, and are instead pulled from theNounsDAOExecutor. This avoids the unlikely situation where a pre-calculatedSafeaddress (prior toSafeProxyFactory.createProxyWithNonce) has been determined incorrectly and funds are sent to an unrecoverable address. - Approvals for spending on
NounsDAOExecutorfrom the to-be-createdSafeare zeroed at the end of the transaction bundle (though, should already be zero).
- Prove that the process can be undertaken from the context of the
NounsDAOExecutor(ie. the timelock). This means we usevm.prankto impersonate theNounsDAOExecutorand execute the swap. - Do a full-stack test that:
- Proposes the transaction bundle
- Vote on the proposal (to affirm).
- Queue the proposal (on successful vote).
- Execute the proposal (verify transaction bundle executes correctly).
- Verify via settlement that the discrete orders settle correctly.
The test suite is designed to run in a forked environment. Running in a self-contained environment is out of scope due to the large number of dependencies that are required. To run the test suite:
forge test -vvv --optimize --optimizer-runs 20000 --rpc-url http://erigon.dappnode:8545 --fork-block-number 17885110NOTE: Substitute the RPC_URL and the fork-block-number as required. Using a consistent fork-block-number will cache state that is pulled from the RPC_URL, resulting in substantially faster runtime on subsequent runs.
NOTE: There is a test item that is designed to always revert and alert any repository fork to ensure that todo items are completed.
Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.
Foundry consists of:
- Forge: Ethereum testing framework (like Truffle, Hardhat and DappTools).
- Cast: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data.
- Anvil: Local Ethereum node, akin to Ganache, Hardhat Network.
- Chisel: Fast, utilitarian, and verbose solidity REPL.