The Standard

The Standard
DeFiHardhat
20,000 USDC
View results
Submission Details
Severity: low
Invalid

[M] PhaseId shift in Chainlink oracle price feed will result in incorrect price calculation

Summary

According to the docs, the protocol is applicable to any evm chain with Chainlink feeds.

Chainlink's roundID is a composite number combining a phaseID and an aggregatorRoundID.
The phaseID changes whenever there is an upgrade to the underlying aggregator,
and this change causes a significant jump in the roundID values due to the bit-shifting operation
described in the documentation.

ref here: https://docs.chain.link/data-feeds/historical-data#solidity

Vulnerability Details

Chainlink's roundID is a composite number combining a phaseID and an aggregatorRoundID.
The phaseID changes whenever there is an upgrade to the underlying aggregator,
and this change causes a significant jump in the roundID values due to the bit-shifting operation
described in the documentation.

The current implementation of avgPrice does not seem to handle the scenario where the phaseID
changes and a significant gap in roundID values exists.

There are several areas in the codebase where this particular issue threatens.

Collateral Evaluation (euroCollateral function):

This function calculates the total Euro value of all accepted tokens in the vault.
It iterates through all accepted tokens and uses tokenToEurAvg to get their Euro value.
If tokenToEurAvg fails due to the phaseID increment issue,
it could incorrectly calculate the total Euro value of the collateral, leading to inaccurate collateral assessments.

Maximum Mintable Calculation (maxMintable function):

This function determines the maximum amount of EUROs that can be minted based on the current collateral value.
It relies on the euroCollateral function, and thus indirectly on tokenToEurAvg.
A failure in tokenToEurAvg could result in an incorrect calculation of the maximum mintable amount,
potentially affecting the vault's solvency and the users' ability to mint EUROs.

removeCollateral & removeAsset functions:

These functions allow the removal of collateral or assets from the vault.
They use tokenToEurAvg to ensure that the removal of assets doesn’t cause the vault to become undercollateralized.
If tokenToEurAvg provides incorrect data, it could lead to inappropriate removal of assets, risking the vault’s stability.

Impact

If a phaseID increment occurs, it results in a jump in roundID values, creating a gap in the sequence.
When avgPrice attempts to access round data for roundIDs within this gap, it will encounter inaccurate rounds,
potentially causing the function to fail or return incorrect data, considering when the phaseID is incremented
the roundID increases by 2 ** 64.

Here is a code snippet from Chainlink's feed on Avax for ETH/USD.

function getAnswer(uint256 _roundId)
public
view
virtual
override
returns (int256 answer)
{
if (_roundId > MAX_ID) return 0;
(uint16 phaseId, uint64 aggregatorRoundId) = parseIds(_roundId);
AggregatorV2V3Interface aggregator = phaseAggregators[phaseId];
if (address(aggregator) == address(0)) return 0;
return aggregator.getAnswer(aggregatorRoundId);
}

Tools Used

Manual Review

Recommendations

Check return values of roundId. If the roundID is a nonzero value and is reverting then the oracle needs to try again with a lower phaseId.

Updates

Lead Judging Commences

hrishibhat Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

informational/invalid

golanger85 Submitter
over 1 year ago
hrishibhat Lead Judge
over 1 year ago
hrishibhat Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

informational/invalid

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.