QuantAMM

QuantAMM
49,600 OP
View results
Submission Details
Severity: low
Invalid

The price acquisition of the _getData() function lacks validation of the returned data

Summary

The price acquisition of the _getData() function lacks validation of the returned data

Vulnerability Details

https://github.com/Cyfrin/2024-12-quantamm/blob/a775db4273eb36e7b4536c5b60207c9f17541b92/pkg/pool-quantamm/contracts/ChainlinkOracle.sol#L27-L33

https://github.com/Cyfrin/2024-12-quantamm/blob/a775db4273eb36e7b4536c5b60207c9f17541b92/pkg/interfaces/contracts/pool-quantamm/OracleWrapper.sol#L15-L17

function _getData() internal view override returns (int216, uint40) {
(, /*uint80 roundID*/ int data, , /*uint startedAt*/ uint timestamp, ) = /*uint80 answeredInRound*/
priceFeed.latestRoundData();
//介个大于0
require(data > 0, "INVLDDATA");
data = data * int(10 ** normalizationFactor);
return (int216(data), uint40(timestamp)); // Overflow of data is extremely improbable and uint40 is large enough for timestamps for a very long time
}
function getData() public view returns (int216 data, uint40 timestamp) {
(data, timestamp) = _getData();
require(timestamp > 0, "INVORCLVAL"); // Sanity check in case oracle returns invalid values
}

When getting the oracle price, the getData function only determines the data and timestamp, without considering answeredInRound and roundID.

Scenario 1: Normal situation
• Current round roundID = 5.
• Oracle returns:
• answeredInRound = 5
• If answeredInRound >= roundID is satisfied, the data is considered valid and can continue to be used.

Scenario 2: Data expiration
• Current round roundID = 5.
• Oracle returns:
• answeredInRound = 4
• If answeredInRound >= roundID is not satisfied, require is triggered, prompting that the data is expired to avoid incorrect use.

Impact

If stale data is allowed, attackers may be able to influence system behavior by manipulating data from old rounds.

Tools Used

Manual review

Recommendations

function _getData() internal view override returns (int216, uint40) {
(, /*uint80 roundID*/ int data, , /*uint startedAt*/ uint timestamp, ) = /*uint80 answeredInRound*/
priceFeed.latestRoundData();
require(answeredInRound >= roundID, "Stale data detected");
require(data > 0, "INVLDDATA");
data = data * int(10 ** normalizationFactor);
return (int216(data), uint40(timestamp)); // Overflow of data is extremely improbable and uint40 is large enough for timestamps for a very long time
}
Updates

Lead Judging Commences

n0kto Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Known issue
Assigned finding tags:

invalid_chainlink_staled_data_updateAt_roundId_known_issue

LightChaser: ## [Medium-4] Insufficient oracle validation

Support

FAQs

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