Yield-Convex contest - cccz's results

Fixed-rate borrowing and lending on Ethereum

General Information

Platform: Code4rena

Start Date: 28/01/2022

Pot Size: $30,000 USDC

Total HM: 4

Participants: 22

Period: 3 days

Judge: GalloDaSballo

Total Solo HM: 2

Id: 80

League: ETH

Yield

Findings Distribution

Researcher Performance

Rank: 19/22

Findings: 2

Award: $69.12

🌟 Selected for report: 0

šŸš€ Solo Findings: 0

Findings Information

🌟 Selected for report: throttle

Also found by: 0x1f8b, TomFrenchBlockchain, WatchPug, cccz, defsec, hack3r-0m, hyh, kenzo, leastwood, sirhashalot, ye0lde

Labels

bug
duplicate
2 (Med Risk)

Awards

69.1238 USDC - $69.12

External Links

Handle

cccz

Vulnerability details

Impact

On Cvx3CrvOracle.sol, we are using latestRoundData, but there is no check if the return value indicates stale data. This could lead to stale prices according to the Chainlink documentation:

https://docs.chain.link/docs/historical-price-data/#historical-rounds https://docs.chain.link/docs/faq/#how-can-i-check-if-the-answer-to-a-round-is-being-carried-over-from-a-previous-round Ā 

function _peek( bytes6 base, bytes6 quote, uint256 baseAmount ) private view returns (uint256 quoteAmount, uint256 updateTime) { require( (base == ethId && quote == cvx3CrvId) || (base == cvx3CrvId && quote == ethId), "Invalid quote or base" ); (, int256 daiPrice, , , ) = DAI.latestRoundData(); (, int256 usdcPrice, , , ) = USDC.latestRoundData(); (, int256 usdtPrice, , , ) = USDT.latestRoundData(); require( daiPrice > 0 && usdcPrice > 0 && usdtPrice > 0, "Chainlink pricefeed reporting 0" );

Proof of Concept

https://github.com/code-423n4/2022-01-yield/blob/main/contracts/Cvx3CrvOracle.sol#L110-L128

Tools Used

None

Consider adding missing checks for stale data.

For example:

function _peek( bytes6 base, bytes6 quote, uint256 baseAmount ) private view returns (uint256 quoteAmount, uint256 updateTime) { require( (base == ethId && quote == cvx3CrvId) || (base == cvx3CrvId && quote == ethId), "Invalid quote or base" ); (uint80 DAIroundID, int256 DAIfeedPrice, , uint256 DAItimestamp, uint80 DAIansweredInRound) = DAI.latestRoundData(); (uint80 USDCroundID, int256 USDCfeedPrice, , uint256 USDCtimestamp, uint80 USDCansweredInRound) = USDC.latestRoundData(); (uint80 USDTroundID, int256 USDTfeedPrice, , uint256 USDTtimestamp, uint80 USDTansweredInRound) = USDT.latestRoundData(); require(DAIansweredInRound >= DAIroundID && USDCansweredInRound >= USDCroundID && USDTansweredInRound >= USDTroundID , "Stale price"); require(DAItimestamp != 0 && USDCtimestamp != 0 && USDTtimestamp != 0, "Round not complete"); require( DAIfeedPrice > 0 && USDCfeedPrice > 0 && USDTfeedPrice > 0, "Chainlink pricefeed reporting 0" );

#0 - iamsahu

2022-02-01T19:31:40Z

Duplicate of #136

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