Hifi's token swap and governance contracts.
Hifi Governance and ERC-20 token implementation are each based on a common foundation stemming from Compound's GovernorBravo Smart Contracts. To meet our requirements we are pulling our ERC-20 token implementation from Uniswap's fork of Compound Governance, and pulling the Governance smart contracts from Ampleforth's fork of Compound Governance.
We chose Uniswap for the token implementation because it comes with the ERC-2612 functionality along with a governance based minting functionality we require. Uniswap's code for token implementation is in a direct fork from the Compound token implementation.
The foundation of our governance contracts came from the Ampleforth fork of GovernorBravo, because similar to us and unlike Uniswap or Compound, they did not have legacy GovernorAlpha smart contracts before their GovernorBravo implementation. All changes we have made on top of this fork are outlined in COMMITLOG.md. Briefly, those changes include updating the Solidity version, adding support for our token swap, and integrating our token requirements to the codebase.
- NVM
- Yarn package manager
Before being able to run any command, you need to create a .env
file and set a BIP-39 compatible mnemonic as an environment
variable. You can follow the example in .env.example
. If you don't already have a mnemonic, you can use this website to generate one.
Then, proceed with the following:
- Set the version of Node to use locally within the project:
$ nvm use
- Install the dependencies with Yarn:
$ yarn install
Compile the smart contracts with Hardhat:
$ yarn compile
Compile the smart contracts and generate TypeChain bindings:
$ yarn typechain
Run the tests with Hardhat:
$ yarn test
Lint the Solidity code:
$ yarn lint:sol
Lint the TypeScript code:
$ yarn lint:ts
Generate the code coverage report:
$ yarn coverage
See the gas usage per unit test and average gas per method call:
$ REPORT_GAS=true yarn test
Delete the smart contract artifacts, the coverage reports and the Hardhat cache:
$ yarn clean
The smart contracts need to be deployed in the following order:
$ yarn hardhat deploy:contract:hifi --account ${ACCOUNT} --minter ${MINTER} --network ${NETWORK_NAME} --confirmations 5 --print true --verify true
$ yarn hardhat deploy:contract:timelock --admin ${ADMIN} --delay ${DELAY} --network ${NETWORK_NAME} --confirmations 5 --print true --verify true
$ yarn hardhat deploy:contract:governor-bravo-delegate --network ${NETWORK_NAME} --confirmations 5 --print true --verify true
$ yarn hardhat deploy:contract:governor-bravo-delegator --timelock ${TIMELOCK} --hifi ${HIFI_TOKEN} --admin ${ADMIN} --implementation ${GOVERNOR_BRAVO_IMPLEMENTATION} --voting-period ${VOTING_PERIOD} --voting-delay ${VOTING_DELAY} --proposal-threshold ${PROPOSAL_THRESHOLD} --network ${NETWORK_NAME} --confirmations 5 --print true --verify true
Note: Before deploying the GovernorBravo proxy, the timelock contract admin needs to queue and execute a transaction with the following params:
Name | Type | Data | |
---|---|---|---|
0 | target | address | TIMELOCK |
1 | value | uint256 | 0 |
2 | signature | string | setPendingAdmin(address) |
3 | data | bytes | PROXY |
4 | eta | uint256 | ETA |
Where:
TIMELOCK
is the timelock contract address.PROXY
is the proxy contract address (predicted before deployment using CREATE1).ETA
is the expected time for executing the transaction (needs to be at leastblock.timestamp + timelock.delay()
).
Example:
- Queue transaction: https://goerli.etherscan.io/tx/0x59eeab99654a624b9ebb824de652acdc9c2bcb66b9d9ab90f074cd5f9eec9fa1.
- Execute transaction: https://goerli.etherscan.io/tx/0xbb3da328c7f7d3960c37f395cd3ff18e5144b77565e386e3b06f05472c799a2a
If you use VSCode, you can get Solidity syntax highlighting with the hardhat-solidity extension.
GitPod is an open-source developer platform for remote development.
To view the coverage report generated by yarn coverage
, just click Go Live
from the status bar to turn the server on/off.