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 token0

  • price1CumulativeLast — cumulative price of token0 in terms of token1

  • blockTimestampLast — 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:

  • price0CumulativeLast and price1CumulativeLast are uint256, but will overflow after a long time.

  • blockTimestampLast is stored as uint32, 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