(uint80 eurRoundID, int256 eurAnswer, , uint256 eurUpdatedAt, uint80 eurAnsweredInRound) = _eurOracle.latestRoundData(); //@audit The eurUpdatedAt data feed property is the timestamp of an answered round and eurAnsweredInRound is the round it was updated in
require(eurUpdatedAt > 0, "EUR price data is stale"); //@audit A timestamp with zero value means the round is not complete and should not be used.
require(eurAnswer > 0, "EUR price data not valid");
require(eurAnsweredInRound >= eurRoundID, "EUR price data is stale"); //@audit If eurAnsweredInRound is less than eurRoundID, the eurAnswer is being carried over. If eurAnsweredInRound is equal to eurRoundID, then the eurAnswer is fresh.
Lines of code
https://github.com/code-423n4/2022-04-mimo/blob/b18670f44d595483df2c0f76d1c57a7bfbfbc083/core/contracts/inception/priceFeed/ChainlinkInceptionPriceFeed.sol#L74-L80 https://github.com/code-423n4/2022-04-mimo/blob/b18670f44d595483df2c0f76d1c57a7bfbfbc083/core/contracts/oracles/BalancerV2LPOracle.sol#L101-L102 https://github.com/code-423n4/2022-04-mimo/blob/b18670f44d595483df2c0f76d1c57a7bfbfbc083/core/contracts/oracles/GUniLPOracle.sol#L103-L104
Vulnerability details
Impact
Here,
latestRoundData()
is missing an additional validation to ensure that the round is complete.Proof of Concept
Affected code:
Tools Used
Manual code review. Chainlink best practices.
Recommended Mitigation Steps
Consider adding missing checks.
As an example: