Skip to content

Oracle price data

Oracles are a common choice to receive price data for assets. The price data from oracles can be harder to manipulate than price data from a DeFi protocol's swap pool, but there are common oracle integration issues that should be kept in mind.

Other resources:

1. Is the spot price of a pool used?

Incorrect

Yes, spot price is used and it can be manipulated by flashloans

Correct

A decentralized oracle (Chainlink, Band, UMA, etc.), Uniswap v3 TWAP or similar

Explanation

Flashloan price manipulation has caused many protocol hacks, making price manipulation hacks one of the most common attack vectors

Links

2. Are variable decimals for different token pair price feeds accounted for?

Incorrect

No, a constant decimals value is hardcoded

Correct

Yes

Explanation

Incorrect decimals can lead to accounting errors

Links

3. If Uniswap v3 TWAP is used for price data, is post-merge PoS manipulation accounted for?

Incorrect

No, TWAP is fully trusted

Correct

Yes

Explanation

Incorrect decimals can lead to accounting errors

Links

Chainlink Oracle

Incorrect

Yes

Correct

No

Explanation

Deprecated functions may not be supported in the future, which could cause a denial of service

Links

2. Is there proper validation of latestRoundData()?

Incorrect

No

Correct

Yes, price is confirmed to be in the range of minAnswer and maxAnswer limits, the timestamp of the latest answer is checked against zero and a stale feed threshold that depends on the update frequency of the oracle for each specific token

Explanation

Insufficient validation of oracle can lead to the acceptance of bad data

Links

3. Is the price query in a try/catch?

Incorrect

No

Correct

Yes, latestRoundData call is in a try/catch block

Explanation

Access to price feed data may be removed due to the multisig ownership of Chainlink's EACAggregatorProxy contract which is queried for price data. If uptime is a key part of a protocol's design and the Chainlink multisig is not considered a trusted entity, a backup mode of operation should exist in the catch block of the try/catch price query to handle the edge case where the primary Chainlink price feed is not available.

Links