diff --git a/package.json b/package.json index 19c4fb8..23e4030 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "@cosmjs/tendermint-rpc": "^0.32.1", "@dydxprotocol/v4-abacus": "^1.3.2", "@dydxprotocol/v4-client-js": "^1.0.17", - "@dydxprotocol/v4-localization": "^1.1.17", + "@dydxprotocol/v4-localization": "^1.1.19", "@ethersproject/providers": "^5.7.2", "@js-joda/core": "^5.5.3", "@radix-ui/react-accordion": "^1.1.2", @@ -92,6 +92,7 @@ "buffer": "^6.0.3", "cmdk": "^0.2.0", "color": "^4.2.3", + "cosmjs-types": "^0.9.0", "crypto-js": "^4.1.1", "ethers": "^6.6.1", "graz": "^0.0.43", @@ -161,4 +162,4 @@ "follow-redirects": "1.15.3" } } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c41990a..684cfd2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5 +1,9 @@ lockfileVersion: '6.0' +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + overrides: follow-redirects: 1.15.3 @@ -9,22 +13,22 @@ dependencies: version: 1.10.0 '@cosmjs/amino': specifier: ^0.32.1 - version: 0.32.2 + version: 0.32.1 '@cosmjs/crypto': specifier: ^0.32.1 - version: 0.32.2 + version: 0.32.1 '@cosmjs/encoding': specifier: ^0.32.1 - version: 0.32.2 + version: 0.32.1 '@cosmjs/proto-signing': specifier: ^0.32.1 - version: 0.32.2 + version: 0.32.1 '@cosmjs/stargate': specifier: ^0.32.1 - version: 0.32.2 + version: 0.32.1 '@cosmjs/tendermint-rpc': specifier: ^0.32.1 - version: 0.32.2 + version: 0.32.1 '@dydxprotocol/v4-abacus': specifier: ^1.3.2 version: 1.3.2 @@ -32,8 +36,8 @@ dependencies: specifier: ^1.0.17 version: 1.0.17 '@dydxprotocol/v4-localization': - specifier: ^1.1.17 - version: 1.1.17 + specifier: ^1.1.19 + version: 1.1.19 '@ethersproject/providers': specifier: ^5.7.2 version: 5.7.2 @@ -184,6 +188,9 @@ dependencies: color: specifier: ^4.2.3 version: 4.2.3 + cosmjs-types: + specifier: ^0.9.0 + version: 0.9.0 crypto-js: specifier: ^4.1.1 version: 4.1.1 @@ -375,7 +382,7 @@ packages: /@0xsquid/sdk@1.10.0: resolution: {integrity: sha512-NKxHYB+g/TMPY+XmCHs+LuhyfbhH4KvAbGpVBOBPXM9Q5FsKcKrDJpTd5YnGYCLF9B3qXAzVTR0XhiC73GmOOA==} dependencies: - '@cosmjs/encoding': 0.31.0 + '@cosmjs/encoding': 0.31.1 '@cosmjs/stargate': 0.31.0 axios: 0.27.2 cosmjs-types: 0.8.0 @@ -682,16 +689,16 @@ packages: resolution: {integrity: sha512-xJ5CCEK7H79FTpOuEmlpSzVI+ZeYESTVvO3wHDgbnceIyAne3C68SvyaKqLUR4uJB0Z4q4+DZHbqW6itUiv4lA==} dependencies: '@cosmjs/crypto': 0.31.0 - '@cosmjs/encoding': 0.31.0 - '@cosmjs/math': 0.31.0 - '@cosmjs/utils': 0.31.0 + '@cosmjs/encoding': 0.31.1 + '@cosmjs/math': 0.31.1 + '@cosmjs/utils': 0.31.1 dev: false - /@cosmjs/amino@0.32.2: - resolution: {integrity: sha512-lcK5RCVm4OfdAooxKcF2+NwaDVVpghOq6o/A40c2mHXDUzUoRZ33VAHjVJ9Me6vOFxshrw/XEFn1f4KObntjYA==} + /@cosmjs/amino@0.32.1: + resolution: {integrity: sha512-5l2xQ2XuAhV/B3kTIMPBcVZ/OQ+9Yyddzw/lIVs4qE5e/oBI0PVNWXw1oyR0wgfGHrMUxgKjsoOOqE2IbXVyCw==} dependencies: - '@cosmjs/crypto': 0.32.2 - '@cosmjs/encoding': 0.32.2 + '@cosmjs/crypto': 0.32.1 + '@cosmjs/encoding': 0.32.1 '@cosmjs/math': 0.32.2 '@cosmjs/utils': 0.32.2 dev: false @@ -746,19 +753,19 @@ packages: /@cosmjs/crypto@0.31.0: resolution: {integrity: sha512-UaqCe6Tgh0pe1QlZ66E13t6FlIF86QrnBXXq+EN7Xe1Rouza3fJ1ojGlPleJZkBoq3tAyYVIOOqdZIxtVj/sIQ==} dependencies: - '@cosmjs/encoding': 0.31.0 - '@cosmjs/math': 0.31.0 - '@cosmjs/utils': 0.31.0 + '@cosmjs/encoding': 0.31.1 + '@cosmjs/math': 0.31.1 + '@cosmjs/utils': 0.31.1 '@noble/hashes': 1.3.3 bn.js: 5.2.1 elliptic: 6.5.4 libsodium-wrappers-sumo: 0.7.11 dev: false - /@cosmjs/crypto@0.32.2: - resolution: {integrity: sha512-RuxrYKzhrPF9g6NmU7VEq++Hn1vZJjqqJpZ9Tmw9lOYOV8BUsv+j/0BE86kmWi7xVJ7EwxiuxYsKuM8IR18CIA==} + /@cosmjs/crypto@0.32.1: + resolution: {integrity: sha512-AsKucEg5o8evU0wXF/lDwX+ZSwCKF4bbc57nFzraHywlp3sNu4dfPPURoMrT0r7kT7wQZAy4Pdnvmm9nnCCm/Q==} dependencies: - '@cosmjs/encoding': 0.32.2 + '@cosmjs/encoding': 0.32.1 '@cosmjs/math': 0.32.2 '@cosmjs/utils': 0.32.2 '@noble/hashes': 1.3.3 @@ -783,16 +790,16 @@ packages: readonly-date: 1.0.0 dev: false - /@cosmjs/encoding@0.31.0: - resolution: {integrity: sha512-NYGQDRxT7MIRSlcbAezwxK0FqnaSPKCH7O32cmfpHNWorFxhy9lwmBoCvoe59Kd0HmArI4h+NGzLEfX3OLnA4Q==} + /@cosmjs/encoding@0.31.1: + resolution: {integrity: sha512-IuxP6ewwX6vg9sUJ8ocJD92pkerI4lyG8J5ynAM3NaX3q+n+uMoPRSQXNeL9bnlrv01FF1kIm8if/f5F7ZPtkA==} dependencies: base64-js: 1.5.1 bech32: 1.1.4 readonly-date: 1.0.0 dev: false - /@cosmjs/encoding@0.32.2: - resolution: {integrity: sha512-WX7m1wLpA9V/zH0zRcz4EmgZdAv1F44g4dbXOgNj1eXZw1PIGR12p58OEkLN51Ha3S4DKRtCv5CkhK1KHEvQtg==} + /@cosmjs/encoding@0.32.1: + resolution: {integrity: sha512-x60Lfds+Eq42rVV29NaoIAson3kBhATBI3zPp7X3GJTryBc5HFHQ6L/976tE1WB2DrvkfUdWS3ayCMVOY/qm1g==} dependencies: base64-js: 1.5.1 bech32: 1.1.4 @@ -852,6 +859,12 @@ packages: bn.js: 5.2.1 dev: false + /@cosmjs/math@0.31.1: + resolution: {integrity: sha512-kiuHV6m6DSB8/4UV1qpFhlc4ul8SgLXTGRlYkYiIIP4l0YNeJ+OpPYaOlEgx4Unk2mW3/O2FWYj7Jc93+BWXng==} + dependencies: + bn.js: 5.2.1 + dev: false + /@cosmjs/math@0.32.2: resolution: {integrity: sha512-b8+ruAAY8aKtVKWSft2IvtCVCUH1LigIlf9ALIiY8n9jtM4kMASiaRbQ/27etnSAInV88IaezKK9rQZrtxTjcw==} dependencies: @@ -875,19 +888,19 @@ packages: dependencies: '@cosmjs/amino': 0.31.0 '@cosmjs/crypto': 0.31.0 - '@cosmjs/encoding': 0.31.0 - '@cosmjs/math': 0.31.0 - '@cosmjs/utils': 0.31.0 + '@cosmjs/encoding': 0.31.1 + '@cosmjs/math': 0.31.1 + '@cosmjs/utils': 0.31.1 cosmjs-types: 0.8.0 long: 4.0.0 dev: false - /@cosmjs/proto-signing@0.32.2: - resolution: {integrity: sha512-UV4WwkE3W3G3s7wwU9rizNcUEz2g0W8jQZS5J6/3fiN0mRPwtPKQ6EinPN9ASqcAJ7/VQH4/9EPOw7d6XQGnqw==} + /@cosmjs/proto-signing@0.32.1: + resolution: {integrity: sha512-IHJMXQ8XnfzR5K1hWb8VV/jEfJof6BL2mgGIA7X4hSPegwoVfb9hnFKPEPgFjGCTTvGZ8SfnCdXxpsOjianVIA==} dependencies: - '@cosmjs/amino': 0.32.2 - '@cosmjs/crypto': 0.32.2 - '@cosmjs/encoding': 0.32.2 + '@cosmjs/amino': 0.32.1 + '@cosmjs/crypto': 0.32.1 + '@cosmjs/encoding': 0.32.1 '@cosmjs/math': 0.32.2 '@cosmjs/utils': 0.32.2 cosmjs-types: 0.9.0 @@ -955,7 +968,7 @@ packages: dependencies: '@confio/ics23': 0.6.8 '@cosmjs/amino': 0.31.0 - '@cosmjs/encoding': 0.31.0 + '@cosmjs/encoding': 0.31.1 '@cosmjs/math': 0.31.0 '@cosmjs/proto-signing': 0.31.0 '@cosmjs/stream': 0.31.0 @@ -971,16 +984,16 @@ packages: - utf-8-validate dev: false - /@cosmjs/stargate@0.32.2: - resolution: {integrity: sha512-AsJa29fT7Jd4xt9Ai+HMqhyj7UQu7fyYKdXj/8+/9PD74xe6lZSYhQPcitUmMLJ1ckKPgXSk5Dd2LbsQT0IhZg==} + /@cosmjs/stargate@0.32.1: + resolution: {integrity: sha512-S0E1qKQ2CMJU79G8bQTquTyrbU03gFsvCkbo3RvK8v2OltVCByjFNh+0nGN5do+uDOzwwmDvnNLhR+SaIyNQoQ==} dependencies: '@confio/ics23': 0.6.8 - '@cosmjs/amino': 0.32.2 - '@cosmjs/encoding': 0.32.2 + '@cosmjs/amino': 0.32.1 + '@cosmjs/encoding': 0.32.1 '@cosmjs/math': 0.32.2 - '@cosmjs/proto-signing': 0.32.2 + '@cosmjs/proto-signing': 0.32.1 '@cosmjs/stream': 0.32.2 - '@cosmjs/tendermint-rpc': 0.32.2 + '@cosmjs/tendermint-rpc': 0.32.1 '@cosmjs/utils': 0.32.2 cosmjs-types: 0.9.0 xstream: 11.14.0 @@ -1031,12 +1044,12 @@ packages: resolution: {integrity: sha512-yo9xbeuI6UoEKIhFZ9g0dvUKLqnBzwdpEc/uldQygQc51j38gQVwFko+6sjmhieJqRYYvrYumcbJMiV6GFM9aA==} dependencies: '@cosmjs/crypto': 0.31.0 - '@cosmjs/encoding': 0.31.0 + '@cosmjs/encoding': 0.31.1 '@cosmjs/json-rpc': 0.31.0 - '@cosmjs/math': 0.31.0 + '@cosmjs/math': 0.31.1 '@cosmjs/socket': 0.31.0 '@cosmjs/stream': 0.31.0 - '@cosmjs/utils': 0.31.0 + '@cosmjs/utils': 0.31.1 axios: 0.21.4 readonly-date: 1.0.0 xstream: 11.14.0 @@ -1046,11 +1059,11 @@ packages: - utf-8-validate dev: false - /@cosmjs/tendermint-rpc@0.32.2: - resolution: {integrity: sha512-DXyJHDmcAfCix4H/7/dKR0UMdshP01KxJOXHdHxBCbLIpck94BsWD3B2ZTXwfA6sv98so9wOzhp7qGQa5malxg==} + /@cosmjs/tendermint-rpc@0.32.1: + resolution: {integrity: sha512-4uGSxB2JejWhwBUgxca4GqcK/BGnCFMIP7ptwEledrC3AY/shPeIYcPXWEBwO7sfwCta8DhAOCLrc9zhVC+VAQ==} dependencies: - '@cosmjs/crypto': 0.32.2 - '@cosmjs/encoding': 0.32.2 + '@cosmjs/crypto': 0.32.1 + '@cosmjs/encoding': 0.32.1 '@cosmjs/json-rpc': 0.32.2 '@cosmjs/math': 0.32.2 '@cosmjs/socket': 0.32.2 @@ -1077,6 +1090,10 @@ packages: resolution: {integrity: sha512-nNcycZWUYLNJlrIXgpcgVRqdl6BXjF4YlXdxobQWpW9Tikk61bEGeAFhDYtC0PwHlokCNw0KxWiHGJL4nL7Q5A==} dev: false + /@cosmjs/utils@0.31.1: + resolution: {integrity: sha512-n4Se1wu4GnKwztQHNFfJvUeWcpvx3o8cWhSbNs9JQShEuB3nv3R5lqFBtDCgHZF/emFQAP+ZjF8bTfCs9UBGhA==} + dev: false + /@cosmjs/utils@0.32.2: resolution: {integrity: sha512-Gg5t+eR7vPJMAmhkFt6CZrzPd0EKpAslWwk5rFVYZpJsM8JG5KT9XQ99hgNM3Ov6ScNoIWbXkpX27F6A9cXR4Q==} dev: false @@ -1092,22 +1109,22 @@ packages: /@dydxprotocol/v4-client-js@1.0.17: resolution: {integrity: sha512-PbTKbzcS7VapuFRofkirUxkF9ThNS2tWYyr0asFOMUfebsQWMvTC1sYC/s1NZIiBeq3cFz9vKdZFbfsKi7Z1bw==} dependencies: - '@cosmjs/amino': 0.32.2 - '@cosmjs/encoding': 0.32.2 + '@cosmjs/amino': 0.32.1 + '@cosmjs/encoding': 0.32.1 '@cosmjs/math': 0.32.2 - '@cosmjs/proto-signing': 0.32.2 - '@cosmjs/stargate': 0.32.2 - '@cosmjs/tendermint-rpc': 0.32.2 + '@cosmjs/proto-signing': 0.32.1 + '@cosmjs/stargate': 0.32.1 + '@cosmjs/tendermint-rpc': 0.32.1 '@cosmjs/utils': 0.32.2 '@dydxprotocol/v4-proto': 3.0.0-dev.0 '@osmonauts/lcd': 0.6.0 - '@scure/bip32': 1.3.2 - '@scure/bip39': 1.2.1 + '@scure/bip32': 1.3.3 + '@scure/bip39': 1.2.2 axios: 1.1.3 bech32: 1.1.4 bignumber.js: 9.1.1 cosmjs-types: 0.9.0 - ethereum-cryptography: 2.1.2 + ethereum-cryptography: 2.1.3 ethers: 6.6.1 long: 4.0.0 protobufjs: 6.11.4 @@ -1118,8 +1135,8 @@ packages: - utf-8-validate dev: false - /@dydxprotocol/v4-localization@1.1.17: - resolution: {integrity: sha512-kal1LrcihLMEv5YxaA/hd6Zl10Mp3x6jicoXDcXvtyNdrczAl3YapyI2nmeifRAPvfueOaY3W/sKkm2BiSKSsA==} + /@dydxprotocol/v4-localization@1.1.19: + resolution: {integrity: sha512-EA0J5dXyjFoAuSaEYOt066wEMJAXpSb1+ByAcxnEW1PbRznJ9LwrwNDlRtHQk0lkcWC5vdi+UtmSV8D2TsS+vQ==} dev: false /@dydxprotocol/v4-proto@3.0.0-dev.0: @@ -2141,18 +2158,18 @@ packages: '@noble/hashes': 1.3.0 dev: false - /@noble/curves@1.1.0: - resolution: {integrity: sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==} - dependencies: - '@noble/hashes': 1.3.1 - dev: false - /@noble/curves@1.2.0: resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} dependencies: '@noble/hashes': 1.3.2 dev: false + /@noble/curves@1.3.0: + resolution: {integrity: sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==} + dependencies: + '@noble/hashes': 1.3.3 + dev: false + /@noble/ed25519@1.7.3: resolution: {integrity: sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==} dev: true @@ -5018,14 +5035,6 @@ packages: '@scure/base': 1.1.1 dev: false - /@scure/bip32@1.3.1: - resolution: {integrity: sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==} - dependencies: - '@noble/curves': 1.1.0 - '@noble/hashes': 1.3.3 - '@scure/base': 1.1.5 - dev: false - /@scure/bip32@1.3.2: resolution: {integrity: sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==} dependencies: @@ -5034,6 +5043,14 @@ packages: '@scure/base': 1.1.5 dev: false + /@scure/bip32@1.3.3: + resolution: {integrity: sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ==} + dependencies: + '@noble/curves': 1.3.0 + '@noble/hashes': 1.3.3 + '@scure/base': 1.1.5 + dev: false + /@scure/bip39@1.2.0: resolution: {integrity: sha512-SX/uKq52cuxm4YFXWFaVByaSHJh2w3BnokVSeUJVCv6K7WulT9u2BuNRBhuFl8vAuYnzx9bEu9WgpcNYTrYieg==} dependencies: @@ -5048,6 +5065,13 @@ packages: '@scure/base': 1.1.5 dev: false + /@scure/bip39@1.2.2: + resolution: {integrity: sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA==} + dependencies: + '@noble/hashes': 1.3.3 + '@scure/base': 1.1.5 + dev: false + /@solana/buffer-layout@4.0.1: resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} engines: {node: '>=5.10'} @@ -5059,7 +5083,7 @@ packages: resolution: {integrity: sha512-up5VG1dK+GPhykmuMIozJZBbVqpm77vbOG6/r5dS7NBGZonwHfTLdBbsYc3rjmaQ4DpCXUa3tUc4RZHRORvZrw==} dependencies: '@babel/runtime': 7.22.10 - '@noble/curves': 1.2.0 + '@noble/curves': 1.3.0 '@noble/hashes': 1.3.3 '@solana/buffer-layout': 4.0.1 agentkeepalive: 4.5.0 @@ -9283,13 +9307,13 @@ packages: fast-safe-stringify: 2.1.1 dev: false - /ethereum-cryptography@2.1.2: - resolution: {integrity: sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==} + /ethereum-cryptography@2.1.3: + resolution: {integrity: sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA==} dependencies: - '@noble/curves': 1.1.0 - '@noble/hashes': 1.3.1 - '@scure/bip32': 1.3.1 - '@scure/bip39': 1.2.1 + '@noble/curves': 1.3.0 + '@noble/hashes': 1.3.3 + '@scure/bip32': 1.3.3 + '@scure/bip39': 1.2.2 dev: false /ethers@5.7.2: @@ -14909,7 +14933,3 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} dev: true - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false diff --git a/public/configs/env.json b/public/configs/env.json index e4ef9ba..ce84f7a 100644 --- a/public/configs/env.json +++ b/public/configs/env.json @@ -88,7 +88,6 @@ "blogs": "https://www.dydx.foundation/blog", "foundation": "https://www.dydx.foundation", "help": "https://help.dydx.exchange/", - "initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes", "reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders", "mintscanBase": "https://testnet.mintscan.io/dydx-testnet", "documentation": "https://docs.dydx.exchange/", @@ -116,6 +115,13 @@ "images": "/wallets/", "signTypedDataAction": "dYdX Chain Onboarding", "signTypedDataDomainName": "dYdX Chain" + }, + "governance": { + "newMarketProposal": { + "initialDepositAmount": 10000000, + "delayBlocks": 900, + "newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing" + } } }, "dydxprotocol-dev-2": { @@ -161,7 +167,6 @@ "blogs": "https://www.dydx.foundation/blog", "foundation": "https://www.dydx.foundation", "help": "https://help.dydx.exchange/", - "initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes", "reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders", "mintscanBase": "https://testnet.mintscan.io/dydx-testnet", "documentation": "https://docs.dydx.exchange/", @@ -189,6 +194,13 @@ "images": "/wallets/", "signTypedDataAction": "dYdX Chain Onboarding", "signTypedDataDomainName": "dYdX Chain" + }, + "governance": { + "newMarketProposal": { + "initialDepositAmount": 10000000, + "delayBlocks": 900, + "newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing" + } } }, "dydxprotocol-dev-4": { @@ -235,7 +247,6 @@ "blogs": "https://www.dydx.foundation/blog", "foundation": "https://www.dydx.foundation", "help": "https://help.dydx.exchange/", - "initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes", "reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders", "mintscanBase": "https://testnet.mintscan.io/dydx-testnet", "documentation": "https://docs.dydx.exchange/", @@ -263,6 +274,13 @@ "images": "/wallets/", "signTypedDataAction": "dYdX Chain Onboarding", "signTypedDataDomainName": "dYdX Chain" + }, + "governance": { + "newMarketProposal": { + "initialDepositAmount": 10000000, + "delayBlocks": 900, + "newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing" + } } }, "dydxprotocol-dev-5": { @@ -308,7 +326,6 @@ "blogs": "https://www.dydx.foundation/blog", "foundation": "https://www.dydx.foundation", "help": "https://help.dydx.exchange/", - "initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes", "reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders", "mintscanBase": "https://testnet.mintscan.io/dydx-testnet", "documentation": "https://docs.dydx.exchange/", @@ -336,6 +353,13 @@ "images": "/wallets/", "signTypedDataAction": "dYdX Chain Onboarding", "signTypedDataDomainName": "dYdX Chain" + }, + "governance": { + "newMarketProposal": { + "initialDepositAmount": 10000000, + "delayBlocks": 900, + "newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing" + } } }, "dydxprotocol-staging": { @@ -385,7 +409,6 @@ "blogs": "https://www.dydx.foundation/blog", "help": "https://help.dydx.exchange", "foundation": "https://www.dydx.foundation", - "initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes", "reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders", "mintscanBase": "https://testnet.mintscan.io/dydx-testnet", "governanceLearnMore": "https://help.dydx.exchange", @@ -411,6 +434,13 @@ "images": "/wallets/", "signTypedDataAction": "dYdX Chain Onboarding", "signTypedDataDomainName": "dYdX Chain" + }, + "governance": { + "newMarketProposal": { + "initialDepositAmount": 10000000, + "delayBlocks": 900, + "newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing" + } } }, "dydxprotocol-staging-forced-update": { @@ -484,6 +514,13 @@ "build": 40000, "url": "https://apps.apple.com/app/dydx/id1564787350" } + }, + "governance": { + "newMarketProposal": { + "initialDepositAmount": 10000000, + "delayBlocks": 900, + "newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing" + } } }, "dydxprotocol-staging-west": { @@ -533,7 +570,6 @@ "blogs": "https://www.dydx.foundation/blog", "help": "https://help.dydx.exchange", "foundation": "https://www.dydx.foundation", - "initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes", "reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders", "mintscanBase": "https://testnet.mintscan.io/dydx-testnet", "governanceLearnMore": "https://help.dydx.exchange", @@ -559,6 +595,13 @@ "images": "/wallets/", "signTypedDataAction": "dYdX Chain Onboarding", "signTypedDataDomainName": "dYdX Chain" + }, + "governance": { + "newMarketProposal": { + "initialDepositAmount": 10000000, + "delayBlocks": 900, + "newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing" + } } }, "dydxprotocol-testnet": { @@ -612,7 +655,6 @@ "blogs": "https://www.dydx.foundation/blog", "foundation": "https://www.dydx.foundation", "help": "https://help.dydx.exchange/", - "initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes", "reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders", "mintscanBase": "https://testnet.mintscan.io/dydx-testnet", "governanceLearnMore": "https://help.dydx.exchange", @@ -638,6 +680,13 @@ "images": "/wallets/", "signTypedDataAction": "dYdX Chain Onboarding", "signTypedDataDomainName": "dYdX V4" + }, + "governance": { + "newMarketProposal": { + "initialDepositAmount": 10000000, + "delayBlocks": 900, + "newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing" + } } }, "dydxprotocol-testnet-dydx": { @@ -688,7 +737,6 @@ "blogs": "https://www.dydx.foundation/blog", "foundation": "https://www.dydx.foundation", "help": "https://help.dydx.exchange/", - "initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes", "reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders", "mintscanBase": "https://testnet.mintscan.io/dydx-testnet", "governanceLearnMore": "https://help.dydx.exchange", @@ -714,6 +762,13 @@ "images": "/wallets/", "signTypedDataAction": "dYdX Chain Onboarding", "signTypedDataDomainName": "dYdX V4" + }, + "governance": { + "newMarketProposal": { + "initialDepositAmount": 10000000, + "delayBlocks": 900, + "newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing" + } } }, "dydxprotocol-testnet-nodefleet": { @@ -764,7 +819,6 @@ "blogs": "https://www.dydx.foundation/blog", "foundation": "https://www.dydx.foundation", "help": "https://help.dydx.exchange/", - "initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes", "reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders", "mintscanBase": "https://testnet.mintscan.io/dydx-testnet", "governanceLearnMore": "https://help.dydx.exchange", @@ -790,6 +844,13 @@ "images": "/wallets/", "signTypedDataAction": "dYdX Chain Onboarding", "signTypedDataDomainName": "dYdX V4" + }, + "governance": { + "newMarketProposal": { + "initialDepositAmount": 10000000, + "delayBlocks": 900, + "newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing" + } } }, "dydxprotocol-testnet-kingnodes": { @@ -840,7 +901,6 @@ "blogs": "https://www.dydx.foundation/blog", "foundation": "https://www.dydx.foundation", "help": "https://help.dydx.exchange/", - "initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes", "reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders", "mintscanBase": "https://testnet.mintscan.io/dydx-testnet", "governanceLearnMore": "https://help.dydx.exchange", @@ -866,6 +926,13 @@ "images": "/wallets/", "signTypedDataAction": "dYdX Chain Onboarding", "signTypedDataDomainName": "dYdX V4" + }, + "governance": { + "newMarketProposal": { + "initialDepositAmount": 10000000, + "delayBlocks": 900, + "newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing" + } } }, "dydxprotocol-testnet-liquify": { @@ -916,7 +983,6 @@ "blogs": "https://www.dydx.foundation/blog", "foundation": "https://www.dydx.foundation", "help": "https://help.dydx.exchange/", - "initialMarginFractionLearnMore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes", "reduceOnlyLearnMore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders", "mintscanBase": "https://testnet.mintscan.io/dydx-testnet", "governanceLearnMore": "https://help.dydx.exchange", @@ -942,6 +1008,13 @@ "images": "/wallets/", "signTypedDataAction": "dYdX Chain Onboarding", "signTypedDataDomainName": "dYdX V4" + }, + "governance": { + "newMarketProposal": { + "initialDepositAmount": 10000000, + "delayBlocks": 900, + "newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing" + } } }, "dydxprotocol-testnet-polkachu": { @@ -1009,6 +1082,13 @@ "images": "/wallets/", "signTypedDataAction": "dYdX Chain Onboarding", "signTypedDataDomainName": "dYdX V4" + }, + "governance": { + "newMarketProposal": { + "initialDepositAmount": 10000000, + "delayBlocks": 900, + "newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing" + } } }, "dydxprotocol-testnet-bware": { @@ -1059,7 +1139,6 @@ "blogs": "https://www.dydx.foundation/blog", "foundation": "https://www.dydx.foundation", "help": "https://help.dydx.exchange/", - "initialMarginFractionLearnmore": "https://help.dydx.exchange/articles/5232637-maximum-position-sizes", "reduceOnlyLearnmore": "https://help.dydx.exchange/articles/6345793-reduce-only-orders", "mintscanBase": "https://testnet.mintscan.io/dydx-testnet", "governanceLearnmore": "https://help.dydx.exchange", @@ -1085,6 +1164,13 @@ "images": "/wallets/", "signTypedDataAction": "dYdX Chain Onboarding", "signTypedDataDomainName": "dYdX V4" + }, + "governance": { + "newMarketProposal": { + "initialDepositAmount": 10000000, + "delayBlocks": 900, + "newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing" + } } }, "dydxprotocol-mainnet": { @@ -1133,7 +1219,6 @@ "feedback": "[HTTP link to feedback form, can be null]", "blogs": "[HTTP link to blogs, can be null]", "foundation": "[HTTP link to foundation, can be null]", - "initialMarginFractionLearnMore": "[HTTP link to initial margin fraction learn more, can be null]", "reduceOnlyLearnMore": "[HTTP link to reduce-only learn more, can be null]", "documentation": "[HTTP link to documentation, can be null]", "community": "[HTTP link to community, can be null]", @@ -1161,6 +1246,13 @@ "images": "[Relative URL for wallet images]", "signTypedDataAction": "dYdX Chain Onboarding", "signTypedDataDomainName": "dYdX Chain" + }, + "governance": { + "newMarketProposal": { + "initialDepositAmount": 0, + "delayBlocks": 0, + "newMarketsMethodology": "[URL to spreadsheet or document that explains methodology]" + } } } } diff --git a/public/configs/markets.json b/public/configs/markets.json index e81e812..f743aa3 100644 --- a/public/configs/markets.json +++ b/public/configs/markets.json @@ -69,6 +69,13 @@ "whitepaperLink": "https://bitcoincash.org/", "coinMarketCapsLink": "https://coinmarketcap.com/currencies/bitcoin-cash/" }, + "BONK-USD": { + "name": "BONK COIN", + "tags": [], + "websiteLink": "https://bonkcoin.com/", + "whitepaperLink": "https://bonkcoin.com/", + "coinMarketCapsLink": "https://coinmarketcap.com/currencies/bonk1/" + }, "BLUR-USD": { "name": "Blur", "tags": [], diff --git a/public/configs/potentialMarketExchangeConfig.csv b/public/configs/potentialMarketExchangeConfig.csv new file mode 100644 index 0000000..ddb12d2 --- /dev/null +++ b/public/configs/potentialMarketExchangeConfig.csv @@ -0,0 +1,704 @@ +base_asset,exchange,pair,min_2_depth,avg_30d_vol,reference_price,risk_assessment,num_oracles,liquidity_tier,asset_name,adjust_by_market +AAVE,Mexc,AAVE_USDT,403707.603,299498.6587,88.46188619,A,7,2,AAVE,USDT-USD +AAVE,Huobi,aaveusdt,49562.27661,34092101.66,88.52768881,A,7,2,AAVE,USDT-USD +AAVE,Kraken,AAVEUSD,84969.1289,732237.4435,88.21901516,A,7,2,AAVE, +AAVE,Okx,AAVE-USDT,120824.3981,5483819.403,88.48717486,A,7,2,AAVE,USDT-USD +AAVE,Kucoin,AAVE-USDT,60134.45372,1454001.73,88.41847956,A,7,2,AAVE,USDT-USD +AAVE,Binance,AAVEUSDT,336646.7802,17941167.87,88.40806057,A,7,2,AAVE,USDT-USD +AAVE,CoinbasePro,AAVE-USD,162207.2275,7955414.095,88.41304215,A,7,2,AAVE, +ADA,Okx,ADA-USDT,303911.146,12693505.79,0.4718322348,A,9,1,Cardano,USDT-USD +ADA,CoinbasePro,ADA-USD,611511.2428,18323224.07,0.4703816721,A,9,1,Cardano, +ADA,Huobi,adausdt,149750.1588,18688486.68,0.470293013,A,9,1,Cardano,USDT-USD +ADA,Kucoin,ADA-USDT,204346.5493,11339662.31,0.470650622,A,9,1,Cardano,USDT-USD +ADA,Bitstamp,ADA/USD,111141.4265,495063.9401,0.4732612949,A,9,1,Cardano, +ADA,Mexc,ADA_USDT,1480561.883,34705754.08,0.4706681442,A,9,1,Cardano,USDT-USD +ADA,Bybit,ADAUSDT,261755.7266,15267158.53,0.4715127504,A,9,1,Cardano,USDT-USD +ADA,Kraken,ADAUSD,631495.1952,4783679.81,0.4728831552,A,9,1,Cardano, +ADA,Binance,ADAUSDT,1014519.017,74913609.68,0.4709109462,A,9,1,Cardano,USDT-USD +AGIX,Okx,AGIX-USDT,144402.4677,1230616.692,0.2534299858,A,6,2,SingularityNET,USDT-USD +AGIX,Bybit,AGIXUSDT,72731.67454,2177116.497,0.2534800192,A,6,2,SingularityNET,USDT-USD +AGIX,Kucoin,AGIX-USDT,86823.62761,4637581.791,0.2531545743,A,6,2,SingularityNET,USDT-USD +AGIX,Mexc,AGIX_USDT,114261.8075,179945.4082,0.2532243225,A,6,2,SingularityNET,USDT-USD +AGIX,Binance,AGIXUSDT,181499.5614,6601700.149,0.2535772917,A,6,2,SingularityNET,USDT-USD +AGIX,Gate,AGIX_USDT,50000,100000,0,A,6,2,SingularityNET,USDT-USD +ALGO,Kucoin,ALGO-USDT,125172.0507,2774508.432,0.1612760665,A,6,2,Algorand,USDT-USD +ALGO,Mexc,ALGO_USDT,471722.5569,391031.4403,0.1615972948,A,6,2,Algorand,USDT-USD +ALGO,Okx,ALGO-USDT,84724.99655,3001155.055,0.1614784231,A,6,2,Algorand,USDT-USD +ALGO,CoinbasePro,ALGO-USD,137293.3037,3626194.058,0.1612613776,A,6,2,Algorand, +ALGO,Kraken,ALGOUSD,94239.46899,856438.0736,0.1611316036,A,6,2,Algorand, +ALGO,Binance,ALGOUSDT,240363.9844,10216526.81,0.1613137606,A,6,2,Algorand,USDT-USD +APE,Mexc,APE_USDT,845830.979,329116.5427,1.31149687,A,7,2,ApeCoin,USDT-USD +APE,Kucoin,APE-USDT,74830.83223,1527594.928,1.306893397,A,7,2,ApeCoin,USDT-USD +APE,CoinbasePro,APE-USD,79825.96928,1765569.337,1.310147807,A,7,2,ApeCoin, +APE,Okx,APE-USDT,127038.7774,4931009.134,1.310171735,A,7,2,ApeCoin,USDT-USD +APE,Binance,APEUSDT,295540.0092,16809984.56,1.309457667,A,7,2,ApeCoin,USDT-USD +APE,Kraken,APEUSD,47261.34196,350969.3303,1.302436726,A,7,2,ApeCoin, +APE,Gate,APE_USDT,50000,100000,0,A,7,2,ApeCoin,USDT-USD +APT,Binance,APTUSDT,970622.772,42662112,8.365109058,A,8,2,Aptos,USDT-USD +APT,Kraken,APTUSD,95252.8507,687239.9038,8.373953519,A,8,2,Aptos, +APT,Bybit,APTUSDT,421662.7604,13658424.61,8.360517459,A,8,2,Aptos,USDT-USD +APT,Kucoin,APT-USDT,59781.95498,3012611.094,8.371347497,A,8,2,Aptos,USDT-USD +APT,Mexc,APT_USDT,188448.7027,6995386.772,8.37360865,A,8,2,Aptos,USDT-USD +APT,CoinbasePro,APT-USD,158248.5255,5176336.024,8.369192123,A,8,2,Aptos, +APT,Okx,APT-USDT,596052.5515,20209030.67,8.37385096,A,8,2,Aptos,USDT-USD +APT,Gate,APT_USDT,50000,100000,0,A,8,2,Aptos,USDT-USD +ARB,Kraken,ARBUSD,100206.2199,4381943.143,1.705803002,A,8,1,Arbitrum, +ARB,Mexc,ARB_USDT,563395.9496,70966050.57,1.700151185,A,8,1,Arbitrum,USDT-USD +ARB,CoinbasePro,ARB-USD,323984.7248,25023919.67,1.706804349,A,8,1,Arbitrum, +ARB,Binance,ARBUSDT,1448064.308,225490594,1.700534337,A,8,1,Arbitrum,USDT-USD +ARB,Bybit,ARBUSDT,188544.697,49644508.17,1.697965318,A,8,1,Arbitrum,USDT-USD +ARB,Okx,ARB-USDT,619050.2317,56911723.48,1.700105696,A,8,1,Arbitrum,USDT-USD +ARB,Kucoin,ARB-USDT,244278.1403,15751598.26,1.705204466,A,8,1,Arbitrum,USDT-USD +ARB,Huobi,arbusdt,111073.3497,24106121.68,1.696818375,A,8,1,Arbitrum,USDT-USD +ATOM,Kucoin,ATOM-USDT,122511.6105,4164205.618,9.196821466,A,8,2,Cosmos,USDT-USD +ATOM,CoinbasePro,ATOM-USD,205758.8309,4244575.601,9.188194158,A,8,2,Cosmos, +ATOM,Binance,ATOMUSDT,500205.8745,32707609.21,9.19886839,A,8,2,Cosmos,USDT-USD +ATOM,Kraken,ATOMUSD,228688.3729,1024035.956,9.218557996,A,8,2,Cosmos, +ATOM,Okx,ATOM-USDT,147209.9881,6727992.679,9.196235185,A,8,2,Cosmos,USDT-USD +ATOM,Mexc,ATOM_USDT,396797.5433,1008586.239,9.21317801,A,8,2,Cosmos,USDT-USD +ATOM,Bybit,ATOMUSDT,100035.0706,5523700.635,9.191262868,A,8,2,Cosmos,USDT-USD +ATOM,Gate,ATOM_USDT,50000,100000,0,A,8,2,Cosmos,USDT-USD +AVAX,Okx,AVAX-USDT,459223.0249,27191336.53,30.3671387,A,9,1,Avalanche,USDT-USD +AVAX,Mexc,AVAX_USDT,2630410.171,40197237.8,30.31335915,A,9,1,Avalanche,USDT-USD +AVAX,CoinbasePro,AVAX-USD,710189.1641,41234008.85,30.43579342,A,9,1,Avalanche, +AVAX,Kraken,AVAXUSD,455749.7351,5083869.862,30.36461631,A,9,1,Avalanche, +AVAX,Huobi,avaxusdt,83674.34414,20197355.5,30.38713582,A,9,1,Avalanche,USDT-USD +AVAX,Bitstamp,AVAX/USD,78931.59345,492591.779,30.51926775,A,9,1,Avalanche, +AVAX,Binance,AVAXUSDT,1424442.662,110228072.3,30.31927119,A,9,1,Avalanche,USDT-USD +AVAX,Bybit,AVAXUSDT,266594.6447,19032772.46,30.37667694,A,9,1,Avalanche,USDT-USD +AVAX,Kucoin,AVAX-USDT,256007.3589,13423273.72,30.36129437,A,9,1,Avalanche,USDT-USD +BCH,Kraken,BCHUSD,203340.9953,1163173.528,236.4383838,A,9,1,Bitcoin Cash, +BCH,Bitstamp,BCH/USD,133890.8622,1113055.48,236.3834073,A,9,1,Bitcoin Cash, +BCH,Kucoin,BCH-USDT,153403.2244,1766025.88,236.2130317,A,9,1,Bitcoin Cash,USDT-USD +BCH,Mexc,BCH_USDT,1688109.018,340077.5421,236.974317,A,9,1,Bitcoin Cash,USDT-USD +BCH,Binance,BCHUSDT,672821.7917,32395763.97,236.0220829,A,9,1,Bitcoin Cash,USDT-USD +BCH,Bybit,BCHUSDT,156013.3525,7323063.446,236.304741,A,9,1,Bitcoin Cash,USDT-USD +BCH,Huobi,bchusdt,65221.14333,14976246.74,236.1401006,A,9,1,Bitcoin Cash,USDT-USD +BCH,Okx,BCH-USDT,351452.4549,15579827.1,236.1496084,A,9,1,Bitcoin Cash,USDT-USD +BCH,CoinbasePro,BCH-USD,448678.0454,10694749.58,236.3332929,A,9,1,Bitcoin Cash, +BLUR,Kraken,BLURUSD,99075.46212,1216513.285,0.6025188372,A,7,2,Blur, +BLUR,Bybit,BLURUSDT,68313.916,6461469.994,0.60531087,A,7,2,Blur,USDT-USD +BLUR,Binance,BLURUSDT,523824.0691,49785352.29,0.6085401119,A,7,2,Blur,USDT-USD +BLUR,Kucoin,BLUR-USDT,114279.3879,3580944.358,0.6060076016,A,7,2,Blur,USDT-USD +BLUR,Okx,BLUR-USDT,242440.7708,21042871.79,0.6072397492,A,7,2,Blur,USDT-USD +BLUR,CoinbasePro,BLUR-USD,156092.3813,8736803.112,0.6038877368,A,7,2,Blur, +BLUR,Mexc,BLUR_USDT,845700.0176,614271.1779,0.6015683969,A,7,2,Blur,USDT-USD +BNB,Okx,BNB-USDT,171035.3871,10049830.17,291.7391615,A,6,2,Binance Coin,USDT-USD +BNB,Kucoin,BNB-USDT,172933.5367,7563235.244,291.8671543,A,6,2,Binance Coin,USDT-USD +BNB,Mexc,BNB_USDT,2668302.204,2095942.424,291.3317029,A,6,2,Binance Coin,USDT-USD +BNB,Binance,BNBUSDT,2315487.589,299938471.1,292.0261567,A,6,2,Binance Coin,USDT-USD +BNB,Bybit,BNBUSDT,73840.12419,11584488.51,291.812684,A,6,2,Binance Coin,USDT-USD +BNB,Gate,BNB_USDT,50000,100000,0,A,6,2,Binance Coin,USDT-USD +BONK,Bybit,BONKUSDT,91223.30674,10108782.84,1.09E-05,A,6,2,Bonk Token,USDT-USD +BONK,Mexc,BONK_USDT,880507.727,1996432.036,1.10E-05,A,6,2,Bonk Token,USDT-USD +BONK,Binance,BONKUSDT,496236.8093,63520367.26,1.09E-05,A,6,2,Bonk Token,USDT-USD +BONK,Okx,BONK-USDT,84194.41757,4939704.699,1.09E-05,A,6,2,Bonk Token,USDT-USD +BONK,CoinbasePro,BONK-USD,291120.8766,24041618.38,1.10E-05,A,6,2,Bonk Token, +BONK,Kucoin,BONK-USDT,104413.0879,5795566.827,1.09E-05,A,6,2,Bonk Token,USDT-USD +BTC,Kucoin,BTC-USDT,1385049.373,192647255.8,39920.8141,A,9,1,Bitcoin,USDT-USD +BTC,Mexc,BTC_USDT,6055794.786,468890338.6,39929.87241,A,9,1,Bitcoin,USDT-USD +BTC,Bybit,BTCUSDT,1934000.115,501075059.1,39905.40634,A,9,1,Bitcoin,USDT-USD +BTC,Okx,BTC-USDT,3216401.515,736570802.6,39910.57726,A,9,1,Bitcoin,USDT-USD +BTC,Bitstamp,BTC/USD,4904357.079,103847807.2,39898.51266,A,9,1,Bitcoin, +BTC,Huobi,btcusdt,1628523.051,85957777.78,39927.11023,A,9,1,Bitcoin,USDT-USD +BTC,CoinbasePro,BTC-USD,11838510.17,799998360.6,39872.42919,A,9,1,Bitcoin, +BTC,Kraken,BTCUSD,11254244.98,152725974.7,39905.34906,A,9,1,Bitcoin, +BTC,Binance,BTCUSDT,13081922.22,1943592587,39912.24136,A,9,1,Bitcoin,USDT-USD +CHZ,Okx,CHZ-USDT,76721.70261,9853334.361,0.1037356507,A,6,2,Chiliz,USDT-USD +CHZ,Mexc,CHZ_USDT,230477.9128,285408.6504,0.1038430482,A,6,2,Chiliz,USDT-USD +CHZ,CoinbasePro,CHZ-USD,51276.07653,1252645.033,0.1054762023,A,6,2,Chiliz, +CHZ,Kraken,CHZUSD,48524.85664,395637.5252,0.1050375877,A,6,2,Chiliz, +CHZ,Binance,CHZUSDT,249888.0127,28501304.85,0.1046721926,A,6,2,Chiliz,USDT-USD +CHZ,Gate,CHZ_USDT,50000,100000,0,A,6,2,Chiliz,USDT-USD +CRV,Kraken,CRVUSD,60416.85503,292275.2165,0.4482389055,A,6,2,Curve DAO Token, +CRV,Kucoin,CRV-USDT,50096.30378,680353.338,0.4434254994,A,6,2,Curve DAO Token,USDT-USD +CRV,Binance,CRVUSDT,265385.0097,9688519.274,0.443424373,A,6,2,Curve DAO Token,USDT-USD +CRV,CoinbasePro,CRV-USD,96582.28361,871025.6346,0.4446821049,A,6,2,Curve DAO Token, +CRV,Mexc,CRV_USDT,202941.3475,133320.8099,0.4438313683,A,6,2,Curve DAO Token,USDT-USD +CRV,Okx,CRV-USDT,109901.21,6873330.009,0.4425725114,A,6,2,Curve DAO Token,USDT-USD +DOGE,CoinbasePro,DOGE-USD,705184.7562,25424875.32,0.07793120656,A,9,1,Dogecoin, +DOGE,Okx,DOGE-USDT,565834.5118,33076839.3,0.07788150395,A,9,1,Dogecoin,USDT-USD +DOGE,Mexc,DOGE_USDT,1091538.578,22937578.29,0.0779243829,A,9,1,Dogecoin,USDT-USD +DOGE,Kraken,DOGEUSD,547998.0729,4621710.265,0.07778464129,A,9,1,Dogecoin, +DOGE,Bybit,DOGEUSDT,290256.381,15914185,0.07796760983,A,9,1,Dogecoin,USDT-USD +DOGE,Bitstamp,DOGE/USD,46447.64873,189541.7938,0.07799339803,A,9,1,Dogecoin, +DOGE,Binance,DOGEUSDT,1252926.134,84403824.56,0.07796643769,A,9,1,Dogecoin,USDT-USD +DOGE,Huobi,dogeusdt,269955.645,21525311.57,0.07794967908,A,9,1,Dogecoin,USDT-USD +DOGE,Kucoin,DOGE-USDT,365702.9014,7810505.65,0.07798714967,A,9,1,Dogecoin,USDT-USD +DOT,Kraken,DOTUSD,368701.8747,4429592.47,6.452188898,A,8,1,Polkadot, +DOT,Okx,DOT-USDT,222355.039,10742911.87,6.458175307,A,8,1,Polkadot,USDT-USD +DOT,Huobi,dotusdt,45783.29935,10974447.87,6.450317276,A,8,1,Polkadot,USDT-USD +DOT,Mexc,DOT_USDT,1098245.94,1339831.03,6.446585762,A,8,1,Polkadot,USDT-USD +DOT,Bybit,DOTUSDT,166496.7868,9913978.391,6.454271244,A,8,1,Polkadot,USDT-USD +DOT,CoinbasePro,DOT-USD,168119.2694,9778920.932,6.452749635,A,8,1,Polkadot, +DOT,Kucoin,DOT-USDT,124303.7984,5544103.268,6.453780538,A,8,1,Polkadot,USDT-USD +DOT,Binance,DOTUSDT,593806.1697,48873686.06,6.451243808,A,8,1,Polkadot,USDT-USD +ENS,Mexc,ENS_USDT,367658.849,670539.5241,17.98863652,A,6,2,Ethereum Name Service (ENS),USDT-USD +ENS,Kucoin,ENS-USDT,54724.81451,3676707.428,17.75880758,A,6,2,Ethereum Name Service (ENS),USDT-USD +ENS,Binance,ENSUSDT,291418.3232,62479176.65,17.81688813,A,6,2,Ethereum Name Service (ENS),USDT-USD +ENS,CoinbasePro,ENS-USD,91775.13594,7641723.902,17.79343763,A,6,2,Ethereum Name Service (ENS), +ENS,Okx,ENS-USDT,137796.003,17044833.9,17.78364476,A,6,2,Ethereum Name Service (ENS),USDT-USD +ENS,Gate,ENS_USDT,50000,100000,0,A,6,2,Ethereum Name Service (ENS),USDT-USD +EOS,Binance,EOSUSDT,372008.7468,8074383.692,0.6830128043,A,8,2,Eos,USDT-USD +EOS,Mexc,EOS_USDT,1199704.281,272102.5368,0.6840073934,A,8,2,Eos,USDT-USD +EOS,Kucoin,EOS-USDT,75854.21225,709014.6871,0.68384828,A,8,2,Eos,USDT-USD +EOS,CoinbasePro,EOS-USD,77320.52881,1313993.017,0.6822937779,A,8,2,Eos, +EOS,Kraken,EOSUSD,88673.50535,723904.186,0.6839062109,A,8,2,Eos, +EOS,Okx,EOS-USDT,139325.4759,9112853.76,0.6825281331,A,8,2,Eos,USDT-USD +EOS,Bybit,EOSUSDT,50578.19146,5841158.864,0.6822045569,A,8,2,Eos,USDT-USD +EOS,Gate,EOS_USDT,50000,100000,0,A,8,2,Eos,USDT-USD +ETC,Kucoin,ETC-USDT,113759.0808,3477554.997,22.85192736,A,8,1,Ethereum Classic,USDT-USD +ETC,Binance,ETCUSDT,655668.4981,60729272.86,22.86694828,A,8,1,Ethereum Classic,USDT-USD +ETC,Bybit,ETCUSDT,49561.58743,2838378.919,22.8367253,A,8,1,Ethereum Classic,USDT-USD +ETC,Kraken,ETCUSD,155878.8877,734888.778,22.88123977,A,8,1,Ethereum Classic, +ETC,CoinbasePro,ETC-USD,584427.6111,7597750.664,22.83725611,A,8,1,Ethereum Classic, +ETC,Huobi,etcusdt,81646.91108,13533193.91,22.77483439,A,8,1,Ethereum Classic,USDT-USD +ETC,Okx,ETC-USDT,338589.5466,23459446.52,22.81594291,A,8,1,Ethereum Classic,USDT-USD +ETC,Mexc,ETC_USDT,1378585.921,911135.813,22.92403344,A,8,1,Ethereum Classic,USDT-USD +ETH,Bitstamp,ETH/USD,1786424.201,19272496.97,2212.492226,A,9,1,Ethereum, +ETH,Okx,ETH-USDT,2444418.764,388934350.5,2210.16441,A,9,1,Ethereum,USDT-USD +ETH,Huobi,ethusdt,1695970.121,34272154.83,2212.288729,A,9,1,Ethereum,USDT-USD +ETH,Kucoin,ETH-USDT,1037412.076,119386693.6,2211.480181,A,9,1,Ethereum,USDT-USD +ETH,Bybit,ETHUSDT,1345249.473,304189767.2,2211.399676,A,9,1,Ethereum,USDT-USD +ETH,Kraken,ETHUSD,5075383.05,56853252.58,2212.377288,A,9,1,Ethereum, +ETH,Mexc,ETH_USDT,4484321.007,210359167.7,2214.032265,A,9,1,Ethereum,USDT-USD +ETH,CoinbasePro,ETH-USD,7298871.343,296252747.3,2210.07616,A,9,1,Ethereum, +ETH,Binance,ETHUSDT,10324165.63,1060630897,2211.179573,A,9,1,Ethereum,USDT-USD +FET,Mexc,FET_USDT,494656.0995,559935.8786,0.5882081836,A,6,2,Fetch AI,USDT-USD +FET,Binance,FETUSDT,465708.0914,22769357.29,0.5862566061,A,6,2,Fetch AI,USDT-USD +FET,Kucoin,FET-USDT,96173.26242,4354855.944,0.5872583338,A,6,2,Fetch AI,USDT-USD +FET,Okx,FET-USDT,80416.82548,1578553.143,0.587271404,A,6,2,Fetch AI,USDT-USD +FET,Kraken,FETUSD,80688.82031,1386327.677,0.5848580771,A,6,2,Fetch AI, +FET,CoinbasePro,FET-USD,241779.2529,9092328.77,0.5848723328,A,6,2,Fetch AI, +FIL,Kucoin,FIL-USDT,136368.2949,7410428.74,4.93172295,A,8,1,Filecoin,USDT-USD +FIL,Kraken,FILUSD,133991.2228,1832800.962,4.933693054,A,8,1,Filecoin, +FIL,CoinbasePro,FIL-USD,258870.6985,11530932.48,4.934286612,A,8,1,Filecoin, +FIL,Bybit,FILUSDT,86576.25386,7525363.033,4.91922609,A,8,1,Filecoin,USDT-USD +FIL,Mexc,FIL_USDT,1094874.372,1819214.992,4.927851525,A,8,1,Filecoin,USDT-USD +FIL,Okx,FIL-USDT,646778.4394,55504900,4.9289709,A,8,1,Filecoin,USDT-USD +FIL,Binance,FILUSDT,844740.0409,75887089.73,4.930605871,A,8,1,Filecoin,USDT-USD +FIL,Huobi,filusdt,68173.55527,16793194.38,4.936018668,A,8,1,Filecoin,USDT-USD +FTM,Bybit,FTMUSDT,71346.61591,4128311.729,0.3352808917,A,6,2,Fantom,USDT-USD +FTM,Kraken,FTMUSD,87646.51897,1176507.833,0.3346537706,A,6,2,Fantom, +FTM,Kucoin,FTM-USDT,106225.8231,4400742.84,0.3358058793,A,6,2,Fantom,USDT-USD +FTM,Mexc,FTM_USDT,632339.7399,1081199.831,0.3365010633,A,6,2,Fantom,USDT-USD +FTM,Binance,FTMUSDT,424997.2126,25764943.66,0.3360637395,A,6,2,Fantom,USDT-USD +FTM,Okx,FTM-USDT,98090.82999,4900885.095,0.3376845609,A,6,2,Fantom,USDT-USD +GALA,Okx,GALA-USDT,189873.4137,6654005.649,0.02204820477,A,6,2,Gala,USDT-USD +GALA,Mexc,GALA_USDT,674173.1073,662194.7213,0.02211283071,A,6,2,Gala,USDT-USD +GALA,Bybit,GALAUSDT,81233.95423,2802651.478,0.02204724605,A,6,2,Gala,USDT-USD +GALA,Kraken,GALAUSD,81853.15768,971887.7737,0.02213452999,A,6,2,Gala, +GALA,Binance,GALAUSDT,415969.0247,23466983.63,0.02205812128,A,6,2,Gala,USDT-USD +GALA,Gate,GALA_USDT,50000,100000,0,A,6,2,Gala,USDT-USD +GRT,CoinbasePro,GRT-USD,212787.1065,5275612.932,0.1493811838,A,7,2,The Graph, +GRT,Okx,GRT-USDT,65342.41311,2506599.164,0.1492456221,A,7,2,The Graph,USDT-USD +GRT,Mexc,GRT_USDT,598125.0805,479952.4649,0.1491757716,A,7,2,The Graph,USDT-USD +GRT,Kraken,GRTUSD,75871.99326,633740.4267,0.1498390276,A,7,2,The Graph, +GRT,Binance,GRTUSDT,326438.7018,17403725.33,0.1491240716,A,7,2,The Graph,USDT-USD +GRT,Kucoin,GRT-USDT,81544.85738,1753762.597,0.1493661616,A,7,2,The Graph,USDT-USD +GRT,Gate,GRT_USDT,50000,100000,0,A,7,2,The Graph,USDT-USD +HBAR,Kucoin,HBAR-USDT,114290.7661,2775278.488,0.07132025496,A,7,2,Hedera Hashgraph,USDT-USD +HBAR,Mexc,HBAR_USDT,460300.1662,483877.2872,0.07108943658,A,7,2,Hedera Hashgraph,USDT-USD +HBAR,CoinbasePro,HBAR-USD,214294.0589,7087561.93,0.07116005717,A,7,2,Hedera Hashgraph, +HBAR,Okx,HBAR-USDT,112689.0708,4026461.082,0.07125365623,A,7,2,Hedera Hashgraph,USDT-USD +HBAR,Huobi,hbarusdt,46422.78344,12502601.52,0.07144363395,A,7,2,Hedera Hashgraph,USDT-USD +HBAR,Binance,HBARUSDT,342801.5964,14209768.84,0.07132722883,A,7,2,Hedera Hashgraph,USDT-USD +HBAR,Bybit,HBARUSDT,45261.49627,1258321.041,0.07136344216,A,7,2,Hedera Hashgraph,USDT-USD +ICP,Binance,ICPUSDT,501774.1138,77170682.6,11.52804787,A,7,2,Internet Computer,USDT-USD +ICP,Okx,ICP-USDT,297422.7336,20593859.34,11.59386803,A,7,2,Internet Computer,USDT-USD +ICP,Mexc,ICP_USDT,229038.0671,2659248.459,11.29959518,A,7,2,Internet Computer,USDT-USD +ICP,Bybit,ICPUSDT,145658.1104,13815502.64,11.47155514,A,7,2,Internet Computer,USDT-USD +ICP,CoinbasePro,ICP-USD,481694.0934,22919263.78,11.51929241,A,7,2,Internet Computer, +ICP,Kucoin,ICP-USDT,243799.5596,21281791.71,11.4267898,A,7,2,Internet Computer,USDT-USD +ICP,Kraken,ICPUSD,152510.8207,4230646.898,11.48180455,A,7,2,Internet Computer, +INJ,Binance,INJUSDT,761854.6344,75471268.13,31.75641906,A,7,2,Injective Protocol,USDT-USD +INJ,Bybit,INJUSDT,46259.03266,8671297.48,31.81868206,A,7,2,Injective Protocol,USDT-USD +INJ,Mexc,INJ_USDT,195130.7785,2547540.558,31.75180875,A,7,2,Injective Protocol,USDT-USD +INJ,Kraken,INJUSD,110554.9597,4615214.653,31.81822066,A,7,2,Injective Protocol, +INJ,CoinbasePro,INJ-USD,263574.9589,21960083.14,31.75834432,A,7,2,Injective Protocol, +INJ,Kucoin,INJ-USDT,112763.3848,13043315.83,31.73964964,A,7,2,Injective Protocol,USDT-USD +INJ,Okx,INJ-USDT,156547.4276,6879780.129,31.838232,A,7,2,Injective Protocol,USDT-USD +JTO,CoinbasePro,JTO-USD,209989.3821,10018464.73,1.887681028,A,6,2,Jito, +JTO,Binance,JTOUSDT,350644.6827,47762160.17,1.883291251,A,6,2,Jito,USDT-USD +JTO,Bybit,JTOUSDT,74864.14695,4967573.71,1.886557933,A,6,2,Jito,USDT-USD +JTO,Mexc,JTO_USDT,138559.5351,998743.8255,1.88425904,A,6,2,Jito,USDT-USD +JTO,Okx,JTO-USDT,96745.66258,8928569.193,1.884792183,A,6,2,Jito,USDT-USD +JTO,Kucoin,JTO-USDT,87953.5565,3015273.183,1.890669659,A,6,2,Jito,USDT-USD +KAVA,CoinbasePro,KAVA-USD,176534.8573,385485.2501,0.6919030037,A,6,2,Kava, +KAVA,Mexc,KAVA_USDT,1176186.319,270495.2643,0.6895330959,A,6,2,Kava,USDT-USD +KAVA,Kucoin,KAVA-USDT,89752.19321,596070.2703,0.6890117656,A,6,2,Kava,USDT-USD +KAVA,Binance,KAVAUSDT,646090.2324,11218433.99,0.6895853325,A,6,2,Kava,USDT-USD +KAVA,Kraken,KAVAUSD,85320.83296,641014.1765,0.6908946014,A,6,2,Kava, +KAVA,Gate,KAVA_USDT,50000,100000,0,A,6,2,Kava,USDT-USD +LDO,Okx,LDO-USDT,181894.181,10111578.42,2.88714217,A,8,2,Lido DAO,USDT-USD +LDO,Binance,LDOUSDT,387738.82,41043700.87,2.883611792,A,8,2,Lido DAO,USDT-USD +LDO,CoinbasePro,LDO-USD,220300.8676,11976409.69,2.884625596,A,8,2,Lido DAO, +LDO,Kraken,LDOUSD,100447.1249,2150960.494,2.887488478,A,8,2,Lido DAO, +LDO,Mexc,LDO_USDT,588930.053,638809.6967,2.882180527,A,8,2,Lido DAO,USDT-USD +LDO,Kucoin,LDO-USDT,91009.30345,4468563.248,2.885880042,A,8,2,Lido DAO,USDT-USD +LDO,Bybit,LDOUSDT,71154.49236,6463827.135,2.885385432,A,8,2,Lido DAO,USDT-USD +LDO,Gate,LDO_USDT,50000,100000,0,A,8,2,Lido DAO,USDT-USD +LINK,Kraken,LINKUSD,552242.3853,5755261.063,13.82357462,A,8,1,ChainLink, +LINK,CoinbasePro,LINK-USD,680356.4439,32122820.26,13.80640803,A,8,1,ChainLink, +LINK,Mexc,LINK_USDT,1218298.471,49003625.57,13.80057366,A,8,1,ChainLink,USDT-USD +LINK,Binance,LINKUSDT,1057623.562,91375865.04,13.7948244,A,8,1,ChainLink,USDT-USD +LINK,Okx,LINK-USDT,275176.1551,13565986.64,13.79776617,A,8,1,ChainLink,USDT-USD +LINK,Bitstamp,LINK/USD,151182.7984,1359533.87,13.84044633,A,8,1,ChainLink, +LINK,Kucoin,LINK-USDT,196203.2947,9579617.943,13.81059009,A,8,1,ChainLink,USDT-USD +LINK,Bybit,LINKUSDT,180315.7755,14220162.33,13.85826731,A,8,1,ChainLink,USDT-USD +LTC,CoinbasePro,LTC-USD,543451.3689,13785634.51,65.4631381,A,9,1,Litecoin, +LTC,Mexc,LTC_USDT,1879096.824,17331806.29,65.43634611,A,9,1,Litecoin,USDT-USD +LTC,Okx,LTC-USDT,507929.3471,26530065.91,65.41225491,A,9,1,Litecoin,USDT-USD +LTC,Kucoin,LTC-USDT,290350.1634,6126387.388,65.4318351,A,9,1,Litecoin,USDT-USD +LTC,Bybit,LTCUSDT,201299.6733,12383937.05,65.45086009,A,9,1,Litecoin,USDT-USD +LTC,Bitstamp,LTC/USD,71302.43935,837193.57,65.38819428,A,9,1,Litecoin, +LTC,Huobi,ltcusdt,150004.7632,4614143.66,65.4369822,A,9,1,Litecoin,USDT-USD +LTC,Kraken,LTCUSD,485564.9077,2601077.121,65.43280684,A,9,1,Litecoin, +LTC,Binance,LTCUSDT,975861.6282,46447198.76,65.43597402,A,9,1,Litecoin,USDT-USD +MANA,Binance,MANAUSDT,161539.8083,8060438.22,0.4335988613,A,7,2,Decentraland,USDT-USD +MANA,Kucoin,MANA-USDT,58087.72222,503402.4757,0.4338408816,A,7,2,Decentraland,USDT-USD +MANA,Kraken,MANAUSD,84924.79935,272373.0049,0.432452467,A,7,2,Decentraland, +MANA,Mexc,MANA_USDT,253761.7046,145519.6743,0.4345951497,A,7,2,Decentraland,USDT-USD +MANA,Okx,MANA-USDT,68844.47795,1431443.961,0.4338122156,A,7,2,Decentraland,USDT-USD +MANA,CoinbasePro,MANA-USD,69142.62162,865483.8728,0.4332575848,A,7,2,Decentraland, +MANA,Gate,MANA_USDT,50000,100000,0,A,7,2,Decentraland,USDT-USD +MASK,Binance,MASKUSDT,527334.4347,29606345.22,3.252034856,A,7,2,Mask Network,USDT-USD +MASK,Okx,MASK-USDT,164626.3439,17425407.01,3.247435343,A,7,2,Mask Network,USDT-USD +MASK,Kucoin,MASK-USDT,68471.50785,2787550.55,3.250394924,A,7,2,Mask Network,USDT-USD +MASK,Mexc,MASK_USDT,551854.5319,340523.7233,3.255251096,A,7,2,Mask Network,USDT-USD +MASK,CoinbasePro,MASK-USD,76371.2574,1172479.2,3.257449365,A,7,2,Mask Network, +MASK,Bybit,MASKUSDT,55836.09372,3549089.841,3.251526238,A,7,2,Mask Network,USDT-USD +MASK,Gate,MASK_USDT,50000,100000,0,A,7,2,Mask Network,USDT-USD +MATIC,Okx,MATIC-USDT,286529.4599,19272111.96,0.7282054395,A,9,1,Matic Network,USDT-USD +MATIC,CoinbasePro,MATIC-USD,392683.598,14444572.98,0.7281953324,A,9,1,Matic Network, +MATIC,Binance,MATICUSDT,880166.8053,97986293.13,0.7281469424,A,9,1,Matic Network,USDT-USD +MATIC,Huobi,maticusdt,109573.122,15234696.66,0.7286294763,A,9,1,Matic Network,USDT-USD +MATIC,Bybit,MATICUSDT,253953.798,21099460.02,0.7281887236,A,9,1,Matic Network,USDT-USD +MATIC,Mexc,MATIC_USDT,985242.4337,45954909.9,0.7282376458,A,9,1,Matic Network,USDT-USD +MATIC,Kraken,MATICUSD,478478.4995,4510025.126,0.7294573007,A,9,1,Matic Network, +MATIC,Bitstamp,MATIC/USD,77920.84684,344911.6889,0.733080163,A,9,1,Matic Network, +MATIC,Kucoin,MATIC-USDT,356785.0871,8215026.183,0.7274795596,A,9,1,Matic Network,USDT-USD +MKR,CoinbasePro,MKR-USD,189657.3728,7901151.839,2113.462825,A,6,2,Maker, +MKR,Mexc,MKR_USDT,659686.2959,230714.6623,2119.293037,A,6,2,Maker,USDT-USD +MKR,Binance,MKRUSDT,368523.4153,23448263.7,2114.219678,A,6,2,Maker,USDT-USD +MKR,Kraken,MKRUSD,49658.74142,622993.922,2107.930364,A,6,2,Maker, +MKR,Okx,MKR-USDT,81342.70903,3487712.056,2111.932327,A,6,2,Maker,USDT-USD +MKR,Kucoin,MKR-USDT,45425.02507,675263.6294,2112.071675,A,6,2,Maker,USDT-USD +NEAR,Kucoin,NEAR-USDT,124294.3172,5843254.667,2.674161205,A,8,1,Near,USDT-USD +NEAR,Bybit,NEARUSDT,58206.62204,4630072.987,2.678918634,A,8,1,Near,USDT-USD +NEAR,CoinbasePro,NEAR-USD,185291.8636,5187550.998,2.67843549,A,8,1,Near, +NEAR,Kraken,NEARUSD,191549.9708,3360632.501,2.667463339,A,8,1,Near, +NEAR,Okx,NEAR-USDT,311377.3773,15382244.05,2.672818299,A,8,1,Near,USDT-USD +NEAR,Binance,NEARUSDT,578778.0911,61784058.07,2.676081404,A,8,1,Near,USDT-USD +NEAR,Mexc,NEAR_USDT,871096.6953,1184958.966,2.678323491,A,8,1,Near,USDT-USD +NEAR,Huobi,nearusdt,74787.28484,6999178.627,2.67181076,A,8,1,Near,USDT-USD +OP,Mexc,OP_USDT,1987545.663,1684136.999,2.871032553,A,7,2,Optimism,USDT-USD +OP,Okx,OP-USDT,456470.0968,40684606.93,2.865726402,A,7,2,Optimism,USDT-USD +OP,Bybit,OPUSDT,121956.4932,12754054.86,2.863599682,A,7,2,Optimism,USDT-USD +OP,Binance,OPUSDT,1189317.678,120606269.7,2.866861935,A,7,2,Optimism,USDT-USD +OP,Kucoin,OP-USDT,151102.3965,7514893.178,2.86647468,A,7,2,Optimism,USDT-USD +OP,CoinbasePro,OP-USD,351393.8984,22928210.76,2.864965623,A,7,2,Optimism, +OP,Gate,OP_USDT,50000,100000,0,A,7,2,Optimism,USDT-USD +ORDI,Kucoin,ORDI-USDT,110936.0169,7517594.63,51.5460857,A,6,2,Ordinals,USDT-USD +ORDI,Bybit,ORDIUSDT,119439.2682,9142897.563,51.46062583,A,6,2,Ordinals,USDT-USD +ORDI,Binance,ORDIUSDT,1816384.797,157536421.3,51.50890555,A,6,2,Ordinals,USDT-USD +ORDI,Okx,ORDI-USDT,897255.021,111729885.1,51.56285708,A,6,2,Ordinals,USDT-USD +ORDI,Huobi,ordiusdt,90017.00367,6939659.846,52.21823543,A,6,2,Ordinals,USDT-USD +ORDI,Gate,ORDI_USDT,50000,100000,0,A,6,2,Ordinals,USDT-USD +PEPE,Binance,PEPEUSDT,1854338.485,21983200.56,1.02E-06,A,6,2,Pepe,USDT-USD +PEPE,Kraken,PEPEUSD,66383.09612,339921.3126,1.02E-06,A,6,2,Pepe, +PEPE,Bybit,PEPEUSDT,70662.28564,5776041.599,1.02E-06,A,6,2,Pepe,USDT-USD +PEPE,Kucoin,PEPE-USDT,117845.5631,6320839.499,1.02E-06,A,6,2,Pepe,USDT-USD +PEPE,Mexc,PEPE_USDT,576088.0345,1051367.142,1.02E-06,A,6,2,Pepe,USDT-USD +PEPE,Okx,PEPE-USDT,253199.6634,10378463.48,1.02E-06,A,6,2,Pepe,USDT-USD +RNDR,Kucoin,RNDR-USDT,93245.66824,3389990.196,3.78277704,A,6,2,Render Token,USDT-USD +RNDR,Binance,RNDRUSDT,456778.1853,34499985.8,3.781059636,A,6,2,Render Token,USDT-USD +RNDR,CoinbasePro,RNDR-USD,180418.0343,11691967.24,3.767943401,A,6,2,Render Token, +RNDR,Kraken,RNDRUSD,62255.2913,1176061.236,3.788017753,A,6,2,Render Token, +RNDR,Mexc,RNDR_USDT,627963.3038,617023.2409,3.770998381,A,6,2,Render Token,USDT-USD +RNDR,Okx,RNDR-USDT,122198.2874,5319549.855,3.772653723,A,6,2,Render Token,USDT-USD +SAND,Okx,SAND-USDT,100469.8264,3508230.948,0.4373225476,A,7,2,SAND,USDT-USD +SAND,Kucoin,SAND-USDT,64668.48254,997968.9032,0.4371193254,A,7,2,SAND,USDT-USD +SAND,Kraken,SANDUSD,47650.66542,278973.929,0.4395664881,A,7,2,SAND, +SAND,CoinbasePro,SAND-USD,54744.16281,731889.0885,0.437434037,A,7,2,SAND, +SAND,Binance,SANDUSDT,263841.1812,14105685.55,0.4370122624,A,7,2,SAND,USDT-USD +SAND,Mexc,SAND_USDT,380990.8836,209883.4311,0.437304002,A,7,2,SAND,USDT-USD +SAND,Gate,SAND_USDT,50000,100000,0,A,7,2,SAND,USDT-USD +SEI,Binance,SEIUSDT,960266.1108,147580247.1,0.613207501,A,7,2,Sei,USDT-USD +SEI,CoinbasePro,SEI-USD,501975.7126,44992922.16,0.6149800585,A,7,2,Sei, +SEI,Huobi,seiusdt,58169.10057,38375753.16,0.6146183588,A,7,2,Sei,USDT-USD +SEI,Bybit,SEIUSDT,131815.1551,20617259.61,0.6146716564,A,7,2,Sei,USDT-USD +SEI,Kraken,SEIUSD,60743.57825,6077393.643,0.6142689745,A,7,2,Sei, +SEI,Kucoin,SEI-USDT,178642.4194,10251443.59,0.6122370319,A,7,2,Sei,USDT-USD +SEI,Mexc,SEI_USDT,456994.8627,3721782.454,0.6209961106,A,7,2,Sei,USDT-USD +SHIB,Okx,SHIB-USDT,186962.879,5752876.108,8.84E-06,A,8,1,Shiba Inu,USDT-USD +SHIB,Bybit,SHIBUSDT,97654.78678,2621562.66,8.84E-06,A,8,1,Shiba Inu,USDT-USD +SHIB,Kucoin,SHIB-USDT,214053.7893,4620710.046,8.84E-06,A,8,1,Shiba Inu,USDT-USD +SHIB,CoinbasePro,SHIB-USD,472915.9234,9834603.706,8.84E-06,A,8,1,Shiba Inu, +SHIB,Binance,SHIBUSDT,711743.4514,34409618.31,8.84E-06,A,8,1,Shiba Inu,USDT-USD +SHIB,Kraken,SHIBUSD,104567.4626,420513.5586,8.84E-06,A,8,1,Shiba Inu, +SHIB,Mexc,SHIB_USDT,1940827.945,796547.7524,8.84E-06,A,8,1,Shiba Inu,USDT-USD +SHIB,Huobi,shibusdt,67117.45039,363334.4836,8.84E-06,A,8,1,Shiba Inu,USDT-USD +SNX,Mexc,SNX_USDT,310714.3857,335052.6602,3.112944227,A,6,2,Synthetix Network Token,USDT-USD +SNX,Kraken,SNXUSD,63489.12006,606793.6628,3.13979134,A,6,2,Synthetix Network Token, +SNX,Okx,SNX-USDT,103282.8979,3298762.932,3.135011753,A,6,2,Synthetix Network Token,USDT-USD +SNX,Bybit,SNXUSDT,60753.04211,1293350.734,3.125053636,A,6,2,Synthetix Network Token,USDT-USD +SNX,Binance,SNXUSDT,287994.4111,12367152.42,3.133185754,A,6,2,Synthetix Network Token,USDT-USD +SNX,CoinbasePro,SNX-USD,138260.8807,3807927.897,3.137731528,A,6,2,Synthetix Network Token, +SOL,Kucoin,SOL-USDT,374442.0549,56433240.02,87.53739207,A,9,1,Solana,USDT-USD +SOL,CoinbasePro,SOL-USD,2257090.149,145521917.4,87.38247282,A,9,1,Solana, +SOL,Okx,SOL-USDT,1397468.011,135207705.4,87.4902174,A,9,1,Solana,USDT-USD +SOL,Mexc,SOL_USDT,1779392.262,299329951.9,87.49495206,A,9,1,Solana,USDT-USD +SOL,Kraken,SOLUSD,2251190.633,64593290.11,87.67728718,A,9,1,Solana, +SOL,Binance,SOLUSDT,3741601.199,607947665.6,87.49377311,A,9,1,Solana,USDT-USD +SOL,Bitstamp,SOL/USD,109890.2738,2646819.043,87.31111501,A,9,1,Solana, +SOL,Bybit,SOLUSDT,831770.3877,120667847.4,87.36083166,A,9,1,Solana,USDT-USD +SOL,Huobi,solusdt,275163.2969,41233952.41,87.4809317,A,9,1,Solana,USDT-USD +STX,Okx,STX-USDT,180203.7241,13352549.39,1.463485107,A,7,2,Stacks,USDT-USD +STX,Kraken,STXUSD,58949.55711,1353219.917,1.468122483,A,7,2,Stacks, +STX,CoinbasePro,STX-USD,258400.6869,14123894.62,1.463175003,A,7,2,Stacks, +STX,Kucoin,STX-USDT,152358.5064,5233980.249,1.465347379,A,7,2,Stacks,USDT-USD +STX,Binance,STXUSDT,584610.0183,45329052.16,1.462632266,A,7,2,Stacks,USDT-USD +STX,Mexc,STX_USDT,227354.8541,915054.5567,1.463303254,A,7,2,Stacks,USDT-USD +STX,Gate,STX_USDT,50000,100000,0,A,7,2,Stacks,USDT-USD +SUI,Kucoin,SUI-USDT,157119.1,12511155.03,1.224163869,A,6,2,SuiNetwork,USDT-USD +SUI,Mexc,SUI_USDT,233548.7548,2056662.292,1.222993101,A,6,2,SuiNetwork,USDT-USD +SUI,Binance,SUIUSDT,1262079.981,111516956.8,1.223930951,A,6,2,SuiNetwork,USDT-USD +SUI,CoinbasePro,SUI-USD,164063.7043,14862283.81,1.225266393,A,6,2,SuiNetwork, +SUI,Bybit,SUIUSDT,212067.1354,19630489.94,1.225408738,A,6,2,SuiNetwork,USDT-USD +SUI,Okx,SUI-USDT,613217.7334,54191478.11,1.223865903,A,6,2,SuiNetwork,USDT-USD +SUSHI,Mexc,SUSHI_USDT,698897.3305,162827.6862,1.069891177,A,6,2,Sushi,USDT-USD +SUSHI,Binance,SUSHIUSDT,314905.5164,8301205.3,1.070356721,A,6,2,Sushi,USDT-USD +SUSHI,Okx,SUSHI-USDT,140667.711,3610840.809,1.067487683,A,6,2,Sushi,USDT-USD +SUSHI,Kraken,SUSHIUSD,60333.51362,206177.6733,1.075978241,A,6,2,Sushi, +SUSHI,CoinbasePro,SUSHI-USD,84615.09476,3085188.166,1.072066002,A,6,2,Sushi, +SUSHI,Gate,SUSHI_USDT,50000,100000,0,A,6,2,Sushi,USDT-USD +TIA,Bybit,TIAUSDT,187918.6442,14660427.8,15.52650347,A,7,2,Celestia,USDT-USD +TIA,Binance,TIAUSDT,841382.0946,102103230.5,15.53648038,A,7,2,Celestia,USDT-USD +TIA,CoinbasePro,TIA-USD,383069.4815,25165071.27,15.51546599,A,7,2,Celestia, +TIA,Kraken,TIAUSD,111097.8042,6238500.3,15.50599396,A,7,2,Celestia, +TIA,Kucoin,TIA-USDT,125355.6151,11079068.85,15.55654998,A,7,2,Celestia,USDT-USD +TIA,Mexc,TIA_USDT,100237.1437,2406206.399,15.72168637,A,7,2,Celestia,USDT-USD +TIA,Okx,TIA-USDT,552714.9757,23266716.08,15.50535992,A,7,2,Celestia,USDT-USD +TRX,Kraken,TRXUSD,256930.9396,749814.9748,0.1113946358,A,8,2,TRON, +TRX,Binance,TRXUSDT,613911.798,39811843.58,0.110779356,A,8,2,TRON,USDT-USD +TRX,Huobi,trxusdt,213398.1056,8135870.339,0.1107429915,A,8,2,TRON,USDT-USD +TRX,Okx,TRX-USDT,162323.4689,5484388.924,0.1107910725,A,8,2,TRON,USDT-USD +TRX,Bybit,TRXUSDT,137021.0481,4074633.26,0.1107581644,A,8,2,TRON,USDT-USD +TRX,Kucoin,TRX-USDT,129267.4773,2807145.376,0.1109288304,A,8,2,TRON,USDT-USD +TRX,Mexc,TRX_USDT,676244.1047,18412701.3,0.1107773897,A,8,2,TRON,USDT-USD +TRX,Gate,TRX_USDT,50000,100000,0,A,8,2,TRON,USDT-USD +UNI,Mexc,UNI_USDT,764302.9979,247466.3051,5.761766722,A,7,2,Uniswap,USDT-USD +UNI,Binance,UNIUSDT,399637.0021,17327263.14,5.766455246,A,7,2,Uniswap,USDT-USD +UNI,Bybit,UNIUSDT,67657.94054,2493651.981,5.759751567,A,7,2,Uniswap,USDT-USD +UNI,Kucoin,UNI-USDT,62238.34996,915687.2194,5.769731774,A,7,2,Uniswap,USDT-USD +UNI,Kraken,UNIUSD,110184.576,575064.438,5.744322919,A,7,2,Uniswap, +UNI,Okx,UNI-USDT,188134.5271,8636195.728,5.755593059,A,7,2,Uniswap,USDT-USD +UNI,CoinbasePro,UNI-USD,136046.1025,4933014.237,5.766666815,A,7,2,Uniswap, +WLD,Okx,WLD-USDT,251129.2683,9586681.603,2.292928825,A,6,2,Worldcoin WLD,USDT-USD +WLD,Mexc,WLD_USDT,487737.0114,273829.0676,2.273495768,A,6,2,Worldcoin WLD,USDT-USD +WLD,Bybit,WLDUSDT,56863.91933,3194845.195,2.293914994,A,6,2,Worldcoin WLD,USDT-USD +WLD,Binance,WLDUSDT,309841.6575,26594366.07,2.291594044,A,6,2,Worldcoin WLD,USDT-USD +WLD,Kucoin,WLD-USDT,82240.3581,1301628.522,2.294060237,A,6,2,Worldcoin WLD,USDT-USD +WLD,Gate,WLD_USDT,50000,100000,0,A,6,2,Worldcoin WLD,USDT-USD +XLM,Kucoin,XLM-USDT,85927.31243,1417810.596,0.1117112483,A,8,1,Stellar,USDT-USD +XLM,CoinbasePro,XLM-USD,225276.1032,8883356.851,0.1117142784,A,8,1,Stellar, +XLM,Okx,XLM-USDT,118111.3781,1765770.66,0.1116885221,A,8,1,Stellar,USDT-USD +XLM,Kraken,XLMUSD,176811.499,408089.0655,0.1115158801,A,8,1,Stellar, +XLM,Bitstamp,XLM/USD,72720.87116,733454.4667,0.1113217575,A,8,1,Stellar, +XLM,Mexc,XLM_USDT,1132933.24,618310.8309,0.1117266616,A,8,1,Stellar,USDT-USD +XLM,Bybit,XLMUSDT,88709.74889,3151890.822,0.111753146,A,8,1,Stellar,USDT-USD +XLM,Binance,XLMUSDT,345297.9107,8403369.953,0.1117183159,A,8,1,Stellar,USDT-USD +XRP,Kraken,XRPUSD,814559.1334,6616229.004,0.5113032699,A,9,1,Ripple, +XRP,Binance,XRPUSDT,1884848.243,189067323.1,0.5112663149,A,9,1,Ripple,USDT-USD +XRP,Okx,XRP-USDT,563822.8277,34832795.43,0.5114652914,A,9,1,Ripple,USDT-USD +XRP,CoinbasePro,XRP-USD,730290.9717,38862484.52,0.5115428632,A,9,1,Ripple, +XRP,Huobi,xrpusdt,130799.1755,30764931.78,0.5116267728,A,9,1,Ripple,USDT-USD +XRP,Kucoin,XRP-USDT,711262.8242,17611337.65,0.5113220721,A,9,1,Ripple,USDT-USD +XRP,Bybit,XRPUSDT,574200.8828,60341501.96,0.511381899,A,9,1,Ripple,USDT-USD +XRP,Bitstamp,XRP/USD,893779.877,8546572.012,0.5101769016,A,9,1,Ripple, +XRP,Mexc,XRP_USDT,2253802.257,64063212.39,0.5113602624,A,9,1,Ripple,USDT-USD +CFX,Mexc,CFX_USDT,741948.4908,377232.5696,0.1828636419,B,5,2,Conflux Token,USDT-USD +CFX,Kucoin,CFX-USDT,55943.9793,3166120.044,0.1814791365,B,5,2,Conflux Token,USDT-USD +CFX,Binance,CFXUSDT,425985.235,21370941.25,0.1814141679,B,5,2,Conflux Token,USDT-USD +CFX,Okx,CFX-USDT,225570.4218,11740974.87,0.1814352472,B,5,2,Conflux Token,USDT-USD +CFX,Gate,CFX_USDT,50000,100000,0,B,5,2,Conflux Token,USDT-USD +COMP,Kraken,COMPUSD,53754.17258,243932.5958,53.11057205,B,5,2,Compound Coin, +COMP,Mexc,COMP_USDT,230873.8911,180053.2444,52.64207051,B,5,2,Compound Coin,USDT-USD +COMP,Okx,COMP-USDT,66721.14412,2254113.721,52.63991084,B,5,2,Compound Coin,USDT-USD +COMP,CoinbasePro,COMP-USD,62085.28523,1437341.815,52.63084228,B,5,2,Compound Coin, +COMP,Binance,COMPUSDT,121785.3724,8389374.272,52.68915121,B,5,2,Compound Coin,USDT-USD +EGLD,Kucoin,EGLD-USDT,65252.11559,1177346.419,48.76618226,B,5,2,MultiversX,USDT-USD +EGLD,Binance,EGLDUSDT,271211.9052,11875041.97,48.79330927,B,5,2,MultiversX,USDT-USD +EGLD,Mexc,EGLD_USDT,376293.4565,276441.7792,48.74594483,B,5,2,MultiversX,USDT-USD +EGLD,CoinbasePro,EGLD-USD,52835.82668,917429.1077,48.88945848,B,5,2,MultiversX, +EGLD,Gate,EGLD_USDT,50000,100000,0,B,5,2,MultiversX,USDT-USD +FLOW,Kraken,FLOWUSD,51916.27241,275346.5158,0.7242278161,B,5,2,Flow - Dapper Labs, +FLOW,Binance,FLOWUSDT,293656.6338,9552308.898,0.7291395058,B,5,2,Flow - Dapper Labs,USDT-USD +FLOW,Mexc,FLOW_USDT,483739.2177,113468.7798,0.7323395177,B,5,2,Flow - Dapper Labs,USDT-USD +FLOW,Okx,FLOW-USDT,80766.53137,9510373.237,0.7285897993,B,5,2,Flow - Dapper Labs,USDT-USD +FLOW,Gate,FLOW_USDT,50000,100000,0,B,5,2,Flow - Dapper Labs,USDT-USD +GMT,CoinbasePro,GMT-USD,67428.76141,2248881.711,0.2560028014,B,5,2,STEPN, +GMT,Binance,GMTUSDT,462665.2276,38705519.52,0.2555371175,B,5,2,STEPN,USDT-USD +GMT,Kucoin,GMT-USDT,72869.96385,2005043.366,0.2557195795,B,5,2,STEPN,USDT-USD +GMT,Okx,GMT-USDT,152103.8921,8914015.232,0.2554599347,B,5,2,STEPN,USDT-USD +GMT,Gate,GMT_USDT,50000,100000,0,B,5,2,STEPN,USDT-USD +MEME,Bybit,MEMEUSDT,74659.94612,1660599.611,0.02253908946,B,5,2,Memecoin Price,USDT-USD +MEME,Binance,MEMEUSDT,489840.1554,31554049.74,0.02249870307,B,5,2,Memecoin Price,USDT-USD +MEME,Kucoin,MEME-USDT,50201.45759,1498743.96,0.02243463802,B,5,2,Memecoin Price,USDT-USD +MEME,Mexc,MEME_USDT,184005.5762,478785.4964,0.02260242467,B,5,2,Memecoin Price,USDT-USD +MEME,Gate,MEME_USDT,50000,100000,0,B,5,2,Memecoin Price,USDT-USD +MINA,Mexc,MINA_USDT,110130.5009,610463.4036,1.00715717,B,5,2,Mina,USDT-USD +MINA,CoinbasePro,MINA-USD,59277.03658,6118487.412,1.008738919,B,5,2,Mina, +MINA,Kraken,MINAUSD,104251.6176,1744827.397,1.002235423,B,5,2,Mina, +MINA,Binance,MINAUSDT,163902.8209,27632789.9,1.009175349,B,5,2,Mina,USDT-USD +MINA,Okx,MINA-USDT,58811.29263,5177907.38,1.013323303,B,5,2,Mina,USDT-USD +PEOPLE,Okx,PEOPLE-USDT,318441.9026,37806408.11,0.02743487292,B,5,2,ConstitutionDAO,USDT-USD +PEOPLE,Kucoin,PEOPLE-USDT,64922.56302,3574827.52,0.0273835447,B,5,2,ConstitutionDAO,USDT-USD +PEOPLE,Mexc,PEOPLE_USDT,168543.6372,757272.2515,0.02744498423,B,5,2,ConstitutionDAO,USDT-USD +PEOPLE,Binance,PEOPLEUSDT,192342.5961,85366302.35,0.02746617133,B,5,2,ConstitutionDAO,USDT-USD +PEOPLE,Gate,PEOPLE_USDT,50000,100000,0,B,5,2,ConstitutionDAO,USDT-USD +WAVES,Okx,WAVES-USDT,91892.84196,2741667.219,2.144997825,B,5,2,Waves,USDT-USD +WAVES,Binance,WAVESUSDT,272620.4813,9543737.677,2.143624016,B,5,2,Waves,USDT-USD +WAVES,Mexc,WAVES_USDT,558956.9951,168193.854,2.142261269,B,5,2,Waves,USDT-USD +WAVES,Kucoin,WAVES-USDT,55367.18425,769644.5638,2.142747289,B,5,2,Waves,USDT-USD +WAVES,Kraken,WAVESUSD,45555.16136,112134.6183,2.154872324,B,5,2,Waves, +1INCH,Binance,1INCHUSDT,223047.9107,10123584.48,0.3759697336,C,4,2,1INCH,USDT-USD +1INCH,CoinbasePro,1INCH-USD,63433.64579,1220856.095,0.3761909036,C,4,2,1INCH, +1INCH,Mexc,1INCH_USDT,220805.8565,397303.2595,0.3751712747,C,4,2,1INCH,USDT-USD +1INCH,Okx,1INCH-USDT,87382.44268,4403164.462,0.375964926,C,4,2,1INCH,USDT-USD +ACE,Binance,ACEUSDT,219186.3365,36291711.39,9.125489437,C,2,2,Fusionist,USDT-USD +ACE,Okx,ACE-USDT,120509.3158,8941538.795,9.092071496,C,2,2,Fusionist,USDT-USD +ACH,CoinbasePro,ACH-USD,97110.58491,894158.4549,0.01675701504,C,3,2,Alchemy Pay, +ACH,Binance,ACHUSDT,84700.65638,4414398.216,0.01675085779,C,3,2,Alchemy Pay,USDT-USD +ACH,Mexc,ACH_USDT,192469.0915,100559.3076,0.01679041985,C,3,2,Alchemy Pay,USDT-USD +AEUR,Binance,AEURUSDT,1270915.824,759036.3652,1.085248864,C,1,2,Anchored Coins AEUR,USDT-USD +API3,Mexc,API3_USDT,152284.022,205441.5,2.043375234,C,2,2,API3,USDT-USD +API3,Binance,API3USDT,90101.84241,17128907.56,2.048019395,C,2,2,API3,USDT-USD +AR,Okx,AR-USDT,49845.96145,2809779.829,8.610082522,C,2,2,Arweave,USDT-USD +AR,Binance,ARUSDT,118756.107,5634710.58,8.603353236,C,2,2,Arweave,USDT-USD +ARKM,Binance,ARKMUSDT,101600.3693,9290971.501,0.5035873534,C,2,2,Arkham,USDT-USD +ARKM,Mexc,ARKM_USDT,104313.7334,237646.8392,0.502258142,C,2,2,Arkham,USDT-USD +ARPA,Binance,ARPAUSDT,141483.7342,6962539.152,0.05938416152,C,1,2,ArpaCoin,USDT-USD +ASTR,Mexc,ASTR_USDT,337777.2363,556571.4433,0.1714246019,C,3,2,ASTR,USDT-USD +ASTR,Binance,ASTRUSDT,272250.3728,29115614.2,0.1710438223,C,3,2,ASTR,USDT-USD +ASTR,Okx,ASTR-USDT,61040.31153,7741218.973,0.1712013965,C,3,2,ASTR,USDT-USD +AUCTION,Mexc,AUCTION_USDT,205068.2365,269845.2565,24.64750337,C,3,2,Auction,USDT-USD +AUCTION,Binance,AUCTIONUSDT,141766.5502,24443787.65,24.52525957,C,3,2,Auction,USDT-USD +AUCTION,Okx,AUCTION-USDT,64014.51076,7264691.478,24.43296353,C,3,2,Auction,USDT-USD +AXS,Mexc,AXS_USDT,262075.6017,132406.1769,7.065952702,C,3,2,Axie Infinity,USDT-USD +AXS,Binance,AXSUSDT,231000.3653,12333785.24,7.054601867,C,3,2,Axie Infinity,USDT-USD +AXS,CoinbasePro,AXS-USD,46520.7417,953800.4786,7.063964044,C,3,2,Axie Infinity, +BAKE,Binance,BAKEUSDT,182011.4866,35921179.76,0.3094882759,C,2,2,Bakery Token,USDT-USD +BAKE,Mexc,BAKE_USDT,185326.3247,583699.372,0.3068157366,C,2,2,Bakery Token,USDT-USD +BAND,Binance,BANDUSDT,55086.31129,6612180.017,1.592617506,C,1,2,Band Protocol,USDT-USD +BEAM,Binance,BEAMUSDT,152991.9166,15969226.65,0.01691214062,C,1,2,BEAM (Merit Circle),USDT-USD +BLZ,Binance,BLZUSDT,108417.3522,5588057.361,0.2904520078,C,2,2,Bluzelle,USDT-USD +BLZ,CoinbasePro,BLZ-USD,58365.73324,369664.6277,0.2910902264,C,2,2,Bluzelle, +BOND,Binance,BONDUSDT,101881.7077,6611834.75,3.051545382,C,1,2,BarnBridge,USDT-USD +BSW,Binance,BSWUSDT,46034.40658,4599238.929,0.08886586012,C,1,2,Biswap (BSW),USDT-USD +C98,Mexc,C98_USDT,285083.0197,153443.734,0.2185707406,C,2,2,Coin98,USDT-USD +C98,Binance,C98USDT,189878.1329,5558051.461,0.2185832922,C,2,2,Coin98,USDT-USD +CAKE,Mexc,CAKE_USDT,405312.078,551396.0436,2.447890968,C,2,2,PancakeSwap,USDT-USD +CAKE,Binance,CAKEUSDT,195778.7099,23654981.25,2.454039405,C,2,2,PancakeSwap,USDT-USD +CELO,Mexc,CELO_USDT,125444.7762,302663.9345,0.6476452305,C,3,2,Celo,USDT-USD +CELO,Okx,CELO-USDT,74867.9216,2248910.392,0.6477003752,C,3,2,Celo,USDT-USD +CELO,Binance,CELOUSDT,188957.1416,10478656.48,0.6474077901,C,3,2,Celo,USDT-USD +CHR,Binance,CHRUSDT,98985.18915,8983410.231,0.2454323105,C,1,2,Chromia,USDT-USD +CTSI,Binance,CTSIUSDT,61529.46969,13400594.76,0.211724629,C,1,2,Cartesi,USDT-USD +CYBER,Binance,CYBERUSDT,157494.8313,21582311.99,6.891553463,C,2,2,CyberConnect,USDT-USD +CYBER,Mexc,CYBER_USDT,245967.0815,775034.3955,6.894934361,C,2,2,CyberConnect,USDT-USD +DATA,Binance,DATAUSDT,56436.38905,6577080.731,0.04655652469,C,1,2,Streamr DATAcoin,USDT-USD +DEGO,Binance,DEGOUSDT,49442.4569,6918692.999,2.058938225,C,2,2,Dego Finance,USDT-USD +DEGO,Mexc,DEGO_USDT,47063.22126,145028.8291,2.061702998,C,2,2,Dego Finance,USDT-USD +DIA,Binance,DIAUSDT,46415.86926,5008591.814,0.398446883,C,1,2,DIAToken,USDT-USD +DUSK,Binance,DUSKUSDT,89726.44858,5994345.592,0.24835762,C,1,2,Dusk Network,USDT-USD +EUR,Binance,EURUSDT,914754.1506,25453392.79,1.086238407,C,3,2,Euro,USDT-USD +EUR,Bitstamp,EUR/USD,161923.2853,2925912.624,1.085974486,C,3,2,Euro, +EUR,Kraken,EURUSD,973749.5483,17562785.59,1.087181078,C,3,2,Euro, +FDUSD,Binance,FDUSDUSDT,20819829.91,791868072.3,0.9982990251,C,1,2,First Digital USD,USDT-USD +FRONT,Binance,FRONTUSDT,116592.5536,8033362.547,0.4244166096,C,1,2,Frontier,USDT-USD +FTT,Binance,FTTUSDT,85361.25321,18918457.67,2.637355962,C,2,2,FTX Token,USDT-USD +FTT,Mexc,FTT_USDT,61679.15314,885931.1891,2.625461927,C,2,2,FTX Token,USDT-USD +FXS,Binance,FXSUSDT,76687.07914,7919284.862,9.870999715,C,1,2,Frax Share,USDT-USD +GAL,Binance,GALUSDT,123198.1518,6183386.884,1.713442116,C,1,2,Project Galaxy,USDT-USD +GAS,Okx,GAS-USDT,71550.26438,3589890.498,5.559745992,C,2,2,Gas,USDT-USD +GAS,Binance,GASUSDT,143459.5949,16249734.4,5.551653689,C,2,2,Gas,USDT-USD +GLMR,Binance,GLMRUSDT,66465.37977,5440648.9,0.351519818,C,2,2,Moonbeam Network Glimmer Token,USDT-USD +GLMR,Mexc,GLMR_USDT,132937.7799,226967.7255,0.3519219251,C,2,2,Moonbeam Network Glimmer Token,USDT-USD +GMX,Binance,GMXUSDT,86050.25266,8488792.893,41.68565019,C,1,2,GMX,USDT-USD +GTC,Binance,GTCUSDT,63833.57202,5559771.674,1.109504239,C,1,2,Gitcoin,USDT-USD +HFT,Mexc,HFT_USDT,92867.50229,155840.9593,0.3163831693,C,3,2,Hashflow,USDT-USD +HFT,CoinbasePro,HFT-USD,67639.33185,1082720.501,0.3166013692,C,3,2,Hashflow, +HFT,Binance,HFTUSDT,86389.41028,4335472.459,0.3155912724,C,3,2,Hashflow,USDT-USD +HIFI,Binance,HIFIUSDT,65279.10529,4308106.952,0.5695358478,C,1,2,Hifi Finance,USDT-USD +HIGH,Binance,HIGHUSDT,94832.54951,5568886.461,1.416275081,C,1,2,Highstreet,USDT-USD +HOOK,Binance,HOOKUSDT,125566.4187,10904796.41,0.8514358619,C,1,2,Hooked Protocol,USDT-USD +HOT,Binance,HOTUSDT,88284.00246,4898150.064,0.00182001891,C,1,2,Holo,USDT-USD +ID,Binance,IDUSDT,105739.9887,10529785.09,0.2642775002,C,2,2,Space ID,USDT-USD +ID,Mexc,ID_USDT,99019.7159,293195.7436,0.2653625693,C,2,2,Space ID,USDT-USD +ILV,Binance,ILVUSDT,65967.97711,4756421.779,72.43485363,C,2,2,Illuvium,USDT-USD +ILV,Mexc,ILV_USDT,101351.5141,124582.7065,72.49241072,C,2,2,Illuvium,USDT-USD +IMX,Binance,IMXUSDT,159306.9212,9773348.424,1.833882485,C,4,2,Immutable X,USDT-USD +IMX,Mexc,IMX_USDT,125843.6309,288710.9571,1.831721582,C,4,2,Immutable X,USDT-USD +IMX,CoinbasePro,IMX-USD,63576.38536,3545209.657,1.832415885,C,4,2,Immutable X, +IMX,Okx,IMX-USDT,63231.7586,4815890.341,1.835477545,C,4,2,Immutable X,USDT-USD +IOTA,Binance,IOTAUSDT,156813.2627,9448427.026,0.2404979188,C,2,2,IOTA,USDT-USD +IOTA,Okx,IOTA-USDT,81364.86526,1422701.965,0.240249504,C,2,2,IOTA,USDT-USD +IOTX,Mexc,IOTX_USDT,63717.81113,114944.2482,0.04098756361,C,2,2,IoTeX,USDT-USD +IOTX,Binance,IOTXUSDT,118425.8892,5645105.663,0.04116999109,C,2,2,IoTeX,USDT-USD +JASMY,CoinbasePro,JASMY-USD,106938.7996,2456750.498,0.004883328831,C,4,2,Jasmy, +JASMY,Kucoin,JASMY-USDT,46532.2408,878234.3701,0.004897641967,C,4,2,Jasmy,USDT-USD +JASMY,Binance,JASMYUSDT,103914.894,4638424.246,0.004895538164,C,4,2,Jasmy,USDT-USD +JASMY,Mexc,JASMY_USDT,118057.5456,426212.9186,0.004900948254,C,4,2,Jasmy,USDT-USD +JOE,Binance,JOEUSDT,95891.84261,4986487.55,0.4210333582,C,2,2,TraderJoe,USDT-USD +JOE,Mexc,JOE_USDT,106334.2549,155616.5895,0.4240505807,C,2,2,TraderJoe,USDT-USD +KDA,Binance,KDAUSDT,52068.57953,6603653.169,0.9864134387,C,1,2,Kadena,USDT-USD +KLAY,Mexc,KLAY_USDT,198792.0879,193094.4612,0.1935774129,C,2,2,Klaytn,USDT-USD +KLAY,Binance,KLAYUSDT,102537.9319,8166690.792,0.1947100267,C,2,2,Klaytn,USDT-USD +KP3R,Binance,KP3RUSDT,54560.4206,6827068.529,68.97052078,C,1,2,Keep3rV1,USDT-USD +KSM,Okx,KSM-USDT,49131.02426,2272156.7,35.8946584,C,4,2,Kusama,USDT-USD +KSM,Kraken,KSMUSD,82906.03275,662412.7086,35.91468468,C,4,2,Kusama, +KSM,Mexc,KSM_USDT,51623.03643,146361.7075,35.99359072,C,4,2,Kusama,USDT-USD +KSM,Binance,KSMUSDT,104173.4084,6749163.486,35.92864815,C,4,2,Kusama,USDT-USD +LEVER,Binance,LEVERUSDT,103584.2033,8631452.701,0.001297870719,C,2,2,leverfi,USDT-USD +LEVER,Mexc,LEVER_USDT,269243.6154,100150.2478,0.001297685532,C,2,2,leverfi,USDT-USD +LOOM,Binance,LOOMUSDT,72863.84961,6250861.053,0.08656430192,C,1,2,Loom Network,USDT-USD +LPT,Binance,LPTUSDT,124147.244,4976570.721,6.65831672,C,1,2,Livepeer,USDT-USD +LQTY,Mexc,LQTY_USDT,289158.432,110300.6315,1.195620223,C,2,2,Liquity,USDT-USD +LQTY,Binance,LQTYUSDT,127715.2767,7023298.015,1.191924708,C,2,2,Liquity,USDT-USD +LRC,CoinbasePro,LRC-USD,59174.11432,3383810.585,0.2285031455,C,3,2,Loopring, +LRC,Mexc,LRC_USDT,45956.53557,124278.9266,0.2288337603,C,3,2,Loopring,USDT-USD +LRC,Binance,LRCUSDT,146930.5688,6969566.753,0.2286497941,C,3,2,Loopring,USDT-USD +LUNA,Okx,LUNA-USDT,140979.1409,2806262.42,9.33E-05,C,4,2,Terra Luna Classic,USDT-USD +LUNA,Mexc,LUNA_USDT,285530.9676,548675.4766,9.33E-05,C,4,2,Terra Luna Classic,USDT-USD +LUNA,Binance,LUNAUSDT,327295.5899,25245311.88,9.32E-05,C,4,2,Terra Luna Classic,USDT-USD +LUNA,Kucoin,LUNA-USDT,162730.8732,2161850.295,9.34E-05,C,4,2,Terra Luna Classic,USDT-USD +LUNA2,Okx,LUNA2-USDT,116714.2838,5214721.607,0.5862913961,C,4,2,Terra Luna 2,USDT-USD +LUNA2,Binance,LUNA2USDT,283182.821,12663702.95,0.5867542898,C,4,2,Terra Luna 2,USDT-USD +LUNA2,Kucoin,LUNA2-USDT,83502.73597,2063709.03,0.586261171,C,4,2,Terra Luna 2,USDT-USD +LUNA2,Mexc,LUNA2_USDT,108379.4362,339907.5678,0.5861178482,C,4,2,Terra Luna 2,USDT-USD +MAGIC,Mexc,MAGIC_USDT,264533.7207,290531.8239,0.9620408497,C,4,2,MAGIC,USDT-USD +MAGIC,Binance,MAGICUSDT,220494.1405,15191286.46,0.9583392892,C,4,2,MAGIC,USDT-USD +MAGIC,Okx,MAGIC-USDT,105405.7972,5401719.867,0.9595420314,C,4,2,MAGIC,USDT-USD +MAGIC,Gate,MAGIC_USDT,50000,100000,0,C,4,2,MAGIC,USDT-USD +MANTA,Bybit,MANTAUSDT,53885.15969,18009025.51,3.063765317,C,2,2,Manta,USDT-USD +MANTA,Binance,MANTAUSDT,403816.6432,259161217.8,3.08167379,C,2,2,Manta,USDT-USD +MAV,Mexc,MAV_USDT,185736.3436,457436.4408,0.5373792545,C,2,2,Maverick Protocol,USDT-USD +MAV,Binance,MAVUSDT,99388.71969,22924519.05,0.536668425,C,2,2,Maverick Protocol,USDT-USD +MOVR,Binance,MOVRUSDT,140137.8354,34228440.2,22.26851193,C,1,2,Moonriver,USDT-USD +NEO,Binance,NEOUSDT,174759.4944,6735135.997,10.50592939,C,2,2,NEO,USDT-USD +NEO,Mexc,NEO_USDT,285086.2477,101306.1126,10.51571434,C,2,2,NEO,USDT-USD +NFP,Binance,NFPUSDT,136224.0611,40056163.12,0.4984980965,C,1,2,NFPrompt,USDT-USD +NMR,Mexc,NMR_USDT,56441.59171,117950.3206,20.80947578,C,1,2,Numeraire,USDT-USD +NTRN,Binance,NTRNUSDT,190762.7558,22412232.21,1.043698576,C,3,2,Neutron,USDT-USD +NTRN,Kucoin,NTRN-USDT,61322.46516,4357183.961,1.0429518,C,3,2,Neutron,USDT-USD +NTRN,Mexc,NTRN_USDT,85753.64033,420380.4134,1.049013149,C,3,2,Neutron,USDT-USD +OGN,Mexc,OGN_USDT,133395.5319,153105.7316,0.1506897838,C,2,2,Origin Protocol,USDT-USD +OGN,Binance,OGNUSDT,114751.9375,8567467.491,0.1509501147,C,2,2,Origin Protocol,USDT-USD +ONE,Mexc,ONE_USDT,103633.3233,169389.5422,0.01381296016,C,1,2,Harmony,USDT-USD +ONT,Binance,ONTUSDT,101745.7079,6573307.838,0.2378290263,C,2,2,Ontology,USDT-USD +ONT,Mexc,ONT_USDT,134099.6108,119281.0604,0.2328763351,C,2,2,Ontology,USDT-USD +OSMO,CoinbasePro,OSMO-USD,45573.4572,505627.9592,1.434332792,C,2,2,osmosis, +OSMO,Binance,OSMOUSDT,184069.0761,6248594.99,1.436154852,C,2,2,osmosis,USDT-USD +OXT,Binance,OXTUSDT,121674.5039,4092402.317,0.08759780776,C,1,2,Orchid,USDT-USD +PENDLE,Mexc,PENDLE_USDT,94363.66432,302375.5024,2.414568281,C,2,2,Pendle,USDT-USD +PENDLE,Binance,PENDLEUSDT,198805.1833,19093374.54,2.411570446,C,2,2,Pendle,USDT-USD +PERP,Mexc,PERP_USDT,70959.09524,263694.8546,1.108616603,C,2,2,Perpetual Protocol,USDT-USD +PERP,Binance,PERPUSDT,97699.23947,18395585.05,1.101367961,C,2,2,Perpetual Protocol,USDT-USD +PHB,Binance,PHBUSDT,87353.37405,5541104.607,0.8191750331,C,1,2,Phoenix Global,USDT-USD +POLYX,Binance,POLYXUSDT,77106.52126,4877840.89,0.1556027116,C,1,2,Polymex,USDT-USD +POWR,Binance,POWRUSDT,101684.5648,32858394.18,0.3110983216,C,1,2,Power Ledger,USDT-USD +PROS,Binance,PROSUSDT,47335.53338,6601983.056,0.4958016306,C,1,2,Prosper,USDT-USD +PYR,Mexc,PYR_USDT,136917.2423,282019.549,5.525717506,C,2,2,Vulcan Forged,USDT-USD +PYR,Binance,PYRUSDT,67837.28685,6095379.499,5.513382639,C,2,2,Vulcan Forged,USDT-USD +QI,Binance,QIUSDT,65705.70399,4479686.822,0.01492820908,C,1,2,Benqi,USDT-USD +QNT,Binance,QNTUSDT,150130.1919,4958738.066,105.1210689,C,3,2,Quant,USDT-USD +QNT,CoinbasePro,QNT-USD,77932.07738,2702196.734,104.8651886,C,3,2,Quant, +QNT,Mexc,QNT_USDT,319187.1936,283469.3662,105.6252627,C,3,2,Quant,USDT-USD +RAD,Binance,RADUSDT,64303.27111,13728893.14,1.863131994,C,1,2,Radicle,USDT-USD +RAY,Binance,RAYUSDT,49059.70839,10476697.73,1.086883488,C,1,2,Raydium,USDT-USD +RDNT,Okx,RDNT-USDT,99487.73444,4908849.751,0.2781249382,C,2,2,Radiant Capital,USDT-USD +RDNT,Binance,RDNTUSDT,202234.405,19676252.31,0.27834352,C,2,2,Radiant Capital,USDT-USD +RIF,Binance,RIFUSDT,102720.0668,5575326.551,0.126668978,C,1,2,RIF Token,USDT-USD +RLC,CoinbasePro,RLC-USD,45038.78592,956263.9594,2.193508506,C,2,2,iExec RLC, +RLC,Binance,RLCUSDT,113296.5214,10458930.76,2.240062189,C,2,2,iExec RLC,USDT-USD +ROSE,CoinbasePro,ROSE-USD,94865.22605,2007709.124,0.09853848605,C,4,2,Oasis Network, +ROSE,Kucoin,ROSE-USDT,60914.79989,2255011.858,0.09829991324,C,4,2,Oasis Network,USDT-USD +ROSE,Binance,ROSEUSDT,188268.4384,13037035.32,0.09827645727,C,4,2,Oasis Network,USDT-USD +ROSE,Mexc,ROSE_USDT,87574.57166,553950.1122,0.09824638256,C,4,2,Oasis Network,USDT-USD +RUNE,Kucoin,RUNE-USDT,150957.3196,4886709.369,4.034373849,C,3,2,Thorchain,USDT-USD +RUNE,Kraken,RUNEUSD,64699.56261,918799.2368,4.070013999,C,3,2,Thorchain, +RUNE,Binance,RUNEUSDT,380276.4214,62447654.52,4.036291948,C,3,2,Thorchain,USDT-USD +SANTOS,Binance,SANTOSUSDT,48414.7599,10421735.09,4.748221741,C,1,2,Santos FC Fan Token,USDT-USD +SATS,Binance,SATSUSDT,270661.8914,65862844.2,0.0003862181853,C,2,2,SATS (Ordinals),USDT-USD +SATS,Okx,SATS-USDT,186918.757,23374134.77,3.87E-07,C,2,2,SATS (Ordinals),USDT-USD +SC,Binance,SCUSDT,56737.90689,11988942.85,0.008758778298,C,2,2,Siacoin,USDT-USD +SC,Kraken,SCUSD,72897.05559,939274.4661,0.009133476567,C,2,2,Siacoin, +SKL,CoinbasePro,SKL-USD,89253.48802,7106650.138,0.07392654734,C,2,2,SKALE Network, +SKL,Binance,SKLUSDT,245593.9026,14952643.43,0.07413113803,C,2,2,SKALE Network,USDT-USD +SLEEPAI,Binance,SLEEPAIUSDT,226926.639,75074601.74,1.03330556,C,1,2,Sleepless AI,USDT-USD +SLP,Binance,SLPUSDT,75829.29241,4740257.278,0.002835530307,C,1,2,Smooth Love Potion,USDT-USD +SSV,Binance,SSVUSDT,323731.8901,22076581.02,28.20046712,C,3,2,SSV Token,USDT-USD +SSV,Okx,SSV-USDT,138780.4853,10437857.38,28.20537722,C,3,2,SSV Token,USDT-USD +SSV,Mexc,SSV_USDT,72456.44543,262132.0541,28.25282324,C,3,2,SSV Token,USDT-USD +STG,Binance,STGUSDT,108865.1255,5746995.142,0.5045724388,C,2,2,Stargate Finance,USDT-USD +STG,Mexc,STG_USDT,84129.48408,141951.2826,0.503347766,C,2,2,Stargate Finance,USDT-USD +STORJ,Okx,STORJ-USDT,107087.3563,3141734.853,0.5481481935,C,4,2,Storj,USDT-USD +STORJ,Mexc,STORJ_USDT,379448.5526,135570.0261,0.542814224,C,4,2,Storj,USDT-USD +STORJ,Binance,STORJUSDT,231654.1428,10131073.03,0.5507150911,C,4,2,Storj,USDT-USD +STORJ,CoinbasePro,STORJ-USD,51027.83869,779419.6502,0.5473696668,C,4,2,Storj, +STRAX,Binance,STRAXUSDT,52905.44524,8603073.461,0.859584148,C,1,2,STRAX Token,USDT-USD +SUPER,CoinbasePro,SUPER-USD,50756.77233,2582255.195,0.5798868417,C,2,2,SuperCoin, +SUPER,Binance,SUPERUSDT,118810.403,6113031.497,0.5750921405,C,2,2,SuperCoin,USDT-USD +SYN,Binance,SYNUSDT,47988.72934,8355559.222,0.8286535512,C,1,2,Synapse,USDT-USD +T,Binance,TUSDT,67613.62552,15650726.81,0.0266303701,C,1,2,Threshold Network Token,USDT-USD +THETA,Okx,THETA-USDT,45307.20349,1748100.687,0.9536451092,C,3,2,Theta Token,USDT-USD +THETA,Kucoin,THETA-USDT,50799.11682,953331.377,0.9531037657,C,3,2,Theta Token,USDT-USD +THETA,Binance,THETAUSDT,124500.3519,6901396.198,0.9509138016,C,3,2,Theta Token,USDT-USD +TRB,Binance,TRBUSDT,390984.8389,100946113.2,103.9610988,C,3,2,Tellor Tributes,USDT-USD +TRB,CoinbasePro,TRB-USD,88075.97643,17801109.2,104.1184355,C,3,2,Tellor Tributes, +TRB,Okx,TRB-USDT,186073.443,21824721.52,104.3779998,C,3,2,Tellor Tributes,USDT-USD +TUSD,Mexc,TUSD_USDT,3321290.381,438627.3706,0.9834745064,C,2,2,TrueUSD,USDT-USD +TUSD,Binance,TUSDUSDT,8528624.338,127150976.8,0.983448235,C,2,2,TrueUSD,USDT-USD +TWT,Mexc,TWT_USDT,53326.82705,174132.0743,1.098094178,C,2,2,Trust Wallet Token,USDT-USD +TWT,Binance,TWTUSDT,82499.98134,4322265.177,1.095769461,C,2,2,Trust Wallet Token,USDT-USD +UMA,Binance,UMAUSDT,59739.75936,40479668.6,4.951798234,C,1,2,UMA,USDT-USD +UNFI,Binance,UNFIUSDT,131780.4267,7051952.799,5.639134191,C,2,2,Unifi Protocol DAO,USDT-USD +UNFI,Mexc,UNFI_USDT,130778.7414,110299.8533,5.64795796,C,2,2,Unifi Protocol DAO,USDT-USD +USTC,Binance,USTCUSDT,104193.9018,15652520.83,0.02414702556,C,3,2,TerraClassicUSD,USDT-USD +USTC,Okx,USTC-USDT,79755.13934,3789072.942,0.02416523268,C,3,2,TerraClassicUSD,USDT-USD +USTC,Mexc,USTC_USDT,160428.8833,291642.1385,0.02413599889,C,3,2,TerraClassicUSD,USDT-USD +VANRY,Binance,VANRYUSDT,52749.63014,6196670.624,0.05698171548,C,1,2,VANAR,USDT-USD +VENUS,Binance,VENUSUSDT,142572.1277,4451222.365,11.45017461,C,1,2,VENUS,USDT-USD +VET,Kucoin,VET-USDT,47075.4841,1459523.548,0.02683736035,C,4,2,VeChain Thor Blockchain,USDT-USD +VET,Binance,VETUSDT,156275.2048,10448229.43,0.02681801761,C,4,2,VeChain Thor Blockchain,USDT-USD +VET,CoinbasePro,VET-USD,76873.43971,1778291.301,0.02682562648,C,4,2,VeChain Thor Blockchain, +VET,Mexc,VET_USDT,206314.8694,264812.6117,0.02680541699,C,4,2,VeChain Thor Blockchain,USDT-USD +WBTC,Binance,WBTCUSDT,112200.2527,1683109.194,39963.72177,C,1,2,Wrapped Bitcoin,USDT-USD +WING,Binance,WINGUSDT,62333.07274,6305353.437,8.576492466,C,2,2,Wing Finance,USDT-USD +WING,Mexc,WING_USDT,145609.7828,144300.5718,8.312628247,C,2,2,Wing Finance,USDT-USD +WOO,Kucoin,WOO-USDT,56843.55491,2278027.521,0.3371057009,C,4,2,Wootrade Network,USDT-USD +WOO,Binance,WOOUSDT,151442.7656,10671160.74,0.3366437512,C,4,2,Wootrade Network,USDT-USD +WOO,Okx,WOO-USDT,69348.19917,2025176.877,0.3367207662,C,4,2,Wootrade Network,USDT-USD +WOO,Mexc,WOO_USDT,199456.2006,304849.2574,0.3360550686,C,4,2,Wootrade Network,USDT-USD +XAI,Binance,XAIUSDT,364809.2616,121646517.1,0.7172651447,C,3,2,Xai,USDT-USD +XAI,Kucoin,XAI-USDT,80369.25096,6679818.276,0.7140484103,C,3,2,Xai,USDT-USD +XAI,Mexc,XAI_USDT,62519.5629,2089596.926,0.7163100149,C,3,2,Xai,USDT-USD +XMR,Mexc,XMR_USDT,637929.6215,5399712.779,155.4816876,C,4,2,Monero,USDT-USD +XMR,Kucoin,XMR-USDT,75861.34173,8391529.693,155.526225,C,4,2,Monero,USDT-USD +XMR,Kraken,XMRUSD,152433.9495,1066363.955,155.8084502,C,4,2,Monero, +XMR,Binance,XMRUSDT,325239.0746,14167130.57,155.4210491,C,4,2,Monero,USDT-USD +XTZ,Binance,XTZUSDT,74018.47298,6036351.412,0.9344370358,C,2,2,Tezos,USDT-USD +XTZ,Kraken,XTZUSD,115428.0625,918276.8649,0.9324110152,C,2,2,Tezos, +YFI,Binance,YFIUSDT,106489.0261,4283188.193,7008.442394,C,2,2,yearn.finance,USDT-USD +YFI,CoinbasePro,YFI-USD,69803.71322,2485716.132,7006.499518,C,2,2,yearn.finance, +YGG,Binance,YGGUSDT,255512.6937,15978592.67,0.4253489864,C,3,2,Yield Guild Games,USDT-USD +YGG,Okx,YGG-USDT,112564.4286,8795935.186,0.4242942872,C,3,2,Yield Guild Games,USDT-USD +YGG,Mexc,YGG_USDT,291214.2319,384654.8937,0.4279915233,C,3,2,Yield Guild Games,USDT-USD +ZEC,Mexc,ZEC_USDT,508650.6599,287365.0153,21.96116327,C,2,2,Zcash,USDT-USD +ZEC,Binance,ZECUSDT,107748.7569,6231023.464,22.06774527,C,2,2,Zcash,USDT-USD +ZEN,Binance,ZENUSDT,121239.4862,5983871.133,7.622205603,C,1,2,Horizen,USDT-USD +ZIL,Binance,ZILUSDT,78122.06511,5951041.305,0.01981457877,C,3,2,Zilliqa,USDT-USD +ZIL,Mexc,ZIL_USDT,164288.1689,136450.7828,0.01983149916,C,3,2,Zilliqa,USDT-USD +ZIL,Kucoin,ZIL-USDT,51622.45768,620061.2048,0.0198240821,C,3,2,Zilliqa,USDT-U diff --git a/public/configs/potentialMarketParameters.csv b/public/configs/potentialMarketParameters.csv new file mode 100644 index 0000000..4be255e --- /dev/null +++ b/public/configs/potentialMarketParameters.csv @@ -0,0 +1,68 @@ +base_asset,reference_price,num_oracles,liquidity_tier,asset_name,p,atomic_resolution,min_exchanges,min_price_change_ppm,price_exponent,step_base_quantum,ticksize_exponent,subticks_per_tick,min_order_size,quantum_conversion_exponent +AAVE,88.41933533,7,2,AAVE,1,-7,3,4000,-8,1000000,-3,1000000,1000000,-9 +ADA,0.4713770925,9,1,Cardano,-1,-5,3,2500,-10,1000000,-3,1000000,1000000,-9 +AGIX,0.2111443656,6,2,SingularityNET,-1,-5,3,4000,-10,1000000,-3,1000000,1000000,-9 +ALGO,0.1613430877,6,2,Algorand,-1,-5,3,4000,-10,1000000,-3,1000000,1000000,-9 +APE,1.121514886,7,2,ApeCoin,0,-6,3,4000,-9,1000000,-3,1000000,1000000,-9 +APT,7.323447408,8,2,Aptos,0,-6,3,4000,-9,1000000,-3,1000000,1000000,-9 +ARB,1.701673341,8,1,Arbitrum,0,-6,3,2500,-9,1000000,-3,1000000,1000000,-9 +ATOM,8.050389759,8,2,Cosmos,0,-6,3,4000,-9,1000000,-3,1000000,1000000,-9 +AVAX,30.38272818,9,1,Avalanche,1,-7,3,2500,-8,1000000,-3,1000000,1000000,-9 +BCH,236.328774,9,1,Bitcoin Cash,2,-8,3,2500,-7,1000000,-3,1000000,1000000,-9 +BLUR,0.6050104719,7,2,Blur,-1,-5,3,4000,-10,1000000,-3,1000000,1000000,-9 +BNB,243.1294766,6,2,Binance Coin,2,-8,3,4000,-7,1000000,-3,1000000,1000000,-9 +BONK,1.09E-05,6,2,Bonk Token,-5,-1,3,4000,-14,1000000,-3,1000000,1000000,-9 +BTC,39909.14585,9,1,Bitcoin,4,-10,3,2500,-5,1000000,-3,1000000,1000000,-9 +CFX,0.1454384387,5,2,Conflux Token,-1,-5,3,4000,-10,1000000,-3,1000000,1000000,-9 +CHZ,0.08712744693,6,2,Chiliz,-2,-4,3,4000,-11,1000000,-3,1000000,1000000,-9 +COMP,52.74250938,5,2,Compound Coin,1,-7,3,4000,-8,1000000,-3,1000000,1000000,-9 +CRV,0.4443624604,6,2,Curve DAO Token,-1,-5,3,4000,-10,1000000,-3,1000000,1000000,-9 +DOGE,0.07793177878,9,1,Dogecoin,-2,-4,3,2500,-11,1000000,-3,1000000,1000000,-9 +DOT,6.452414058,8,1,Polkadot,0,-6,3,2500,-9,1000000,-3,1000000,1000000,-9 +EGLD,39.03897897,5,2,MultiversX,1,-7,3,4000,-8,1000000,-3,1000000,1000000,-9 +ENS,14.85690244,6,2,Ethereum Name Service (ENS),1,-7,3,4000,-8,1000000,-3,1000000,1000000,-9 +EOS,0.5977251446,8,2,Eos,-1,-5,3,4000,-10,1000000,-3,1000000,1000000,-9 +ETC,22.84861344,8,1,Ethereum Classic,1,-7,3,2500,-8,1000000,-3,1000000,1000000,-9 +ETH,2211.721168,9,1,Ethereum,3,-9,3,2500,-6,1000000,-3,1000000,1000000,-9 +FET,0.5864541562,6,2,Fetch AI,-1,-5,3,4000,-10,1000000,-3,1000000,1000000,-9 +FIL,4.930296959,8,1,Filecoin,0,-6,3,2500,-9,1000000,-3,1000000,1000000,-9 +FLOW,0.5828593278,5,2,Flow - Dapper Labs,-1,-5,3,4000,-10,1000000,-3,1000000,1000000,-9 +FTM,0.3359983176,6,2,Fantom,-1,-5,3,4000,-10,1000000,-3,1000000,1000000,-9 +GALA,0.01840015547,6,2,Gala,-2,-4,3,4000,-11,1000000,-3,1000000,1000000,-9 +GMT,0.2045438866,5,2,STEPN,-1,-5,3,4000,-10,1000000,-3,1000000,1000000,-9 +GRT,0.128018834,7,2,The Graph,-1,-5,3,4000,-10,1000000,-3,1000000,1000000,-9 +HBAR,0.07127967284,7,2,Hedera Hashgraph,-2,-4,3,4000,-11,1000000,-3,1000000,1000000,-9 +ICP,11.47442186,7,2,Internet Computer,1,-7,3,4000,-8,1000000,-3,1000000,1000000,-9 +INJ,31.78305093,7,2,Injective Protocol,1,-7,3,4000,-8,1000000,-3,1000000,1000000,-9 +JTO,1.886208515,6,2,Jito,0,-6,3,4000,-9,1000000,-3,1000000,1000000,-9 +KAVA,0.5751546332,6,2,Kava,-1,-5,3,4000,-10,1000000,-3,1000000,1000000,-9 +LDO,2.524539255,8,2,Lido DAO,0,-6,3,4000,-9,1000000,-3,1000000,1000000,-9 +LINK,13.81655633,8,1,ChainLink,1,-7,3,2500,-8,1000000,-3,1000000,1000000,-9 +LTC,65.43204352,9,1,Litecoin,1,-7,3,2500,-8,1000000,-3,1000000,1000000,-9 +MANA,0.3716510229,7,2,Decentraland,-1,-5,3,4000,-10,1000000,-3,1000000,1000000,-9 +MASK,2.787727403,7,2,Mask Network,0,-6,3,4000,-9,1000000,-3,1000000,1000000,-9 +MATIC,0.7288467315,9,1,Matic Network,-1,-5,3,2500,-10,1000000,-3,1000000,1000000,-9 +MEME,0.01801497104,5,2,Memecoin Price,-2,-4,3,4000,-11,1000000,-3,1000000,1000000,-9 +MINA,1.008126033,5,2,Mina,0,-6,3,4000,-9,1000000,-3,1000000,1000000,-9 +MKR,2113.151651,6,2,Maker,3,-9,3,4000,-6,1000000,-3,1000000,1000000,-9 +NEAR,2.674751578,8,1,Near,0,-6,3,2500,-9,1000000,-3,1000000,1000000,-9 +OP,2.456951554,7,2,Optimism,0,-6,3,4000,-9,1000000,-3,1000000,1000000,-9 +ORDI,43.0494516,6,2,Ordinals,1,-7,3,4000,-8,1000000,-3,1000000,1000000,-9 +PEOPLE,0.02194591464,5,2,ConstitutionDAO,-2,-4,3,4000,-11,1000000,-3,1000000,1000000,-9 +PEPE,1.02E-06,6,2,Pepe,-6,0,3,4000,-15,1000000,-3,1000000,1000000,-9 +RNDR,3.777241656,6,2,Render Token,0,-6,3,4000,-9,1000000,-3,1000000,1000000,-9 +SAND,0.3751083804,7,2,SAND,-1,-5,3,4000,-10,1000000,-3,1000000,1000000,-9 +SEI,0.6149970988,7,2,Sei,-1,-5,3,4000,-10,1000000,-3,1000000,1000000,-9 +SHIB,8.84E-06,8,1,Shiba Inu,-6,0,3,2500,-15,1000000,-3,1000000,1000000,-9 +SNX,3.130619706,6,2,Synthetix Network Token,0,-6,3,4000,-9,1000000,-3,1000000,1000000,-9 +SOL,87.46988589,9,1,Solana,1,-7,3,2500,-8,1000000,-3,1000000,1000000,-9 +STX,1.255152213,7,2,Stacks,0,-6,3,4000,-9,1000000,-3,1000000,1000000,-9 +SUI,1.224271493,6,2,SuiNetwork,0,-6,3,4000,-9,1000000,-3,1000000,1000000,-9 +SUSHI,0.8926299706,6,2,Sushi,-1,-5,3,4000,-10,1000000,-3,1000000,1000000,-9 +TIA,15.55257715,7,2,Celestia,1,-7,3,4000,-8,1000000,-3,1000000,1000000,-9 +TRX,0.09702155504,8,2,TRON,-2,-4,3,4000,-11,1000000,-3,1000000,1000000,-9 +UNI,5.760612586,7,2,Uniswap,0,-6,3,4000,-9,1000000,-3,1000000,1000000,-9 +WAVES,2.145700544,5,2,Waves,0,-6,3,4000,-9,1000000,-3,1000000,1000000,-9 +WLD,1.907665645,6,2,Worldcoin WLD,0,-6,3,4000,-9,1000000,-3,1000000,1000000,-9 +XLM,0.1116437262,8,1,Stellar,-1,-5,3,2500,-10,1000000,-3,1000000,1000000,-9 +XRP,0.5112717386,9,1,Ripple,-1,-5,3,2500,-10,1000000,-3,1000000,1000000,-9 diff --git a/public/currencies/bonk.png b/public/currencies/bonk.png new file mode 100644 index 0000000..2f1f9f8 Binary files /dev/null and b/public/currencies/bonk.png differ diff --git a/src/App.tsx b/src/App.tsx index 416b110..23d1a39 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,7 +5,7 @@ import { WagmiConfig } from 'wagmi'; import { QueryClient, QueryClientProvider } from 'react-query'; import { GrazProvider } from 'graz'; -import { AppRoute, DEFAULT_TRADE_ROUTE } from '@/constants/routes'; +import { AppRoute, DEFAULT_TRADE_ROUTE, MarketsRoute } from '@/constants/routes'; import { useBreakpoints, @@ -21,6 +21,7 @@ import { DialogAreaProvider, useDialogArea } from '@/hooks/useDialogArea'; import { LocaleProvider } from '@/hooks/useLocaleSeparators'; import { NotificationsProvider } from '@/hooks/useNotifications'; import { LocalNotificationsProvider } from '@/hooks/useLocalNotifications'; +import { PotentialMarketsProvider } from '@/hooks/usePotentialMarkets'; import { RestrictionProvider } from '@/hooks/useRestrictions'; import { SubaccountProvider } from '@/hooks/useSubaccount'; @@ -44,6 +45,7 @@ import '@/styles/constants.css'; import '@/styles/fonts.css'; import '@/styles/web3modal.css'; +const NewMarket = lazy(() => import('@/pages/markets/NewMarket')); const MarketsPage = lazy(() => import('@/pages/markets/Markets')); const PortfolioPage = lazy(() => import('@/pages/portfolio/Portfolio')); const AlertsPage = lazy(() => import('@/pages/AlertsPage')); @@ -81,7 +83,10 @@ const Content = () => { } /> - } /> + + } /> + } /> + } /> {isTablet && ( <> @@ -136,6 +141,7 @@ const providers = [ wrapProvider(LocalNotificationsProvider), wrapProvider(NotificationsProvider), wrapProvider(DialogAreaProvider), + wrapProvider(PotentialMarketsProvider), wrapProvider(AppThemeProvider), ]; diff --git a/src/components/AssetIcon.tsx b/src/components/AssetIcon.tsx index 1ea994b..9d30239 100644 --- a/src/components/AssetIcon.tsx +++ b/src/components/AssetIcon.tsx @@ -16,6 +16,7 @@ const assetIcons = { AVAX: '/currencies/avax.png', BCH: '/currencies/bch.png', BLUR: '/currencies/blur.png', + BONK: '/currencies/bonk.png', BTC: '/currencies/btc.png', CELO: '/currencies/celo.png', COMP: '/currencies/comp.png', diff --git a/src/components/ComboboxMenu.tsx b/src/components/ComboboxMenu.tsx index 8009145..e322047 100644 --- a/src/components/ComboboxMenu.tsx +++ b/src/components/ComboboxMenu.tsx @@ -51,8 +51,9 @@ export const ComboboxMenu = { - if (value.replace(/ /g, '').includes(search.replace(/ /g, ''))) return 1; - return 0; + value.replace(/ /g, '').toLowerCase().includes(search.replace(/ /g, '').toLowerCase()) + ? 1 + : 0; }} className={className} $withStickyLayout={withStickyLayout} diff --git a/src/components/FormInput.tsx b/src/components/FormInput.tsx index da0591f..588c5df 100644 --- a/src/components/FormInput.tsx +++ b/src/components/FormInput.tsx @@ -32,7 +32,7 @@ export const FormInput = forwardRef( isValidationAttached={validationConfig?.attached} > - + {slotRight} @@ -85,11 +85,11 @@ Styled.InputContainer = styled.div<{ hasSlotRight?: boolean }>` `} `; -Styled.WithLabel = styled(WithLabel)` +Styled.WithLabel = styled(WithLabel)<{ disabled?: boolean }>` ${formMixins.inputLabel} label { - cursor: text; + ${({ disabled }) => !disabled && 'cursor: text;'} padding: var(--form-input-paddingY) var(--form-input-paddingX) 0; } `; diff --git a/src/components/Loading/LoadingSpinner.tsx b/src/components/Loading/LoadingSpinner.tsx index d4bb299..400438e 100644 --- a/src/components/Loading/LoadingSpinner.tsx +++ b/src/components/Loading/LoadingSpinner.tsx @@ -11,6 +11,7 @@ export const LoadingSpinner: React.FC<{ return ( {tag}} + {slotRight} ); } diff --git a/src/components/WithDetailsReceipt.tsx b/src/components/WithDetailsReceipt.tsx index 6f733cd..44fb64e 100644 --- a/src/components/WithDetailsReceipt.tsx +++ b/src/components/WithDetailsReceipt.tsx @@ -40,5 +40,5 @@ Styled.Details = styled(Details)` padding: 0.375rem 0.75rem 0.25rem; - font-size: 0.8125em; + font-size: var(--details-item-fontSize, 0.8125em); `; diff --git a/src/constants/dialogs.ts b/src/constants/dialogs.ts index 7ce2904..e5cf8fd 100644 --- a/src/constants/dialogs.ts +++ b/src/constants/dialogs.ts @@ -19,6 +19,8 @@ export enum DialogTypes { Transfer = 'Transfer', Withdraw = 'Withdraw', ManageFunds = 'ManageFunds', + NewMarketMessageDetails = 'NewMarketMessageDetails', + NewMarketAgreement = 'NewMarketAgreement', } export enum TradeBoxDialogTypes { diff --git a/src/constants/indexer.ts b/src/constants/indexer.ts new file mode 100644 index 0000000..12c2f02 --- /dev/null +++ b/src/constants/indexer.ts @@ -0,0 +1,23 @@ +/** + * Temporary Indexer types + * remove when Indexer type lib is available through @dydxprotocol/v4-client-js + */ +export type PerpetualMarketResponse = { + clobPairId: string; + ticker: string; + status: string; + oraclePrice: string; + priceChange24H: string; + volume24H: string; + trades24H: number; + nextFundingRate: string; + initialMarginFraction: string; + maintenanceMarginFraction: string; + openInterest: string; + atomicResolution: number; + quantumConversionExponent: number; + tickSize: string; + stepSize: string; + stepBaseQuantums: number; + subticksPerTick: number; +}; diff --git a/src/constants/potentialMarkets.ts b/src/constants/potentialMarkets.ts new file mode 100644 index 0000000..da2707d --- /dev/null +++ b/src/constants/potentialMarkets.ts @@ -0,0 +1,85 @@ +export type ExchangeConfigParsedCsv = Array<{ + base_asset: string; + exchange: string; + pair: string; + + adjust_by_market: string; + min_2_depth: string; + avg_30d_vol: string; + reference_price: string; + risk_assessment: string; + num_oracles: string; + liquidity_tier: string; + asset_name: string; +}>; + +export type ExchangeConfigItem = { + exchangeName: string; + ticker: string; + adjustByMarket?: string; +}; + +export type PotentialMarketParsedCsv = Array<{ + base_asset: string; + reference_price: string; + num_oracles: string; + liquidity_tier: string; + asset_name: string; + p: string; + atomic_resolution: string; + min_exchanges: string; + min_price_change_ppm: string; + price_exponent: string; + step_base_quantum: string; + ticksize_exponent: string; + subticks_per_tick: string; + min_order_size: string; + quantum_conversion_exponent: string; +}>; + +export type PotentialMarketItem = { + baseAsset: string; + referencePrice: string; + numOracles: number; + liquidityTier: number; + assetName: string; + p: number; + atomicResolution: number; + minExchanges: number; + minPriceChangePpm: number; + priceExponent: number; + stepBaseQuantum: number; + ticksizeExponent: number; + subticksPerTick: number; + minOrderSize: number; + quantumConversionExponent: number; +}; + +export const NUM_ORACLES_TO_QUALIFY_AS_SAFE = 6; + +export const LIQUIDITY_TIERS = { + 0: { + label: 'Large-cap', + initialMarginFraction: 0.05, + maintenanceMarginFraction: 0.03, + impactNotional: 10_000, + }, + 1: { + label: 'Mid-cap', + initialMarginFraction: 0.1, + maintenanceMarginFraction: 0.05, + impactNotional: 5_000, + }, + 2: { + label: 'Long-tail', + initialMarginFraction: 0.2, + maintenanceMarginFraction: 0.1, + impactNotional: 2_500, + }, + 3: { + label: 'Safety', + initialMarginFraction: 1, + maintenanceMarginFraction: 0.2, + impactNotional: 2_500, + }, +}; diff --git a/src/constants/routes.ts b/src/constants/routes.ts index 529efae..5c86896 100644 --- a/src/constants/routes.ts +++ b/src/constants/routes.ts @@ -11,6 +11,10 @@ export enum AppRoute { Privacy = '/privacy', } +export enum MarketsRoute { + New = 'new', +} + export enum PortfolioRoute { Fees = 'fees', History = 'history', diff --git a/src/constants/tooltips/trade.ts b/src/constants/tooltips/trade.ts index 84724b9..081e3f0 100644 --- a/src/constants/tooltips/trade.ts +++ b/src/constants/tooltips/trade.ts @@ -57,10 +57,9 @@ export const tradeTooltips: TooltipStrings = { title: stringGetter({ key: TOOLTIP_STRING_KEYS.INDEX_PRICE_TITLE }), body: stringGetter({ key: TOOLTIP_STRING_KEYS.INDEX_PRICE_BODY }), }), - 'initial-margin-fraction': ({ stringGetter, urlConfigs }) => ({ + 'initial-margin-fraction': ({ stringGetter }) => ({ title: stringGetter({ key: TOOLTIP_STRING_KEYS.INITIAL_MARGIN_FRACTION_TITLE }), body: stringGetter({ key: TOOLTIP_STRING_KEYS.INITIAL_MARGIN_FRACTION_BODY }), - learnMoreLink: urlConfigs?.initialMarginFractionLearnMore, }), 'initial-stop': ({ stringGetter }) => ({ title: stringGetter({ key: TOOLTIP_STRING_KEYS.INITIAL_STOP_TITLE }), @@ -163,6 +162,10 @@ export const tradeTooltips: TooltipStrings = { title: stringGetter({ key: TOOLTIP_STRING_KEYS.REDUCE_ONLY_TIMEINFORCE_IOC_FOK_TITLE }), body: stringGetter({ key: TOOLTIP_STRING_KEYS.REDUCE_ONLY_TIMEINFORCE_IOC_FOK_BODY }), }), + 'reference-price': ({ stringGetter }) => ({ + title: stringGetter({ key: TOOLTIP_STRING_KEYS.REFERENCE_PRICE_TITLE }), + body: stringGetter({ key: TOOLTIP_STRING_KEYS.REFERENCE_PRICE_BODY }), + }), spread: () => ({ title: 'Spread', body: 'The difference in price between the highest bid (the price a buyer is willing to buy for) and lowest ask (the price a seller is willing to sell for) an asset.', diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 1d2ed1e..fc985a8 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -7,6 +7,7 @@ import { useDebounce } from './useDebounce'; import { useInterval } from './useInterval'; import { useDocumentTitle } from './useDocumentTitle'; import { useDydxClient } from './useDydxClient'; +import { useGovernanceVariables } from './useGovernanceVariables'; import { useAccountBalance } from './useAccountBalance'; import { useAccounts } from './useAccounts'; import { useAnalytics } from './useAnalytics'; @@ -14,6 +15,7 @@ import { useInitializePage } from './useInitializePage'; import { useIsFirstRender } from './useIsFirstRender'; import { useLocaleSeparators } from './useLocaleSeparators'; import { useLocalStorage } from './useLocalStorage'; +import { useNextClobPairId } from './useNextClobPairId'; import { useNow } from './useNow'; import { useOnClickOutside } from './useOnClickOutside'; import { usePageTitlePriceUpdates } from './usePageTitlePriceUpdates'; @@ -34,6 +36,7 @@ export { useDebounce, useDocumentTitle, useDydxClient, + useGovernanceVariables, useAccountBalance, useAccounts, useAnalytics, @@ -42,6 +45,7 @@ export { useIsFirstRender, useLocaleSeparators, useLocalStorage, + useNextClobPairId, useNow, useOnClickOutside, usePageTitlePriceUpdates, diff --git a/src/hooks/useDydxClient.tsx b/src/hooks/useDydxClient.tsx index cf3d7d2..581dd58 100644 --- a/src/hooks/useDydxClient.tsx +++ b/src/hooks/useDydxClient.tsx @@ -1,5 +1,6 @@ import { createContext, useCallback, useContext, useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; + import { BECH32_PREFIX, CompositeClient, @@ -9,6 +10,7 @@ import { onboarding, Network, ValidatorConfig, + type ProposalStatus, } from '@dydxprotocol/v4-client-js'; import type { ResolutionString } from 'public/tradingview/charting_library'; @@ -68,17 +70,21 @@ const useDydxClientContext = () => { new Network( selectedNetwork, new IndexerConfig(networkConfig.indexerUrl, networkConfig.websocketUrl), - new ValidatorConfig(networkConfig.validatorUrl, networkConfig.chainId, + new ValidatorConfig( + networkConfig.validatorUrl, + networkConfig.chainId, { USDC_DENOM: tokensConfigs[DydxChainAsset.USDC].denom, USDC_DECIMALS: tokensConfigs[DydxChainAsset.USDC].decimals, USDC_GAS_DENOM: tokensConfigs[DydxChainAsset.USDC].gasDenom, CHAINTOKEN_DENOM: tokensConfigs[DydxChainAsset.CHAINTOKEN].denom, CHAINTOKEN_DECIMALS: tokensConfigs[DydxChainAsset.CHAINTOKEN].decimals, - }, { - broadcastPollIntervalMs: 3_000, - broadcastTimeoutMs: 60_000, - }) + }, + { + broadcastPollIntervalMs: 3_000, + broadcastTimeoutMs: 60_000, + } + ) ) ); setCompositeClient(initializedClient); @@ -111,6 +117,36 @@ const useDydxClientContext = () => { }; // ------ Public Methods ------ // + const requestAllPerpetualMarkets = useCallback(async () => { + try { + const { markets } = + (await compositeClient?.indexerClient.markets.getPerpetualMarkets()) || {}; + return markets || []; + } catch (error) { + log('useDydxClient/getPerpetualMarkets', error); + return []; + } + }, [compositeClient]); + + /** + * @param proposalStatus - Optional filter for proposal status. If not provided, all proposals in ProposalStatus.VotingPeriod will be returned. + */ + const requestAllGovernanceProposals = useCallback( + async (proposalStatus?: ProposalStatus) => { + try { + const allGovProposals = await compositeClient?.validatorClient.get.getAllGovProposals( + proposalStatus + ); + + return allGovProposals; + } catch (error) { + log('useDydxClient/getProposals', error); + return undefined; + } + }, + [compositeClient] + ); + const requestCandles = useCallback( async ({ marketId, @@ -225,6 +261,8 @@ const useDydxClientContext = () => { getWalletFromEvmSignature, // Public Methods + requestAllPerpetualMarkets, + requestAllGovernanceProposals, getCandlesForDatafeed, screenAddresses, }; diff --git a/src/hooks/useGovernanceVariables.ts b/src/hooks/useGovernanceVariables.ts new file mode 100644 index 0000000..0234ea0 --- /dev/null +++ b/src/hooks/useGovernanceVariables.ts @@ -0,0 +1,16 @@ +import { ENVIRONMENT_CONFIG_MAP } from '@/constants/networks'; +import { useSelectedNetwork } from '@/hooks'; + +export interface GovernanceVariables { + newMarketProposal: { + initialDepositAmount: number; + delayBlocks: number; + newMarketsMethodology: string; + }; +} + +export const useGovernanceVariables = (): GovernanceVariables => { + const { selectedNetwork } = useSelectedNetwork(); + const governanceVars = ENVIRONMENT_CONFIG_MAP[selectedNetwork].governance as GovernanceVariables; + return governanceVars; +}; diff --git a/src/hooks/useNextClobPairId.ts b/src/hooks/useNextClobPairId.ts new file mode 100644 index 0000000..f2c74e6 --- /dev/null +++ b/src/hooks/useNextClobPairId.ts @@ -0,0 +1,118 @@ +import { useMemo } from 'react'; +import { useQuery } from 'react-query'; + +import { + MsgCreateClobPair, + MsgCreateOracleMarket, + MsgCreatePerpetual, + MsgDelayMessage, + MsgUpdateClobPair, + TYPE_URL_MSG_CREATE_CLOB_PAIR, + TYPE_URL_MSG_CREATE_ORACLE_MARKET, + TYPE_URL_MSG_CREATE_PERPETUAL, + TYPE_URL_MSG_DELAY_MESSAGE, + TYPE_URL_MSG_UPDATE_CLOB_PAIR, +} from '@dydxprotocol/v4-client-js'; + +import type { PerpetualMarketResponse } from '@/constants/indexer'; +import { useDydxClient } from '@/hooks/useDydxClient'; + +export const useNextClobPairId = () => { + const { isConnected, requestAllPerpetualMarkets, requestAllGovernanceProposals } = + useDydxClient(); + + const { data: perpetualMarkets, status: perpetualMarketsStatus } = useQuery({ + enabled: isConnected, + queryKey: 'requestAllPerpetualMarkets', + queryFn: requestAllPerpetualMarkets, + refetchInterval: 60_000, + staleTime: 60_000, + }); + + const { data: allGovProposals, status: allGovProposalsStatus } = useQuery({ + enabled: isConnected, + queryKey: 'requestAllActiveGovernanceProposals', + queryFn: () => requestAllGovernanceProposals(), + refetchInterval: 10_000, + staleTime: 10_000, + }); + + /** + * + * @param message from proposal. Each message is wrapped in a type any (on purpose). + * @param callback method used to compile all clobPairIds, perpetualIds, marketIds, etc. + */ + const decodeMsgForClobPairId = (message: any, callback: (id?: number) => void): any => { + const { typeUrl, value } = message; + + switch (typeUrl) { + case TYPE_URL_MSG_CREATE_ORACLE_MARKET: { + const decodedValue = MsgCreateOracleMarket.decode(value); + callback(decodedValue.params?.id); + break; + } + case TYPE_URL_MSG_CREATE_PERPETUAL: { + const decodedValue = MsgCreatePerpetual.decode(value); + callback(decodedValue.params?.id); + callback(decodedValue.params?.marketId); + break; + } + case TYPE_URL_MSG_CREATE_CLOB_PAIR: { + const decodedValue = MsgCreateClobPair.decode(value); + callback(decodedValue.clobPair?.id); + callback(decodedValue.clobPair?.perpetualClobMetadata?.perpetualId); + break; + } + case TYPE_URL_MSG_UPDATE_CLOB_PAIR: { + const decodedValue = MsgUpdateClobPair.decode(value); + callback(decodedValue.clobPair?.id); + callback(decodedValue.clobPair?.perpetualClobMetadata?.perpetualId); + break; + } + case TYPE_URL_MSG_DELAY_MESSAGE: { + const decodedValue = MsgDelayMessage.decode(value); + decodeMsgForClobPairId(decodedValue.msg, callback); + break; + } + default: { + break; + } + } + }; + + const nextAvailableClobPairId = useMemo(() => { + const idsFromProposals: number[] = []; + + if (allGovProposals && Object.values(allGovProposals.proposals).length > 0) { + const proposals = allGovProposals.proposals; + proposals.forEach((proposal) => { + if (proposal.messages) { + proposal.messages.map((message) => { + decodeMsgForClobPairId(message, (id?: number) => { + if (id) { + idsFromProposals.push(id); + } + }); + }); + } + }); + } + + if (perpetualMarkets && Object.values(perpetualMarkets).length > 0) { + const clobPairIds = Object.values(perpetualMarkets)?.map((perpetualMarket) => + Number((perpetualMarket as PerpetualMarketResponse).clobPairId) + ); + + const nextAvailableClobPairId = Math.max(...[...clobPairIds, ...idsFromProposals]) + 1; + return nextAvailableClobPairId; + } + + return undefined; + }, [perpetualMarkets, allGovProposals]); + + return { + allGovProposalsStatus, + perpetualMarketsStatus, + nextAvailableClobPairId, + }; +}; diff --git a/src/hooks/usePotentialMarkets.tsx b/src/hooks/usePotentialMarkets.tsx new file mode 100644 index 0000000..0708486 --- /dev/null +++ b/src/hooks/usePotentialMarkets.tsx @@ -0,0 +1,135 @@ +import { createContext, useContext, useEffect, useState } from 'react'; + +import type { + ExchangeConfigItem, + ExchangeConfigParsedCsv, + PotentialMarketItem, + PotentialMarketParsedCsv, +} from '@/constants/potentialMarkets'; + +import csvToArray from '@/lib/csvToArray'; +import { log } from '@/lib/telemetry'; + +const PotentialMarketsContext = createContext>({ + potentialMarkets: undefined, + exchangeConfigs: undefined, + hasPotentialMarketsData: false, +}); + +PotentialMarketsContext.displayName = 'PotentialMarkets'; + +export const PotentialMarketsProvider = ({ ...props }) => ( + +); + +export const usePotentialMarkets = () => useContext(PotentialMarketsContext); + +const EXCHANGE_CONFIG_FILE_PATH = '/configs/potentialMarketExchangeConfig.csv'; +const POTENTIAL_MARKETS_FILE_PATH = '/configs/potentialMarketParameters.csv'; + +export const usePotentialMarketsContext = () => { + const [potentialMarkets, setPotentialMarkets] = useState(); + const [exchangeConfigs, setExchangeConfigs] = useState>(); + + useEffect(() => { + try { + fetch(POTENTIAL_MARKETS_FILE_PATH) + .then((response) => response.text()) + .then((data) => { + const parsedData = csvToArray({ + stringVal: data, + splitter: ',', + }); + const parsedPotentialMarkets = parsedData.map( + ({ + base_asset, + reference_price, + num_oracles, + liquidity_tier, + asset_name, + p, + atomic_resolution, + min_exchanges, + min_price_change_ppm, + price_exponent, + step_base_quantum, + ticksize_exponent, + subticks_per_tick, + min_order_size, + quantum_conversion_exponent, + }) => ({ + // convert to camelCase + baseAsset: base_asset, + referencePrice: reference_price, + numOracles: Number(num_oracles), + liquidityTier: Number(liquidity_tier), + assetName: asset_name, + p: Number(p), + atomicResolution: Number(atomic_resolution), + minExchanges: Number(min_exchanges), + minPriceChangePpm: Number(min_price_change_ppm), + priceExponent: Number(price_exponent), + stepBaseQuantum: Number(step_base_quantum), + ticksizeExponent: Number(ticksize_exponent), + subticksPerTick: Number(subticks_per_tick), + minOrderSize: Number(min_order_size), + quantumConversionExponent: Number(quantum_conversion_exponent), + }) + ); + + setPotentialMarkets(parsedPotentialMarkets); + }); + } catch (error) { + log('usePotentialMarkets/potentialMarkets', error); + setPotentialMarkets(undefined); + } + + try { + fetch(EXCHANGE_CONFIG_FILE_PATH) + .then((response) => response.text()) + .then((data) => { + const parsedData = csvToArray({ + stringVal: data, + splitter: ',', + }); + // create an object with the base_asset as the key and the value as an array of exchanges + const exchangeConfigMap = parsedData.reduce( + (acc: Record, curr) => { + const { base_asset, exchange, pair, adjust_by_market } = curr; + if (!acc[base_asset]) { + acc[base_asset] = []; + } + + const exchangeItem: { + exchangeName: string; + ticker: string; + adjustByMarket?: string; + } = { + exchangeName: exchange, + ticker: pair, + }; + + if (adjust_by_market) { + exchangeItem.adjustByMarket = adjust_by_market; + } + + acc[base_asset].push(exchangeItem); + return acc; + }, + {} + ); + + setExchangeConfigs(exchangeConfigMap); + }); + } catch (error) { + log('usePotentialMarkets/exchangeConfigs', error); + setExchangeConfigs(undefined); + } + }, []); + + return { + potentialMarkets, + exchangeConfigs, + hasPotentialMarketsData: Boolean(potentialMarkets && exchangeConfigs), + }; +}; diff --git a/src/hooks/useSubaccount.tsx b/src/hooks/useSubaccount.tsx index 3189717..cfd2588 100644 --- a/src/hooks/useSubaccount.tsx +++ b/src/hooks/useSubaccount.tsx @@ -2,11 +2,16 @@ import { createContext, useCallback, useContext, useEffect, useMemo, useState } import { shallowEqual, useSelector, useDispatch } from 'react-redux'; import type { Nullable } from '@dydxprotocol/v4-abacus'; import Long from 'long'; -import type { IndexedTx } from '@cosmjs/stargate'; +import { type IndexedTx } from '@cosmjs/stargate'; import type { EncodeObject } from '@cosmjs/proto-signing'; import { Method } from '@cosmjs/tendermint-rpc'; -import { type LocalWallet, SubaccountClient } from '@dydxprotocol/v4-client-js'; +import { + type LocalWallet, + SubaccountClient, + type GovAddNewMarketParams, + utils, +} from '@dydxprotocol/v4-client-js'; import type { AccountBalance, @@ -16,7 +21,6 @@ import type { } from '@/constants/abacus'; import { AMOUNT_RESERVED_FOR_GAS_USDC } from '@/constants/account'; -import { AnalyticsEvent } from '@/constants/analytics'; import { QUANTUM_MULTIPLIER } from '@/constants/numbers'; import { DydxAddress } from '@/constants/wallets'; @@ -24,14 +28,13 @@ import { setSubaccount, setHistoricalPnl, removeUncommittedOrderClientId } from import { getBalances } from '@/state/accountSelectors'; import abacusStateManager from '@/lib/abacus'; -import { track } from '@/lib/analytics'; -import { MustBigNumber } from '@/lib/numbers'; +import { hashFromTx } from '@/lib/hashfromTx'; import { log } from '@/lib/telemetry'; import { useAccounts } from './useAccounts'; import { useTokenConfigs } from './useTokenConfigs'; import { useDydxClient } from './useDydxClient'; -import { hashFromTx } from '@/lib/hashfromTx'; +import { useGovernanceVariables } from './useGovernanceVariables'; type SubaccountContextType = ReturnType; const SubaccountContext = createContext({} as SubaccountContextType); @@ -201,8 +204,8 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo value: { ...transaction.msg, timeoutTimestamp: transaction.msg.timeoutTimestamp - // Squid returns timeoutTimestamp as Long, but the signer expects BigInt - ? BigInt(Long.fromValue(transaction.msg.timeoutTimestamp).toString()) + ? // Squid returns timeoutTimestamp as Long, but the signer expects BigInt + BigInt(Long.fromValue(transaction.msg.timeoutTimestamp).toString()) : undefined, }, }; @@ -301,9 +304,8 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo const sendSquidWithdraw = useCallback( async (amount: number, payload: string, isCctp?: boolean) => { - const cctpWithdraw = () => { - return new Promise((resolve, reject) => + return new Promise((resolve, reject) => abacusStateManager.cctpWithdraw((success, error, data) => { const parsedData = JSON.parse(data); if (success && parsedData?.code == 0) { @@ -312,8 +314,8 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo reject(error); } }) - ) - } + ); + }; if (isCctp) { return await cctpWithdraw(); } @@ -413,6 +415,32 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo [subaccountClient] ); + const { newMarketProposal } = useGovernanceVariables(); + + // ------ Governance Methods ------ // + const submitNewMarketProposal = useCallback( + async (params: GovAddNewMarketParams) => { + if (!compositeClient) { + throw new Error('client not initialized'); + } else if (!localDydxWallet) { + throw new Error('wallet not initialized'); + } else if (!newMarketProposal) { + throw new Error('governance variables not initialized'); + } + + const response = await compositeClient.submitGovAddNewMarketProposal( + localDydxWallet, + params, + utils.getGovAddNewMarketTitle(params.ticker), + utils.getGovAddNewMarketSummary(params.ticker, newMarketProposal.delayBlocks), + newMarketProposal.initialDepositAmount + ); + + return response; + }, + [compositeClient, localDydxWallet] + ); + return { // Deposit/Withdraw/Faucet Methods deposit, @@ -427,5 +455,8 @@ export const useSubaccountContext = ({ localDydxWallet }: { localDydxWallet?: Lo placeOrder, closePosition, cancelOrder, + + // Governance Methods + submitNewMarketProposal, }; }; diff --git a/src/layout/DialogManager.tsx b/src/layout/DialogManager.tsx index 49faff7..d7145ae 100644 --- a/src/layout/DialogManager.tsx +++ b/src/layout/DialogManager.tsx @@ -27,6 +27,8 @@ import { ManageFundsDialog } from '@/views/dialogs/ManageFundsDialog'; import { OrderDetailsDialog } from '@/views/dialogs/DetailsDialog/OrderDetailsDialog'; import { FillDetailsDialog } from '@/views/dialogs/DetailsDialog/FillDetailsDialog'; +import { NewMarketMessageDetailsDialog } from '@/views/dialogs/NewMarketMessageDetailsDialog'; +import { NewMarketAgreementDialog } from '@/views/dialogs/NewMarketAgreementDialog'; export const DialogManager = () => { const dispatch = useDispatch(); @@ -67,5 +69,7 @@ export const DialogManager = () => { [DialogTypes.Transfer]: , [DialogTypes.Withdraw]: , [DialogTypes.ManageFunds]: , + [DialogTypes.NewMarketMessageDetails]: , + [DialogTypes.NewMarketAgreement]: , }[type]; }; diff --git a/src/lib/csvToArray.ts b/src/lib/csvToArray.ts new file mode 100644 index 0000000..eb3dbf5 --- /dev/null +++ b/src/lib/csvToArray.ts @@ -0,0 +1,16 @@ +const csvToArray = ({ stringVal, splitter }: { stringVal: string; splitter: string }) => { + const [keys, ...rest] = stringVal + .trim() + .split('\n') + .map((item) => item.split(splitter)); + + const formedArr = rest.map((item) => { + const object: Record = {}; + keys.forEach((key, index) => (object[key] = item[index])); + return object; + }); + + return formedArr as T; +}; + +export default csvToArray; diff --git a/src/pages/markets/Markets.tsx b/src/pages/markets/Markets.tsx index 79a63e9..7644f8b 100644 --- a/src/pages/markets/Markets.tsx +++ b/src/pages/markets/Markets.tsx @@ -1,21 +1,25 @@ import styled, { AnyStyledComponent } from 'styled-components'; +import { useNavigate } from 'react-router-dom'; import { breakpoints } from '@/styles'; import { STRING_KEYS } from '@/constants/localization'; - +import { AppRoute, MarketsRoute } from '@/constants/routes'; import { useBreakpoints, useDocumentTitle, useStringGetter } from '@/hooks'; +import { usePotentialMarkets } from '@/hooks/usePotentialMarkets'; import { layoutMixins } from '@/styles/layoutMixins'; +import { Button } from '@/components/Button'; import { ContentSectionHeader } from '@/components/ContentSectionHeader'; - import { ExchangeBillboards } from '@/views/ExchangeBillboards'; import { MarketsTable } from '@/views/tables/MarketsTable'; const Markets = () => { const stringGetter = useStringGetter(); const { isNotTablet } = useBreakpoints(); + const navigate = useNavigate(); + const { hasPotentialMarketsData } = usePotentialMarkets(); useDocumentTitle(stringGetter({ key: STRING_KEYS.MARKETS })); @@ -25,6 +29,13 @@ const Markets = () => { navigate(`${AppRoute.Markets}/${MarketsRoute.New}`)}> + {stringGetter({ key: STRING_KEYS.ADD_A_MARKET })} + + ) + } /> diff --git a/src/pages/markets/NewMarket.tsx b/src/pages/markets/NewMarket.tsx new file mode 100644 index 0000000..0d722c9 --- /dev/null +++ b/src/pages/markets/NewMarket.tsx @@ -0,0 +1,259 @@ +import { useMemo, useState } from 'react'; +import styled, { AnyStyledComponent } from 'styled-components'; +import { useNavigate } from 'react-router-dom'; + +import { STRING_KEYS } from '@/constants/localization'; +import { isMainnet } from '@/constants/networks'; +import { AppRoute } from '@/constants/routes'; + +import { + useBreakpoints, + useDocumentTitle, + useGovernanceVariables, + useStringGetter, + useTokenConfigs, +} from '@/hooks'; + +import { breakpoints } from '@/styles'; +import { layoutMixins } from '@/styles/layoutMixins'; + +import { Button } from '@/components/Button'; +import { ContentSectionHeader } from '@/components/ContentSectionHeader'; +import { IconButton } from '@/components/IconButton'; +import { Icon, IconName } from '@/components/Icon'; +import { Link } from '@/components/Link'; +import { NewMarketForm } from '@/views/forms/NewMarketForm'; + +import { MustBigNumber } from '@/lib/numbers'; + +const StepItem = ({ step, subtitle, title }: { step: number; subtitle: string; title: string }) => ( + + {step} + + {title} + {subtitle} + + +); + +const NewMarket = () => { + const { isNotTablet } = useBreakpoints(); + const { newMarketProposal } = useGovernanceVariables(); + const navigate = useNavigate(); + const [displaySteps, setDisplaySteps] = useState(true); + const stringGetter = useStringGetter(); + const { chainTokenLabel, chainTokenDecimals } = useTokenConfigs(); + + useDocumentTitle(stringGetter({ key: STRING_KEYS.ADD_A_MARKET })); + + const steps = useMemo(() => { + return [ + { + step: 1, + title: stringGetter({ key: STRING_KEYS.ADD_MARKET_STEP_1_TITLE }), + subtitle: stringGetter({ + key: STRING_KEYS.ADD_MARKET_STEP_1_DESCRIPTION, + params: { + HERE: ( + + {stringGetter({ key: STRING_KEYS.HERE })} + + ), + }, + }), + }, + { + step: 2, + title: stringGetter({ key: STRING_KEYS.ADD_MARKET_STEP_2_TITLE }), + subtitle: stringGetter({ key: STRING_KEYS.ADD_MARKET_STEP_2_DESCRIPTION }), + }, + { + step: 3, + title: stringGetter({ key: STRING_KEYS.ADD_MARKET_STEP_3_TITLE }), + subtitle: stringGetter({ + key: STRING_KEYS.ADD_MARKET_STEP_3_DESCRIPTION, + params: { + REQUIRED_NUM_TOKENS: MustBigNumber(newMarketProposal?.initialDepositAmount) + .div(Number(`1e${chainTokenDecimals}`)) + .toFixed(isMainnet ? 0 : chainTokenDecimals), + NATIVE_TOKEN_DENOM: chainTokenLabel, + }, + }), + }, + ]; + }, [stringGetter, newMarketProposal, chainTokenLabel]); + + return ( + + + navigate(AppRoute.Markets)} /> + } + subtitle={isNotTablet && stringGetter({ key: STRING_KEYS.ADD_DETAILS_TO_LAUNCH_MARKET })} + /> + + +
+ + {displaySteps && ( + <> + + {stringGetter({ key: STRING_KEYS.STEPS_TO_CREATE })} + + {steps.map((item) => ( + + ))} + + )} +
+ + + +
+
+ ); +}; + +const Styled: Record = {}; + +Styled.Page = styled.div` + ${layoutMixins.contentContainerPage} + gap: 1.5rem; + + > * { + --content-max-width: 80rem; + max-width: min(calc(100vw - 4rem), var(--content-max-width)); + } + + @media ${breakpoints.tablet} { + --stickyArea-topHeight: var(--page-header-height-mobile); + padding: 0 1rem 1rem; + + > * { + max-width: calc(100vw - 2rem); + width: 100%; + } + } +`; + +Styled.ContentSectionHeader = styled(ContentSectionHeader)` + @media ${breakpoints.notTablet} { + padding: 1rem 0; + } + + @media ${breakpoints.tablet} { + padding: 1.25rem 0; + + h3 { + font: var(--font-extra-medium); + } + } +`; + +Styled.HeaderSection = styled.section` + ${layoutMixins.contentSectionDetached} + + @media ${breakpoints.tablet} { + ${layoutMixins.flexColumn} + gap: 1rem; + + margin-bottom: 0.5rem; + } +`; + +Styled.Content = styled.div` + display: flex; + flex-direction: row; + gap: 2rem; + margin: 0 auto; + + @media ${breakpoints.tablet} { + display: flex; + flex-direction: column; + gap: 1rem; + margin: 0 auto; + } +`; + +Styled.StepsTitle = styled.h2` + font: var(--font-large-medium); + color: var(--color-text-2); + margin: 1rem; + + @media ${breakpoints.tablet} { + margin: 1rem 0; + } +`; + +Styled.Icon = styled(Icon)` + margin-right: 0.5ch; +`; + +Styled.StepItem = styled.div` + display: flex; + flex-direction: row; + gap: 1rem; + align-items: center; + margin-bottom: 1rem; +`; + +Styled.StepNumber = styled.div` + width: 2.5rem; + height: 2.5rem; + min-width: 2.5rem; + min-height: 2.5rem; + border-radius: 50%; + background-color: var(--color-layer-5); + display: flex; + align-items: center; + justify-content: center; + color: var(--color-text-2); +`; + +Styled.Column = styled.div` + display: flex; + flex-direction: column; +`; + +Styled.Title = styled.span` + color: var(--color-text-2); + font: var(--font-medium-book); +`; + +Styled.Subtitle = styled.span` + color: var(--color-text-0); +`; + +Styled.Link = styled(Link)` + --link-color: var(--color-accent); + display: inline-block; +`; + +Styled.FormContainer = styled.div` + min-width: 31.25rem; + height: fit-content; + border-radius: 1rem; + background-color: var(--color-layer-3); + padding: 1rem; + + @media ${breakpoints.tablet} { + width: 100%; + min-width: unset; + } +`; + +export default NewMarket; diff --git a/src/pages/rewards/NewMarketsPanel.tsx b/src/pages/rewards/NewMarketsPanel.tsx new file mode 100644 index 0000000..a88d80b --- /dev/null +++ b/src/pages/rewards/NewMarketsPanel.tsx @@ -0,0 +1,103 @@ +import styled, { AnyStyledComponent } from 'styled-components'; +import { useNavigate } from 'react-router-dom'; + +import { ButtonAction, ButtonSize } from '@/constants/buttons'; +import { STRING_KEYS } from '@/constants/localization'; +import { isMainnet } from '@/constants/networks'; +import { AppRoute, MarketsRoute } from '@/constants/routes'; + +import { useStringGetter, useTokenConfigs } from '@/hooks'; +import { usePotentialMarkets } from '@/hooks/usePotentialMarkets'; +import { useGovernanceVariables } from '@/hooks/useGovernanceVariables'; + +import { Panel } from '@/components/Panel'; +import { IconName } from '@/components/Icon'; +import { IconButton } from '@/components/IconButton'; +import { Output, OutputType } from '@/components/Output'; +import { Tag } from '@/components/Tag'; + +import { MustBigNumber } from '@/lib/numbers'; +import { layoutMixins } from '@/styles/layoutMixins'; + +export const NewMarketsPanel = () => { + const stringGetter = useStringGetter(); + const navigate = useNavigate(); + const { hasPotentialMarketsData } = usePotentialMarkets(); + const { chainTokenDecimals, chainTokenLabel } = useTokenConfigs(); + const { newMarketProposal } = useGovernanceVariables(); + const initialDepositAmountBN = MustBigNumber(newMarketProposal.initialDepositAmount).div( + Number(`1e${chainTokenDecimals}`) + ); + const initialDepositAmountDecimals = isMainnet ? 0 : chainTokenDecimals; + + if (!hasPotentialMarketsData) return null; + + return ( + + {stringGetter({ key: STRING_KEYS.ADD_A_MARKET })} + {stringGetter({ key: STRING_KEYS.NEW })} + + } + slotRight={ + + + + } + onClick={() => navigate(`${AppRoute.Markets}/${MarketsRoute.New}`)} + > + + {stringGetter({ + key: STRING_KEYS.NEW_MARKET_REWARDS_ENTRY_DESCRIPTION, + params: { + REQUIRED_NUM_TOKENS: ( + + ), + NATIVE_TOKEN_DENOM: chainTokenLabel, + }, + })} + + + ); +}; + +const Styled: Record = {}; + +Styled.Description = styled.div` + color: var(--color-text-0); +`; + +Styled.IconButton = styled(IconButton)` + color: var(--color-text-0); + --color-border: var(--color-layer-6); +`; + +Styled.Arrow = styled.div` + padding-right: 1.5rem; +`; + +Styled.Title = styled.h3` + font: var(--font-medium-book); + color: var(--color-text-2); + margin-bottom: -1rem; + ${layoutMixins.inlineRow} +`; + +Styled.Output = styled(Output)` + display: inline-block; +`; + +Styled.NewTag = styled(Tag)` + color: var(--color-accent); + background-color: var(--color-accent-faded); +`; diff --git a/src/pages/rewards/RewardsPage.tsx b/src/pages/rewards/RewardsPage.tsx index 0e4031a..4329ca6 100644 --- a/src/pages/rewards/RewardsPage.tsx +++ b/src/pages/rewards/RewardsPage.tsx @@ -14,11 +14,12 @@ import { BackButton } from '@/components/BackButton'; import { Panel } from '@/components/Panel'; import { DYDXBalancePanel } from './DYDXBalancePanel'; -import { MigratePanel } from './MigratePanel'; import { LaunchIncentivesPanel } from './LaunchIncentivesPanel'; +import { MigratePanel } from './MigratePanel'; import { RewardsHelpPanel } from './RewardsHelpPanel'; import { GovernancePanel } from './GovernancePanel'; import { StakingPanel } from './StakingPanel'; +import { NewMarketsPanel } from './NewMarketsPanel'; const RewardsPage = () => { const dispatch = useDispatch(); @@ -44,9 +45,9 @@ const RewardsPage = () => { )} - {isNotTablet && ( + diff --git a/src/views/MarketsDropdown.tsx b/src/views/MarketsDropdown.tsx index 2c2ba6b..8998944 100644 --- a/src/views/MarketsDropdown.tsx +++ b/src/views/MarketsDropdown.tsx @@ -3,23 +3,26 @@ import { useNavigate } from 'react-router-dom'; import styled, { type AnyStyledComponent, css, keyframes } from 'styled-components'; import { useSelector } from 'react-redux'; +import { ButtonSize } from '@/constants/buttons'; import { STRING_KEYS } from '@/constants/localization'; import { MarketFilters, type MarketData } from '@/constants/markets'; -import { AppRoute } from '@/constants/routes'; - +import { AppRoute, MarketsRoute } from '@/constants/routes'; import { useStringGetter } from '@/hooks'; +import { useMarketsData } from '@/hooks/useMarketsData'; +import { usePotentialMarkets } from '@/hooks/usePotentialMarkets'; + import { popoverMixins } from '@/styles/popoverMixins'; import { layoutMixins } from '@/styles/layoutMixins'; import { AssetIcon } from '@/components/AssetIcon'; +import { Button } from '@/components/Button'; import { Icon, IconName } from '@/components/Icon'; import { Output, OutputType } from '@/components/Output'; import { Popover, TriggerType } from '@/components/Popover'; +import { ColumnDef, Table } from '@/components/Table'; import { Tag } from '@/components/Tag'; import { Toolbar } from '@/components/Toolbar'; -import { ColumnDef, Table } from '@/components/Table'; -import { useMarketsData } from '@/hooks/useMarketsData'; import { getSelectedLocale } from '@/state/localizationSelectors'; import { MustBigNumber } from '@/lib/numbers'; @@ -32,6 +35,8 @@ const MarketsDropdownContent = ({ onRowAction }: { onRowAction?: (market: string const selectedLocale = useSelector(getSelectedLocale); const [searchFilter, setSearchFilter] = useState(); const { filteredMarkets, marketFilters } = useMarketsData(filter, searchFilter); + const navigate = useNavigate(); + const { hasPotentialMarketsData } = usePotentialMarkets(); return ( <> @@ -134,16 +139,16 @@ const MarketsDropdownContent = ({ onRowAction }: { onRowAction?: (market: string })}

{stringGetter({ key: STRING_KEYS.MARKET_SEARCH_DOES_NOT_EXIST_YET })}

- {/* TODO TRCL-1693 - uncomment when feedback modal is finalized -
- -
*/} + {hasPotentialMarketsData && ( +
+ +
+ )} } /> diff --git a/src/views/dialogs/NewMarketAgreementDialog.tsx b/src/views/dialogs/NewMarketAgreementDialog.tsx new file mode 100644 index 0000000..1346f02 --- /dev/null +++ b/src/views/dialogs/NewMarketAgreementDialog.tsx @@ -0,0 +1,105 @@ +import { useState } from 'react'; +import styled, { AnyStyledComponent } from 'styled-components'; + +import { ButtonAction } from '@/constants/buttons'; +import { AppRoute } from '@/constants/routes'; +import { STRING_KEYS } from '@/constants/localization'; +import { useStringGetter } from '@/hooks'; +import breakpoints from '@/styles/breakpoints'; +import { layoutMixins } from '@/styles/layoutMixins'; + +import { Button } from '@/components/Button'; +import { Checkbox } from '@/components/Checkbox'; +import { Dialog } from '@/components/Dialog'; +import { Link } from '@/components/Link'; + +type ElementProps = { + acceptTerms: () => void; + setIsOpen: (open: boolean) => void; +}; + +export const NewMarketAgreementDialog = ({ acceptTerms, setIsOpen }: ElementProps) => { + const [hasAcknowledged, setHasAcknowledged] = useState(false); + + const stringGetter = useStringGetter(); + + return ( + + +

+ {stringGetter({ + key: STRING_KEYS.NEW_MARKET_PROPOSAL_AGREEMENT, + params: { + DOCUMENTATION_LINK: ( + + {stringGetter({ key: STRING_KEYS.WEBSITE }).toLowerCase()} + + ), + TERMS_OF_USE: ( + + {stringGetter({ key: STRING_KEYS.TERMS_OF_USE })} + + ), + }, + })} +

+ + + + + + +
+
+ ); +}; + +const Styled: Record = {}; + +Styled.Dialog = styled(Dialog)` + @media ${breakpoints.notMobile} { + --dialog-width: 30rem; + } +`; + +Styled.Content = styled.div` + ${layoutMixins.column} + gap: 1rem; + + p { + border-radius: 0.5rem; + padding: 1rem; + background-color: var(--color-layer-1); + } +`; + +Styled.Link = styled(Link)` + --link-color: var(--color-accent); + display: inline-block; +`; + +Styled.ButtonRow = styled.div` + display: grid; + grid-template-columns: 1fr 2fr; + gap: 1rem; +`; diff --git a/src/views/dialogs/NewMarketMessageDetailsDialog.tsx b/src/views/dialogs/NewMarketMessageDetailsDialog.tsx new file mode 100644 index 0000000..e43ca1f --- /dev/null +++ b/src/views/dialogs/NewMarketMessageDetailsDialog.tsx @@ -0,0 +1,361 @@ +import { useMemo, useState } from 'react'; +import styled, { AnyStyledComponent } from 'styled-components'; +import { utils } from '@dydxprotocol/v4-client-js'; + +import { STRING_KEYS } from '@/constants/localization'; +import { isMainnet } from '@/constants/networks'; +import { PotentialMarketItem } from '@/constants/potentialMarkets'; +import { useGovernanceVariables, useStringGetter, useTokenConfigs } from '@/hooks'; +import { usePotentialMarkets } from '@/hooks/usePotentialMarkets'; +import { layoutMixins } from '@/styles/layoutMixins'; + +import { Details } from '@/components/Details'; +import { Dialog } from '@/components/Dialog'; +import { Output, OutputType } from '@/components/Output'; +import { Tag, TagType } from '@/components/Tag'; +import { ToggleGroup } from '@/components/ToggleGroup'; + +import { MustBigNumber } from '@/lib/numbers'; + +type ElementProps = { + preventClose?: boolean; + setIsOpen?: (open: boolean) => void; + assetData?: PotentialMarketItem; + clobPairId?: number; + liquidityTier?: string; +}; + +export enum CodeToggleGroup { + CREATE_ORACLE = 'CREATE_ORACLE', + MSG_CREATE_PERPETUAL = 'MSG_CREATE_PERPETUAL', + MSG_CREATE_CLOB_PAIR = 'MSG_CREATE_CLOB_PAIR', + MSG_DELAY_MESSAGE = 'MSG_DELAY_MESSAGE', + MSG_SUBMIT_PROPOSAL = 'MSG_SUBMIT_PROPOSAL', +} + +export const NewMarketMessageDetailsDialog = ({ + assetData, + clobPairId, + liquidityTier, + preventClose, + setIsOpen, +}: ElementProps) => { + const [codeToggleGroup, setCodeToggleGroup] = useState(CodeToggleGroup.CREATE_ORACLE); + const { exchangeConfigs } = usePotentialMarkets(); + const { baseAsset } = assetData ?? {}; + const { newMarketProposal } = useGovernanceVariables(); + const stringGetter = useStringGetter(); + const { chainTokenDecimals, chainTokenLabel } = useTokenConfigs(); + const initialDepositAmountDecimals = isMainnet ? 0 : chainTokenDecimals; + + const exchangeConfig = useMemo(() => { + return baseAsset ? exchangeConfigs?.[baseAsset] : undefined; + }, [baseAsset]); + + const ticker = useMemo(() => `${baseAsset}-USD`, [baseAsset]); + + const toggleGroupItems: Parameters[0]['items'] = useMemo(() => { + return [ + { + value: CodeToggleGroup.CREATE_ORACLE, + label: 'Create oracle market', + }, + { + value: CodeToggleGroup.MSG_CREATE_PERPETUAL, + label: 'Msg create perpetual', + }, + { + value: CodeToggleGroup.MSG_CREATE_CLOB_PAIR, + label: 'Msg create clobPair', + }, + { + value: CodeToggleGroup.MSG_DELAY_MESSAGE, + label: 'Msg delay message', + }, + { + value: CodeToggleGroup.MSG_SUBMIT_PROPOSAL, + label: 'Msg submit proposal', + }, + ]; + }, []); + + return ( + + + + { + { + [CodeToggleGroup.CREATE_ORACLE]: ( + + + + exchange_config_json{' '} + {exchangeConfig && {exchangeConfig.length}} + + {'['} + {exchangeConfig?.map((exchange) => { + return ( + + {'{'} + {Object.keys(exchange).map((key) => ( + + {key}: {exchange[key as keyof typeof exchange]} + + ))} + {'},'} + + ); + })} + {']'} + + ), + [CodeToggleGroup.MSG_CREATE_PERPETUAL]: ( + + + + ), + [CodeToggleGroup.MSG_CREATE_CLOB_PAIR]: ( + + + + ), + [CodeToggleGroup.MSG_DELAY_MESSAGE]: ( + + + ), + }, + ]} + /> +
MSG_UPDATE_CLOB_PAIR
+ +
+ ), + [CodeToggleGroup.MSG_SUBMIT_PROPOSAL]: ( + + title: + {utils.getGovAddNewMarketTitle(ticker)} + + initial_deposit_amount: + + { + + } + + + summary: + + {utils.getGovAddNewMarketSummary(ticker, newMarketProposal.delayBlocks)} + + + ), + }[codeToggleGroup] + } +
+
+ ); +}; + +const Styled: Record = {}; + +Styled.Content = styled.div` + ${layoutMixins.column} + gap: 0; +`; + +Styled.ProposedMessageDetails = styled.div` + display: flex; + flex-direction: column; + gap: 1rem; + width: 100%; + background-color: var(--color-layer-3); + margin-top: 1rem; + border-radius: 10px; +`; + +Styled.Tabs = styled(ToggleGroup)` + overflow-x: auto; +`; + +Styled.Text0 = styled.span` + color: var(--color-text-0); +`; + +Styled.Code = styled.div` + background-color: var(--color-layer-1); + padding: 1rem; + border-radius: 10px; + font: var(--font-mini-book); + font-family: var(--fontFamily-monospace); + margin-top: 1rem; + display: flex; + flex-direction: column; + gap: 0rem; +`; + +Styled.Details = styled(Details)` + --details-item-height: 1.5rem; +`; + +Styled.Line = styled.pre` + margin-left: 1rem; +`; + +Styled.Description = styled.p` + margin-bottom: 1rem; +`; diff --git a/src/views/forms/NewMarketForm/NewMarketPreviewStep.tsx b/src/views/forms/NewMarketForm/NewMarketPreviewStep.tsx new file mode 100644 index 0000000..d4edce3 --- /dev/null +++ b/src/views/forms/NewMarketForm/NewMarketPreviewStep.tsx @@ -0,0 +1,396 @@ +import { FormEvent, useCallback, useMemo, useState } from 'react'; +import styled, { AnyStyledComponent } from 'styled-components'; +import { useDispatch } from 'react-redux'; +import Long from 'long'; +import { encodeJson } from '@dydxprotocol/v4-client-js'; +import type { IndexedTx } from '@cosmjs/stargate'; + +import { AlertType } from '@/constants/alerts'; +import { ButtonAction, ButtonSize, ButtonType } from '@/constants/buttons'; +import { DialogTypes } from '@/constants/dialogs'; +import { STRING_KEYS } from '@/constants/localization'; +import { isMainnet } from '@/constants/networks'; +import { NumberSign, TOKEN_DECIMALS } from '@/constants/numbers'; +import { LIQUIDITY_TIERS, type PotentialMarketItem } from '@/constants/potentialMarkets'; + +import { + useAccountBalance, + useGovernanceVariables, + useStringGetter, + useSubaccount, + useTokenConfigs, +} from '@/hooks'; +import { usePotentialMarkets } from '@/hooks/usePotentialMarkets'; + +import { formMixins } from '@/styles/formMixins'; +import { layoutMixins } from '@/styles/layoutMixins'; + +import { AlertMessage } from '@/components/AlertMessage'; +import { Button } from '@/components/Button'; +import { DiffOutput } from '@/components/DiffOutput'; +import { FormInput } from '@/components/FormInput'; +import { Icon, IconName } from '@/components/Icon'; +import { InputType } from '@/components/Input'; +import { Output, OutputType } from '@/components/Output'; +import { Tag } from '@/components/Tag'; +import { WithDetailsReceipt } from '@/components/WithDetailsReceipt'; + +import { openDialog } from '@/state/dialogs'; + +import { MustBigNumber } from '@/lib/numbers'; +import { log } from '@/lib/telemetry'; + +type NewMarketPreviewStepProps = { + assetData: PotentialMarketItem; + clobPairId: number; + liquidityTier: number; + onBack: () => void; + onSuccess: (hash: string) => void; + tickSizeDecimals: number; +}; + +export const NewMarketPreviewStep = ({ + assetData, + clobPairId, + liquidityTier, + onBack, + onSuccess, + tickSizeDecimals, +}: NewMarketPreviewStepProps) => { + const { nativeTokenBalance } = useAccountBalance(); + const dispatch = useDispatch(); + const stringGetter = useStringGetter(); + const { chainTokenDecimals, chainTokenLabel } = useTokenConfigs(); + const [errorMessage, setErrorMessage] = useState(); + const { exchangeConfigs } = usePotentialMarkets(); + const { submitNewMarketProposal } = useSubaccount(); + const { newMarketProposal } = useGovernanceVariables(); + const initialDepositAmountBN = MustBigNumber(newMarketProposal.initialDepositAmount).div( + Number(`1e${chainTokenDecimals}`) + ); + const initialDepositAmountDecimals = isMainnet ? 0 : chainTokenDecimals; + const initialDepositAmount = initialDepositAmountBN.toFixed(initialDepositAmountDecimals); + const [hasAcceptedTerms, setHasAcceptedTerms] = useState(false); + + const { label, initialMarginFraction, maintenanceMarginFraction, impactNotional } = + LIQUIDITY_TIERS[liquidityTier as unknown as keyof typeof LIQUIDITY_TIERS]; + + const ticker = `${assetData.baseAsset}-USD`; + + const alertMessage = useMemo(() => { + if (errorMessage) { + return { + type: AlertType.Error, + message: errorMessage, + }; + } + if (nativeTokenBalance.lt(initialDepositAmountBN)) { + return { + type: AlertType.Error, + message: stringGetter({ + key: STRING_KEYS.NOT_ENOUGH_BALANCE, + params: { + NUM_TOKENS_REQUIRED: initialDepositAmount, + NATIVE_TOKEN_DENOM: chainTokenLabel, + }, + }), + }; + } + + return null; + }, [nativeTokenBalance, errorMessage]); + + const isDisabled = alertMessage !== null; + + return ( + ) => { + e.preventDefault(); + + if (!hasAcceptedTerms) { + dispatch( + openDialog({ + type: DialogTypes.NewMarketAgreement, + dialogProps: { + acceptTerms: () => setHasAcceptedTerms(true), + }, + }) + ); + } else { + setErrorMessage(undefined); + + try { + const tx = await submitNewMarketProposal({ + id: clobPairId, + ticker, + priceExponent: assetData.priceExponent, + minPriceChange: assetData.minPriceChangePpm, + minExchanges: assetData.minExchanges, + exchangeConfigJson: JSON.stringify({ + exchanges: exchangeConfigs?.[assetData.baseAsset], + }), + atomicResolution: assetData.atomicResolution, + liquidityTier: liquidityTier, + quantumConversionExponent: assetData.quantumConversionExponent, + stepBaseQuantums: Long.fromNumber(assetData.stepBaseQuantum), + subticksPerTick: assetData.subticksPerTick, + delayBlocks: newMarketProposal.delayBlocks, + }); + + if ((tx as IndexedTx)?.code === 0) { + const encodedTx = encodeJson(tx); + const parsedTx = JSON.parse(encodedTx); + const hash = parsedTx.hash.toUpperCase(); + + if (!hash) { + throw new Error('Invalid transaction hash'); + } + + onSuccess(hash); + } else { + throw new Error('Transaction failed to commit.'); + } + } catch (error) { + log('NewMarketPreviewForm/submitNewMarketProposal', error); + setErrorMessage(error.message); + } + } + }} + > +

+ {stringGetter({ key: STRING_KEYS.CONFIRM_NEW_MARKET_PROPOSAL })} + + {stringGetter({ key: STRING_KEYS.BALANCE })}:{' '} + {chainTokenLabel}} + /> + +

+ + + ), + }, + { + key: 'mmf', + label: 'MMF', + tooltip: 'maintenance-margin-fraction', + value: ( + + ), + }, + { + key: 'impact-notional', + label: stringGetter({ key: STRING_KEYS.IMPACT_NOTIONAL }), + value: , + }, + ]} + > + + + + + ), + }, + { + key: 'message-details', + label: stringGetter({ key: STRING_KEYS.MESSAGE_DETAILS }), + value: ( + + dispatch( + openDialog({ + type: DialogTypes.NewMarketMessageDetails, + dialogProps: { assetData, clobPairId, liquidityTier }, + }) + ) + } + > + {stringGetter({ key: STRING_KEYS.VIEW_DETAILS })} → + + ), + }, + { + key: 'required-balance', + label: ( + + {stringGetter({ key: STRING_KEYS.REQUIRED_BALANCE })} {chainTokenLabel} + + ), + value: ( + + {'+ '} + + + } + /> + ), + }, + { + key: 'wallet-balance', + label: ( + + {stringGetter({ key: STRING_KEYS.WALLET_BALANCE })} {chainTokenLabel} + + ), + value: ( + + ), + }, + ]} + > +
+ + {alertMessage && ( + {alertMessage.message} + )} + + + + + + {stringGetter({ + key: STRING_KEYS.PROPOSAL_DISCLAIMER, + params: { + NUM_TOKENS_REQUIRED: initialDepositAmount, + NATIVE_TOKEN_DENOM: chainTokenLabel, + }, + })} + + + ); +}; + +const Styled: Record = {}; + +Styled.Form = styled.form` + ${formMixins.transfersForm} + ${layoutMixins.stickyArea0} + --stickyArea0-background: transparent; + + h2 { + ${layoutMixins.row} + justify-content: space-between; + margin: 0; + font: var(--font-large-medium); + color: var(--color-text-2); + } +`; + +Styled.Balance = styled.span` + ${layoutMixins.inlineRow} + font: var(--font-small-book); + margin-top: 0.125rem; + + output { + margin-left: 0.5ch; + } +`; + +Styled.Tag = styled(Tag)` + margin-left: 0.5ch; +`; + +Styled.FormInput = styled(FormInput)` + input { + font-size: 1rem; + } +`; + +Styled.Icon = styled(Icon)<{ $hasError?: boolean }>` + margin-left: 0.5ch; + + ${({ $hasError }) => ($hasError ? 'color: var(--color-error);' : 'color: var(--color-success);')} +`; + +Styled.WithDetailsReceipt = styled(WithDetailsReceipt)` + --details-item-fontSize: 1rem; +`; + +Styled.CheckboxContainer = styled.div` + display: flex; + flex-direction: row; + padding: 1rem; + align-items: center; +`; + +Styled.Disclaimer = styled.div<{ textAlign?: string }>` + font: var(--font-small); + color: var(--color-text-0); + text-align: center; + margin-left: 0.5ch; + + ${({ textAlign }) => textAlign && `text-align: ${textAlign};`} +`; + +Styled.ButtonRow = styled.div` + display: grid; + grid-template-columns: 1fr 2fr; + gap: 1rem; + width: 100%; +`; + +Styled.Button = styled(Button)` + --button-padding: 0; +`; diff --git a/src/views/forms/NewMarketForm/NewMarketSelectionStep.tsx b/src/views/forms/NewMarketForm/NewMarketSelectionStep.tsx new file mode 100644 index 0000000..a2bbd1c --- /dev/null +++ b/src/views/forms/NewMarketForm/NewMarketSelectionStep.tsx @@ -0,0 +1,466 @@ +import { FormEvent, useEffect, useMemo, useState } from 'react'; +import styled, { AnyStyledComponent } from 'styled-components'; +import { Root, Item } from '@radix-ui/react-radio-group'; +import { shallowEqual, useDispatch, useSelector } from 'react-redux'; + +import { OnboardingState } from '@/constants/account'; +import { AlertType } from '@/constants/alerts'; +import { ButtonAction, ButtonShape, ButtonSize, ButtonType } from '@/constants/buttons'; +import { DialogTypes } from '@/constants/dialogs'; +import { STRING_KEYS } from '@/constants/localization'; +import { isMainnet } from '@/constants/networks'; +import { TOKEN_DECIMALS } from '@/constants/numbers'; + +import { + LIQUIDITY_TIERS, + NUM_ORACLES_TO_QUALIFY_AS_SAFE, + type PotentialMarketItem, +} from '@/constants/potentialMarkets'; + +import { + useAccountBalance, + useBreakpoints, + useGovernanceVariables, + useStringGetter, + useTokenConfigs, +} from '@/hooks'; +import { usePotentialMarkets } from '@/hooks/usePotentialMarkets'; + +import { breakpoints } from '@/styles'; +import { formMixins } from '@/styles/formMixins'; +import { layoutMixins } from '@/styles/layoutMixins'; + +import { AlertMessage } from '@/components/AlertMessage'; +import { Button } from '@/components/Button'; +import { Details } from '@/components/Details'; +import { Icon, IconName } from '@/components/Icon'; +import { Output, OutputType } from '@/components/Output'; +import { Tag } from '@/components/Tag'; +import { SearchSelectMenu } from '@/components/SearchSelectMenu'; +import { WithReceipt } from '@/components/WithReceipt'; + +import { OnboardingTriggerButton } from '@/views/dialogs/OnboardingTriggerButton'; + +import { getOnboardingState } from '@/state/accountSelectors'; +import { openDialog } from '@/state/dialogs'; +import { getMarketIds } from '@/state/perpetualsSelectors'; + +import { isTruthy } from '@/lib/isTruthy'; +import { MustBigNumber } from '@/lib/numbers'; + +type NewMarketSelectionStepProps = { + assetToAdd?: PotentialMarketItem; + clobPairId?: number; + setAssetToAdd: (assetToAdd?: PotentialMarketItem) => void; + onConfirmMarket: () => void; + liquidityTier?: number; + setLiquidityTier: (liquidityTier?: number) => void; + tickSizeDecimals: number; +}; + +export const NewMarketSelectionStep = ({ + assetToAdd, + clobPairId, + setAssetToAdd, + onConfirmMarket, + liquidityTier, + setLiquidityTier, + tickSizeDecimals, +}: NewMarketSelectionStepProps) => { + const dispatch = useDispatch(); + const { nativeTokenBalance } = useAccountBalance(); + const onboardingState = useSelector(getOnboardingState); + const isDisconnected = onboardingState === OnboardingState.Disconnected; + const { isMobile } = useBreakpoints(); + const marketIds = useSelector(getMarketIds, shallowEqual); + const { chainTokenDecimals, chainTokenLabel } = useTokenConfigs(); + const { potentialMarkets, exchangeConfigs } = usePotentialMarkets(); + const stringGetter = useStringGetter(); + const { newMarketProposal } = useGovernanceVariables(); + const initialDepositAmountBN = MustBigNumber(newMarketProposal.initialDepositAmount).div( + Number(`1e${chainTokenDecimals}`) + ); + const initialDepositAmountDecimals = isMainnet ? 0 : chainTokenDecimals; + const initialDepositAmount = initialDepositAmountBN.toFixed(initialDepositAmountDecimals); + + const [tempLiquidityTier, setTempLiquidityTier] = useState(); + const [canModifyLiqTier, setCanModifyLiqTier] = useState(false); + + const alertMessage = useMemo(() => { + if (nativeTokenBalance.lt(initialDepositAmountBN)) { + return { + type: AlertType.Warning, + message: stringGetter({ + key: STRING_KEYS.NOT_ENOUGH_BALANCE, + params: { + NUM_TOKENS_REQUIRED: initialDepositAmount, + NATIVE_TOKEN_DENOM: chainTokenLabel, + }, + }), + }; + } + + return null; + }, [nativeTokenBalance, stringGetter]); + + useEffect(() => { + if (assetToAdd) { + setTempLiquidityTier(assetToAdd.liquidityTier); + setLiquidityTier(assetToAdd.liquidityTier); + } + }, [assetToAdd]); + + const filteredPotentialMarkets = useMemo(() => { + return potentialMarkets?.filter( + ({ baseAsset, numOracles }) => + exchangeConfigs?.[baseAsset] !== undefined && + Number(numOracles) >= NUM_ORACLES_TO_QUALIFY_AS_SAFE && + !marketIds.includes(`${baseAsset}-USD`) + ); + }, [exchangeConfigs, potentialMarkets, marketIds]); + + return ( + ) => { + e.preventDefault(); + if (canModifyLiqTier) { + setLiquidityTier(tempLiquidityTier); + setCanModifyLiqTier(false); + } else { + onConfirmMarket(); + } + }} + > +

