Compound V3 Smart Contract Architecture Explained

·

This article provides an in-depth analysis of the smart contract architecture of Compound V3, a leading lending protocol in the DeFi space. We will explore how to lend and borrow assets, provide collateral, and liquidate undercollateralized loans. Additionally, we break down the core structure of the Comet contract and its related components, along with the governance mechanisms for updating protocol parameters.

Introduction and Prerequisites

Compound is one of the most significant lending protocols in decentralized finance (DeFi), inspiring the design of numerous lending platforms across various blockchains. This guide explains the smart contract architecture of Compound V3.

Since Compound is a lending protocol, we assume readers are familiar with how interest rates work in DeFi and understand the concepts of collateral and liquidation.

Unlike Compound V2, each instance of Compound V3 only supports borrowing a single asset. For example, you can only borrow USDC from the USDC market and ETH from the ETH market—cross-asset borrowing is not supported. To borrow these assets, users must supply collateral according to the market's collateral ratio, which is set through governance.

In Compound V3, the borrowable asset is referred to as the base asset. Given USDC's popularity as a borrowing asset, we will use it as our primary example. The core smart contract handling lending and borrowing logic is called Comet. Currently, Compound is deployed on Ethereum mainnet and several Layer 2 solutions: Polygon, Base, and Arbitrum.

This overview will explain how to interact with these smart contracts and delve into the structure of the Solidity code.

Part 1: Using Compound V3

There are three primary actions users can perform on Compound V3:

  1. Lending the base asset
  2. Supplying collateral to borrow the base asset
  3. Liquidating undercollateralized loans.

Lending USDC

Users can lend USDC to the protocol and earn interest over time. Participating lenders also receive COMP token rewards as incentives. The interest earned and COMP rewards are displayed in the user interface.

It is important to note that the price of USDC is not always exactly $1.00, as it can fluctuate slightly based on market conditions and oracle price feeds.

Borrowing USDC

To borrow USDC, users must first supply approved collateral, such as ETH. The amount that can be borrowed depends on the value of the collateral and the loan-to-value ratio set by the protocol.

After borrowing, users can repay the loan along with accrued interest to reclaim their collateral. The entire process is designed to be transparent and efficient.

Understanding Net Borrow and Lend Rates

In Compound V3, the net supply APR (lending rate) can sometimes appear higher than the net borrow APR. This is because the protocol incorporates the value of COMP rewards into these calculations.

Borrowers pay interest in the base asset but also receive COMP rewards, which effectively reduce their net borrowing cost. Similarly, lenders earn interest from the base asset and additional COMP rewards, boosting their overall yield.

The difference between the interest paid by borrowers and the interest earned by lenders represents the protocol's revenue.

Part 2: Navigating the Codebase

The Compound V3 codebase consists of 4,304 lines of Solidity code, excluding comments and whitespace.

High-Level Architecture

The GitHub repository for Compound V3 contains several key components:

Users primarily interact with the protocol through a proxy contract that delegates calls to the current Comet implementation. All user-facing logic resides in the Comet contract.

Unconventional Parameter Updates via Governance

Compound V3 stores key parameters in immutable variables rather than storage. To change these values, a new Comet instance must be deployed, and the proxy must be updated to point to this new implementation.

This design offers two main advantages:

We will examine the lifecycle of a parameter change later in this article.

Comet Inheritance Structure

The Comet contract inherits from multiple parent contracts, each serving a specific purpose:

CometExt: Extending Functionality via Delegatecall

To avoid exceeding the 24kb deployment limit, Comet uses a fallback-extension pattern. Additional functions, such as name(), are offloaded to the CometExt contract, which is called via delegatecall.

This approach allows the protocol to extend its functionality without compromising the core contract's size or efficiency.

Reward Distribution

COMP token rewards for lenders and borrowers are managed by a separate rewards contract. This contract reads the state from Comet and distributes tokens based on participation rates set by governance.

Lifecycle of a Parameter Update

As mentioned earlier, changing parameters requires deploying a new Comet instance. This process involves several steps:

  1. Governance proposes and votes on parameter changes.
  2. The Configurator contract updates the stored configuration values.
  3. A new Comet instance is deployed using the updated configuration.
  4. The proxy contract is updated to point to the new implementation.

This ensures that all changes are transparent and governed by the community.

CometConfiguration and ConfiguratorStorage

The CometConfiguration.sol file defines structures that parameterize Comet's behavior. ConfiguratorStorage.sol inherits these definitions and stores the structures in mappings.

These storage variables are not part of the Comet contract itself. Instead, the Configurator contract uses them to deploy new Comet instances.

Configurator.sol

The Configurator contract inherits from ConfiguratorStorage and provides functions that only governance can call. It includes a deploy() function for creating new Comet instances.

The CometFactory.sol contract is responsible for actually deploying these new instances.

Practical Example of a Parameter Change

Governance Proposal 162 serves as a real-world example of this process. The proposal called several functions to update parameters and ultimately deployed a new Comet instance.

Conclusion

Compound V3's smart contract architecture is designed for efficiency, transparency, and upgradability. By using immutable variables and a modular design, the protocol minimizes gas costs and allows for community-driven parameter updates.

The combination of core lending logic, extension patterns, and rewards distribution creates a robust system for decentralized lending and borrowing.


Frequently Asked Questions

What is the base asset in Compound V3?
The base asset is the primary borrowable asset in a specific Compound V3 market. For example, in the USDC market, USDC is the base asset.

How are interest rates calculated in Compound V3?
Interest rates are determined by the utilization rate of the base asset. The protocol uses a linear interest rate model that adjusts based on supply and demand.

What is the role of COMP tokens in Compound V3?
COMP tokens are distributed as rewards to both lenders and borrowers. These incentives encourage participation and liquidity provision within the protocol.

How does liquidation work in Compound V3?
If a borrower's collateral value falls below the required threshold, liquidators can repay a portion of the borrowed amount in exchange for collateral at a discounted rate.

Can parameters be changed in Compound V3?
Yes, but changing parameters requires deploying a new Comet instance via governance voting. This ensures that all changes are transparent and community-approved.

What are the advantages of using immutable variables?
Immutable variables are more gas-efficient than storage variables and help keep the core contract simple without unnecessary setter functions. 👉 Explore advanced DeFi strategies