#43314 [SC-Insight] Oracle functions mislead integrators as it is not compatible with Chainlink Price feed behaviour
Submitted on Apr 4th 2025 at 14:14:13 UTC by @holydevoti0n for Audit Comp | Spectra Finance
Report ID: #43314
Report Type: Smart Contract
Report severity: Insight
Target: https://github.com/immunefi-team/Spectra-Audit-Competition/blob/main/src/spectra-oracles/oracles/BaseOracleCurveLPT.sol
Impacts:
Description
Vulnerability Details
All the new oracles from Spectra inherits from AggregatorV3Interface
which is the Chainlink interface for price feeds. Problem is all oracles from Spectra that implement this interface do not behave as expected for a Chainlink Price Feed Integration.
First issue is:
The
getRoundData
andlatestRoundData
will always return the same data, asgetRoundData
completely ignores theroundId
passed as a parameter. Proof here: https://github.com/immunefi-team/Spectra-Audit-Competition/blob/1cebdc67a9276fd87105d13f302fd77d000d0c0b/src/spectra-oracles/oracles/BaseOracle.sol#L46
function getRoundData(
uint80
)
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
)
{ // @audit - `latestRoundData` return same output, regardless of the input passed in `getRoundData`
@> return (0, int256(_getQuoteAmount()), 0, 0, 0);
}
/** @dev See {AggregatorV3Interface-latestRoundData}. */
function latestRoundData()
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
)
{ // @audit - `latestRoundData` and `getRoundData` return same output, regardless of the input passed in `getRoundData`
@> return (0, int256(_getQuoteAmount()), 0, 0, 0);
}
Second issue is that: the returned variables
roundId
,startedAt
,updatedAt
andansweredInRound
are always zero. Integrators use those variables to check whether the current price is still valid. As Spectra always returns those variables with the value0
, this means the current price being returned is INVALID.
You can see this is the Chainlink recommendation for consuming valid price from the price feed oracles: https://docs.chain.link/data-feeds#check-the-timestamp-of-the-latest-answer
So Spectra implements Chainlink Price Feed interface for an oracle that do not reflect the Chainlink Implementation's behaviour.
Impact Details
The current implementation always returns an "invalid price" according to Chainlink, which will mislead integrators to avoid using Spectra's oracles.
getRoundData
will mislead integrators that wants to check specific rounds for prices as this function works exactly aslatestRoundData
returning the latest price.
Recommendation
Spectra should not use AggregatorV3Interface
to its oracles as they are not reflecting a Chainlink Price Feed.
Spectra should create a specific interface based on its current implementation and remove the Chainlink functions completely.
Proof of Concept
Proof of Concept
Was this helpful?