Oracle Infrastructure: Chainlink Proposal

Hey everyone, this post is a follow up on the recent developer call we had describing the proposal to switch the current oracle mechanism to Chainlink price feeds combined with a Uniswap anchor acting as a safety net.

This proposal is based on the feedback of Compound community members. Today, I want to describe the implementation we put in place and ensure everyone understands the workflow this new oracle system will have if voted in. The last part of this post will also contain links to testing contracts we’ve deployed on mainnet.

Current Mechanism

First off, I would like to give a quick description of the current system so we all have shared context. The UniswapAnchoredView (UAV) is currently configured with multiple markets, each containing the name, cToken, underlying token, Uniswap V2 pool data and conversion data. Prices are posted to it via a configured reporter. If it is believed that the reporter account has been compromised (private keys stolen, etc.), there is a function called invalidateReporter(), which can be called by the reporter which permanently switches over to the Uniswap V2 TWAP prices.

Signed prices are posted to the UniswapAnchoredView regularly, by the reporter. During this transaction, the following steps occur:

  • Signatures are verified
  • For each posted price:
    • Update the Uniswap V2 TWAP window if due
    • Update the anchor price
      • If posted price is within threshold of anchor price: store the posted price
      • Else, if posted price is outside of the threshold: store the anchor price

New Community Proposal

UniswapAnchoredView Modifications

The community indicated their desire to switch over to Chainlink production price feeds in place of the current reporter. They also indicated a desire to keep a Uniswap Anchor as a safety net to remain in place. Hence, our current proposal modifies the existing architecture whilst maintaining the same anchor mechanism. This architecture is very much optimized to give compound users low gas costs.

The key differences are:

  • Prices will now be pushed from production aggregators, each responsible for a single asset. They call the validate() function, which replaces the postPrices() function. This change is so that the UAV conforms to the AggregatorValidatorInterface , which production aggregators are compatible with.
  • The Compound community multisig will be able to failover single markets, on a per-market basis. In this scenario (as in the current architecture) the Uniswap V2 TWAP price is used as the failover. Function: activateFailover(bytes32 symbolHash)
  • The community can also reverse this failover. Function: deactivateFailover(bytes32 symbolHash)

Price Feeds

Usually, contracts that consume price feeds read the data from an AggregatorProxy contract, which itself reads the price from an underlying OffchainAggregator contract. This proxy pattern is used so that the underlying aggregator can be upgraded without disruption of service for contracts that consume prices from the proxy. More information on this model in the docs: https://docs.chain.link/docs/architecture-decentralized-model/#contracts-overview

UniswapAnchoredView's anchor mechanism relies on prices being pushed to it, not read, so reading from aggregator contracts (as shown in our initial proposal: https://github.com/compound-finance/compound-protocol/pull/105) is not feasible. However, OffchainAggregator contracts enable a validator to be set. Every price transmission that the aggregator receives from nodes is passed to the validator via the validate() function. This is the entry point for the modified UAV. Upon deployment, production aggregators will have their validator set to point to the UAV.

Adding new markets

Given how UniswapAnchoredView is written, any changes (like adding a new market) requires a fresh deployment with a new configuration, which then goes through governance to be set as the oracle in the Comptroller.

An example: If the community deploys a new UAV, the OffchainAggregator of each asset would need to have its validator changed to push prices to the new UAV. Changing the validator would mean that the old UAV no longer receives prices from the aggregator. A transition period exists where both UAVs need to have prices pushed to them so that:

  • Service is not disrupted on the existing UAV.
  • The new UAV can be tested and have its prices verified on-chain before being accepted by governance.

To solve this challenge, we have created the ValidatorProxy contract to sit in between each OffchainAggregator and the UniswapAnchoredView . For the most part, this contract just forwards validate() calls from the aggregator to the UAV. However, It also supports a “proposed” validator (a second UAV), which it also pushes prices to when it is set.

Simple Architecture

This image describes 4 asset prices being pushed to the UniswapAnchoredView. It does not include the anchor mechanism that is performed during the validate() call on the UAV.

Uniswap Anchor Flow

This anchor mechanism has not changed in our proposal. Here is a flowchart (might need to zoom in on this one) representation of the BAT/USD price being posted to it via the validate() function:

Mainnet Tests

To test the modifications to the UAV and the overall architecture, we deployed the contracts to mainnet and tested them using a node network providing prices for the UNI/USD market over the course of roughly 2 days. Here are the addresses:

Code

UniswapAnchoredView

Chainlink has forked the Compound open-oracle repo to make the proposed changes to the UniswapAnchoredView. This PR is being used for internal reviews and can be seen here: https://github.com/smartcontractkit/open-oracle/pull/1.

Once this has been audited in the coming few days, Chainlink will open a pull request from our fork to the Compound open-oracle repo.

ValidatorProxy

Initial PR: https://github.com/smartcontractkit/chainlink/pull/4265

Second PR: https://github.com/smartcontractkit/chainlink/pull/4301

Aggregators

Chainlink aggregator code can be found in the libocr repo: https://github.com/smartcontractkit/libocr

Conclusion

This should be it with all the details for this proposal, if you have any questions please reach out here, I’ll be happy to answer it. We’re looking forward for a long term collaboration with the Compound community and making sure we can help build out the best oracle system available for Compound to keep being a leader in the money market space through the use of secure and accurate oracles. As Uniswap v3 gains momentum we will be looking to work with the community in upgrading to its oracles as a new safety net mechanism and have already started coordinating this process with their team.

9 Likes