Omniscia Euler Finance Audit

RiskManager Manual Review Findings

RiskManager Manual Review Findings

RMR-01M: Inexplicable Upper Price Enforcement

Description:

The linked upper price enforcement for a particular reported price is inexplicable and incorrectly implemented as an asset with a price higher than 1e36 must not be normalized to 1e36 as it would present arbitrage opportunities.

Impact:

A highly valued asset that may exceed the 1e36 threshold (i.e. an alt-coin evaluation against BTC) will cause arbitrage opportunities in the current implementation of the Euler system.

Example:

contracts/modules/RiskManager.sol
200if (price > 1e36) price = 1e36;

Recommendation:

We advise the linked normalization pattern to be omitted and an error or a zero-price causing fallback measuring methodologies to be yielded by the function instead ensuring that it does not expose arbitrage opportunities.

Alleviation:

The Euler Finance team stated that while this is a valid point of discussion, it does not currently represent an active threat to the protocol as the price evaluated in the conditional is after decimal normalization and thus would practically be impossible to exceed with the current token list of the protocol. Nonetheless, the Euler Finance team will actively monitor new tokens introduced to the system and potential external project changes that may break this assumption and react as needed. As a result, we consider this an adequate response to the exhibit and will mark it as alleviated.

Description:

The callChainlinkLatestAnswer function simply invokes the latestAnswer function of the Chainlink aggregator and does not properly validate that the oracle itself is operating properly.

Impact:

Improper integration of the Chainlink oracles allows sudden market events to significantly impact the Euler protocol as the price points utilized will be invalid.

Example:

contracts/modules/RiskManager.sol
187function callChainlinkLatestAnswer(address chainlinkAggregator) private view returns (uint price) {
188 (bool success, bytes memory data) = chainlinkAggregator.staticcall(abi.encodeWithSelector(IChainlinkAggregatorV2V3.latestAnswer.selector));
189
190 if (!success) {
191 return 0;
192 }
193
194 int256 answer = abi.decode(data, (int256));
195 if (answer <= 0) {
196 return 0;
197 }
198
199 price = uint(answer);
200 if (price > 1e36) price = 1e36;
201}

Recommendation:

We advise multiple safeguards to be put in place with the primary safeguard being the validation of data staleness. As the Chainlink aggregator is an off-chain oracle, the data it reports entirely relies on timely operation of the off-chain Chainlink system.

There is no guarantee that the latestAnswer result is actually the latest of the market, it simply implies that it is the latest one reported on-chain. To validate that the data retrieved via the function is fresh, a different function needs to be utilized called latestRoundData.

The data point of interest it yields is the updatedAt timestamp. The desire is to enforce a particular "heartbeat" of data validity that ensures the updatedAt value satisfies the time threshold imposed by the Euler protocol. We should note that Chainlink imposes different heartbeats for different asset types and as such the time limit that should be imposed needs to be sensible based on the Euler protocol's needs and the idle-time threshold Chainlink has set for the particular data feed.

A secondary protection measure that should be put in place is extreme asset volatility protection. This measure can be put in place in two ways. A universal one that should potentially be applied across the protocol is the measurement of volatility in terms of percentage changes over a time period. This would permit sharp increases or decreases in price to allow the Euler protocol to pause borrowing or supplying of the asset in question within the system, proactively reacting to a significant market event.

An alternative, easier to implement and Chainlink-specific way to detect extreme market events is to compare the price reported by the aggregator against the minimum and maximum acceptable values the oracle is capable of reporting. If the price reported is approaching these values, it means that the oracle will soon cease reporting correct values for the asset and the asset should be measured using alternative price points (i.e. Uniswap V3 TWAPs) or be temporarily paused altogether. The minimum and maximum permitted values can be identified in the AccessControlledOffchainAggregator and require an additional data point to be stored whenever a new Chainlink feed is accepted into the protocol pointing to the access-controlled implementation.

Alleviation:

We deliberated on this issue with the Euler Finance team via extensive discussions as to what types of solutions are available to deal with misbehaving Chainlink oracles and what their implications would be and the final conclusion we arrived to is that off-chain monitoring will be required under all circumstances (albeit to a different degree) and thus a reliance on off-chain management is unavoidable. Based on this fact, we both agreed that a completely off-chain solution is the best choice based on criteria of flexibility, time-to-reaction, and overall drawback / benefit comparison between the available choices. As a result, we consider this exhibit nullified given that a dynamic data staleness policy would significantly increase the complexity of the project and based on the current short-comings of Chainlink oracles an off-chain solution is mandatory to properly combat misbehaving oracles.