In solidity with openzeppelin’s 'Governor' suite.
Purpose: to reproduce and debug the contract deployment error.
This issue has been fixed in this PR.
Not exactly the same contracts as during the hackathon, I took the simplest classic example found in all the examples namely a DAO to execute a value change on a 'Box' contract.
The contracts are: Box, GovToken (the governance token), TimeLock and MyGovernor. The last 3 being generated by the openzeppelin wizard.
Interactions:
- Box is the target contract on which successful proposals are executed. TimeLock is its owner
- GovToken is the governance token allowing a snapshot and delegation mechanism (in this example there's no ownership protection)
- MyGovernor is the main contract called by users to make a proposal, vote...
- TimeLock ensures that the different periods and roles are respected, and the one that authorizes the execution of proposals
We are not interested in securing or setting everything but just have basic functional contracts to deploy.
I used env variables in commands and in script to ensure there's no problem of ownership or authorization and to have the same behavior in all configurations.
- clone the repo then :
forge install
to install/update dependencies
commands used:
`forge init` or `forge init --force` (to force the init if cloned an empty project for example)forge install OpenZeppelin/openzeppelin-contracts --no-commit
forge install Cyfrin/foundry-devops --no-commit
fs_permissions in foundry.toml is used by foundry-devops to get most recent deployed contracts from broadcast folder
-
Update your '.env' file
-
First and after any change in the '.env' file, load environment variables:
source .env
In GovernorTest.t.sol, this version not using a deployment script is commented
command: forge test
SEPOLIA test command: forge test --fork-url $SEPOLIA_RPC_URL --match-contract "GovernorTest"
ALLFEAT test command: forge test --fork-url $ALLFEAT_RPC_URL --match-contract "GovernorTest"
add -vvvvv for max log traces if needed
using : GovernorTest.t.sol, HelperConfig.s.sol, DeployGovernor.s.sol
Sepolia test: forge test --fork-url $SEPOLIA_RPC_URL -vvvvv
Allfeat test: forge test --fork-url $ALLFEAT_RPC_URL -vvvvv
all the tests pass:
Test result: ok. 2 passed; 0 failed; 0 skipped; finished in 464.60msRan 1 test suites: 2 tests passed, 0 failed, 0 skipped (2 total tests)
Sepolia: forge script script/DeployGovernor.s.sol --rpc-url $SEPOLIA_RPC_URL --private-key $SEPOLIA_PRIVATE_KEY --broadcast
✅ Sepolia deployment is ok.
Allfeat: forge script script/DeployGovernor.s.sol --rpc-url $ALLFEAT_RPC_URL --private-key $ALLFEAT_PRIVATE_KEY --broadcast
❗same success output as for sepolia but at the end :
Transaction Failure: 0x4ef1f6c96fc4cf38a5bcc589b1ad8e8d7a6c70c8615542beb96f8ad7e8f50203 Transaction Failure: 0x9ed993ce30b37af7934b7754c47f2c23d2576ead4cd31530b6ad149809fc2b8c Transaction Failure: 0x6ad0fa1cd0d7f303ed6974b3be1dcdffe55c76afef8bdba050d526a5d268bbc1
When examining the allfeat explorer we may see that the 'out of gas' errors are referenced for tx concerning the deployment address specified for 'TimeLock'.
For this address, there is an element (ethereum.Executed) 'succeded' and 3 with the same error. This confirms that the contract is well deployed but that the 3 calls to TimeLock to manage the roles are problematic
using test/stepDeployment folder
these scripts segregate each action to ensure that deployment is not the issue.
order of commands to run for sepolia:
- Box deployment:
forge script script/stepDeployment/DeployOnlyBox.s.sol --rpc-url $SEPOLIA_RPC_URL --private-key $SEPOLIA_PRIVATE_KEY --broadcast
- Token deployment:
forge script script/stepDeployment/DeployOnlyToken.s.sol --rpc-url $SEPOLIA_RPC_URL --private-key $SEPOLIA_PRIVATE_KEY --broadcast
- TimeLock deployment:
forge script script/stepDeployment/DeployOnlyTimeLock.s.sol --rpc-url $SEPOLIA_RPC_URL --private-key $SEPOLIA_PRIVATE_KEY --broadcast
- Governor deployment:
forge script script/stepDeployment/DeployOnlyGovernor.s.sol --rpc-url $SEPOLIA_RPC_URL --private-key $SEPOLIA_PRIVATE_KEY --broadcast
- Setup of Box and Token:
forge script script/stepDeployment/SetupBoxAndToken.s.sol --rpc-url $SEPOLIA_RPC_URL --private-key $SEPOLIA_PRIVATE_KEY --broadcast
- Setup of TimeLock:
forge script script/stepDeployment/SetupDAO.s.sol --rpc-url $SEPOLIA_RPC_URL --private-key $SEPOLIA_PRIVATE_KEY --broadcast
- First action: propose:
forge script script/stepDeployment/Action1_propose.s.sol --rpc-url $SEPOLIA_RPC_URL --private-key $SEPOLIA_PRIVATE_KEY --broadcast
The scripts of the following actions are not finished at the moment (still buggy) but they go beyond the context of the error.
order of commands to run for allfeat:
- Box deployment:
forge script script/stepDeployment/DeployOnlyBox.s.sol --rpc-url $ALLFEAT_RPC_URL --private-key $ALLFEAT_PRIVATE_KEY --broadcast
- Token deployment:
forge script script/stepDeployment/DeployOnlyToken.s.sol --rpc-url $ALLFEAT_RPC_URL --private-key $ALLFEAT_PRIVATE_KEY --broadcast
- TimeLock deployment:
forge script script/stepDeployment/DeployOnlyTimeLock.s.sol --rpc-url $ALLFEAT_RPC_URL --private-key $ALLFEAT_PRIVATE_KEY --broadcast
- Governor deployment:
forge script script/stepDeployment/DeployOnlyGovernor.s.sol --rpc-url $ALLFEAT_RPC_URL --private-key $ALLFEAT_PRIVATE_KEY --broadcast
- Setup of Box and Token:
forge script script/stepDeployment/SetupBoxAndToken.s.sol --rpc-url $ALLFEAT_RPC_URL --private-key $ALLFEAT_PRIVATE_KEY --broadcast
- Setup of TimeLock
forge script script/stepDeployment/SetupDAO.s.sol --rpc-url $ALLFEAT_RPC_URL --private-key $ALLFEAT_PRIVATE_KEY --broadcast
This last command causes the problem in the same way as with the global script, so the 3 calls to TimeLock are the problem.