Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Fixed some price pusher edge cases #179

Merged
merged 6 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pragma-oracle
Submodule pragma-oracle updated 38 files
+4 −7 .env.example
+1 −1 .github/workflows/gas_snapshot.yml
+38 −42 .github/workflows/run_scripts.yml
+1 −0 .github/workflows/spell_check.yml
+1 −0 .gitignore
+5 −5 README.md
+0 −1 Scarb.toml
+0 −0 deployments/devnet/declarations.json
+22 −0 deployments/devnet/deployments.json
+0 −22 deployments/katana/deployments.json
+0 −2,642 poetry.lock
+2,184 −0 pragma-deployer/poetry.lock
+99 −0 pragma-deployer/pragma_deployer/add_pairs.py
+97 −0 pragma-deployer/pragma_deployer/deploy_pragma.py
+94 −0 pragma-deployer/pragma_deployer/deploy_randomness.py
+78 −0 pragma-deployer/pragma_deployer/deploy_summary_stats.py
+5 −3 pragma-deployer/pragma_deployer/gas_usage/compare_snapshot.py
+2 −2 pragma-deployer/pragma_deployer/gas_usage/gen_snapshot.py
+66 −61 pragma-deployer/pragma_deployer/register_publishers.py
+72 −0 pragma-deployer/pragma_deployer/remove_publishers.py
+94 −0 pragma-deployer/pragma_deployer/remove_source.py
+89 −0 pragma-deployer/pragma_deployer/test_randomness.py
+85 −0 pragma-deployer/pragma_deployer/upgrade_pragma.py
+38 −42 pragma-deployer/pragma_deployer/utils/constants.py
+0 −0 pragma-deployer/pragma_deployer/utils/erc20.json
+18 −17 pragma-deployer/pragma_deployer/utils/starknet.py
+96 −0 pragma-deployer/pyproject.toml
+23 −0 pragma-deployer/scripts/devnet.sh
+0 −38 pyproject.toml
+0 −86 scripts/add_pairs.py
+0 −87 scripts/deploy_pragma.py
+0 −80 scripts/deploy_randomness.py
+0 −60 scripts/deploy_summary_stats.py
+0 −25 scripts/katana.sh
+0 −62 scripts/remove_publishers.py
+0 −74 scripts/remove_source.py
+0 −70 scripts/test_randomness.py
+0 −67 scripts/upgrade_pragma.py
3 changes: 2 additions & 1 deletion pragma-sdk/pragma_sdk/common/fetchers/fetchers/bitstamp.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import time
from typing import Any, List

from aiohttp import ClientSession
Expand Down Expand Up @@ -39,7 +40,7 @@ def format_url(self, pair: Pair) -> str:
return url

def _construct(self, pair: Pair, result: Any) -> SpotEntry:
timestamp = int(result["timestamp"])
timestamp = int(time.time())
price = float(result["last"])
price_int = int(price * (10 ** pair.decimals()))

Expand Down
3 changes: 2 additions & 1 deletion pragma-sdk/pragma_sdk/common/fetchers/fetchers/defillama.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import time
from typing import Any, List, Optional

from aiohttp import ClientSession
Expand Down Expand Up @@ -89,7 +90,7 @@ def _construct(
self, pair: Pair, result: Any, hop_result: Optional[Any] = None
) -> SpotEntry:
base_id = AssetConfig.get_coingecko_id_from_ticker(pair.base_currency.id)
timestamp = int(result["coins"][f"coingecko:{base_id}"]["timestamp"])
timestamp = int(time.time())
decimals = pair.decimals()
if hop_result is not None:
quote_id = AssetConfig.get_coingecko_id_from_ticker(pair.quote_currency.id)
Expand Down
3 changes: 2 additions & 1 deletion pragma-sdk/pragma_sdk/common/fetchers/fetchers/huobi.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import time
from typing import List, Optional, Any

