-
Notifications
You must be signed in to change notification settings - Fork 201
feat: Migrate price feeds to USDC-based denomination #3233
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
Open
ad-0xpp
wants to merge
1
commit into
main
Choose a base branch
from
chore/update-usdc-price-sources
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
211 changes: 211 additions & 0 deletions
211
protocol/marketmap_updates/step1_msg_upsert_markets_core.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,211 @@ | ||
| { | ||
| "@type": "/cosmos.gov.v1.MsgSubmitProposal", | ||
| "messages": [ | ||
| { | ||
| "@type": "/slinky.marketmap.v1.MsgUpsertMarkets", | ||
| "authority": "dydx10d07y265gmmuvt4z0w9aw880jnsr700jnmapky", | ||
| "markets": [ | ||
| { | ||
| "ticker": { | ||
| "currency_pair": { | ||
| "Base": "BTC", | ||
| "Quote": "USDC" | ||
| }, | ||
| "decimals": "5", | ||
| "min_provider_count": "3", | ||
| "enabled": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| "provider_configs": [ | ||
| { | ||
| "name": "binance_ws", | ||
| "off_chain_ticker": "BTCUSDC", | ||
| "normalize_by_pair": null, | ||
| "invert": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "bybit_ws", | ||
| "off_chain_ticker": "BTCUSDC", | ||
| "normalize_by_pair": null, | ||
| "invert": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "kucoin_ws", | ||
| "off_chain_ticker": "BTC-USDC", | ||
| "normalize_by_pair": null, | ||
| "invert": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "gate_ws", | ||
| "off_chain_ticker": "BTC_USDC", | ||
| "normalize_by_pair": null, | ||
| "invert": false, | ||
| "metadata_JSON": "" | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| "ticker": { | ||
| "currency_pair": { | ||
| "Base": "ETH", | ||
| "Quote": "USDC" | ||
| }, | ||
| "decimals": "6", | ||
| "min_provider_count": "3", | ||
| "enabled": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| "provider_configs": [ | ||
| { | ||
| "name": "binance_ws", | ||
| "off_chain_ticker": "ETHUSDC", | ||
| "normalize_by_pair": null, | ||
| "invert": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "bybit_ws", | ||
| "off_chain_ticker": "ETHUSDC", | ||
| "normalize_by_pair": null, | ||
| "invert": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "kucoin_ws", | ||
| "off_chain_ticker": "ETH-USDC", | ||
| "normalize_by_pair": null, | ||
| "invert": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "gate_ws", | ||
| "off_chain_ticker": "ETH_USDC", | ||
| "normalize_by_pair": null, | ||
| "invert": false, | ||
| "metadata_JSON": "" | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| "ticker": { | ||
| "currency_pair": { | ||
| "Base": "SOL", | ||
| "Quote": "USDC" | ||
| }, | ||
| "decimals": "8", | ||
| "min_provider_count": "3", | ||
| "enabled": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| "provider_configs": [ | ||
| { | ||
| "name": "binance_ws", | ||
| "off_chain_ticker": "SOLUSDC", | ||
| "normalize_by_pair": null, | ||
| "invert": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "bybit_ws", | ||
| "off_chain_ticker": "SOLUSDC", | ||
| "normalize_by_pair": null, | ||
| "invert": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "kucoin_ws", | ||
| "off_chain_ticker": "SOL-USDC", | ||
| "normalize_by_pair": null, | ||
| "invert": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "gate_ws", | ||
| "off_chain_ticker": "SOL_USDC", | ||
| "normalize_by_pair": null, | ||
| "invert": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "kraken_api", | ||
| "off_chain_ticker": "SOLUSDC", | ||
| "normalize_by_pair": null, | ||
| "invert": false, | ||
| "metadata_JSON": "" | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| "ticker": { | ||
| "currency_pair": { | ||
| "Base": "USDT", | ||
| "Quote": "USDC" | ||
| }, | ||
| "decimals": "6", | ||
| "min_provider_count": "3", | ||
| "enabled": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| "provider_configs": [ | ||
| { | ||
| "name": "binance_ws", | ||
| "off_chain_ticker": "USDCUSDT", | ||
| "normalize_by_pair": null, | ||
| "invert": true, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "bybit_ws", | ||
| "off_chain_ticker": "USDCUSDT", | ||
| "normalize_by_pair": null, | ||
| "invert": true, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "coinbase_ws", | ||
| "off_chain_ticker": "USDT-USDC", | ||
| "normalize_by_pair": null, | ||
| "invert": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "huobi_ws", | ||
| "off_chain_ticker": "usdcusdt", | ||
| "normalize_by_pair": null, | ||
| "invert": true, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "kraken_api", | ||
| "off_chain_ticker": "USDCUSDT", | ||
| "normalize_by_pair": null, | ||
| "invert": true, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "kucoin_ws", | ||
| "off_chain_ticker": "USDC-USDT", | ||
| "normalize_by_pair": null, | ||
| "invert": true, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "okx_ws", | ||
| "off_chain_ticker": "USDC-USDT", | ||
| "normalize_by_pair": null, | ||
| "invert": true, | ||
| "metadata_JSON": "" | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| "metadata": "Create helper markets for USDC-based normalization", | ||
| "deposit": "10000000adv4tnt", | ||
| "title": "Create USDC Helper Markets", | ||
| "summary": "Create BTC/USDC, ETH/USDC, SOL/USDC, and USDT/USDC markets (enabled: false) for use as normalization sources" | ||
| } | ||
57 changes: 57 additions & 0 deletions
57
protocol/marketmap_updates/step2_msg_create_oracle_markets_fixed.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| { | ||
| "@type": "/cosmos.gov.v1.MsgSubmitProposal", | ||
| "messages": [ | ||
| { | ||
| "@type": "/dydxprotocol.prices.MsgCreateOracleMarket", | ||
| "authority": "dydx10d07y265gmmuvt4z0w9aw880jnsr700jnmapky", | ||
| "params": { | ||
| "id": 9000, | ||
| "pair": "BTC-USDC", | ||
| "exponent": -5, | ||
| "min_exchanges": 3, | ||
| "min_price_change_ppm": 500, | ||
| "exchange_config_json": "{\"exchanges\":[]}" | ||
| } | ||
| }, | ||
| { | ||
| "@type": "/dydxprotocol.prices.MsgCreateOracleMarket", | ||
| "authority": "dydx10d07y265gmmuvt4z0w9aw880jnsr700jnmapky", | ||
| "params": { | ||
| "id": 9001, | ||
| "pair": "ETH-USDC", | ||
| "exponent": -6, | ||
| "min_exchanges": 3, | ||
| "min_price_change_ppm": 500, | ||
| "exchange_config_json": "{\"exchanges\":[]}" | ||
| } | ||
| }, | ||
| { | ||
| "@type": "/dydxprotocol.prices.MsgCreateOracleMarket", | ||
| "authority": "dydx10d07y265gmmuvt4z0w9aw880jnsr700jnmapky", | ||
| "params": { | ||
| "id": 9002, | ||
| "pair": "SOL-USDC", | ||
| "exponent": -8, | ||
| "min_exchanges": 3, | ||
| "min_price_change_ppm": 500, | ||
| "exchange_config_json": "{\"exchanges\":[]}" | ||
| } | ||
| }, | ||
| { | ||
| "@type": "/dydxprotocol.prices.MsgCreateOracleMarket", | ||
| "authority": "dydx10d07y265gmmuvt4z0w9aw880jnsr700jnmapky", | ||
| "params": { | ||
| "id": 9003, | ||
| "pair": "USDT-USDC", | ||
| "exponent": -6, | ||
| "min_exchanges": 3, | ||
| "min_price_change_ppm": 10, | ||
| "exchange_config_json": "{\"exchanges\":[]}" | ||
| } | ||
| } | ||
| ], | ||
| "metadata": "Enable BTC/USDC, ETH/USDC, SOL/USDC, USDT/USDC markets for price normalization", | ||
| "title": "Enable USDC Helper Markets", | ||
| "summary": "Create and enable BTC/USDC, ETH/USDC, SOL/USDC, and USDT/USDC markets in x/prices to enable USDC-based price normalization across all markets", | ||
| "deposit": "10000000adv4tnt" | ||
| } |
83 changes: 83 additions & 0 deletions
83
protocol/marketmap_updates/step3_msg_update_usdc_usd_market.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| { | ||
| "@type": "/cosmos.gov.v1.MsgSubmitProposal", | ||
| "messages": [ | ||
| { | ||
| "@type": "/slinky.marketmap.v1.MsgUpsertMarkets", | ||
| "authority": "dydx10d07y265gmmuvt4z0w9aw880jnsr700jnmapky", | ||
| "markets": [ | ||
| { | ||
| "ticker": { | ||
| "currency_pair": { | ||
| "Base": "USDC", | ||
| "Quote": "USD" | ||
| }, | ||
| "decimals": "10", | ||
| "min_provider_count": "1", | ||
| "enabled": true, | ||
| "metadata_JSON": "{\"reference_price\":9987985104,\"liquidity\":452991176,\"aggregate_ids\":[{\"venue\":\"coinmarketcap\",\"ID\":\"3408\"}]}" | ||
| }, | ||
| "provider_configs": [ | ||
| { | ||
| "name": "bitstamp_api", | ||
| "off_chain_ticker": "USDC/USD", | ||
| "normalize_by_pair": null, | ||
| "invert": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "kraken_api", | ||
| "off_chain_ticker": "USDCUSD", | ||
| "normalize_by_pair": null, | ||
| "invert": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "kraken_btc_usd", | ||
| "off_chain_ticker": "XXBTZUSD", | ||
| "normalize_by_pair": { | ||
| "Base": "BTC", | ||
| "Quote": "USDC" | ||
| }, | ||
| "invert": false, | ||
| "metadata_JSON": "" | ||
| }, | ||
| { | ||
| "name": "raydium_api", | ||
| "off_chain_ticker": "SOL,RAYDIUM,SO11111111111111111111111111111111111111112/USDC,RAYDIUM,EPJFWDD5AUFQSSQEM2QN1XZYBAPC8G4WEGGKZWYTDT1V", | ||
| "normalize_by_pair": { | ||
| "Base": "SOL", | ||
| "Quote": "USDC" | ||
| }, | ||
| "invert": true, | ||
| "metadata_JSON": "{\"base_token_vault\":{\"token_vault_address\":\"DQyrAcCrDXQ7NeoqGgDCZwBvWDcYmFCjSb9JtteuvPpz\",\"token_decimals\":9},\"quote_token_vault\":{\"token_vault_address\":\"HLmqeL62xR1QoZ1HKKbXRrdN1p3phKpxRMb2VVopvBBz\",\"token_decimals\":6},\"amm_info_address\":\"58oQChx4yWmvKdwLLZzBi4ChoCc2fqCUWBkwMihLYQo2\",\"open_orders_address\":\"HmiHHzq4Fym9e1D4qzLS6LDDM3tNsCTBPDWHTLZ763jY\"}" | ||
| }, | ||
| { | ||
| "name": "uniswapv3_api-base", | ||
| "off_chain_ticker": "USDC,UNISWAP_V3_BASE,0X833589FCD6EDB6E08F4C7C32D4F71B54BDA02913/WETH,UNISWAP_V3_BASE,0X4200000000000000000000000000000000000006", | ||
| "normalize_by_pair": { | ||
| "Base": "ETH", | ||
| "Quote": "USDC" | ||
| }, | ||
| "invert": false, | ||
| "metadata_JSON": "{\"address\":\"0xd0b53d9277642d899df5c87a3966a349a798f224\",\"base_decimals\":6,\"quote_decimals\":18,\"invert\":true}" | ||
| }, | ||
| { | ||
| "name": "uniswapv3_api-ethereum", | ||
| "off_chain_ticker": "WETH,UNISWAP_V3,0XC02AAA39B223FE8D0A0E5C4F27EAD9083C756CC2/USDC,UNISWAP_V3,0XA0B86991C6218B36C1D19D4A2E9EB0CE3606EB48", | ||
| "normalize_by_pair": { | ||
| "Base": "ETH", | ||
| "Quote": "USDC" | ||
| }, | ||
| "invert": true, | ||
| "metadata_JSON": "{\"address\":\"0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640\",\"base_decimals\":18,\"quote_decimals\":6,\"invert\":true}" | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| "metadata": "Update USDC/USD market to use BTC/USDC, ETH/USDC, SOL/USDC normalizations", | ||
| "deposit": "10000000adv4tnt", | ||
| "title": "Update USDC/USD Market Normalizations", | ||
| "summary": "Add Kraken BTC/USD (normalized by BTC/USDC), Raydium SOL, and Uniswap ETH providers to USDC/USD market" | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify USDT/USDC decimals: 9 seems unexpectedly high for a stablecoin pair.
The USDT/USDC market is configured with
decimals: "9", which is unusual. Stablecoin pairs (1:1 or near-parity) typically require only 6–8 decimals of precision. A 9-decimal specification may indicate misalignment with actual exchange pair precision, potentially causing rounding errors or data interpretation issues downstream. This may be a copy-paste error or misconfiguration.Verify that 9 decimals is intentional and aligns with how exchanges (binance, bybit, coinbase, etc.) actually quote this pair. Consider cross-referencing against step 2 and step 3 of the migration to ensure consistency.
I'll verify the concerns raised in the review comment. Let me examine the JSON file and search for external context.
🏁 Script executed:
Length of output: 59
🏁 Script executed:
Length of output: 59
🏁 Script executed:
Length of output: 59
🌐 Web query:
💡 Result:
Short answer — use each exchange's "exchange/symbol info" endpoint and read the price/tick/quote precision fields:
Binance (Spot / Futures): GET /api/v3/exchangeInfo (spot) or the futures Exchange Information endpoints. The JSON for each symbol contains pricePrecision and filters[].PRICE_FILTER.tickSize (and quotePrecision). Use those to determine allowed decimal places for price (and LOT_SIZE.stepSize for quantity). [1]
Bybit: call the public symbols endpoint (e.g. v2: GET https://api.bybit.com/v2/public/symbols or v5 market-symbols endpoints). Each symbol includes a price_filter / tick_size or price_scale field you must use to compute allowed price decimals. [2]
Coinbase (Advanced Trade / Exchange API): GET the product/instrument (products or instruments endpoints). The product object includes base_increment and quote_increment (or base_increment/quote_increment or base_increment/quote_increment-like fields) which give the minimum increments for quantity and price. Use those to derive decimal precision. [3]
If you want, I can fetch the current tickSize / quote_increment values for specific pairs (e.g. USDT‑USD, USDC‑USD, USDT/USDC) right now.
Sources: [Binance exchangeInfo API docs][1], [Bybit public symbols / API docs][2], [Coinbase product/instruments API docs][3].
🌐 Web query:
💡 Result:
"adv4tnt" is the dYdX testnet native token denomination (the mainnet native denom is "adydx"). [1][2]
Sources:
[1] dYdX Network Constants (Native Token Denom: testnet = adv4tnt, mainnet = adydx).
[2] dYdX Docs — Accounts (example showing adv4tnt used as the testnet denom).
🌐 Web query:
💡 Result:
Short answer
Details
References
Let me correct my approach and read the JSON structure directly:
🏁 Script executed:
Length of output: 1415
🏁 Script executed:
Length of output: 352
🏁 Script executed:
Length of output: 213
🌐 Web query:
💡 Result:
Short answer: both USDC and USDT are commonly implemented with 6 decimals (i.e., smallest unit = 10^-6). Use the token contract's decimals() call (or a reliable issuer doc) to confirm for the specific chain/deployment before integrating. [1][2]
Sources:
USDT/USDC decimals configuration: 9 is anomalous and should be 6.
USDT and USDC are standard 6-decimal tokens. The USDT/USDC market is configured with
decimals: "9"(line 141), which deviates from both token standards and the typical precision needed for stablecoin pairs. This differs from the pattern in the same proposal: BTC/USDC (5), ETH/USDC (6), SOL/USDC (8). The 9-decimal specification is likely a data entry error or misalignment with actual exchange pair precision, and may cause rounding or interpretation issues downstream.Correct the USDT/USDC decimals to
"6"unless there is explicit documentation justifying the 9-decimal choice (e.g., matching a specific exchange API).🤖 Prompt for AI Agents