Skip to content

Latest commit

 

History

History
57 lines (32 loc) · 2.22 KB

File metadata and controls

57 lines (32 loc) · 2.22 KB

Shiny Garnet Pheasant

Medium

Chainlink oracle gives wrong price if the latest price from aggregator hits the extreme values (either minPrice or maxPrice)

Summary

Chainlink aggregators include a circuit breaker that activates when an asset's price moves outside a preset range. In extreme cases, like the LUNA crash, the oracle will return the minPrice or maxPrice instead of the asset's actual value.

Root Cause

In getOraclePrice function in OracleReader.sol contract, it tries to get the latest price from the oracle.

https://github.com/sherlock-audit/2024-12-plaza-finance/blob/main/plaza-evm/src/OracleReader.sol#L55-L76

In the above function it calls the latestRoundData function, which returns latest price and updated timestamp, which helps to check the price is not staled one.

When an asset's price exceeds these predefined thresholds, the oracle returns the capped value (minAnswer or maxAnswer) instead of the actual market price. This mechanism is intended to protect protocols from outlier data but fails in scenarios where the real market price diverges significantly, such as during the LUNA crash.

Example — Let's assume the token that to be created be TokenA, TokenA has minPrice of $1. The price of TokenA drops to $0.1. The aggregator still returns $1 allowing the user to borrow against TokenA as if it is $1 which is 10X it’s actual value.

Internal Pre-conditions

No response

External Pre-conditions

Oracle price get's down below the minPrice of aggregator. Let's say TokenA drops to $0.1 from $1.

Attack Path

Attacker Strategy:

  1. Buy that asset using DEX at very low price
  2. Deposit the asset into lending/ borrowing platforms using Chainlinks price feeds
  3. Borrow against that asset at the minimum price Chainlink price feed returns, even though actual price is far lower

Impact

This allow users to create or redeem token at wrong prices. This is precisely what occurred with Venus on BSC during the LUNA crash.

PoC

No response

Mitigation

(uint80, int256 answer, uint, uint, uint80) = oracle.latestRoundData();

// minPrice check
require(answer > minPrice, "Min price exceeded");
// maxPrice check
require(answer < maxPrice, "Max price exceeded");