Managing cToken Versions

The Compound protocol (v2) has been evolving since its launch in 2019.

Initially, all cToken contracts were immutable; this fit well with the protocol’s reliance on an administrator (the team at Compound Labs), to give users confidence that the functionality of the protocol wouldn’t change unnecessarily. As the admin powers were weakened, and then replaced entirely by :comp: Governance, new markets were introduced with upgradable cToken contracts.

The later-generation cToken contracts have a few advantages over the immutable, original model; the ability to sweep assets into other protocols (e.g. DAI into MakerDAO’s Dai Savings Rate), vote governance tokens, recover orphaned funds, and support future/upcoming features (like supply caps).

As follows, a list of cToken models:

ETH: Immutable
USDC: Immutable
WBTC: Immutable
ZRX: Immutable
BAT: Immutable
SAI: Immutable (deprecated)
REP: Immutable (deprecated)
DAI: Upgradable
USDT: Upgradable
UNI: Upgradable
COMP: Upgradable

The community may want to consider migrating cTokens.

Migrating a market from an immutable cToken contract, to an upgradable one, requires creating a new market for the asset. This would create a duplicate market (e.g., there are two ETH markets, with their own interest rates), which users would voluntarily migrate to. After a period of time, the original market could be deprecated.

The downside of duplicated markets include separate interest rates / incentives, chores for the ecosystem, potential user confusion, etc.

Sample Migration Process
As follows, is a sample migration process that could be used by the community, for an example asset (e.g. BAT):

  1. Deploy a second cBAT contract (“new”), using the latest upgradable contracts; potentially deploy an updated interest rate model
  2. Deploy an updated price feed proxy, to recognize new cBAT
  3. Create a governance proposal, that adds support for new cBAT, and the new price feed proxy; set the new cBAT collateral factor and reserve factor equal to the legacy market;
  4. Incentivize the migration to the new market; set the reserve factor on the legacy market to 100%, disable the COMP distribution to the legacy market, and activate the COMP distribution for the new market
  5. After the ecosystem has had ample time to integrate the new market, deprecate the legacy market; disable supply/borrowing (but preserve repaying/withdrawing), and set the collateral factor for the legacy market to 0%

Ecosystem Considerations
Migrating assets is cumbersome, and the community may want to approach this slowly, e.g. not at all, or one market at a time. Interfaces, dashboards, and tooling would have to be updated to reflect the new market.

Would love others thoughts / considerations as part of this process.


For the most part, everything seems good; however, I think this is a bit harsh.

I believe that legacy markets should continue to function normally without COMP distribution for a while before bringing the RF to 100%.


That’s a fair point; increasing the reserve factor could be staggered, and done in a follow-up proposal, while the COMP distribution could be switched at launch.


How about to also incentivise the existing lenders with minor COMP distributions to shift to the new cTokens?

One issue I see with migration is that currently gas prices are so high that moving funds is crazy expensive.

1 Like

Wouldn’t upgradeability bring in more risk?

Perhaps migration done gradually on a set schedule would make it a bit more manageable. (smallest market size first)

Wouldn’t migration also need positions to be wound down? So probably tooling to make migration of positions easier would really be welcome.

I actually saw one cool tool, FlashPos, demoed during the ethglobal hackathon that probably would be similar to what we need. But it seems we would need to have a flashloan market available first, unless ofcourse we’re kay using our neighbor’s offering.
The event was partly sponsored by a competing lending platform. Apologies, as they figure quite prominently in the video above.

As a project that integrates with Compound, i want to bring the community attention to the fact that some integrated projects have cETH as an immutable parameter in their contract. As interacting with cETH requires different interface.
And if a new cETH is deployed, then compatibility could be maintained if it would be cWETH instead of cETH.

Probably also from other reasons, it could make sense to consider having the next generation of cETH token as cWETH, same way aave did.


Legacy market migration: WBTC, Proposal 41 passed today (3/17) with a unanimous vote and was queued. In a couple days the proposal changes will be executed for the upgraded WBTC market.


@yaronvel this is a creative and solid idea; and ETH could be handled in the interface with a proxy/forwarding contract. Thanks for raising this idea. It would be fun to architect this.

1 Like

Why not keep the user interface like it is? Only everytime a user supplies, it interacts with the new contract. Anytime users borrow, the old and new contracts, should be the exact same values as long as the price feed is the same. If you change the IRM, then the UI should show users a button to migrate to the new token if they want and have a “?” that will explain the upgraded cToken. Also, the UI could display 2 interest rates explaining that if supplied before X date APR is Old% on or after X date APR is New%.

If possible, everytime a user repays a debt, it uses the new contract and the new contract burns an equal amount of of the old contract’s cTokens from that user’s ETH address.

Another possibility would be to add both old and new cTokens supply and borrow to get the utilization percentage, after all, its the same underlying asset.

Eventually the old cTokens will all get recycled into the new cTokens.