hats-finance / Velvet-Capital-0x0bb0c08fd9eeaf190064f4c66f11d18182961f77

Core smart contracts of Velvet Capital
Other
0 stars 1 forks source link

Risk of Incorrect Price Feeds Due to Chainlink Oracle Circuit Breaker Activation #8

Open hats-bug-reporter[bot] opened 1 week ago

hats-bug-reporter[bot] commented 1 week ago

Github username: -- Twitter username: -- Submission hash (on-chain): 0xdb1d03b9e1c9425e6fa34585398ac2572f3b0d2cddfac1e0788d1a366ed32a42 Severity: medium

Description: Description\

The PriceOracle:: _latestRoundData function in the PriceFeed contract is vulnerable to returning incorrect prices if the Chainlink oracle's circuit breaker mechanism is triggered. This can lead to users Trade the market against assets at incorrect prices, potentially causing significant financial losses and instability in the protocol. This scenario occurred on Venus on the Binance Smart Chain (BSC) during the collapse of LUNA.

  1. Proof of Concept (PoC) File

When using the latestRoundData() the price of an asset deviates significantly from a predefined price range, Chainlink aggregators activate a circuit breaker mechanism. This mechanism causes the oracle to consistently return the minimum price instead of the actual price of the asset.

Consequently, users can continue to Trade the asset, but at an incorrect price.

For instance, consider TokenA with a minPrice set at $1. If the price of TokenA drops to $0.10, the aggregator still reports $1. This scenario enables users to Trade significant amounts of token, potentially leading to bankruptcy for the protocol.


  function _latestRoundData(
    address base,
    address quote
  ) internal view override returns (int256) {
    // Fetch the latest round data from the aggregator for the given token pair.
    (, int256 answer, , uint256 updatedAt, ) = tokenPairToAggregator[base]
      .aggregators[quote]
      .latestRoundData();

    // Validate that the retrieved price is a valid non-zero value.
    if (updatedAt + oracleExpirationThreshold < block.timestamp)
      revert ErrorLibrary.PriceOracleExpired();

    if (answer <= 0) revert ErrorLibrary.PriceOracleInvalid();

    return answer;
  }
  1. Revised Code File (Optional)

chainlink oracle should check the returned answer against the minPrice/maxPrice and revert if the answer is outside of the bounds:

langnavina97 commented 1 week ago

DUPLICATE #2

We are aware of the dependency on Chainlink. We decided not to implement a secondary oracle to cross-check the values because the price oracle is only being used for calculating the performance fee.

This is out of scope, it was already pointed out by the auditors.