Files
managing-apps/src/Managing.Infrastructure.Web3/Services/Gmx/TokenV2Service.cs
Oda 65bdb8e34f GMX v2 - Trading (#7)
* Move PrivateKeys.cs

* Update gitignore

* Update gitignore

* updt

* Extract GmxServiceTests.cs

* Refact

* update todo

* Update code

* Fix hashdata

* Replace static token hashed datas

* Set allowance

* Add get orders

* Add get orders tests

* Add ignore

* add close orders

* revert

* Add get gas limit

* Start increasePosition. Todo: Finish GetExecutionFee and estimateGas

* little refact

* Update gitignore

* Fix namespaces and clean repo

* Add tests samples

* Add execution fee

* Add increase position

* Handle backtest on the frontend

* Add tests

* Update increase

* Test increase

* fix increase

* Fix size

* Start get position

* Update get positions

* Fix get position

* Update rpc and trade mappers

* Finish close position

* Fix leverage
2025-01-30 23:06:22 +07:00

457 lines
17 KiB
C#

using Managing.Common;
using Nethereum.Util;
namespace Managing.Infrastructure.Evm.Services.Gmx;
public static class TokenV2Service
{
public static List<GmxToken> TOKENS { get; set; } = new List<GmxToken>
{
new GmxToken
{
Name = "Ethereum",
Symbol = "ETH",
Decimals = 18,
PriceDecimals = 12,
Address = AddressUtil.ZERO_ADDRESS,
IsNative = true,
IsShortable = true,
ImageUrl = "https://assets.coingecko.com/coins/images/279/small/ethereum.png?1595348880",
CoingeckoUrl = "https://www.coingecko.com/en/coins/ethereum",
IsV1Available = true
},
new GmxToken
{
Name = "Wrapped Ethereum",
Symbol = "WETH",
Decimals = 18,
PriceDecimals = 12,
Address = Constants.GMX.TokenAddress.WETH,
IsWrapped = true,
BaseSymbol = "ETH",
ImageUrl = "https://assets.coingecko.com/coins/images/2518/thumb/weth.png?1628852295",
CoingeckoUrl = "https://www.coingecko.com/en/coins/ethereum",
IsV1Available = true
},
new GmxToken
{
Name = "Wrapped Stacked Ethereum",
Symbol = "WSTETH",
Decimals = 18,
PriceDecimals = 12,
Address = Constants.GMX.TokenAddress.WSTETH,
IsWrapped = true,
BaseSymbol = "wstETH",
ImageUrl = "https://assets.coingecko.com/coins/images/2518/thumb/wsteth.png?1628852295",
CoingeckoUrl = "https://www.coingecko.com/en/coins/ethereum",
},
new GmxToken
{
Name = "Bitcoin (WBTC)",
Symbol = "BTC",
AssetSymbol = "WBTC",
Decimals = 8,
PriceDecimals = 22,
Address = Constants.GMX.TokenAddress.WBTC,
IsShortable = true,
ImageUrl = "https://assets.coingecko.com/coins/images/26115/thumb/btcb.png?1655921693",
CoingeckoUrl = "https://www.coingecko.com/en/coins/wrapped-bitcoin",
ExplorerUrl = "https://arbiscan.io/address/0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f",
IsV1Available = true
},
new GmxToken
{
Name = "Arbitrum",
Symbol = "ARB",
Decimals = 18,
PriceDecimals = 3,
Address = Constants.GMX.TokenAddress.ARB,
ImageUrl =
"https://assets.coingecko.com/coins/images/16547/small/photo_2023-03-29_21.47.00.jpeg?1680097630",
CoingeckoUrl = "https://www.coingecko.com/en/coins/arbitrum",
ExplorerUrl = "https://arbiscan.io/token/0x912ce59144191c1204e64559fe8253a0e49e6548"
},
new GmxToken
{
Name = "Wrapped SOL (Wormhole)",
Symbol = "SOL",
AssetSymbol = "WSOL (Wormhole)",
Decimals = 9,
Address = Constants.GMX.TokenAddress.SOL,
ImageUrl = "https://assets.coingecko.com/coins/images/4128/small/solana.png?1640133422",
CoingeckoUrl = "https://www.coingecko.com/en/coins/solana",
ExplorerUrl = "https://arbiscan.io/token/0x2bCc6D6CdBbDC0a4071e48bb3B969b06B3330c07",
},
new GmxToken
{
Name = "Chainlink",
Symbol = "LINK",
Decimals = 18,
PriceDecimals = 3,
Address = Constants.GMX.TokenAddress.LINK,
IsStable = false,
IsShortable = true,
ImageUrl = "https://assets.coingecko.com/coins/images/877/thumb/chainlink-new-logo.png?1547034700",
CoingeckoUrl = "https://www.coingecko.com/en/coins/chainlink",
ExplorerUrl = "https://arbiscan.io/token/0xf97f4df75117a78c1a5a0dbb814af92458539fb4",
IsV1Available = true
},
new GmxToken
{
Name = "Uniswap",
Symbol = "UNI",
Decimals = 18,
PriceDecimals = 3,
Address = Constants.GMX.TokenAddress.UNI,
IsStable = false,
IsShortable = true,
ImageUrl = "https://assets.coingecko.com/coins/images/12504/thumb/uniswap-uni.png?1600306604",
CoingeckoUrl = "https://www.coingecko.com/en/coins/uniswap",
ExplorerUrl = "https://arbiscan.io/token/0xfa7f8980b0f1e64a2062791cc3b0871572f1f7f0",
IsV1Available = true
},
new GmxToken
{
Name = "Bridged USDC (USDC.e)",
Symbol = "USDC.e",
Decimals = 6,
Address = Constants.GMX.TokenAddress.USDCE,
IsStable = true,
ImageUrl = "https://assets.coingecko.com/coins/images/6319/thumb/USD_Coin_icon.png?1547042389",
CoingeckoUrl = "https://www.coingecko.com/en/coins/bridged-usdc-arbitrum",
ExplorerUrl = "https://arbiscan.io/token/0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8",
IsV1Available = true
},
new GmxToken
{
Name = "USD Coin",
Symbol = "USDC",
Decimals = 6,
Address = Constants.GMX.TokenAddress.USDC,
IsStable = true,
IsV1Available = true,
ImageUrl = "https://assets.coingecko.com/coins/images/6319/thumb/USD_Coin_icon.png?1547042389",
CoingeckoUrl = "https://www.coingecko.com/en/coins/usd-coin",
ExplorerUrl = "https://arbiscan.io/address/0xaf88d065e77c8cC2239327C5EDb3A432268e5831"
},
new GmxToken
{
Name = "Tether",
Symbol = "USDT",
Decimals = 6,
Address = Constants.GMX.TokenAddress.USDT,
IsStable = true,
ImageUrl = "https://assets.coingecko.com/coins/images/325/thumb/Tether-logo.png?1598003707",
ExplorerUrl = "https://arbiscan.io/address/0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
CoingeckoUrl = "https://www.coingecko.com/en/coins/tether",
IsV1Available = true
},
new GmxToken
{
Name = "Dai",
Symbol = "DAI",
Decimals = 18,
Address = Constants.GMX.TokenAddress.DAI,
IsStable = true,
ImageUrl = "https://assets.coingecko.com/coins/images/9956/thumb/4943.png?1636636734",
CoingeckoUrl = "https://www.coingecko.com/en/coins/dai",
ExplorerUrl = "https://arbiscan.io/token/0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1",
IsV1Available = true
},
new GmxToken
{
Name = "USDe",
Symbol = "USDe",
Decimals = 18,
Address = Constants.GMX.TokenAddress.USDE,
IsStable = true,
ImageUrl = "https://assets.coingecko.com/coins/images/9956/thumb/4943.png?1636636734",
CoingeckoUrl = "https://www.coingecko.com/en/coins/usde",
ExplorerUrl = "https://arbiscan.io/token/0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1",
},
new GmxToken
{
Name = "Frax",
Symbol = "FRAX",
Decimals = 18,
Address = Constants.GMX.TokenAddress.FRAX,
IsStable = true,
ImageUrl = "https://assets.coingecko.com/coins/images/13422/small/frax_logo.png?1608476506",
CoingeckoUrl = "https://www.coingecko.com/en/coins/frax",
ExplorerUrl = "https://arbiscan.io/token/0x17fc002b466eec40dae837fc4be5c67993ddbd6f",
IsV1Available = true
},
new GmxToken
{
Name = "Magic Internet Money",
Symbol = "MIM",
Decimals = 18,
Address = Constants.GMX.TokenAddress.MIM,
IsStable = true,
ImageUrl = "https://assets.coingecko.com/coins/images/16786/thumb/mimlogopng.png?1624979612",
CoingeckoUrl = "https://www.coingecko.com/en/coins/magic-internet-money",
ExplorerUrl = "https://arbiscan.io/token/0xFEa7a6a0B346362BF88A9e4A88416B77a57D6c2A",
IsV1Available = true
},
new GmxToken
{
Name = "Bitcoin",
Symbol = "BTC",
Decimals = 8,
Address = Constants.GMX.TokenAddress.BTC,
IsSynthetic = true,
ImageUrl = "https://assets.coingecko.com/coins/images/1/small/bitcoin.png?1547033579",
CoingeckoUrl = "https://www.coingecko.com/en/coins/bitcoin",
},
new GmxToken()
{
Name = "DogeCoin",
Symbol = "DOGE",
Decimals = 8,
PriceDecimals = 4,
Address = Constants.GMX.TokenAddress.DOGE,
IsSynthetic = true,
ImageUrl = "https://assets.coingecko.com/coins/images/5/small/dogecoin.png?1547792256",
CoingeckoUrl = "https://www.coingecko.com/en/coins/dogecoin",
},
new GmxToken
{
Name = "Litecoin",
Symbol = "LTC",
Decimals = 8,
Address = Constants.GMX.TokenAddress.LTC,
IsSynthetic = true,
ImageUrl = "https://assets.coingecko.com/coins/images/2/small/litecoin.png?1547033580",
CoingeckoUrl = "https://www.coingecko.com/en/coins/litecoin",
},
new GmxToken
{
Name = "XRP",
Symbol = "XRP",
Decimals = 6,
PriceDecimals = 4,
Address = Constants.GMX.TokenAddress.XRP,
ImageUrl = "https://assets.coingecko.com/coins/images/44/small/xrp-symbol-white-128.png?1605778731",
CoingeckoUrl = "https://www.coingecko.com/en/coins/xrp",
IsSynthetic = true,
},
new GmxToken
{
Name = "GMX",
Symbol = "GMX",
Address =
Constants.GMX.TokenAddress.GMX,
Decimals = 18,
ImageUrl = "https://assets.coingecko.com/coins/images/18323/small/arbit.png?1631532468",
CoingeckoUrl = "https://www.coingecko.com/en/coins/gmx",
ExplorerUrl = "https://arbiscan.io/address/0xfc5a1a6eb076a2c7ad06ed22c90d7e710e35ad0a",
IsPlatform = true
},
new GmxToken
{
Name = "Wrapped BNB (LayerZero)",
Symbol = "BNB",
AssetSymbol = "WBNB (LayerZero)",
Address = Constants.GMX.TokenAddress.WBNB,
Decimals = 18,
ImageUrl = "https://assets.coingecko.com/coins/images/825/standard/bnb-icon2_2x.png?1696501970",
CoingeckoUrl = "https://www.coingecko.com/en/coins/bnb",
},
new GmxToken
{
Name = "Cosmos",
Symbol = "ATOM",
AssetSymbol = "ATOM",
Address = Constants.GMX.TokenAddress.ATOM,
Decimals = 6,
ImageUrl = "https://assets.coingecko.com/coins/images/1481/standard/cosmos_hub.png?1696502525",
CoingeckoUrl = "https://www.coingecko.com/en/coins/cosmos-hub",
IsSynthetic = true
},
new GmxToken
{
Name = "Near",
Symbol = "NEAR",
AssetSymbol = "NEAR",
Address = Constants.GMX.TokenAddress.NEAR,
Decimals = 24,
ImageUrl = "https://assets.coingecko.com/coins/images/10365/standard/near.jpg?1696510367",
CoingeckoUrl = "https://www.coingecko.com/en/coins/near",
IsSynthetic = true
},
new GmxToken
{
Name = "Aave",
Symbol = "AAVE",
AssetSymbol = "AAVE",
Address = Constants.GMX.TokenAddress.AAVE,
Decimals = 18,
ImageUrl = "https://assets.coingecko.com/coins/images/12645/standard/AAVE.png?1696512452",
CoingeckoUrl = "https://www.coingecko.com/en/coins/aave"
},
new GmxToken
{
Name = "Wrapped AVAX (Wormhole)",
Symbol = "AVAX",
AssetSymbol = "WAVAX (Wormhole)",
Address = Constants.GMX.TokenAddress.AVAX,
Decimals = 18,
ImageUrl = "https://assets.coingecko.com/coins/images/12559/small/coin-round-red.png?1604021818",
CoingeckoUrl = "https://www.coingecko.com/en/coins/avalanche"
},
new GmxToken
{
Name = "Optimism",
Symbol = "OP",
Address = Constants.GMX.TokenAddress.OP,
Decimals = 18,
ImageUrl = "https://assets.coingecko.com/coins/images/25244/standard/Optimism.png?1696524385",
CoingeckoUrl = "https://www.coingecko.com/en/coins/optimism"
},
new GmxToken
{
Name = "Pepe",
Symbol = "PEPE",
Address = Constants.GMX.TokenAddress.PEPE,
Decimals = 18,
PriceDecimals = 8,
ImageUrl = "https://assets.coingecko.com/coins/images/29850/standard/pepe-token.jpeg?1696528776",
CoingeckoUrl = "https://www.coingecko.com/en/coins/pepe"
},
new GmxToken
{
Name = "dogwifhat",
Symbol = "WIF",
Address = Constants.GMX.TokenAddress.WIF,
Decimals = 6,
ImageUrl = "https://assets.coingecko.com/coins/images/33566/standard/dogwifhat.jpg?1702499428",
CoingeckoUrl = "https://www.coingecko.com/en/coins/dogwifhat"
},
new GmxToken
{
Name = "Shiba Inu",
Symbol = "SHIB",
Address = Constants.GMX.TokenAddress.SHIB,
Decimals = 18,
ImageUrl = "https://assets.coingecko.com/coins/images/11939/standard/shiba.png?1696511800",
CoingeckoUrl = "https://www.coingecko.com/en/coins/shiba-inu",
IsSynthetic = true,
PriceDecimals = 8
},
new GmxToken
{
Name = "APE Coin",
Symbol = "APE",
Address = Constants.GMX.TokenAddress.APE,
Decimals = 18,
ImageUrl = "https://assets.coingecko.com/coins/images/11939/standard/shiba.png?1696511800",
CoingeckoUrl = "https://www.coingecko.com/en/coins/shiba-inu",
IsSynthetic = true,
PriceDecimals = 8
},
new GmxToken
{
Name = "Stacks",
Symbol = "STX",
Address = Constants.GMX.TokenAddress.STX,
Decimals = 6,
ImageUrl = "https://assets.coingecko.com/coins/images/2069/standard/Stacks_Logo_png.png?1709979332",
CoingeckoUrl = "https://www.coingecko.com/en/coins/stacks",
IsSynthetic = true,
},
new GmxToken
{
Name = "ORDI",
Symbol = "ORDI",
Address = Constants.GMX.TokenAddress.ORDI,
Decimals = 18,
ImageUrl = "https://assets.coingecko.com/coins/images/30162/standard/ordi.png?1696529082",
CoingeckoUrl = "https://www.coingecko.com/en/coins/ordi",
IsSynthetic = true,
},
};
public static GmxToken NATIVE_TOKEN = TOKENS.First(t => t.IsNative);
public static GmxToken WRAPPRED_NATIVE_TOKEN = TOKENS.First(t => t.IsWrapped);
public static List<GmxToken> GetTokens()
{
return TOKENS;
}
public static GmxToken GetTokenByAddress(string address)
{
var token = TOKENS.FirstOrDefault(t => GmxV2Helpers.SameAddress(t.Address, address));
if (token == null)
throw new Exception($"Token with address '{address}' not found");
return token;
}
public static string ConvertTokenAddress(string address, string convertTo = null)
{
if (convertTo == "wrapped" && address == NATIVE_TOKEN.Address)
{
return WRAPPRED_NATIVE_TOKEN.Address;
}
if (convertTo == "native" && address == WRAPPRED_NATIVE_TOKEN.Address)
{
return NATIVE_TOKEN.Address;
}
return address;
}
public static string GetMarketFullName(string indexToken, string longToken, string shortToken, bool isSpotOnly)
{
return $"{GetMarketIndexName(indexToken, isSpotOnly)} [{GetMarketPoolName(longToken, shortToken)}]";
}
public static string GetMarketIndexName(string indexToken, bool isSpotOnly)
{
if (isSpotOnly)
{
return "SPOT-ONLY";
}
return indexToken;
}
public static string GetMarketPoolName(string longToken, string shortToken)
{
if (longToken == shortToken)
{
return longToken;
}
return $"{longToken}-{shortToken}";
}
public static GmxToken GetByTicker(Enums.Ticker ticker)
{
return TOKENS.FirstOrDefault(t => t.Symbol == ticker.ToString()) ?? throw new InvalidOperationException();
}
}
public class GmxToken
{
public string Name { get; set; }
public string Symbol { get; set; }
public int Decimals { get; set; }
public string Address { get; set; }
public bool IsNative { get; set; }
public bool IsShortable { get; set; }
public string ImageUrl { get; set; }
public string CoingeckoUrl { get; set; }
public bool IsV1Available { get; set; }
public bool IsStable { get; set; }
public string ExplorerUrl { get; set; }
public string BaseSymbol { get; set; }
public string AssetSymbol { get; set; }
public bool IsWrapped { get; set; }
public int PriceDecimals { get; set; }
public bool IsSynthetic { get; set; }
public bool IsPlatform { get; set; }
}