+ {stringGetter({ key: STRING_KEYS.ADD_A_MARKET })} + + {stringGetter({ key: STRING_KEYS.BALANCE })}:{' '} + {chainTokenLabel}} + /> + +

+ ({ + value: potentialMarket.baseAsset, + label: potentialMarket?.assetName ?? potentialMarket.baseAsset, + tag: `${potentialMarket.baseAsset}-USD`, + onSelect: () => { + setAssetToAdd(potentialMarket); + }, + })) ?? [], + }, + ]} + label={stringGetter({ key: STRING_KEYS.MARKETS })} + > + {assetToAdd ? ( + + {assetToAdd?.assetName ?? assetToAdd.baseAsset} {assetToAdd?.baseAsset}-USD + + ) : ( + 'e.g. "BTC-USD"' + )} + + {assetToAdd && ( + <> +
{stringGetter({ key: STRING_KEYS.POPULATED_DETAILS })}
+
+ + + {stringGetter({ key: STRING_KEYS.LIQUIDITY_TIER })} + + + {canModifyLiqTier && ( + + )} + + + + {Object.keys(LIQUIDITY_TIERS).map((tier) => { + const { maintenanceMarginFraction, impactNotional, label, initialMarginFraction } = + LIQUIDITY_TIERS[tier as unknown as keyof typeof LIQUIDITY_TIERS]; + return ( + + + {label} + {Number(tier) === assetToAdd?.liquidityTier && ( + + ✨ {stringGetter({ key: STRING_KEYS.RECOMMENDED })} + + )} + + + ), + }, + { + key: 'mmf', + label: 'MMF', + tooltip: 'maintenance-margin-fraction', + value: ( + + ), + }, + { + key: 'impact-notional', + label: stringGetter({ key: STRING_KEYS.IMPACT_NOTIONAL }), + value: , + }, + ]} + /> + + ); + })} + +
+ + )} + {alertMessage && ( + {alertMessage.message} + )} + + ), + }, + assetToAdd && { + key: 'message-details', + label: stringGetter({ key: STRING_KEYS.MESSAGE_DETAILS }), + value: ( + + dispatch( + openDialog({ + type: DialogTypes.NewMarketMessageDetails, + dialogProps: { assetData: assetToAdd, clobPairId, liquidityTier }, + }) + ) + } + > + {stringGetter({ key: STRING_KEYS.VIEW_DETAILS })} → + + ), + }, + { + key: 'dydx-required', + label: ( + + {stringGetter({ key: STRING_KEYS.REQUIRED_BALANCE })}{' '} + {chainTokenLabel} + + ), + value: ( + + {stringGetter({ + key: STRING_KEYS.OR_MORE, + params: { + NUMBER: ( + + ), + }, + })} + + ), + }, + ].filter(isTruthy)} + /> + } + > + {isDisconnected ? ( + + ) : ( + + )} + +
+ ); +}; + +const Styled: Record = {}; + +Styled.Form = styled.form` + ${formMixins.transfersForm} + ${layoutMixins.stickyArea0} + --stickyArea0-background: transparent; + + h2 { + ${layoutMixins.row} + justify-content: space-between; + margin: 0; + font: var(--font-large-medium); + color: var(--color-text-2); + } +`; + +Styled.Balance = styled.span` + ${layoutMixins.inlineRow} + font: var(--font-small-book); + margin-top: 0.125rem; + + output { + margin-left: 0.5ch; + } +`; + +Styled.Tag = styled(Tag)` + margin-left: 0.5ch; +`; + +Styled.SelectedAsset = styled.span` + color: var(--color-text-2); +`; + +Styled.Disclaimer = styled.div` + color: var(--color-text-0); + margin-left: 0.5ch; +`; + +Styled.Header = styled.div` + display: flex; + flex: 1; + align-items: center; + color: var(--color-text-2); + font: var(--font-base-medium); + justify-content: space-between; +`; + +Styled.ButtonRow = styled.div` + display: flex; + flex-direction: row; + gap: 0.5rem; + + button { + min-width: 80px; + } +`; + +Styled.Root = styled(Root)` + display: flex; + flex-direction: column; + gap: 1rem; + padding: 1rem; + border-radius: 10px; + border: 1px solid var(--color-layer-6); + background-color: var(--color-layer-4); +`; + +Styled.LiquidityTierRadioButton = styled(Item)<{ selected?: boolean }>` + display: flex; + flex-direction: column; + border-radius: 0.625rem; + border: 1px solid var(--color-layer-6); + padding: 1rem 0; + font: var(--font-mini-book); + + ${({ selected }) => selected && 'background-color: var(--color-layer-2)'} +`; + +Styled.Details = styled(Details)` + margin-top: 0.5rem; + padding: 0; + + dt { + text-align: left; + } + + @media ${breakpoints.mobile} { + padding: 0 1rem; + + dd { + margin-bottom: 0.5rem; + } + } +`; + +Styled.ReceiptDetails = styled(Details)` + padding: 0.375rem 0.75rem 0.25rem; +`; + +Styled.Output = styled(Output)` + display: inline-block; +`; + +Styled.Button = styled(Button)` + --button-padding: 0; +`; diff --git a/src/views/forms/NewMarketForm/NewMarketSuccessStep.tsx b/src/views/forms/NewMarketForm/NewMarketSuccessStep.tsx new file mode 100644 index 0000000..32fda43 --- /dev/null +++ b/src/views/forms/NewMarketForm/NewMarketSuccessStep.tsx @@ -0,0 +1,81 @@ +import styled, { AnyStyledComponent } from 'styled-components'; + +import { ButtonAction, ButtonType } from '@/constants/buttons'; +import { STRING_KEYS } from '@/constants/localization'; +import { useStringGetter } from '@/hooks'; +import { LinkOutIcon } from '@/icons'; + +import { Button } from '@/components/Button'; +import { Icon, IconName } from '@/components/Icon'; + +type NewMarketSuccessStepProps = { + href: string; +}; + +export const NewMarketSuccessStep = ({ href }: NewMarketSuccessStepProps) => { + const stringGetter = useStringGetter(); + + return ( + + + + + + +

{stringGetter({ key: STRING_KEYS.SUBMITTED_PROPOSAL })}

+ {stringGetter({ key: STRING_KEYS.PROPOSAL_SUBMISSION_SUCCESSFUL })} + +
+ ); +}; + +const Styled: Record = {}; + +Styled.ProposalSent = styled.div` + text-align: center; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 1rem; + padding: 1rem; + + && { + h2 { + margin: 0 1rem; + } + } +`; + +Styled.OuterCircle = styled.div` + width: 5.25rem; + height: 5.25rem; + min-width: 5.25rem; + height: 5.25rem; + border-radius: 50%; + background-color: var(--color-gradient-positive); + + display: flex; + align-items: center; + justify-content: center; +`; + +Styled.InnerCircle = styled.div` + width: 2rem; + height: 2rem; + min-width: 2rem; + height: 2rem; + border-radius: 50%; + background-color: var(--color-success); + + display: flex; + align-items: center; + justify-content: center; + + svg { + color: var(--color-layer-2); + } +`; diff --git a/src/views/forms/NewMarketForm/index.tsx b/src/views/forms/NewMarketForm/index.tsx new file mode 100644 index 0000000..85604ce --- /dev/null +++ b/src/views/forms/NewMarketForm/index.tsx @@ -0,0 +1,80 @@ +import { useMemo, useState } from 'react'; +import styled, { AnyStyledComponent } from 'styled-components'; + +import { TOKEN_DECIMALS } from '@/constants/numbers'; +import { type PotentialMarketItem } from '@/constants/potentialMarkets'; +import { useNextClobPairId, useURLConfigs } from '@/hooks'; +import { usePotentialMarkets } from '@/hooks/usePotentialMarkets'; + +import { LoadingSpace } from '@/components/Loading/LoadingSpinner'; + +import { NewMarketSelectionStep } from './NewMarketSelectionStep'; +import { NewMarketPreviewStep } from './NewMarketPreviewStep'; +import { NewMarketSuccessStep } from './NewMarketSuccessStep'; + +enum NewMarketFormStep { + SELECTION, + PREVIEW, + SUCCESS, +} + +export const NewMarketForm = () => { + const [step, setStep] = useState(NewMarketFormStep.SELECTION); + const [assetToAdd, setAssetToAdd] = useState(); + const [liquidityTier, setLiquidityTier] = useState(); + const [proposalTxHash, setProposalTxHash] = useState(); + const { mintscan: mintscanTxUrl } = useURLConfigs(); + + const { nextAvailableClobPairId } = useNextClobPairId(); + const { hasPotentialMarketsData } = usePotentialMarkets(); + + const tickSizeDecimals = useMemo(() => { + if (!assetToAdd) return TOKEN_DECIMALS; + const p = Math.floor(Math.log(Number(assetToAdd.referencePrice))); + return Math.abs(p - 3); + }, [assetToAdd]); + + if (!hasPotentialMarketsData || !nextAvailableClobPairId) { + return ; + } + + if (NewMarketFormStep.SUCCESS === step && proposalTxHash) { + return ; + } + + if (NewMarketFormStep.PREVIEW === step) { + if (assetToAdd && liquidityTier && nextAvailableClobPairId) { + return ( + setStep(NewMarketFormStep.SELECTION)} + onSuccess={(hash: string) => { + setProposalTxHash(hash); + setStep(NewMarketFormStep.SUCCESS); + }} + tickSizeDecimals={tickSizeDecimals} + /> + ); + } + } + + return ( + setStep(NewMarketFormStep.PREVIEW)} + assetToAdd={assetToAdd} + clobPairId={nextAvailableClobPairId} + setAssetToAdd={setAssetToAdd} + liquidityTier={liquidityTier} + setLiquidityTier={setLiquidityTier} + tickSizeDecimals={tickSizeDecimals} + /> + ); +}; + +const Styled: Record = {}; + +Styled.LoadingSpace = styled(LoadingSpace)` + min-height: 18.75rem; +`; diff --git a/src/views/menus/useGlobalCommands.tsx b/src/views/menus/useGlobalCommands.tsx index 396fcd1..017df38 100644 --- a/src/views/menus/useGlobalCommands.tsx +++ b/src/views/menus/useGlobalCommands.tsx @@ -11,6 +11,7 @@ import { setSelectedTradeLayout } from '@/state/layout'; import { getAssets } from '@/state/assetsSelectors'; import { getPerpetualMarkets } from '@/state/perpetualsSelectors'; +import { Asset, PerpetualMarket } from '@/constants/abacus'; enum ThemeItems { SetClassicTheme = 'SetDefaultTheme', @@ -44,7 +45,7 @@ export const useGlobalCommands = (): MenuConfig => { const joinedPerpetualMarketsAndAssets = Object.values(allPerpetualMarkets).map((market) => ({ ...market, ...allAssets[market?.assetId], - })); + })) as Array; return [ { @@ -129,10 +130,10 @@ export const useGlobalCommands = (): MenuConfig => { { value: NavItems.NavigateToMarket, label: 'Navigate to Market', - subitems: joinedPerpetualMarketsAndAssets.map(({ market = '', name = '', id = '' }) => ({ - value: market, + subitems: joinedPerpetualMarketsAndAssets.map(({ market, name, id }) => ({ + value: market ?? '', slotBefore: , - label: name, + label: name ?? '', tag: id, onSelect: () => navigate(`/trade/${market}`), })),