Skip to content
This repository has been archived by the owner on Nov 26, 2023. It is now read-only.

Kose - Check for stale data before trusting Chainlink's response #173

Closed
sherlock-admin opened this issue May 23, 2023 · 0 comments
Closed
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A valid Medium severity issue Reward A payout will be made for this issue

Comments

@sherlock-admin
Copy link
Contributor

sherlock-admin commented May 23, 2023

Kose

medium

Check for stale data before trusting Chainlink's response

Summary

Lack of checks for round completeness may result in the utilization of stale prices, leading to incorrect price return values or outdated pricing information. Consequently, functions that depend on accurate price feeds may not operate as intended, potentially resulting in financial losses.

Vulnerability Detail

While Chainlinks' latestRoundData() function is used along with other oracles in StablOracleDAI.sol, in StablOracleWBTC.sol and StableOracleWETH.sol it is used as an only source for getting real world price. The problem though lies in the usage of this function.
As Chainlink recommends:

Your application should track the latestTimestamp variable or use the updatedAt value from the latestRoundData() function to make sure that the latest answer is recent enough for your application to use it. If your application detects that the reported answer is not updated within the heartbeat or within time limits that you determine are acceptable for your application, pause operation or switch to an alternate operation mode while identifying the cause of the delay.

So it is recommended to use extra informations provided in latestRoundData function, such as:

  • If answeredInRound is less than roundId, the answer is being carried over.
  • A timestamp with zero value means the round is not complete and should not be used.

Impact

Functions that depend on accurate price feeds may not operate as intended, potentially resulting in financial losses.

Code Snippet

StableOracleDAI.sol#L48

(, int256 price, , , ) = priceFeedDAIETH.latestRoundData();

StableOracleWBTC.sol#L48

(, int256 price, , , ) = priceFeed.latestRoundData();

StableOracleWETH.sol#L23

(, int256 price, , , ) = priceFeed.latestRoundData();

Tool used

Manual Review

Recommendation

Instead of just taking price from Chainlinks' latestRoundData() function, get all return values as commented out in StableOracleDAI.sol#L47

//(uint80 roundID, int256 price, uint256 startedAt, uint256 timeStamp, uint80 answeredInRound) = priceFeedDAIETH.latestRoundData();

and to make sure that the data is not stale, use checks such as:

require(timeStamp != 0);
require(answeredInRound >= roundID);

before returning price.

Duplicate of #31

@github-actions github-actions bot closed this as completed Jun 5, 2023
@github-actions github-actions bot added Medium A valid Medium severity issue Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label labels Jun 5, 2023
@sherlock-admin sherlock-admin added the Reward A payout will be made for this issue label Jun 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A valid Medium severity issue Reward A payout will be made for this issue
Projects
None yet
Development

No branches or pull requests

1 participant