Skip to content

Latest commit

 

History

History
66 lines (40 loc) · 2.96 KB

006.md

File metadata and controls

66 lines (40 loc) · 2.96 KB

Deep Orange Bison

Medium

Oracle Returns Incorrect Price During Flash Crashes

Summary

The smart contract getThePrice function on DebitaChainlink contract relies on Chainlink price feeds without checking for the minAnswer and maxAnswer bounds set within the oracle. This lack of validation opens the system to potential mispricing, especially during flash crashes, bridge compromises, or other events causing sharp, temporary price drops. Chainlink price feeds enforce a minimum and maximum price; when an asset’s market price falls below this threshold, the feed continues to report the minimum price rather than reflecting the actual lower value.

In such scenarios, an attacker could exploit the discrepancy by obtaining the asset at its true lower price through decentralized exchanges, depositing it into lending or borrowing platforms that use Chainlink’s price feed, and borrowing against the artificially high minimum price. This would allow the attacker to drain value from these platforms.

Root Cause

The getThePrice function doesn’t validate that the price returned by Chainlink falls within minAnswer and maxAnswer bounds, meaning it may return an outdated or incorrect minimum price during extreme market events.

Failure to account for differing decimal precision among oracle feeds could also compound calculation errors, though this specific risk is secondary to the mispricing issue.

Internal pre-conditions

No response

External pre-conditions

No response

Attack Path

No response

Impact

Reference

PoC

The getThePrice function leverages ChainlinkFeedRegistry to retrieve token prices by accessing the corresponding price feed.

function getThePrice(address tokenAddress) public view returns (int) {
    // Check needed for Layer 2 networks
    address _priceFeed = priceFeeds[tokenAddress];
    require(!isPaused, "Contract is paused");
    require(_priceFeed != address(0), "Price feed not set");
    AggregatorV3Interface priceFeed = AggregatorV3Interface(_priceFeed);

    // If a sequencer is set, confirm its status; revert if unavailable
    if (address(sequencerUptimeFeed) != address(0)) {
        checkSequencer();
    }
    (, int price, , , ) = priceFeed.latestRoundData();

    require(isFeedAvailable[_priceFeed], "Price feed not available");
    require(price > 0, "Invalid price");
    return price;
}

The ChainlinkFeedRegistry#latestRoundData function retrieves data from the linked aggregator. During severe price fluctuations, if an asset’s value drops below a predefined minPrice, the oracle may continue reporting the minPrice instead of the actual, lower market value.

A similar issue is seen here.

Mitigation

No response