CIP-4: Upgrade Compound v2 Oracle To Disable UAV

Preamble

Name: Upgrade Compound v2 Oracle To Disable UAV
Author(s): Michael - Chainlink Labs (@CL_Michael)
Status: Idea
Type: Protocol Enhancement
Created: 2023-10-17

Abstract

This proposal aims to reduce risks around the operation of Compound v2 by disabling the UniswapAnchoredView (UAV) by upgrading to a PriceOracle contract that directly consumes data from Chainlink Feeds Prices, similar to Compound III. The proposal also includes a configuration update to use the relevant Chainlink Price Feeds for stablecoin valuations, similar to Compound III, instead of using the hardcoded ‘FixedPrice’ values.

Motivation

Compound v2 fetches market data about supported tokens from Chainlink Price Feeds. Before data is ingested, the UAV is used as a reference anchor mechanism, where updates from Chainlink feeds are rejected if the reported value differs by a predefined percentage compared to the reported value by a Uniswap v3 TWAP oracle.

In times of market volatility, the UAV has caused several problems by blocking accurate price data from Chainlink Price Feeds from being ingested into the protocol due to the high latency and delayed pricing from Uniswap v3 TWAP oracles.

For example, below we showcase an incident where the UAV caused data from Chainlink Price Feeds regarding the SUSHI/USD exchange rate to be rejected in the Compound v2 protocol, despite data from the Chainlink feed closely tracking highly liquid exchanges.

Key:

  • Green Dots: successful Compound v2 Price Oracle updates
  • Blue Dots: Reporter - Chainlink SUSHI/USD Price Feed updates
  • Red Dots: Anchor - Uniswap v3 TWAP
  • Control: Grey Line - historic Coinbase/Binance ‘close’ price for SUSHI/USD

In this example, the Uniswap V3 TWAP oracle fell out of sync with spot market pricing during a sharp price drop around ~4:23 AM on June 10, 2023. After a sudden drop, the reporter (Chainlink Price Feed) was in the $0.50 - $0.59 range closely tracking the controls, but the TWAP anchor was above the $0.70 range.

Here is an example transaction during the PriceGuarded event at 04:33 AM:

  • reporterPrice: 569140 = $0.569
  • anchorPrice: 735443 = $0.735

The result was that updates to the Price Oracle were blocked, and Compound v2 was stuck with stale, inaccurate prices for nearly 15 hours.

Other instances of this have happened with tokens such as BAT, ZRX, and COMP in the past. Although there have been initiatives to reduce these risks by pausing the supply of specific markets, operating the UAV is an overall detriment to the protocol regarding efficiency and safety. This proposal aims to remedy these pitfalls at the source by disabling the UAV.

Proposal Details

To mitigate the above issues that are a result of the UAV’s underperformance, this proposal defines a migration path for Compound v2 to use an upgraded PriceOracle contract that directly consumes market data from Chainlink Price Feeds. Note that this method of directly consuming data from Chainlink Price Feeds is comparable to how Compound III has operated since its original deployment without issue.

With this proposal, Chainlink Labs will write and deploy an upgraded version of the PriceOracle contract.

  1. Store mapping of cToken assets to respective Chainlink Price Feeds for all pairs.

  2. Store baseUnit config for each asset

  3. Write the getUnderlyingPrice function to retrieve prices directly from Chainlink Price Feeds. Documentation
    3A. Call latestRoundData on the Chainlink Price Feed for the specific pair to retrieve the price
    3B. Read decimals from the Chainlink Price Feed to use when formatting the data
    3C. Convert the price into the expected format. Example

    • Comptroller needs prices in the format: ${raw price} * 1e36 / baseUnit. The baseUnit of an asset is the amount of the smallest denomination of that asset per whole. For example, the baseUnit of ETH is 1e18. Since the price in the ETH Feed has 8 decimals, we must scale them by 1e(36 - 8) / baseUnit
  4. Write methods to update configs on the PriceOracle contracts to allow the Compound community to update or add new feeds without a contract redeployment.

After community vote, an approval will result in disabling the Compound v2 UAV by replacing the contract with the new version of the PriceOracle in the Comptroller. No changes are needed in how the Comptroller works. It will interact with the upgraded PriceOracle the same way it did with the UAV.

Rationale

