Full Report
Price oracles are providing the price of a specific asset; this can either be on-chain or off-chain data powering this. AMMs, loan providers and more use this to provide proper prices. Integrating with price oracles properly is incredibly important for the security of the protocol. The author posts some code and has a bunch of questions about the oracle. A few of these are listed below: What if the price is zero or very large? What about the unit (decimals) of the price? Or what if the price is inverted. How is the oracle updated? How often? delays? Can it be shut down? The goal is to build robust oracles that handle anything that comes to it. From large price swings to broke oracles. The first, and most popular, price feed is Chainlink. This is queried through the AggregatorProxy, which interacts with the trading price contract directly. Within this, the latestRoundData() is called. It is reccomended that this is wrapped in a try/catch block that then has a fallback oracle in case of failure. On top of this, the decimals and ordering of assets should be considered when programming with this. Uniswap Time Weighted Average Prices. Simply querying from Uniswap pools is dangerous, due to the ability to manipulate the pool beforehand. As a result, by using a time weighted average, the price cannot be manipulated as easily. UniswapV2 has an oracle library for doing this for you. When using this there is a trade off length. Although it's more protected against price manipulation, large jumps or drops in price would be less accurate. Another consideration is that TWAP of A in B is not the reciprocal of TWAP of B in A. For Uniswap v3, the TWAP is built into the pool themselves instead of having developers keep track of this information themselves. When using this, tick information is returned; not the price. The price needs to be calculated from the tick. The Open Price Feed is used by many protocols but is operated by Compound. UniswapAnchoredView contract manages the price for multiple assets. This has two price feeds: a trusted source (chainlink) and an anchor price (uniswap). If the posted price deviates too much from the anchor price, then the program will revert. The final mentioned price feed is the maker oracles. These oracles have privileged accounts called relayers that aggregate data off-chain in a p2p network. The price data being added calculates the median price from various observations to get a price. Overall, an interesting article on oracles in the DeFi space as well as their trade offs. I enjoyed the article, even though it is over 2 years old now.
Analysis Summary
# Best Practices: Secure Price Oracle Integration
## Overview
Price oracles serve as the bridge between off-chain asset values and on-chain smart contracts. Improper integration can lead to catastrophic DeFi failures, including drained liquidity pools and mass liquidations. These practices focus on defensive programming to handle oracle failures, price manipulation, and data inaccuracies.
## Key Recommendations
### Immediate Actions
1. **Implement Fallbacks:** Wrap oracle calls (e.g., Chainlink’s `latestRoundData()`) in `try/catch` blocks. If the primary oracle fails, the contract must switch to a secondary fallback oracle or revert to prevent execution with stale/zero prices.
2. **Sanitize Output:** Validate that the returned price is greater than zero and within "sane" bounds.
3. **Verify Decimals:** Explicitly check and normalize the decimals of the price feed to ensure they match your contract’s internal accounting (e.g., converting 8-decimal USD feeds to 18-decimal WEI).
### Short-term Improvements (1-3 months)
1. **Avoid Spot Prices:** Cease using Uniswap v2/v3 spot prices directly, as they are susceptible to flash loan manipulation.
2. **Integrate TWAPs:** Implement Time-Weighted Average Prices (TWAP) for DEX-based oracles to increase the cost of manipulation, acknowledging the trade-off in price freshness.
3. **Add Integrity Checks:** For Uniswap v3, ensure logic correctly converts "ticks" into prices. For Compound’s Open Price Feed, implement the "Anchored View" which validates a primary source against a secondary anchor.
### Long-term Strategy (3+ months)
1. **Multi-Oracle Aggregation:** Move toward a medianized architecture (similar to Maker Oracles) where multiple independent data sources are aggregated to eliminate single points of failure.
2. **Circuit Breakers:** Implement administrative or automated "kill-switches" to pause the protocol if the oracle deviates significantly from a known baseline or stops updating.
3. **Active Monitoring:** Deploy off-chain bots to monitor oracle "heartbeats" and update delays, alerting the team before a stale price causes a protocol-wide issue.
## Implementation Guidance
### For Small Organizations
- Focus on established providers like **Chainlink**.
- Use simple `try/catch` logic.
- Avoid building custom oracles; rely on battle-tested community libraries.
### For Medium Organizations
- Implement the **Uniswap Anchored View** model.
- Use a trusted source (Chainlink) as the primary and a TWAP (Uniswap v3) as the anchor.
- Revert transactions if the deviation between the two exceeds a predefined threshold (e.g., 10%).
### For Large Enterprises
- Establish a **P2P Relayer Network** for medianized data (Maker style).
- Maintain an internal security team specifically for monitoring oracle health and upgrading aggregator logic.
- Perform formal verification on oracle-related math logic.
## Configuration Examples
### Defensive Chainlink Query
solidity
try IPriceFeed(oracle).latestRoundData() returns (
uint80 roundId, int256 price, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound
) {
require(price > 0, "Invalid price");
require(updatedAt != 0, "Incomplete round");
require(block.timestamp - updatedAt < MAX_STALENESS_THRESHOLD, "Stale price");
return uint256(price);
} catch {
// Logic for fallback oracle
}
## Compliance Alignment
- **NIST Cybersecurity Framework:** Relates to *Detection* and *Protection* of data integrity.
- **ISO/IEC 27001:** Addresses Asset Management and Information Security.
- **SCSVS (Smart Contract Security Verification Standard):** Aligns with Price Oracle security requirements.
## Common Pitfalls to Avoid
- **Reciprocal Trap:** Assuming the TWAP of Token A in Token B is simply the math mathematical reciprocal (1/x) of Token B in Token A. Always query the specific pair direction needed.
- **Unchecked Governance:** Allowing a single `owner` to change the oracle address without a timelock, creating a rug-pull vector.
- **Missing Events:** Failing to emit an event when an oracle is changed or when a fallback is triggered, making off-chain monitoring impossible.
- **Ignoring Staleness:** Using a price without checking the `updatedAt` timestamp, which can lead to using prices from hours or days ago.
## Resources
- **Chainlink Documentation:** [docs.chain.link]
- **Uniswap Oracle Library:** [github.com/Uniswap/v2-periphery]
- **OpenZeppelin Security Research:** [openzeppelin.com/research]
- **Oracle Manipulation Guide:** [samczsun.com/so-you-want-to-use-a-price-oracle]