Stratax Contracts

First Flight #57
Beginner FriendlyDeFi
100 EXP
View results
Submission Details
Severity: medium
Valid

Missing Chainlink data freshness check leads to stale price usage

Root + Impact

Description

  • The getPrice function retrieves the latest price from the Chainlink aggregator using latestRoundData.

  • However, it ignores the updatedAt and answeredInRound return values, failing to validate if the reported price is fresh and valid for the current block.

function getPrice(address _token) public view returns (uint256 price) {
// ...
AggregatorV3Interface priceFeed = AggregatorV3Interface(priceFeedAddress);
// @> Root cause: Only 'answer' is retrieved; 'updatedAt' and 'answeredInRound' are ignored.
(, int256 answer,,,) = priceFeed.latestRoundData();
require(answer > 0, "Invalid price from oracle");
price = uint256(answer);
}

Risk

Likelihood:

  • Chainlink oracles can stop updating

Impact:

  • The protocol calculates leverage and health factors based on outdated prices.

Proof of Concept

// Scenario:
// 1. ETH price is $2000. Oracle updates.
// 2. Market crashes, ETH is now $1000.
// 3. Oracle gets stuck or congested and hasn't updated for 5 hours.
// 4. User calls createLeveragedPosition().
// 5. getPrice() returns $2000 (stale) instead of reverting.
// 6. User borrows 2x what they should be allowed to.

Recommended Mitigation

function getPrice(address _token) public view returns (uint256 price) {
address priceFeedAddress = priceFeeds[_token];
require(priceFeedAddress != address(0), "Price feed not set for token");
AggregatorV3Interface priceFeed = AggregatorV3Interface(priceFeedAddress);
- (, int256 answer,,,) = priceFeed.latestRoundData();
+ (uint80 roundId, int256 answer, , uint256 updatedAt, uint80 answeredInRound) = priceFeed.latestRoundData();
+
require(answer > 0, "Invalid price from oracle");
+ require(updatedAt != 0, "Incomplete round");
+ require(answeredInRound >= roundId, "Stale price");
+ require(block.timestamp - updatedAt < 3600, "Price too old"); // Example 1 hour heartbeat
price = uint256(answer);
}
Updates

Lead Judging Commences

izuman Lead Judge 16 days ago
Submission Judgement Published
Validated
Assigned finding tags:

Price feed has no staleness check

StrataxOracle contract fails to check if the price is stale, which can mess up swap calculations.

Support

FAQs

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

Give us feedback!