Oracle
📈 Building a Price Oracle on Zealous Swap
Zealous Swap pairs track cumulative price data over time, making it possible to build efficient, on-chain time-weighted average price (TWAP) oracles. This page explains how to create and maintain your own oracle using the cumulative price mechanism built into each pair contract.
🎯 Determine Your Oracle Requirements
Before implementing an oracle, ask the following:
Do you need fresh data? If yes, your oracle must include the most recent block’s cumulative price.
Should recent prices have more weight than older ones? If yes, you may want a moving average (e.g., exponential or sliding window).
🧠 Oracle Design Strategies
🪵 Fixed Window Oracle
If you're fine with delayed updates and want equal weighting across time, a fixed window approach works well:
Store cumulative price once per fixed period (e.g. once every 24 hours).
Compute average price over the window by comparing two saved observations.
Simple and efficient for use cases like dashboards or low-frequency strategies.
🔁 Moving Average Oracle
If you need more up-to-date data, use a sliding window:
Take frequent cumulative price snapshots.
Compute averages over the desired lookback window.
Two popular types:
Simple Moving Average (SMA) — Equal weight to each observation.
Exponential Moving Average (EMA) — More weight to recent data (harder to implement securely, more sensitive to manipulation).
🧮 How to Compute Average Price
Each pair stores:
price0CumulativeLast— cumulative price of token1 in terms of token0price1CumulativeLast— cumulative price of token0 in terms of token1blockTimestampLast— timestamp of the last update
To compute the average price:
averagePrice = (priceCumulativeEnd - priceCumulativeStart) / (timestampEnd - timestampStart);This gives a Q112.112 fixed point value — the upper 112 bits represent the integer part, and the lower 112 bits the fraction.
🕓 Getting the Current Cumulative Price
Sometimes a swap hasn’t occurred recently, and the latest cumulative price isn't updated. Instead of calling sync() (which is costly), you can compute the counterfactual cumulative price using the current reserves and elapsed time.
You can write a small utility or library in your contract to do this, or call a helper function like:
function currentCumulativePrices(address pair) public view returns (
uint price0Cumulative,
uint price1Cumulative,
uint32 blockTimestamp
)This simulates the current cumulative price as if an update occurred, using getReserves() and the last recorded timestamp.
⚠️ Overflow Considerations
The cumulative price and timestamp values will eventually overflow:
price0CumulativeLastandprice1CumulativeLastareuint256, but will overflow after a long time.blockTimestampLastis stored asuint32, and wraps every ~136 years.
This is fine. All that matters is the difference between two observations, which always fits within range if your time windows are reasonably short.
🔌 Integrating the Oracle
To use your oracle in production:
Store regular observations of cumulative price and timestamp.
Ensure your oracle contract has at least two valid observations for any lookup.
Compute TWAP from the difference between start and end observations.
uint avgPrice = (price1CumulativeNow - price1CumulativeThen) / (timestampNow - timestampThen);🛠 Oracle Maintenance
Maintaining oracle data means regularly recording snapshots. This can be done:
In a scheduled job (e.g., bot or cron task)
In user-triggered transactions (e.g., hooks inside your app logic)
By incentivizing third parties to call an update function
Regular updates keep the oracle accurate and reliable.
💤 No-Maintenance Option (Advanced)
It’s possible to avoid storing snapshots altogether by verifying cumulative price data from the blockchain directly using Merkle proofs (i.e., storage proofs). However, this is complex, more gas-intensive, and limited by block range constraints.
In most cases, it's simpler and safer to store the necessary data periodically within your oracle contract.
✅ Summary
Use Zealous Swap’s built-in cumulative prices to calculate average prices.
Choose a fixed or moving window based on your use case.
Compute TWAP using two observations.
Store and maintain observations regularly to keep your oracle accurate.
Last updated