Phuture Finance contest - tabish's results

Crypto index platform, that simplifies your investments through automated, themed index products.

General Information

Platform: Code4rena

Start Date: 19/04/2022

Pot Size: $30,000 USDC

Total HM: 10

Participants: 43

Period: 3 days

Judges: moose-code, JasoonS

Total Solo HM: 7

Id: 90

League: ETH

Phuture Finance

Findings Distribution

Researcher Performance

Rank: 43/43

Findings: 1

Award: $22.05

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

Awards

22.0499 USDC - $22.05

Labels

bug
duplicate
2 (Med Risk)

External Links

Lines of code

https://github.com/code-423n4/2022-04-phuture/blob/594459d0865fb6603ba388b53f3f01648f5bb6fb/contracts/ChainlinkPriceOracle.sol#L80

Vulnerability details

Impact

Detailed description of the impact of this finding. Stale price from data feed can lead to incorrect value of assetPerBaseInUQ

Proof of Concept

Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.

Oracle data feed is insufficiently validated. There is no check for stale price and round completeness.

/// @inheritdoc IPriceOracle function refreshedAssetPerBaseInUQ(address _asset) public override returns (uint) { AssetInfo storage assetInfo = assetInfoOf[_asset]; (, int basePrice, , , ) = baseAggregator.latestRoundData(); (, int quotePrice, , , ) = assetInfo.aggregator.latestRoundData(); require(basePrice > 0 && quotePrice > 0, "ChainlinkPriceOracle: NEGATIVE"); uint assetPerBaseInUQ = ((uint(basePrice) * 10**assetInfo.decimals).mulDiv( FixedPoint112.Q112, (uint(quotePrice) * 10**baseDecimals) ) * 10**assetInfo.answerDecimals) / 10**baseAnswerDecimals; assetInfo.lastAssetPerBaseInUQ = assetPerBaseInUQ; return assetPerBaseInUQ; }

Validate data feed

/// @inheritdoc IPriceOracle function refreshedAssetPerBaseInUQ(address _asset) public override returns (uint) { AssetInfo storage assetInfo = assetInfoOf[_asset]; (uint80 roundID, int basePrice, , uint256 timestamp, uint80 answeredInRound) = baseAggregator.latestRoundData(); require(basePrice > 0, "ChainLink: base price <= 0"); require(answeredInRound >= roundID, "ChainLink: Stale price"); require(timestamp > 0, "ChainLink: Round not complete"); (uint80 roundID, int quotePrice, , uint256 timestamp, uint80 answeredInRound) = assetInfo.aggregator.latestRoundData(); require(quotePrice > 0, "ChainLink: asset price <= 0"); require(answeredInRound >= roundID, "ChainLink: Stale price"); require(timestamp > 0, "ChainLink: Round not complete"); uint assetPerBaseInUQ = ((uint(basePrice) * 10**assetInfo.decimals).mulDiv( FixedPoint112.Q112, (uint(quotePrice) * 10**baseDecimals) ) * 10**assetInfo.answerDecimals) / 10**baseAnswerDecimals; assetInfo.lastAssetPerBaseInUQ = assetPerBaseInUQ; return assetPerBaseInUQ; }

#0 - olivermehr

2022-05-02T20:31:07Z

Duplicate issue of #1

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter