# Oracle price tick

StarkEx for perpetual trading uses external oracle price feeds in order to take the most recent prices into account in the business logic.

The process is as follows:

1. The application gets price updates signed by the price oracles.

2. The application aggregates the signed prices and sends them to StarkEx as an oracle price tick request.

3. StarkEx checks the validity of the request and includes the new prices in a batch.

 For information about who is authorized to sign a new price and the required number of signatures, see On-chain configuration.

## 1. The application collects signatures on a price

Oracle providers that are registered in the system sign on a price update of a synthetic asset. This update is represented by the tuple `(price, time, name)`, where `price` represents the new price, `time` is the timestamp of the update and `name` is a unique identifier of the type of asset and the oracle identity. For information on how to generate price feeds, see Becoming an oracle provider.

The application aggregates these signatures and sends an oracle price tick transaction to the StarkEx gateway that includes the following:

• The new value for `system_time`.

• A list of asset ids for which the price is updated.

• For each asset id in the list, it sends `(price, time, name, sig)` and `current_price`, with the resolution for synthetic assets applied . StarkEx uses the value for `current_price` for subsequent transactions. The current price is the internal price in the system.

## 2. Prices are included in the batch and StarkEx verifies the batch

StarkEx does not explicitly prove the validity of all Oracle signatures in all the oracle price ticks, since it is not efficient. Instead, it uses a hybrid approach. StarkEx includes in the batch header, for each `assetId`, the entire quorum of signatures that attests to the minimal and maximal prices in a batch. For the rest of the prices, StarkEx only proves that they are between the minimal and maximal price.

 Since the application can already play with the order of transaction and/or mix and match different signatures from different legitimate oracle sources to create a variety of possible medians, this optimization doesn’t reduce the security of the system.

We proceed to describe two phases of batch verification. The first phase is performed on the full batch and the second phase is performed per an oracle price tick transaction.

• The price is the median of the list (price_1,\ldots, price_n)

• n \geq \text{config\[assetId].quorum}

• For each tuple i \in \{1,...,n\}

• sig_iis a valid signature with a unique public key pk_ifrom the list `config[assetId].keys` , on the tuple (price_i,time_i, name_i)

• name_iappears in the list `config[assetId].names`

• Each value in the list (time_1,\ldots, time_n) is in a `price_validity_period`-hours window. Furthermore, \min(time_1,\ldots, time_n)is at least `batch_starting_time - price_validity_period` and \max (time_1,\ldots, time_n)is at most `batch_end_time`.

### Phase 1: StarkEx verifies the batch’s minimal and maximal price

For each `assetId` (including assets that didn’t receive an update in this batch), StarkEx verifies the `minimal_price` and `maximal_price`. This is done by verifying the following conditions for the oracle price tick that attests to each of them. Bear in mind that an oracle price tick contains a list of n tuples (price_i,time_i, name_i, sig_i).

• The price is the median of the list (price_1,\ldots, price_n)

• n \geq \text{config\[assetId].quorum}

• For each tuple i \in \{1,...,n\}

• sig_iis a valid signature with a unique public key pk_ifrom the list `config[assetId].keys` , on the tuple (price_i,time_i, name_i)

• name_iappears in the list `config[assetId].names`

• Each value in the list (time_1,\ldots, time_n) is in a 24-hours window. Furthermore, \min(time_1,\ldots, time_n)is at least one day less than `batch_starting_time` and \max (time_1,\ldots, time_n)is at most `batch_end_time`.

### Phase 2: StarkEx verifies the validity of each oracle price tick separately

For each oracle price tick in the batch, StarkEx verifies the following conditions:

• The new system time is greater than or equal to the previous system time.

• For every `assetId:`

• The current price is greater than or equal to the lowest price of this batch.

• The current price is less than or equal to the highest price of this batch.

## Implementing an oracle price tick in your application

To send a funding tick from your application, use the `add_transaction` API method with the `OraclePricesTick` transaction type.