We have seen that the Compound community is increasingly inclined to shift users over to Compound III as it offers better efficiency and safety. To learn more about these efforts, @Gauntlet has posted about Compound v2 Deprecation Strategy. Disabling the UAV can be seen as another way to reduce existing issues and overhead with Compound v2 for those still using the protocol. Compound III has been operating using Chainlink Price Feeds directly without a UAV since its original deployment due to Chainlink’s proven historical reliability and accuracy, even during extreme network congestion and market volatility.

As an additional risk mitigation move for Compound v2, this proposal includes an updated config that uses the relevant Chainlink Price Feeds for the valuation of stablecoins, similar to Compound III, as opposed to the current hardcoded ‘FixedPrice’ values (which can become inaccurate and introduce protocol risk during stablecoin depeg events).

Another noteworthy benefit, the upgraded PriceOracle contract will include methods that make it significantly easier for the Compound community to update or add new feeds to the PriceOracle, as a redeployment from Chainlink Labs would no longer be required.

Expected Impact

The architecture has been intentionally designed to be a low-lift change. If the on-chain vote approves the proposal, Uniswap V3 TWAP prices will be disabled in the reference anchor immediately without downtime or changing the Comptroller.

Security Considerations

To replace a critical component in the Compound v2 protocol, it is crucial to prioritize security. Therefore, Chainlink Labs will partner with OpenZeppelin, Compound’s security service provider, to ensure a seamless upgrade process.

One of the essential steps involves meeting the testing standards established by the Compound community, as described in OpenZeppelin’s process:

  • Proposal Simulations - comprehensive simulation testing before being submitted for a governance vote.
  • Change management - ensure that code deployed on-chain always matches the versions of the Compound protocol repository to maintain high quality and readability.

OpenZeppelin will perform an audit, and we will collaborate on any necessary changes resulting from their findings.

The community will also have the opportunity to test the new oracle contract themselves by using the framework in the oracle repo and following the instructions provided (we encourage you to do so!). After completing the required coding work, Chainlink Labs will monitor the performance on mainnet before the community vote.

Next Steps

  1. Chainlink Labs will begin development on the new PriceOracle based on community feedback
  2. OpenZeppelin to conduct an audit on the PriceOracle
  3. Test and monitor the new PriceOracle on mainnet
  4. Share the results with the community for review and feedback before going to an on-chain vote

We welcome the Compound community to share their thoughts and feedback regarding this proposed upgrade to Compound v2’s oracle architecture.

Disclaimer

Chainlink Labs’ development work is offered “as is” without representations, guarantees, or warranties of any kind, on a commercially feasible basis and subject to the Compound DAO’s acceptance of the Chainlink Labs terms of service (available at Terms of Use – Chainlink Labs). The benefits are solely being made available to the Compound Protocol and not to any other party, including the Compound DAO.

Copyright and related rights waived via CC0.

3 Likes

OpenZeppelin has been involved in early discussions to disable the UAV and supports this initiative.

While the original motivation behind UAV is sound, the implementation in practice has only introduced additional complexity by blocking otherwise valid prices during times of illiquidity on Uniswap. Given that Compound V3 has operated safely over the past year without a UAV, it makes sense to change Compound V2 to follow the same approach.

3 Likes

Compound Labs has also been involved in discussions with the Chainlink team on this and supports the proposal.

The UAV oracle has historically been difficult to upgrade as adding or changing a single price feed requires a full re-deploy of the entire oracle. This is largely why some stablecoins, like USDC, still have a hard-coded fixed price in v2. The new, simplified v2 oracle will enable the community to more easily add and update existing price feeds.

3 Likes

Exactly what happened during uni price surge on Feb. which caused a bad debt of 56045 UNI, I write a report for that incident.

So I support this proposal to disable UAV as soon as possible given recent volatile market environment

1 Like

UAV to Oracle Audit

April 12, 2024

Summary

Total Issues: 2 (2 resolved)

Critical Severity Issues: 0 (0 resolved)

High Severity Issues: 0 (0 resolved)

Medium Severity Issues: 0 (0 resolved)

Low Severity Issues: 0 (0 resolved)

Notes & Additional Information: 2 (2 resolved)

Scope

We audited the smartcontractkit/open-oracle repository at commit d15c5fb.

In scope were the following files:

contracts
└── PriceOracle
    └── PriceOracle.sol

System Overview

