From cb98f3cdb58e3d673efbc4276e7c3b80a00fdae8 Mon Sep 17 00:00:00 2001 From: Aditya Arora Date: Mon, 12 Aug 2024 12:45:07 -0400 Subject: [PATCH 1/6] (feat) Add delayed settlement section --- pages/price-feeds/best-practices.mdx | 32 +++++++++++++++++++++------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/pages/price-feeds/best-practices.mdx b/pages/price-feeds/best-practices.mdx index 34e9cf7d..53224ecb 100644 --- a/pages/price-feeds/best-practices.mdx +++ b/pages/price-feeds/best-practices.mdx @@ -20,6 +20,9 @@ The confidence interval is `1500 * 10^(-5) = $0.015`, and the price is `12276250 Sometimes, Pyth will not be able to provide a current price for a product. This situation can happen for various reasons. For example, US equity markets only trade during certain hours, and outside those hours, it's not clear what an equity's price is. +Pyth price feeds follow the [traditional market hours](https://www.cmegroup.com/trading-hours.html) for each asset class. \ +Consult [Market Hours](./market-hours.md) to know the market hours for each asset class. + Alternatively, a network outage (at the internet level, blockchain level, or at multiple data providers) may prevent the protocol from producing new price updates. (Such outages are unlikely, but integrators should still be prepared for the possibility.) In such cases, Pyth may return a stale price for the product. @@ -32,15 +35,15 @@ The SDK provides a sane default for the staleness threshold, but users may confi ## Adversarial selection -Pull updates gives users of Pyth Network some ability to select which price to use in a transaction. +Pull updates give users of Pyth Network some ability to select which price to use in a transaction. This ability is highly circumscribed by various constraints: on-chain prices must move forward in time and cannot be from too far in the past. -However, users can still chose any price update that satisfies these constraints. +However, users can still choose any price update that satisfies these constraints. This ability is functionally equivalent to latency: it allows users to see the price in the future before using a price from the past. -The simplest way to guard against this attack vector is to incorporate a staleness check to ensure that the price used in a transaction is sufficiently recent. -The Pyth Network SDKs include this check by default, where queries for the price will fail if the on-chain time differs from the price's timestamp by more than a threshold amount. -The default threshold is set per-chain, but is typically around 1 minute. -Highly latency-sensitive protocols may wish to reduce this threshold to a few seconds to better suit their needs. +The simplest way to guard against this attack vector is to incorporate a **staleness check** to ensure that the price used in a transaction is sufficiently recent. + +Pyth SDK provides the [`getPriceNoOlderThan()`](https://api-reference.pyth.network/price-feeds/evm/getPriceNoOlderThan) method to help users guard against this attack vector. This method returns the most recent price update that is not older than a specified threshold. +Highly latency-sensitive protocols may wish to reduce the threshold to a few seconds to better suit their needs. Please also see the section below on [latency mitigations](best-practices.md#latency) for additional ideas on how latency-sensitive protocols can minimize the impact of oracle latency. ## Latency @@ -51,7 +54,7 @@ The threat model for integrating protocols should assume that adversaries see pr In this threat model, protocol designers should avoid situations where a Pyth price update must race against an adversary's transaction. Adversaries are highly likely to win these races, as they have a head start, and sophisticated adversaries can additionally optimize their network latencies or pay miners for priority blockspace. -This situation is analogous to market making in traditional finance. +This situation is analogous to market-making in traditional finance. Market makers place resting orders on exchanges with the hope of earning the bid/ask spread. When the “true price” moves, these market makers get picked off by adverse “smart flow” that is faster than they are. The smart flow is balanced by two-way flow, that is, people wanting to trade for other reasons besides a price change. @@ -61,7 +64,7 @@ This analogy suggests two simple solutions to races: 1. Configure protocol parameters to balance the losses from smart flow against the gains from two-way flow. Market makers in traditional finance implement this approach by offering a bid/ask spread and limited liquidity. The limited liquidity caps the losses to smart flow, while still earning profits from the two-way flow. - A successful market maker tunes the spread and offered liquidity to limit adverse selection from smart traders while still interacting with two-way flow. + A successful market maker tunes the spread and offers liquidity to limit adverse selection from smart traders while still interacting with the two-way flow. 2. Give the protocol a "last look" to decide which transactions to accept. In traditional finance, some exchanges give market makers a chance to walk back a trade offer after someone else has requested it. Protocols can implement this technique by splitting transactions into two parts: a request and a fulfillment. @@ -70,6 +73,19 @@ This analogy suggests two simple solutions to races: The protocol can require a short delay between the two transactions, and the user's request gets fulfilled at the Pyth price as of the second transaction. This technique gives the protocol extra time to observe price changes, giving it a head start in the latency race. +### Latency Mitigations for Derivative Protocols + +To mitigate the risk of latency, derivative protocols should consider the following strategies: + +1. **Use a Delayed Settlement**: Derivative protocols can introduce a delay between the time a contract is executed and the time it is settled. This delay gives the protocol time to observe price changes and reject transactions that are based on manipulated prices. + Moreover, As mentioned above the protocol can introduce a short delay (~5 seconds) between the time a user submits the tx to the application and the keeper submits the tx to the blockchain. + The keeper can use Pyth Benchmark to get the price of `t - 5` seconds, where `t` is the current time and `t - 5` is the time when the user submitted the tx to the dApp. + Now the keeper can use [`parsePriceFeedUpdates()`](https://api-reference.pyth.network/price-feeds/evm/parsePriceFeedUpdates) to parse the prices and submit to prevent price frontrunning. + +1. **Use a Confidence Interval**: Pyth provides a confidence interval for each price update. Derivative protocols can use this confidence interval to determine the range in which the true price probably lies. + By using the lower bound of the confidence interval, derivative protocols can protect themselves from price manipulation that drives the price down. By using the upper bound of the confidence interval, derivative protocols can protect themselves from price manipulation that drives the price up. + + ## Confidence Intervals At every point in time, Pyth publishes both a price and a confidence interval for each product. For example, Pyth may publish the current price of bitcoin as \$50000 ± \$10. Pyth publishes a confidence interval because, in real markets, there is _no one single price for a product_. For example, at any given time, bitcoin trades at different prices at different venues around the world. While these prices are typically similar, they can diverge for a number of reasons, such as when a cryptocurrency exchange blocks withdrawals on an asset. If this happens, prices diverge because arbitrageurs can no longer bring prices across exchanges into line. Alternatively, prices on different venues can differ simply because an asset is highly volatile at a particular point in time. At such times, bid/ask spreads tend to be wider, and trades on different markets at around the same time tend to occur at a wider range of prices. From a659fb2d99d1bf82bc66757f68cffdaacfc45c2f Mon Sep 17 00:00:00 2001 From: Aditya Arora Date: Mon, 12 Aug 2024 12:45:41 -0400 Subject: [PATCH 2/6] pre-commit --- pages/price-feeds/best-practices.mdx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pages/price-feeds/best-practices.mdx b/pages/price-feeds/best-practices.mdx index 53224ecb..2ed67cac 100644 --- a/pages/price-feeds/best-practices.mdx +++ b/pages/price-feeds/best-practices.mdx @@ -78,14 +78,13 @@ This analogy suggests two simple solutions to races: To mitigate the risk of latency, derivative protocols should consider the following strategies: 1. **Use a Delayed Settlement**: Derivative protocols can introduce a delay between the time a contract is executed and the time it is settled. This delay gives the protocol time to observe price changes and reject transactions that are based on manipulated prices. - Moreover, As mentioned above the protocol can introduce a short delay (~5 seconds) between the time a user submits the tx to the application and the keeper submits the tx to the blockchain. + Moreover, As mentioned above the protocol can introduce a short delay (~5 seconds) between the time a user submits the tx to the application and the keeper submits the tx to the blockchain. The keeper can use Pyth Benchmark to get the price of `t - 5` seconds, where `t` is the current time and `t - 5` is the time when the user submitted the tx to the dApp. Now the keeper can use [`parsePriceFeedUpdates()`](https://api-reference.pyth.network/price-feeds/evm/parsePriceFeedUpdates) to parse the prices and submit to prevent price frontrunning. -1. **Use a Confidence Interval**: Pyth provides a confidence interval for each price update. Derivative protocols can use this confidence interval to determine the range in which the true price probably lies. +1. **Use a Confidence Interval**: Pyth provides a confidence interval for each price update. Derivative protocols can use this confidence interval to determine the range in which the true price probably lies. By using the lower bound of the confidence interval, derivative protocols can protect themselves from price manipulation that drives the price down. By using the upper bound of the confidence interval, derivative protocols can protect themselves from price manipulation that drives the price up. - ## Confidence Intervals At every point in time, Pyth publishes both a price and a confidence interval for each product. For example, Pyth may publish the current price of bitcoin as \$50000 ± \$10. Pyth publishes a confidence interval because, in real markets, there is _no one single price for a product_. For example, at any given time, bitcoin trades at different prices at different venues around the world. While these prices are typically similar, they can diverge for a number of reasons, such as when a cryptocurrency exchange blocks withdrawals on an asset. If this happens, prices diverge because arbitrageurs can no longer bring prices across exchanges into line. Alternatively, prices on different venues can differ simply because an asset is highly volatile at a particular point in time. At such times, bid/ask spreads tend to be wider, and trades on different markets at around the same time tend to occur at a wider range of prices. From 796cf65e51393f85f240d1b82bcdc153abe510dd Mon Sep 17 00:00:00 2001 From: Aditya Arora Date: Mon, 12 Aug 2024 14:12:50 -0400 Subject: [PATCH 3/6] requested changes --- pages/price-feeds/best-practices.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pages/price-feeds/best-practices.mdx b/pages/price-feeds/best-practices.mdx index 2ed67cac..7a144850 100644 --- a/pages/price-feeds/best-practices.mdx +++ b/pages/price-feeds/best-practices.mdx @@ -75,9 +75,9 @@ This analogy suggests two simple solutions to races: ### Latency Mitigations for Derivative Protocols -To mitigate the risk of latency, derivative protocols should consider the following strategies: +Derivative protocols are encouraged to consider the following strategies to mitigate the impact of oracle latency: -1. **Use a Delayed Settlement**: Derivative protocols can introduce a delay between the time a contract is executed and the time it is settled. This delay gives the protocol time to observe price changes and reject transactions that are based on manipulated prices. +1. **Use a Delayed Settlement**: Derivative protocols can introduce a delay between the time a ordere is created and the time it is executed. This delay gives the protocol time to observe price changes and reject trades/transactions that profit over latency. Moreover, As mentioned above the protocol can introduce a short delay (~5 seconds) between the time a user submits the tx to the application and the keeper submits the tx to the blockchain. The keeper can use Pyth Benchmark to get the price of `t - 5` seconds, where `t` is the current time and `t - 5` is the time when the user submitted the tx to the dApp. Now the keeper can use [`parsePriceFeedUpdates()`](https://api-reference.pyth.network/price-feeds/evm/parsePriceFeedUpdates) to parse the prices and submit to prevent price frontrunning. From 5ff371bc86aa11337a1c3b4a670e5779e480c61f Mon Sep 17 00:00:00 2001 From: Aditya Arora Date: Tue, 13 Aug 2024 14:49:29 -0400 Subject: [PATCH 4/6] requeste changes --- pages/price-feeds/best-practices.mdx | 32 ++++++---------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/pages/price-feeds/best-practices.mdx b/pages/price-feeds/best-practices.mdx index 7a144850..337852e7 100644 --- a/pages/price-feeds/best-practices.mdx +++ b/pages/price-feeds/best-practices.mdx @@ -20,7 +20,7 @@ The confidence interval is `1500 * 10^(-5) = $0.015`, and the price is `12276250 Sometimes, Pyth will not be able to provide a current price for a product. This situation can happen for various reasons. For example, US equity markets only trade during certain hours, and outside those hours, it's not clear what an equity's price is. -Pyth price feeds follow the [traditional market hours](https://www.cmegroup.com/trading-hours.html) for each asset class. \ +Pyth price feeds follow the traditional market hours for each asset class. \ Consult [Market Hours](./market-hours.md) to know the market hours for each asset class. Alternatively, a network outage (at the internet level, blockchain level, or at multiple data providers) may prevent the protocol from producing new price updates. @@ -42,7 +42,7 @@ This ability is functionally equivalent to latency: it allows users to see the p The simplest way to guard against this attack vector is to incorporate a **staleness check** to ensure that the price used in a transaction is sufficiently recent. -Pyth SDK provides the [`getPriceNoOlderThan()`](https://api-reference.pyth.network/price-feeds/evm/getPriceNoOlderThan) method to help users guard against this attack vector. This method returns the most recent price update that is not older than a specified threshold. +The Pyth SDK provides the [`getPriceNoOlderThan()`](https://api-reference.pyth.network/price-feeds/evm/getPriceNoOlderThan) method to help users guard against this attack vector. This method returns the most recent price update that is not older than a specified threshold. Highly latency-sensitive protocols may wish to reduce the threshold to a few seconds to better suit their needs. Please also see the section below on [latency mitigations](best-practices.md#latency) for additional ideas on how latency-sensitive protocols can minimize the impact of oracle latency. @@ -54,35 +54,15 @@ The threat model for integrating protocols should assume that adversaries see pr In this threat model, protocol designers should avoid situations where a Pyth price update must race against an adversary's transaction. Adversaries are highly likely to win these races, as they have a head start, and sophisticated adversaries can additionally optimize their network latencies or pay miners for priority blockspace. -This situation is analogous to market-making in traditional finance. -Market makers place resting orders on exchanges with the hope of earning the bid/ask spread. -When the “true price” moves, these market makers get picked off by adverse “smart flow” that is faster than they are. -The smart flow is balanced by two-way flow, that is, people wanting to trade for other reasons besides a price change. - -This analogy suggests two simple solutions to races: - -1. Configure protocol parameters to balance the losses from smart flow against the gains from two-way flow. - Market makers in traditional finance implement this approach by offering a bid/ask spread and limited liquidity. - The limited liquidity caps the losses to smart flow, while still earning profits from the two-way flow. - A successful market maker tunes the spread and offers liquidity to limit adverse selection from smart traders while still interacting with the two-way flow. -2. Give the protocol a "last look" to decide which transactions to accept. - In traditional finance, some exchanges give market makers a chance to walk back a trade offer after someone else has requested it. - Protocols can implement this technique by splitting transactions into two parts: a request and a fulfillment. - In the first transaction, the user requests to perform an action. - In the second transaction, the protocol chooses whether or not to fulfill the user's request; this step can be implemented as a permissionless operation. - The protocol can require a short delay between the two transactions, and the user's request gets fulfilled at the Pyth price as of the second transaction. - This technique gives the protocol extra time to observe price changes, giving it a head start in the latency race. - ### Latency Mitigations for Derivative Protocols Derivative protocols are encouraged to consider the following strategies to mitigate the impact of oracle latency: -1. **Use a Delayed Settlement**: Derivative protocols can introduce a delay between the time a ordere is created and the time it is executed. This delay gives the protocol time to observe price changes and reject trades/transactions that profit over latency. - Moreover, As mentioned above the protocol can introduce a short delay (~5 seconds) between the time a user submits the tx to the application and the keeper submits the tx to the blockchain. - The keeper can use Pyth Benchmark to get the price of `t - 5` seconds, where `t` is the current time and `t - 5` is the time when the user submitted the tx to the dApp. - Now the keeper can use [`parsePriceFeedUpdates()`](https://api-reference.pyth.network/price-feeds/evm/parsePriceFeedUpdates) to parse the prices and submit to prevent price frontrunning. +1. **Use Delayed Settlement**: Derivative protocols can introduce a delay between the time an order is created and the time it is executed. This delay gives the protocol time to observe price changes and reject trades/transactions that profit over latency. + Suppose a user submits a trade transaction at a time `t`. The protocol should execute the trade by using the price at the time `t`, which will be available to the protocol after a short delay. + The protocol can fetch this price from [Pyth Benchmark service](https://benchmarks.pyth.network/docs#/Updates/price_updates_timestamp_route_v1_updates_price__timestamp__get) and then can use [`parsePriceFeedUpdates()`](https://api-reference.pyth.network/price-feeds/evm/parsePriceFeedUpdates) to parse the prices and submit to prevent price frontrunning. -1. **Use a Confidence Interval**: Pyth provides a confidence interval for each price update. Derivative protocols can use this confidence interval to determine the range in which the true price probably lies. +1. **Use a Spread**: Pyth provides a confidence interval for each price update. Derivative protocols can use this confidence interval to determine the range in which the true price probably lies. By using the lower bound of the confidence interval, derivative protocols can protect themselves from price manipulation that drives the price down. By using the upper bound of the confidence interval, derivative protocols can protect themselves from price manipulation that drives the price up. ## Confidence Intervals From 94f04ee2fbdfa53772c421fcc2217a503236d167 Mon Sep 17 00:00:00 2001 From: Aditya Arora Date: Mon, 19 Aug 2024 17:22:58 -0400 Subject: [PATCH 5/6] replaced benchmarks with hermes --- pages/price-feeds/best-practices.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/price-feeds/best-practices.mdx b/pages/price-feeds/best-practices.mdx index 337852e7..b3e79d27 100644 --- a/pages/price-feeds/best-practices.mdx +++ b/pages/price-feeds/best-practices.mdx @@ -60,7 +60,7 @@ Derivative protocols are encouraged to consider the following strategies to miti 1. **Use Delayed Settlement**: Derivative protocols can introduce a delay between the time an order is created and the time it is executed. This delay gives the protocol time to observe price changes and reject trades/transactions that profit over latency. Suppose a user submits a trade transaction at a time `t`. The protocol should execute the trade by using the price at the time `t`, which will be available to the protocol after a short delay. - The protocol can fetch this price from [Pyth Benchmark service](https://benchmarks.pyth.network/docs#/Updates/price_updates_timestamp_route_v1_updates_price__timestamp__get) and then can use [`parsePriceFeedUpdates()`](https://api-reference.pyth.network/price-feeds/evm/parsePriceFeedUpdates) to parse the prices and submit to prevent price frontrunning. + The protocol can fetch this price update of a specific timestamp from [Hermes](https://hermes.pyth.network/docs/#/rest/timestamp_price_updates) and can use [`parsePriceFeedUpdates()`](https://api-reference.pyth.network/price-feeds/evm/parsePriceFeedUpdates) to parse the prices and submit to prevent price frontrunning. 1. **Use a Spread**: Pyth provides a confidence interval for each price update. Derivative protocols can use this confidence interval to determine the range in which the true price probably lies. By using the lower bound of the confidence interval, derivative protocols can protect themselves from price manipulation that drives the price down. By using the upper bound of the confidence interval, derivative protocols can protect themselves from price manipulation that drives the price up. From d8ca83b132eec999b239890831b819e1fa518c51 Mon Sep 17 00:00:00 2001 From: Aditya Arora Date: Mon, 26 Aug 2024 11:17:47 -0400 Subject: [PATCH 6/6] added footer --- pages/price-feeds/best-practices.mdx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pages/price-feeds/best-practices.mdx b/pages/price-feeds/best-practices.mdx index b3e79d27..deba8d4a 100644 --- a/pages/price-feeds/best-practices.mdx +++ b/pages/price-feeds/best-practices.mdx @@ -54,7 +54,7 @@ The threat model for integrating protocols should assume that adversaries see pr In this threat model, protocol designers should avoid situations where a Pyth price update must race against an adversary's transaction. Adversaries are highly likely to win these races, as they have a head start, and sophisticated adversaries can additionally optimize their network latencies or pay miners for priority blockspace. -### Latency Mitigations for Derivative Protocols +### Latency Mitigations for Derivative Protocols[^1] Derivative protocols are encouraged to consider the following strategies to mitigate the impact of oracle latency: @@ -65,6 +65,10 @@ Derivative protocols are encouraged to consider the following strategies to miti 1. **Use a Spread**: Pyth provides a confidence interval for each price update. Derivative protocols can use this confidence interval to determine the range in which the true price probably lies. By using the lower bound of the confidence interval, derivative protocols can protect themselves from price manipulation that drives the price down. By using the upper bound of the confidence interval, derivative protocols can protect themselves from price manipulation that drives the price up. +1. **Enforce Position Holding**: Derivative protocols can enforce hold times on positions to prevent users from exploiting oracle latency. + For example, a protocol could require users to hold an asset or a position for a certain period before they can trade or close it. + This hold time gives the protocol time to observe price changes and reject trades that profit over latency. + ## Confidence Intervals At every point in time, Pyth publishes both a price and a confidence interval for each product. For example, Pyth may publish the current price of bitcoin as \$50000 ± \$10. Pyth publishes a confidence interval because, in real markets, there is _no one single price for a product_. For example, at any given time, bitcoin trades at different prices at different venues around the world. While these prices are typically similar, they can diverge for a number of reasons, such as when a cryptocurrency exchange blocks withdrawals on an asset. If this happens, prices diverge because arbitrageurs can no longer bring prices across exchanges into line. Alternatively, prices on different venues can differ simply because an asset is highly volatile at a particular point in time. At such times, bid/ask spreads tend to be wider, and trades on different markets at around the same time tend to occur at a wider range of prices. @@ -87,3 +91,9 @@ The same principle would apply if you wrote a derivative contract. If someone wa 1. Using Pyth's exponential moving average price, which represents estimates of the average price of the asset over a specified time period (e.g., over the past 1 hour). The exponential moving average price is computed such that it lessens the influence of prices with wide confidence intervals. You may find more details in [EMA Price Aggregation](./how-pyth-works/ema-price-aggregation.md). 2. Using the aggregate price, which is Pyth's best estimate of the price at a single point in time. The quality of this estimate depends on the width of the confidence interval at settlement time and on occasion, it may be imprecise. However, it is the best you can do with Pyth data if you need a single price at that exact point in time. 3. Defining the contract to depend on confidence. For example, you could create an option that refunds the option premium to the buyer (so both sides of the transaction are even) if the strike price is within the confidence interval at settlement time. You could also create a contract that delayed settlement until the confidence interval was sufficiently small. If you choose this second option, you should ensure that your contract is guaranteed to eventually settle even if the confidence interval never narrows. + +## + +[^1]: + _The strategies and methodologies outlined in this page, including those addressing price latency mitigation, are provided solely for informational purposes and might not fully eliminate the discussed problems. Do your own research before using them. \ + Refer to [Terms of Use](https://www.pyth.network/terms-of-use) for more information._