A Walkthrough of Contributing to the Compound Protocol
The Compound Protocol is free and open financial infrastructure running on the Ethereum blockchain. Anyone with a future vision of the protocol can propose an improvement by writing code.
Not all protocol changes necessarily require code, but the most involved ones do. In this short guide, we’ll walk through changing the source code and proposing a formal change with Compound Governance.
Here is an overview of the steps we will take, with the end goal of proposing a new cToken market for the protocol:
- Remove legacy verification checks from the source code for new cTokens that will be added in the future.
- Remove tests for the legacy verification checks, so that all tests succeed. Note that when adding new code, the developer should write additional unit tests to ensure optimal code coverage.
- Create a pull request into the Compound Protocol GitHub repository, so the community can review the code changes, and eventually sync them (if approved through governance).
- Deploy a brand new cToken contract for an ERC-20 asset.
- Verify the contract code on Etherscan.
- Create a Compound Governance Proposal to add the new asset to the protocol.
Prerequisites
New to Ethereum development? Try starting a bit smaller with a more basic guide: Setting up an Ethereum Development Environment.
Compound Protocol changes are ideated and discussed publicly on the Compound Community Forum. Before continuing, please read the full manual in the forum for Contributing to the Compound Protocol.
We’ll need to create a GitHub account, and install git. We’ll use these tools to publicly merge new code into the open source repository.
Skim the repository readme to become familiar with the available tools and the development process.
Learn what Compound Governance is by reading the related blog posts on the Compound Blog. The governance process is required for incorporating new code changes into the on-chain protocol.
Changing Protocol Source Code
First, we’ll fork the Compound Protocol source code to our GitHub account. We’ll make changes on the forked repository and create a pull request into the original repository.
Code
To start, we’ll go to the GitHub repository and click the fork button on the right. This makes a personal copy of the repository.
Next we’ll go to the forked repository page in our account’s repositories. We’ll click the green code button, then the SSH tab, and finally the ‘copy to clipboard’ button on the right.
Next we’ll copy the repository to our local machine. We’ll open the terminal and navigate to our programming projects folder. Type “git clone” followed by the ssh address of the forked repository.
git clone git@github.com:ajb413/compound-protocol.git
Next, we’ll navigate into the repository and install dependencies. Now is a good time to install Node.js (LTS) and Yarn.
cd compound-protocol/
yarn install
After everything has been installed, we can open the source code with a text editor and begin making changes. The one contract file we will modify is /contracts/CToken.sol
. We’ll remove the following lines.
We can see in the definitions in /contracts/Comptroller.sol
that these methods do not make any changes or conditionally revert. We’ll treat them as dead code that needs to be removed. The existing cToken contracts call them, so we won’t remove them from the Comptroller today.
Tests
After saving the modified contract file, we’ll change the test code so it succeeds with the newest changes. If we were adding new contract code, we would add more tests to ensure thorough code coverage.
To run all of the projects tests, use this command on the command line:
yarn test
To run an individual test file, try something like:
yarn test tests/Tokens/borrowAndRepayTest.js
When running all tests, we’ll see that 6 tests fail as a result of our contract code changes. Those particular tests can be commented out or deleted. Once the test command yields 0 failed tests, we can continue with our protocol change.
Pull Request
Once the tests pass, we can create a pull request. When a pull request is open, the community can publicly analyze the code changes to ensure integrity and that best practices are implemented. If the community approves the changes through governance with a passing proposal, the pull request will be merged into the master branch.
Next we’ll commit the contract and test code changes to the forked repository using Git on the command line.
git add contracts/ tests/
git commit -m "ctoken changes"
git push origin master
We’ll go back to the forked repository page on GitHub and refresh it. There should now be a pull request button above the file explorer on the right. We’ll click it to see the merge comparison page.
Next we’ll click the green “Create pull request” button to open the public pull request.
Deploying New Ethereum Smart Contracts
Some, but not all protocol changes require deploying of new smart contracts. When adding a new asset to the protocol, deploying a new cToken contract is required.
Deploying a cToken contract can be done using Saddle. The Compound Labs team created a command line tool called Saddle for Ethereum development. It is already included in the dependencies of the protocol repository.
Local Environment Contract Deploy
Before we deploy to a public Ethereum network, we’ll first try to deploy the contract on a localhost fork. We’ll need a JSON RPC provider URL for this. One can be acquired for free from Infura or a similar service.
We’ll go back to our text editor and open saddle.config.js in the project root folder. We’ll duplicate the development object within the networks object. The duplicate should be named something like local_fork.
In the providers array of local_fork, we’ll remove the second object that begins with ganache. Instead, we’ll replace the entire second object with a localhost JSON RPC URL. The local_fork’s providers array should now look like the following:
providers: [
{env: "PROVIDER"},
{http: "http://127.0.0.1:8545"}
],
Now is a good time to globally install Ganache CLI (more on this tool in the primary guide).
In a separate terminal window, we’ll use the following command to make a local fork of the Kovan network blockchain. The mnemonic generates accounts that have been used in previous developer guides. Note that there is an environment variable (infuraProjectId
) that contains the Infura project ID.
ganache-cli \
-f https://kovan.infura.io/v3/$infuraProjectId \
-m "clutch captain shoe salt awake harvest setup primary inmate ugly among become"
Next we’ll make a new network config file for local_fork. This can be done by copying the Kovan configuration and naming it local_fork.json. From the root directory of the project, run the following command.
cp networks/kovan.json networks/local_fork.json
We copied Kovan because all of the addresses will be the same in our Ganache CLI network fork.
Next we’ll deploy the contract using Saddle. The new cToken will be Kyber Network Crystal. The underlying token address can be found in the Kyber documentation.
In a terminal window that is navigated to the project directory, we’ll use the following command to deploy the cToken to the local fork.
npx saddle -n local_fork script token:deploy '{
"underlying": "0xad67cB4d63C9da94AcA37fDF2761AaDF780ff4a2",
"comptroller": "$Comptroller",
"interestRateModel": "$Base200bps_Slope3000bps",
"initialExchangeRateMantissa": "2.0e18",
"name": "Compound Kyber Network Crystal",
"symbol": "cKNC",
"decimals": "8",
"admin": "$Timelock"
}'
On success, Saddle will log the address of the new cToken contract.
Contract Deploy & Etherscan Code Verification
Now that we know the deployment works in the local test environment, we can try it on the public network.
Before we do that, we’ll get an Etherscan API key so we can publicly verify the source code. We’ll sign up for a free account at etherscan.io. Once we have an account, we’ll create an API key by clicking the profile dropdown, API Keys, and the “Add” button at the top of the page.
Now that we have an API key, we can add it to our command line environment variables. On a Mac, this is in ~/.bash_profile
or ~/.zshrc
. We’ll add the key on a new line with export ETHERSCAN_API_KEY="JI4D..."
and restart the terminal window.
Next we’ll add a private key for the Kovan test net, so Saddle will know who is deploying the new contract. We’ll create a new directory using mkdir ~/.ethereum/
and then a new file to contain the private key with touch ~/.ethereum/kovan
.
We’ll paste a Kovan private key in this file without the “0x” at the beginning of the hexadecimal string.
Next, we’ll run the same deploy command that we ran earlier except this time we will replace local_fork with kovan. This change will deploy the contract to Kovan, for real. We’ll run the command. Be sure to save the contract address that is logged.
Visit kovan.etherscan.io and search for the newly created contract address. In the contract tab, we’ll see that there currently isn’t any verified source code.
Next, we’ll go back to the command line, and run a command to verify the source code with Etherscan. We’ll replace 0x9aF1962Dadf179e2aAa66F994ef09c65360b958e
with our newly created contract address.
npx saddle -n kovan script token:verify 0x9aF1962Dadf179e2aAa66F994ef09c65360b958e '{
"underlying": "0xad67cB4d63C9da94AcA37fDF2761AaDF780ff4a2",
"comptroller": "$Comptroller",
"interestRateModel": "$Base200bps_Slope3000bps",
"initialExchangeRateMantissa": "2.0e18",
"name": "Compound Kyber Network Crystal",
"symbol": "cKNC",
"decimals": "8",
"admin": "$Timelock"
}'
Once the verification completes, we’ll see that the contract code is now explorable on the contract Etherscan page.
This same process can be followed to deploy a contract to the Ethereum Mainnet.
Initializing a Compound Governance Proposal
The final major step of changing the Compound Protocol is to create a Governance proposal that the community collectively agrees to pass.
Note that the new cToken in this guide is already supported by the on-chain Open Price Feed. If we were proposing a new asset that is not yet reported in the Open Price Feed, we would need to create changes for that component too.
Proposal or Autonomous Proposal
There are several options to go about creating a Compound Governance Proposal. We’ll review them here. If they don’t make sense, take some time to read up on Governance on the Compound Blog and on the comp.xyz forum.
- Acquire at least 100,000 COMP or the equivalent delegated voting weight and create a proposal using app.compound.finance/propose.
- Discuss ideas for change with the greater Compound community on the forum or in the #governance channel of the Compound Discord. Find a user that agrees with the change, has the ability, and ask them to create the proposal.
- Acquire at least 100 COMP and create a Compound Autonomous Proposal.
Let’s walk through using the app interface to highlight the necessary “calldatas” for a new cToken proposal. Again, this is only for users that control at least 100,000 votes.
Visit app.compound.finance/propose. Fill in the proposal Title and Overview sections. Be as thorough as possible. Markdown is supported. Be sure to include a link to the GitHub pull request created earlier. Review a similar past proposal and use it as a guide to write the Overview. Add the following Actions in the specified order.
- Comptroller contract, _supportMarket function, new cToken contract address.
- Comptroller contract, _addCompMarkets function, new cToken contract address.
- Comptroller contract, _setCollateralFactor function, new cToken contract address and 600000000000000000 for 60% collateral factor.
- Other contract (new cToken contract address and ABI from the Etherscan page, code tab, toward the bottom), _setReserveFactor, 200000000000000000 for 20% reserve factor.
This proposal adds the new cToken to the official Comptroller, enables it as a market that participates in COMP Distribution, sets the collateral factor to 60%, and sets the reserve factor to 20%. Once the Actions are filled in, click the Submit Proposal button and submit the transaction using MetaMask.
For a more detailed walkthrough of creating a proposal, check out the Compound Governance guide - How To Propose.
Wrapping Up
Compound is a living, on-chain protocol, not just a repository of code that can be pulled and run. Proposing changes is a serious undertaking that requires the entire community’s attention and scrutiny. Not all proposals pass. For more ideas about how to submit successful proposals, see the Contributing to the Compound Protocol manual.
The most important part of developing Compound Protocol improvements is participating in open discourse. Please join the discussion in the Compound Community Forum and in the #governance channel of the Compound Discord.
Thanks for reading and be sure to subscribe to the Compound Newsletter. Feel free to comment on this post, or get in touch with the team on the Compound Twitter.