Compound stands as a prominent lending platform that enables liquidity providers to deposit their funds and earn interest, while simultaneously offering borrowers the opportunity to secure loans against collateral. Although the community is gradually transitioning to Compound V3 (aka Comet), Compound V2 continues to be actively utilized. From the start, Compound V3 has been using Chainlink price feeds.

In contrast, Compound V2 employs an anchoring system, which rejects price feeds from Chainlink oracles if there is a significant difference from the recent Time-Weighted Average Price (TWAP), potentially leading to price inaccuracies and delays during periods of market volatility. The price oracle under review in this audit is designed to replace the anchoring system in Compound V2, addressing these price update issues.

Security Model and Trust Assumptions

The PriceOracle contract is designated to be overseen by an owner address which is tasked with the deployment, addition, and maintenance of price feeds for various assets and cTokens. It is presumed that all incorporated price feeds and configurations are accurately established. The audit focuses on the oracle’s structure and verifies its appropriate interaction with the Comptroller.

Notes & Additional Information

Redundant Data Storage

The TokenConfig struct is defined as shown below:

    struct TokenConfig {
        // Decimals of the underlying asset (e.g. 18 for ETH)
        uint8 underlyingAssetDecimals;
        // Address of the Compound Token
        address cToken;
        // Address of the feed used to retrieve the asset's price
        address priceFeed;
    }

The same struct is stored in the storage like:

/// @dev Mapping of cToken address to TokenConfig used to maintain the supported assets
    mapping (address => TokenConfig) tokenConfigs

In this configuration, storing the cToken address within the struct may seem redundant. However, including the cToken address enhances code readability and simplifies comprehension of the structure. On the other hand, this approach incurs additional gas costs due to the necessity of updating storage, resulting in users incurring higher expenses for extra SSTORE and SLOAD operations.

Update: Resolved at commit 3682d02.

Unnecessary Usage of Storage

In PriceOracle at line 160, storing the loaded configuration in memory could lower gas expenses. As the storage modifications occur at line 171, unnecessary storage accesses happen in the updateConfigPriceFeed function.

Consider using memory as data location for the config variable to reduce gas costs.

Update: Resolved at commit 4df9c25.

Conclusion

During this audit, we thoroughly examined the PriceOracle contract, focusing on its role in replacing the UAV. Our analysis covered two key areas:

  • We verified that state transitions and management of configurations for diverse price feeds are executed properly within the PriceOracle contract.
  • We confirmed that the getUnderlyingPrice function accurately returns the expected price format for the Comptroller.

Based on our evaluation, we are confident that the PriceOracle contract will seamlessly integrate with the Comptroller and deliver precise pricing even in times of high volatility, as long as the underlying oracles and price feeds act appropriately and reliably.

1 Like

Hey everyone,

Now that OpenZeppelin has completed their above audit with all notes resolved, we have deployed the new PriceOracle contract here.

Most of the price feed values of the new PriceOracle contract match the existing UAV deployment apart from two extra decimals of precision that the new contract provides. The only prices that didn’t match are below, but this is expected as they are not expected to match given the upgraded design.

  1. Fixed price stablecoins - The existing UAV returns a hard-coded value of “1” for these tokens, while the new contract uses Chainlink Data Feeds to return the actual market price.
  2. WBTCv2 - while the existing UAV uses one dedicated Data Feed, the new contract uses the custom Data Feed from Compound Labs used in the Compound III USDC Ethereum Market, which uses a combination of two Chainlink Data Feeds under the hood for a WBTC-USD Price Feed. Learn more here.

We encourage the community to review the new PriceOracle contract and deployed configurations, and provide any feedback on the forum here.

Next Steps

If there’s no feedback from the community or service providers, then we will proceed with replacing the UAV with the new PriceOracle contract by

  1. Transferring ownership of the PriceOracle contract to the Compound Community multisig.
  2. Working with one of the Compound Service Providers or delegates to initiate a DAO vote that points the Comptroller to the new PriceOracle contract.

Additionally, OpenZeppelin will conduct a fork test before the vote begins or during the 2-day wait period to ensure a seamless deployment.

We’re excited to continue working with the Compound community in completing this upgrade!

Disclaimer

Chainlink Labs’ development work is offered “as is” without representations, guarantees, or warranties of any kind, on a commercially feasible basis and subject to the Compound DAO’s acceptance of the Chainlink Labs terms of service (available at Terms of Use – Chainlink Labs). The benefits are solely being made available to the Compound Protocol and not to any other party, including the Compound DAO.

2 Likes