Contributing to Compound Protocol

:wave: Welcome! Thanks for your interest in the Compound Protocol. If you’d like to propose a change to the protocol, you’ve come to the right place.

Developing for a production Ethereum protocol is significantly different than contributing to other open source projects, so please read this entire guide. For a patch to be accepted, it will need to follow all of the advice below and may take a few iterations. We thank you for your dedication to improving the protocol.

Links to Important Resources

Where to ask questions

  • Community-Led Governance Forum
    • Here is the best spot to ask provocative or philosophical questions
  • Compound Discord
    • This is a better place to ask mundane questions or for help understanding how to use the protocol
  • We recommend discussing questions in the #development room in Discord first, and then posting to the governance forum once the idea has been solidified and could use guidance from the community.

Source Code versus On-Chain Protocol

The Protocol is governed by COMP token holders. The GitHub repository is a great place to build code and solicit feedback from the community. We at Compound will do our best to keep the master branch in sync with the on-chain Protocol (and help keep test-nets up to date as well). That said, we do not control the on-chain Protocol and deviations may occur. We also encourage forking the Protocol if you want to develop patches separately. Finally, the Protocol has many iterations of contracts and you may need to view earlier commits to find relevant code.

Comparison to Standard Open-Source Projects

Compound is a living on-chain protocol, not just a repository of code that you pull and run. Commits in the repository represent mere suggestions for upgrades to the Protocol. Once a patch is built, it needs to be proposed to the Compound Governor system and accepted by vote by a majority of COMP holders. As such, expect that the process of filing issues, vetting pull requests and merging code may be substantially different from other code repos you have interacted with in the past. These changes are meant to help get your patch approved by the community.

How to Submit a Patch

Style & Conventions

The most important principle in writing code for this project is clarity. Code should be as obvious as possible. We’ll always prefer clear over clever. The following are a list of principles to follow to lead in the right direction for your patch.

  • Prefer local context. Try to not do too much in one function. Do not hide complexity by calling into complex sub-routines. Inline code when it would be more clear, even if you repeat it (e.g. require(msg.sender == owner) is clearer than checkAuth()).
  • Avoid complex Solidity features, such as modifiers and external libraries.
  • Variables should be clearly named, even if it makes the name long. You can use Hungarian-like notation for variables like supplyAmountMantissa, here indicating the value is a real number with 18 decimals of precision.
  • Your code should be clear without comments (though feel free to add comments if they do add clarity).
  • Prefer the order “checks, effects then interactions,” and generally avoid cross-contract interactions where possible. Additionally, avoid interspersing computation with effects and interactions (e.g. if you can calculate a value upfront, do so).
  • Try to match the code-style that already exists in the repository. Please do not refactor existing code styles.
  • Public functions should have NatSpec documentation, including: a notice briefly describing the purpose, what the parameters are, and what the return value is.

Testing & Auditing

  • The protocol has several layers of testing: unit testing, integration “scenario” tests, and formal verification.
  • All contributions should have total code coverage. You may use harnesses, etc, but try to test your code as realistic as possible. You can see your coverage on codecov.io. Note: the accuracy of the coverage tool is not authoritative; if you can show your lines of code were covered, that’s sufficient.
  • We prefer having scenario testing, as well, which is a DSL for interactions with Compound. These tests will give significant extra confidence in your code changes. See SCENARIO.md for more information.
    • Scenarios can also be used in conjunction with Web3 forking to test the outcome of implementing a given change.
    • If you have a question, feel free to ping us in Discord!
  • You may contribute to formal analysis for your patch, but that is not a strict requirement. The formal verification tool we use is currently closed-source and not generally available.
    • If you want to build on the K Framework, we would be supportive.

Unit Tests and Scenarios

Unit tests can be found in the /tests directory. Scenarios are located in spec/scenario. To run both unit tests and scenarios, use:

yarn test

Scenarios automatically get compiled into unit tests, thus e.g. to run an individual scenario:

yarn test tests/Scenarios/Governor/VoteScenTest.js

Test-nets & Deployment

Every change should be run first on test-net, with source code verified and bytecode matched, just like on mainnet.

Saddle can be used to deploy, verify, and match code, though it need not be. All of the example commands can also be run from Docker builds, to run against a given commit. A private key can be passed via the ACCOUNT environment variable, or a file (e.g. "~/.ethereum/kovan") containing newline separated keys. Hardware wallets are not yet supported. See the README and assorted documentation for more information about compiling and using the code in this repository.

The easiest way to deploy and update the networks configuration files at the same time is to create an executable scenario script, like this one and run it like so from the repository directory:

spec/sim/0001-comp-distribution-patch/deploy.scen

Etherscan Verification

Contributors should make it as easy as possible for others to inspect their source code and audit their changes. Verifying source code on Etherscan is an important part of doing that.

For example:

npx saddle verify -n mainnet ETHERSCAN_API_KEY 0xAf601CbFF871d0BE62D18F79C31e387c76fa0374 Comptroller

Bytecode Matching

Contributors should prove to themselves and others that the bytecode on-chain matches other versions that are compiled from the same source. Saddle match is a tool that can help do that.

For example:

npx saddle match -n mainnet 0xAf601CbFF871d0BE62D18F79C31e387c76fa0374 Comptroller

Making a Proposal

At a high level, a proposal should make a minimal code change to achieve the desired result. The contributor should demonstrate that the code achieves the result, as best as possible. Anyone should be able to see what the code on-chain is, and verify that any changes match a particular diff in source control. The bytecode should identically match what is obtained by compiling the changes in this repository or a fork, as of a specific commit. The steps in detail are as follows:

  • Develop your code, unit test, scenario test and simulate your changes
  • Open a pull request for peer review and community auditing
  • Deploy contracts to test-net
    • Verify your contract on Etherscan
    • Saddle match your contract
    • Record deployed contract addresses and deployment arguments
  • Craft a proposal for test-net making the change
    • You may need test-net Comp to propose the change; you may include your proposed change in a post on the Compound Governance forum for support.
    • Alternatively, you can deploy a full Compound test-net using Eureka and test your change there.
      • If you have questions about Eureka, ping us in Discord!
    • After the proposal has passed, manually test the change and have others help with quality assurance.
  • Deploy your contracts to mainnet, preferably identical to your test-net deployment
    • Verify your contract on Etherscan verify
    • Saddle match your contract
    • Record deployed contract addresses and deployment arguments
    • Simulate the effect of ratifying a proposal with the actual deployed contract using a fork
      • Another great place to reach out to us or the community if you have questions on how best to do this.
    • The proposal should match exactly the one that will be voted upon
  • Craft the proposal on mainnet
    • You may need to find a sponsor with sufficient COMP to vouch for and propose your change.
    • Simulate after creating, that passing the actual proposal in a fork behaves as expected

Conclusion

We understand there are a lot of steps here, but your patch will have a potentially huge affect on a large number of people, so we should be vigilant to provide the highest-quality code we can offer. If you have any questions, feel free to ask here, in Discord, on GitHub or on Twitter. Remember: the Compound Protocol is governed by all of us, so we need to work together to keep the protocol up to the highest possible standards.

5 Likes