from aiohttp import ClientSession
Expand Down Expand Up @@ -104,7 +105,7 @@ def _construct(
hop_ask = float(hop_result["tick"]["ask"][0])
hop_price = (hop_bid + hop_ask) / 2
price = hop_price / price
timestamp = int(result["ts"] / 1000)
timestamp = int(time.time())
price_int = int(price * (10 ** pair.decimals()))
volume = float(result["tick"]["vol"]) if hop_result is None else 0
logger.debug("Fetched price %d for %s from Huobi", price_int, pair)
Expand Down
4 changes: 3 additions & 1 deletion pragma-sdk/pragma_sdk/common/fetchers/fetchers/kucoin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import asyncio
import time

from typing import List, Optional, Any

from aiohttp import ClientSession
Expand Down Expand Up @@ -98,7 +100,7 @@ def _construct(
if hop_result is not None:
hop_price = float(hop_result["data"]["price"])
price = hop_price / price
timestamp = int(result["data"]["time"] / 1000)
timestamp = int(time.time())
price_int = int(price * (10 ** pair.decimals()))
logger.debug("Fetched price %d for %s from Kucoin", price_int, pair)

Expand Down
3 changes: 2 additions & 1 deletion pragma-sdk/pragma_sdk/common/fetchers/fetchers/okx.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import time
import json
from typing import Any, List

Expand Down Expand Up @@ -67,7 +68,7 @@ def format_url(self, pair: Pair) -> str:
def _construct(self, pair: Pair, result: Any, usdt_price: float = 1) -> SpotEntry:
data = result["data"][0]

timestamp = int(int(data["ts"]) / 1000)
timestamp = int(time.time())
price = float(data["last"]) / usdt_price
price_int = int(price * (10 ** pair.decimals()))
volume = float(data["volCcy24h"])
Expand Down
5 changes: 2 additions & 3 deletions pragma-sdk/pragma_sdk/common/fetchers/fetchers/starknetamm.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,8 @@ async def fetch_pair(
def format_url(self, pair: Pair, timestamp: Optional[int] = None) -> str:
new_pair = self.hop_handler.get_hop_pair(pair) or pair
if timestamp:
return f"{self.EKUBO_PUBLIC_API}/price/{pair.base_currency.id}/{new_pair}?atTime={timestamp}&period=3600"

return f"{self.EKUBO_PUBLIC_API}/price/{pair.base_currency.id}/{new_pair}?period=3600"
return f"{self.EKUBO_PUBLIC_API}/price/{new_pair}?atTime={timestamp}&period=3600"
return f"{self.EKUBO_PUBLIC_API}/price/{new_pair}?period=3600"

async def fetch(
self, session: ClientSession
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import json
import time

from datetime import datetime, timezone
from typing import Any, List, Optional, Tuple

Expand Down Expand Up @@ -92,7 +94,6 @@ def _construct(
result_arr = []
decimals = pair.decimals()
for data in result:
timestamp = int(data["time"])
price = float(data["markPrice"])
price_int = int(price * (10**decimals))
volume = float(self._retrieve_volume(data["symbol"], volume_arr)) / (
Expand All @@ -116,7 +117,7 @@ def _construct(
pair_id=pair.id,
price=price_int,
volume=int(volume),
timestamp=int(timestamp / 1000),
timestamp=int(time.time()),
source=self.SOURCE,
publisher=self.publisher,
expiry_timestamp=expiry_timestamp * 1000,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import asyncio
import json
import time
from typing import Any, List

from aiohttp import ClientSession
Expand Down Expand Up @@ -59,7 +60,6 @@ def format_url(self, pair: Pair) -> str:
def _construct(self, pair: Pair, result: Any) -> FutureEntry:
data = result["result"]["list"][0]
decimals = pair.decimals()
timestamp = int(int(result["time"]) / 1000)

price = float(data["lastPrice"])
price_int = int(price * (10**decimals))
Expand All @@ -73,7 +73,7 @@ def _construct(self, pair: Pair, result: Any) -> FutureEntry:
pair_id=pair.id,
price=price_int,
volume=volume,
timestamp=timestamp,
timestamp=int(time.time()),
source=self.SOURCE,
publisher=self.publisher,
expiry_timestamp=expiry_timestamp,
Expand Down
5 changes: 3 additions & 2 deletions pragma-sdk/pragma_sdk/common/fetchers/future_fetchers/okx.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import json
import time

from typing import Any, List, Union

from aiohttp import ClientSession
Expand Down Expand Up @@ -85,7 +87,6 @@ def format_url(self, pair: Pair) -> str:
return url

def _construct(self, pair: Pair, data: Any, expiry_timestamp: int) -> FutureEntry:
timestamp = int(int(data["ts"]) / 1000)
decimals = pair.decimals()
price = float(data["last"])
price_int = int(price * (10**decimals))
Expand All @@ -97,7 +98,7 @@ def _construct(self, pair: Pair, data: Any, expiry_timestamp: int) -> FutureEntr
pair_id=pair.id,
price=price_int,
volume=volume,
timestamp=timestamp,
timestamp=int(time.time()),
source=self.SOURCE,
publisher=self.publisher,
expiry_timestamp=int(expiry_timestamp),
Expand Down
4 changes: 4 additions & 0 deletions pragma-sdk/pragma_sdk/onchain/mixins/oracle.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ async def set_future_checkpoints(
],
aggregation_mode.serialize(),
max_fee=self.execution_config.max_fee,
callback=self.track_nonce,
)
index += pagination
logger.info(
Expand All @@ -412,6 +413,7 @@ async def set_future_checkpoints(
],
aggregation_mode.serialize(),
max_fee=self.execution_config.max_fee,
callback=self.track_nonce,
)

return invocation
Expand Down Expand Up @@ -448,6 +450,7 @@ async def set_checkpoints(
],
aggregation_mode.serialize(),
max_fee=self.execution_config.max_fee,
callback=self.track_nonce,
)
index += pagination
logger.info(
Expand All @@ -463,6 +466,7 @@ async def set_checkpoints(
],
aggregation_mode.serialize(),
max_fee=self.execution_config.max_fee,
callback=self.track_nonce,
)

return invocation
Expand Down
26 changes: 12 additions & 14 deletions pragma-sdk/tests/integration/fetchers/fetcher_configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,17 @@
"fetcher_class": DefillamaFetcher,
"name": "Defillama",
"expected_result": [
SpotEntry(
"BTC/USD", 2604800000000, 1692779346, "DEFILLAMA", PUBLISHER_NAME
),
SpotEntry("ETH/USD", 164507000000, 1692779707, "DEFILLAMA", PUBLISHER_NAME),
SpotEntry("BTC/USD", 2604800000000, 12345, "DEFILLAMA", PUBLISHER_NAME),
SpotEntry("ETH/USD", 164507000000, 12345, "DEFILLAMA", PUBLISHER_NAME),
],
},
"BitstampFetcher": {
"mock_file": MOCK_DIR / "responses" / "bitstamp.json",
"fetcher_class": BitstampFetcher,
"name": "Bitstamp",
"expected_result": [
SpotEntry("BTC/USD", 2602100000000, 1692781034, "BITSTAMP", PUBLISHER_NAME),
SpotEntry("ETH/USD", 164250000000, 1692780986, "BITSTAMP", PUBLISHER_NAME),
SpotEntry("BTC/USD", 2602100000000, 12345, "BITSTAMP", PUBLISHER_NAME),
SpotEntry("ETH/USD", 164250000000, 12345, "BITSTAMP", PUBLISHER_NAME),
],
},
"CoinbaseFetcher": {
Expand All @@ -55,15 +53,15 @@
SpotEntry(
"BTC/USD",
2640240000000,
1692829724,
12345,
"OKX",
PUBLISHER_NAME,
volume=18382.3898,
),
SpotEntry(
"ETH/USD",
167372000000,
1692829751,
12345,
"OKX",
PUBLISHER_NAME,
volume=185341.3646,
Expand Down Expand Up @@ -145,7 +143,7 @@
FutureEntry(
"BTC/USD",
2589900000000,
1692982428,
12345,
"BYBIT",
PUBLISHER_NAME,
0,
Expand All @@ -154,7 +152,7 @@
FutureEntry(
"ETH/USD",
164025000000,
1692982480,
12345,
"BYBIT",
PUBLISHER_NAME,
0,
Expand Down Expand Up @@ -196,7 +194,7 @@
FutureEntry(
pair_id="BTC/USD",
price=2664490000000,
timestamp=1695293953,
timestamp=12345,
source="OKX",
publisher=PUBLISHER_NAME,
volume=274,
Expand All @@ -205,7 +203,7 @@
FutureEntry(
pair_id="BTC/USD",
price=2666120000000,
timestamp=1695293953,
timestamp=12345,
source="OKX",
publisher=PUBLISHER_NAME,
volume=1020,
Expand All @@ -214,7 +212,7 @@
FutureEntry(
pair_id="ETH/USD",
price=159390000000,
timestamp=1695293986,
timestamp=12345,
source="OKX",
publisher=PUBLISHER_NAME,
volume=2276,
Expand All @@ -223,7 +221,7 @@
FutureEntry(
pair_id="ETH/USD",
price=159092000000,
timestamp=1695293987,
timestamp=12345,
source="OKX",
publisher=PUBLISHER_NAME,
volume=6178,
Expand Down
9 changes: 1 addition & 8 deletions price-pusher/config/config.example.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
- pairs:
spot:
- STRK/USD
- BTC/USD
- ETH/USD
- DAI/USD
- LORDS/USD
time_difference: 120
price_deviation: 0.0025

- pairs:
future:
- BTC/USD
- ETH/USD
time_difference: 600
price_deviation: 0.05
2 changes: 2 additions & 0 deletions price-pusher/price_pusher/configs/fetchers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
OkxFetcher,
BinanceFetcher,
PropellerFetcher,
StarknetAMMFetcher,
)
from pragma_sdk.common.fetchers.future_fetchers import BinanceFutureFetcher, ByBitFutureFetcher

Expand All @@ -27,6 +28,7 @@
BybitFetcher,
BinanceFetcher,
PropellerFetcher,
StarknetAMMFetcher,
]

ALL_FUTURE_FETCHERS: List[FetcherInterfaceT] = [BinanceFutureFetcher, ByBitFutureFetcher]
Expand Down
2 changes: 1 addition & 1 deletion price-pusher/price_pusher/core/listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ def _new_price_is_deviating(self, pair_id: str, new_price: int, oracle_price: in
"""
max_deviation = self.price_config.price_deviation * oracle_price
deviation = abs(new_price - oracle_price)
is_deviating = deviation >= max_deviation
is_deviating = deviation > max_deviation
if is_deviating:
deviation_percentage = (deviation / oracle_price) * 100
logger.info(
Expand Down
1 change: 0 additions & 1 deletion price-pusher/price_pusher/core/request_handlers/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ async def _fetch_latest_spot_entry(self, pair: Pair) -> List[Entry]:
)
if entry_result is None:
return []

entry = SpotEntry(
pair_id=entry_result.pair_id,
price=int(entry_result.data, 16),
Expand Down
2 changes: 1 addition & 1 deletion price-pusher/tests/unit/core/test_listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ async def test_oracle_needs_update_because_deviating(caplog, price_listener):
caplog.set_level(logging.INFO)
orchestrator_entry = SpotEntry(
pair_id="BTC/USD",
price=110,
price=111,
timestamp=1000000000,
source="source_1",
publisher="publisher_1",
Expand Down
Loading