Oracle

iZiSwap, as a DEX, has the ability to provide price feeds externally. While the pools have real-time prices, real-time prices are susceptible to manipulation. Therefore, iZiSwap provides TWA (Time-Weighted Average) prices to external sources.

In this example, we will show how to query a recent TWA price point of a swap pool, in Solidity code.

Expand Observation Queue

If we want to query a TWA price point of a swap pool, we should guarantee that the observation queue has enough capacity.

One can call the pool.state(…) interface of a swap pool to get the current capacity (slots) of the queue. Each slot records the latest trading price, and it is updated only once per block.

 1interface IiZiSwapPool {
 2    function state()
 3        external view
 4        returns(
 5            uint160 sqrtPrice_96,
 6            int24 currentPoint,
 7            uint16 observationCurrentIndex,
 8            uint16 observationQueueLen,
 9            uint16 observationNextQueueLen,
10            bool locked,
11            uint128 liquidity,
12            uint128 liquidityX
13        );
14}

The returned value observationNextQueueLen is the current capacity of of the pool.

To expand the capacity of observation queue on a pool, just call following interface of swap pool.

1interface IiZiSwapPool {
2    function expandObservationQueue(uint16 newNextQueueLen) external;
3}

Here newNextQueueLen is the new capacity you want to expand to.

Query TWA Price Point

One can easily query recent TWA point from deployed oracle contract by calling the following interface.

1interface IOracle {
2    function getTWAPoint(address pool, uint256 delta)
3        external
4        view
5        returns (bool enough, int24 avgPoint, uint256 oldestTime);
6}

where the interface getTWAPoint has following params

1pool: address, swap pool address you want to query
2
3delta: uint256, seconds of time period. This interface calculates TWA point from delta ago to now, i.e., the time period is [block.Timestamp - delta, block.Timestamp]

The interface will return following values.

1enough: bool, whether oldest point in the observation queue is older than (currentTime - delta)
2
3avgPoint: int24, TWA point within [block.Timestamp - delta, block.Timestamp]
4
5oldestTime: the oldest time of point in the observation queue.

We also provide a simple example to call oracle’s interface in solidity.

 1pragma solidity ^0.8.4;
 2
 3interface IOracle {
 4    function getTWAPoint(address pool, uint256 delta)
 5        external
 6        view
 7        returns (bool enough, int24 avgPoint, uint256 oldestTime);
 8}
 9
10contract TestOracle {
11
12    address public oracleAddress;
13
14    constructor(address _oracleAddress) {
15        oracleAddress = _oracleAddress;
16    }
17
18    function testOracle(address pool, uint256 delta)
19        external
20        view
21        returns (bool enough, int24 avgPoint, uint256 oldestTime)
22    {
23        // call getTWAPoint interface
24        (enough, avgPoint, oldestTime) = IOracle(oracleAddress).getTWAPoint(pool, delta);
25    }
26}

The code above can also be spotted here.