Supplying Assets to the Compound Protocol
Quick Start Guide

The Compound Protocol is a series of interest rate markets running on the Ethereum blockchain. When users and applications supply an asset to the Compound Protocol, they begin earning a variable interest rate instantly. Interest accrues every Ethereum block (currently ~13 seconds), and users can withdraw their principal plus interest anytime.
Under the hood, users are contributing their assets to a large pool of liquidity (a “market”) that is available for other users to borrow, and they share in the interest that borrowers pay back to the pool.
When users supply assets, they receive cTokens from Compound in exchange. cTokens are ERC20 tokens that can be redeemed for their underlying assets at any time. As interest accrues to the assets supplied, cTokens are redeemable at an exchange rate (relative to the underlying asset) that constantly increases over time, based on the rate of interest earned by the underlying asset.
Non-technical users can interact with the Compound Protocol using an interface like Argent, Coinbase Wallet, or app.compound.finance; developers can create their own applications that interact with Compound’s smart contracts.
In this guide, we’re going to walk through supplying assets via Web3.js JSON RPC and via proxy smart contracts that live on the blockchain. These are two methods in which developers can write software to utilize the Compound Protocol.
There are examples in JavaScript and also Solidity.
Table of Contents for This Guide
- Compound Markets
- Connecting to the Ethereum Network
- Supplying on a Localhost Network
- Supplying on a Public Network
- How to Supply ETH to the protocol via Web3.js
- How to Supply a Supported ERC20 Token to the protocol via Solidity
If you are new to Ethereum, we suggest that you start by Setting up your Development Environment for Ethereum.
All of the code referenced in this guide can be found in this GitHub Repository: Quick Start: Supplying Assets to the Compound Protocol.
To copy the repository to your computer, run this on the command line after you’ve installed git:
git clone git@github.com:compound-developers/compound-supply-examples.gitCompound Markets
The Compound Protocol enables developers to build innovative products on DeFi. So far, we’ve seen crypto wallets equipped with savings APRs, a no-loss lottery system, an interest-earning system for donation income, and more.
The smart contracts that power the protocol are deployed to the Ethereum blockchain. This means that at the time of this guide’s writing, the only types of assets that Compound can support are Ether and ERC-20 tokens.
The currently supported assets are listed here https://compound.finance/markets. Based on the different implementation of Ether (ETH) and ERC-20 tokens, we have to utilize two similar processes:
- The ETH supply method
- The ERC20 token supply method
Like mentioned earlier, when someone supplies an asset to the protocol, they are given cTokens in exchange. The method for getting cETH is different from the method for getting cDAI, cUNI, or any other cToken for an ERC-20 asset. We’ll run through code examples and explanations for the two different asset supply methods.
When supplying Ether to the Compound protocol, an application can send ETH directly to the payable mint function in the cEther contract. Following that mint, cEther is minted for the wallet or contract that invoked the mint function. Remember that if you are calling this function from another smart contract, that contract needs a payable function in order to receive ETH when you redeem the cTokens later.
The operation is slightly different for cERC20 tokens. In order to mint cERC20 tokens, the invoking wallet or contract needs to first call the approve function on the underlying token’s contract. All ERC20 token contracts have an approve function.
The approval needs to indicate that the corresponding cToken contract is permitted to take up to the specified amount from the sender address. Subsequently, when the mint function is invoked, the cToken contract retrieves the indicated amount of underlying tokens from the sender address, based on the prior approve call.
Example code for each method (JS and Solidity) is available, open source, in the GitHub Repository linked above.
Connecting to the Ethereum Network
You will need to use the contract address for the particular network that you’re developing on; start by identifying the contract address for each network in the Docs. In this guide, we’ll create a fork of Mainnet, which will run on our localhost; copy the Mainnet addresses.
If you want to use a public test net (like Ropsten, Göerli, Kovan, or Rinkeby), make an Infura account at https://infura.io/ to get your API key. If you are using your own localhost test net, or the production mainnet, we will also use Infura.
If you are not hosting your own Ethereum node to access the blockchain, make an Infura account before continuing.
For more on connecting to a public Ethereum network, see the instructions in Setting up your Development Environment for Ethereum.
Supplying to the Compound Protocol on a Localhost Network
To run an Ethereum local test net on your machine, we will fork the Main network (a.k.a Homestead or Mainnet). This means that you can interact with the production smart contracts in a test environment. No real ETH will be used and no modifications to the production blockchain will occur. If you haven’t already, install Node.js. Click here to install the LTS of Node.js and NPM.
Let’s install all of the dependencies required by the project.
cd compound-supply-examples/
npm install
npm install -g npx## or for yarn fans:
## yarn install
## yarn add global npxThis will install all of the dependencies listed in the package.json file, as well as a CLI tool called npx.
Run this command in a second command line window before you start running the code referenced later in this guide. The command spins up a test Ethereum blockchain on your localhost. It also seeds your localhost account with ERC20 tokens referenced at the top of the script file. Be sure to add your Infura project ID and Ethereum mnemonic as environment variables beforehand.
## Set environment variables for the script to useexport MAINNET_PROVIDER_URL="https://mainnet.infura.io/v3/<YOUR INFURA PROJECT ID HERE>"export DEV_ETH_MNEMONIC="clutch captain shoe salt awake harvest setup primary inmate ugly among become"## Runs the Hardhat node locally
## Also seeds your first mnemonic account with test Ether and ERC20snode ./scripts/run-localhost-fork.jsThe script that we are running uses Hardhat to run an Ethereum node locally which has a fork of the history of Ethereum Mainnet. We have test Ether and test ERC-20 tokens that are seeded in the first account of the development mnemonic. Wait for the script logs to appear before continuing.
Running a hardhat localhost fork of mainnet at http://localhost:8545Impersonating address on localhost... 0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643
Impersonating address on localhost... 0x35a18000230da775cac24873d00ff85bccded550
Impersonating address on localhost... 0x39AA39c021dfbaE8faC545936693aC917d5E7563
Local test account successfully seeded with DAI
Local test account successfully seeded with UNI
Local test account successfully seeded with USDC
DAI amount in first localhost account wallet: 100
UNI amount in first localhost account wallet: 10
USDC amount in first localhost account wallet: 100Ready to test locally! To exit, hold Ctrl+C.To change the types of ERC-20 assets provided to the account, uncomment the lines in the amounts object near the top of the run-localhost-fork.js script.
Supplying to Compound on a Public Network
If you are supplying to the protocol on the Mainnet, Ropsten, Göerli, Kovan, or Rinkeby, you should have already located and copied the Compound contract address for that network (see how above). You’ll need it for later.
You also should have collected some ETH for that network by purchasing/mining (Main), or a test net’s faucet (all the others). This is not necessary when using a localhost fork.
For example, here is Ropsten’s faucet https://faucet.ropsten.be/. You can send yourself 1 ETH every 24 hours from a single IP address. This is test ETH that is only applicable to the Ropsten test network.
Next, copy and safely store your wallet’s private key. Don’t do this if you are only testing on your localhost. The private key is used to sign transactions that are sent on the Ethereum network. The purpose of this is to certify that the transaction was created and submitted by a unique wallet.
If you are using MetaMask for your Ethereum wallet, open the menu, click the 3 dots on the right, Account Details, Export Private Key, and input your MetaMask password. This will reveal your private key. Keep it safe! Copy this value and save it for later.
It is a best practice to store a test key like this as an environment variable on your local machine. When a key is stored as an environment variable, it can be referenced in code files by a variable name, instead of explicitly with a string. This promotes code cleanliness, and reduces the risk of exposing your secret.
Again, if you are only testing smart contracts on your localhost Hardhat node today, don’t get your MetaMask private key. We’ll rely on a private key that comes from your environment variable mnemonic (see instructions above).
How to Supply ETH to Compound via Web3.js
Supplying Ether (ETH) to the Compound Protocol is as easy as calling the “mint” function in the Compound cEther smart contract. The “mint” function transfers ETH to the Compound contract address, and mints cETH tokens. The cETH tokens are transferred to the wallet of the supplier.
Remember that the amount of ETH that can be exchanged for cETH increases every Ethereum block, which is about every 13 seconds. There is no minimum or maximum amount of time that suppliers need to keep their asset in the protocol. See the varying exchange rate for each cToken by clicking on one at https://compound.finance/markets.
For more information on cToken concepts see the cToken documentation.
In order to call the mint function, you need to first:
- Have ETH in your Ethereum wallet.
- Find your Ethereum wallet’s private key.
- Connect to the network via Infura API key (see above section Connecting to the Ethereum Network)
There are several programming languages that have Ethereum Web3 libraries, but the most popular at the time of this guide’s writing is JavaScript.
We’ll be using Node.js JavaScript to call the mint function. The following code snippets are from this Node.js file in the supplying assets guide GitHub Repository. Web browser JavaScript is nearly identical to these code examples.
Let’s import Web3.js, and initialize the Web3 object. It’s pointing to our localhost’s Hardhat node, which has 10000 test ETH in each of the test wallets. We get the same test wallet addresses every time we run a Hardhat node with the mnemonic environment variable (from the Connecting to the Ethereum Network section).
If you are using a public network (Ropsten, Kovan, etc.), make sure your wallet has ETH, and that you have your wallet private key stored as an environment variable. Also, have your Infura API key ready if you are deploying to a public test net.
Replace the HTTP provider URL in the Web3 declaration line with the appropriate network’s provider if you are not using the Hardhat test environment.






