# \[DRAFT\] Proposal: On-Chain Report Price Filter

**URL:** https://forum.celo.org/t/draft-proposal-on-chain-report-price-filter/3725
**Category:** Mento
**Created:** [June 2, 2022, 9:29pm UTC](https://forum.celo.org/t/draft-proposal-on-chain-report-price-filter/3725 "2022-06-02T21:29:37Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![bayological](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.celo.org/bayological/32/8381_2.png) [@bayological](https://forum.celo.org/u/bayological)
#### Post date: [June 2, 2022, 9:29pm UTC](https://forum.celo.org/t/draft-proposal-on-chain-report-price-filter/3725/1 "2022-06-02T21:29:37Z")

</div>

This is a draft proposal for a change that aims to improve the functionality of the stability mechanism. The change will update the SortedOracles contract and will introduce two new contracts to the mento protocol.

###### Simple Summary

1. Design of an oracle report filter with modular filter conditions.
2. Design of an oracle report price deviation filter condition.

###### Abstract

The Celo oracle client is currently responsible for running checks against new price reports before submitting them to the `SortedOracles` contract. One of these checks determines if prices from data sources have a deviation greater than a specified threshold. If a report fails any of the checks, the oracle will ignore the report and will not send an update to the contract. This proposal is to move this functionality on-chain to allow new checks to be added easily in the future.

A new contract, the `ReportFilter`, will be created and injected into the `SortedOracles` contract. The new contract will act as a simple interface to allow the `SortedOracles` to filter incoming reports without knowing the filter conditions, their dependencies or how they are checked. Filter conditions are created as separate modules to allow new ones to be added or removed independently in future updates.

###### Motivation

The Mento protocol relies on price reports from centralized oracle clients run by cLabs. Whilst cLabs is a trusted entity, as long as the protocol depends on the centralized oracle setup, it will remain a single point of failure for Mento. This change aims to move one of the current responsibilities, in addition to providing price reports, held by the oracle clients on-chain.

In addition to providing price reports, the oracle clients also perform additional checks before sending reports to the `SortedOracles` contract:

1. Before submitting a report, the oracle client pulls prices from all configured exchange data sources. The first of multiple checks verify that the prices received do not deviate more than a configurable value, the `maxPercentageDeviation`. If the deviation is too large, the oracle will not submit an update.
2. The next check determines if the current report price change relative to the last report price is greater than a calculated threshold. If the difference exceeds the threshold, the oracle circuit breaker will be opened, stopping the oracle client from reporting prices indefinitely.
3. The last check determines if the current report price change is significant enough to trigger a new report. If the difference is too small, the oracle client will not send the report to the `SortedOracles` contract.

The last check will not be moved, as this is just an optimization for the oracle client, and authorized accounts should be able to report as often as they like. The first two checks will be moved on-chain to be performed in a trustless and transparent manner. Moving these checks on-chain will support a move to a decentralized oracle setup which eliminates the single failure point and contributes to providing Mento stablecoin users with a strong guarantee of price data availability, among other advantages.

This proposal, however, will focus only on moving the first check for price deviation on-chain. An on-chain circuit breaker will be implemented in a follow-up proposal which will cover the second check.

##### Specification

###### Overview

The `SortedOracles` contract will be amended to include a new modifier, `checkReport(address token, uint256 value)`. The modifier will be added to the report function. A reference to a new contract, `ReportFilter`, will be added to `SortedOracles`. The responsibility of the new contract will be to check a specified price report meets all conditions before the `SortedOracles` contract processes the report. When an oracle client calls the report function, the `ReportFilter` will return a bool indicating whether or not the specified report meets all conditions. If the report doesn’t meet a condition, it will not be taken up by the `SortedOracles` contract. `FilterCondition` contracts each have a single responsibility, the same interface and will be manageable through the `ReportFilter`. A new filter condition contract, `PriceDeviationFilter`, will be created to check that a given report does not deviate more than the `maxPercentageDeviation` when compared with the existing reports. The `maxPercentageDeviation` will initially be set to the value currently used in the oracle clients but can be changed by governance.

 ![](https://us1.discourse-cdn.com/flex020/uploads/celo/original/2X/b/bc0aab5ee50c24a99a3cb7d104906725532d6128.png)

###### Rationale

The design follows a modular approach to give us flexibility with the option to add additional filter conditions at a later date without redeploying SortedOracles or ReportFilter. The ReportFilter only needs to store a mapping of enabled filters and their addresses. The logic for executing the checks should not need to change as all filters will implement the same interface.

###### Caveats

This implementation will increase the gas cost for each report submitted by oracle clients. With each new condition added, the gas cost will increase further. This increase is an unfortunate effect but necessary.

###### Technical Specification

`IFilterCondition` interface:

 ![](https://us1.discourse-cdn.com/flex020/uploads/celo/original/2X/3/351dcc471bf753d94aa28870a96e4773cef9bebb.png)

`IReportFilter` interface:

 ![](https://us1.discourse-cdn.com/flex020/uploads/celo/original/2X/6/62ac760b028b4f40838482223d96a79d0a957fae.png)

###### Implementation

TBD

###### Summary of Changes:

- Create IReportFilter & IFilterCondition interfaces
- Create PriceDeviationFilter contract
- Create ReportFilter contract
- Add modifier to SortedOracles
- Update SortedOracles.report()

###### Test Cases

Will be included with implementation.

###### Security Considerations

Enabling and disabling filter conditions will be left to governance. However, this potentially leaves the system vulnerable to a governance attack. In this case, it would be possible for an attacker to disable all filters to allow a bad price to be taken up by SortedOracles. This is a low risk as cLabs still run the oracle clients. Before moving to a decentralized oracle setup, there will be other layers in place to protect the system’s integrity should this occur.

---

<div class="post-metadata">

### Author: ![diwu1989](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.celo.org/diwu1989/32/6551_2.png) [@diwu1989](https://forum.celo.org/u/diwu1989)
#### Post date: [June 16, 2022, 6:34pm UTC](https://forum.celo.org/t/draft-proposal-on-chain-report-price-filter/3725/2 "2022-06-16T18:34:01Z")

</div>

Earlier this year when celo price pumped to double on that Korean exchange listing, if that happened again, what should the behavior be?

It was a huge instantaneous price change and all oracles saw the same pump and decided to stop reporting.

It’s a little dangerous for official oracle to keep the old price and not report new price. Moola for example had a few minutes where people could have borrowed based on stale price… luckily nobody exploited this, but it was possible due to all oracle clients circuit breaking

---

<div class="post-metadata">

### Author: ![bayological](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.celo.org/bayological/32/8381_2.png) [@bayological](https://forum.celo.org/u/bayological)
#### Post date: [June 16, 2022, 11:28pm UTC](https://forum.celo.org/t/draft-proposal-on-chain-report-price-filter/3725/3 "2022-06-16T23:28:50Z")

</div>

> [@diwu1989](#):
>
> Earlier this year when celo price pumped to double on that Korean exchange listing, if that happened again, what should the behavior be?

If that happens again, the first oracle reporting the new price will be filtered out. Once more oracles start reporting a similar price, the mean will get closer to this price, and any new oracle reports close to the new price will no longer be filtered. The same check is implemented in the oracle client [here](https://github.com/celo-org/celo-oracle/blob/main/src/aggregator_functions.ts#L116), and the behaviour should be the same.

> [@diwu1989](#):
>
> It was a huge instantaneous price change and all oracles saw the same pump and decided to stop reporting.

Currently, if the price deviation check fails, the oracle client will not send a report for that assigned block but should not stop reporting completely. The oracle client will stop reporting if the new price [trips the circuit breaker](https://github.com/celo-org/celo-oracle/blob/836c55e6b23683c479d506f3de2bd9d6015f7cca/src/reporters/base.ts#L358).

> [@diwu1989](#):
>
> It’s a little dangerous for official oracle to keep the old price and not report new price

There’s also another proposed change for an [on-chain circuit breaker](https://forum.celo.org/t/draft-proposal-on-chain-circuit-breaker/3786) that would have halted mento trading in this situation. Maybe Moola would benefit from this also, but I think all protocols should have protections in place when using oracles.

---

<div class="post-metadata">

### Author: ![diwu1989](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.celo.org/diwu1989/32/6551_2.png) [@diwu1989](https://forum.celo.org/u/diwu1989)
#### Post date: [June 16, 2022, 11:43pm UTC](https://forum.celo.org/t/draft-proposal-on-chain-report-price-filter/3725/4 "2022-06-16T23:43:23Z")

</div>

Okay we should run some simulation scenarios to see how this behaves, there was also CEX disagreement for a few minutes during the pump, but soon it stabilized.

Having different CEX disagree for a brief while might have been what caused the circuit to get tripped that night.

We did fix up moola oracle but we still wait for the official oracle price to go stale first before moving to fallback twap oracle. During this period the protocol is slightly at risk.
