My favorite setup for writing Solidity smart contracts as well as auditing/testing external contracts.
- Hardhat: compile, run and test smart contracts on a local development network
- TypeChain: generate TypeScript bindings for smart contracts
- Ethers: renowned Ethereum library and wallet implementation
- Solhint: code linter
- Solcover: code coverage
- Prettier Plugin Solidity: code formatter
- Tracer: trace events, calls and storage operations
- Storage Layout: generate smart contract storage layout
- Fork the mainnet or another EVM based network as a Hardhat Network instance
- Download external contracts and their dependencies (via Python script)
- Gather contracts in scope from Immuenfi bug bounty (via Python script)
- Attach tests to external contracts and impersonate accounts (in mainnet fork)
Click the Use this template
button at the top of
the page to create a new repository with this repo as the initial state.
This template builds upon the frameworks and libraries mentioned above, so for details about their specific features, please consult their respective documentations.
For example, for Hardhat, you can refer to the Hardhat Tutorial and the Hardhat Docs. You might be in particular interested in reading the Testing Contracts section.
This template comes with sensible default configurations in the following files:
├── .commitlintrc.yml
├── .editorconfig
├── .eslintignore
├── .eslintrc.yml
├── .gitignore
├── .prettierignore
├── .prettierrc.yml
├── .solcover.js
├── .solhintignore
├── .solhint.json
├── .yarnrc.yml
└── hardhat.config.ts
This template comes with GitHub Actions pre-configured (disabled per default). Your contracts will be linted and tested
on every push and pull request made to the main
branch.
Note though that to make this work, you must use your INFURA_API_KEY
and your MNEMONIC
as GitHub secrets and rename
the CI script to ci.yml
in order to enable it.
You can edit the CI script in .github/workflows/ci.yml.example.
This template enforces the Conventional Commits standard for git commit messages. This is a lightweight convention that creates an explicit commit history, which makes it easier to write automated tools on top of.
This template uses Husky to run automated checks on commit messages, and Lint Staged to automatically format the code with Prettier when making a git commit.
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 installing dependencies:
$ yarn install
$ pip install -r contract-downloader/requirements.txt # for Python contract downloader
- Download external contract + dependencies or download contracts from Immunefi bug bounty
$ yarn clone <contract address>
# OR
$ yarn immunefi <bug bounty URL>
- Set Solidity version in
hardhat.config.ts
- Compile contract(s) and generate typings
$ yarn compile
- Export the contracts' storage layouts
$ yarn storage
- Fork the mainnet as a local Hardhat Network instance
$ yarn fork
- Adapt the test templates to break/exploit the external contract in the local Hardhat Network instance
$ yarn attach <contract address>
$ yarn attachContract <contract address>
Compile the smart contracts with Hardhat:
$ yarn compile
Compile the smart contracts and generate TypeChain bindings:
$ yarn typechain
Run the Mocha test for the example Greeter contract:
$ 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
Shows events, calls and storage operations when running the tests:
$ yarn test --trace # shows logs + calls
$ yarn test --fulltrace # shows logs + calls + sloads + sstores
Shows the compiled contracts' storage layouts:
$ yarn storage
Starts an instance of Hardhat Network that forks mainnet. This means that it will simulate having the same state as mainnet, but it will work as a local development network. That way you can interact with deployed protocols and test complex interactions locally.
To use this feature you need to set your Infura API key in the .env
file.
$ yarn fork
$ yarn fork --fork-block-number <num> # pin the block number
Starts an instance of Hardhat Network that forks an EVM based network. Supported networks are given by chainIds[]
in
hardhat.config.ts
.
$ yarn forkNetwork --network <chain> # e.g. rinkeby or polygon-mainnet
Downloads a verified smart contract and its dependencies from Etherscan, etc. To use this feature you need to set the
relevant API keys in the .env
file.
$ yarn clone <contract address>
$ yarn clone <contract address> --network <chain> # e.g. polygon or bsc
In order to remove a previously downloaded smart contract and its dependencies from the local filesystem, run:
$ yarn clone <contract address> --remove
Furthermore, implementation contracts can be downloaded through proxies by:
$ yarn clone <proxy contract address> --impl
Gathers all block explorer links to verified smart contracts in scope from an Immunefi bug bounty page and forwards them to the downloader, see Clone.
$ yarn immunefi <bug bounty URL>
$ yarn immunefi <bug bounty URL> --remove # delete contracts
Attaches the Mocha test external/Attach
to a deployed contract in your local Hardhat Network (e.g. mainnet fork). The
test contains sample code for the Greeter contract and therefore needs to be adapted according to your needs.
$ yarn attach <contract address> [--impersonate <address>]
Features like Report Gas and Tracer can also be used with this test.
Attaches the Mocha test external/AttachContract
and the contract test/Test
to a deployed contract in your local
Hardhat Network (e.g. mainnet fork). The test contains sample code for the Greeter contract and therefore needs to be
adapted according to your needs.
$ yarn attachContract <contract address> [--impersonate <address>]
Features like Report Gas and Tracer can also be used with this test.
Delete the smart contract artifacts, the coverage reports and the Hardhat cache:
$ yarn clean
Delete all non-template contracts from the contract directory:
$ yarn cleanContracts
Combines Clean and Clean contracts:
$ yarn cleanAll
Deploy the example Greeter contract to the Hardhat Network:
$ yarn deploy --greeting "Hello, world!"
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.
MIT © Paul Razvan Berg & Mario Poneder