Refact multicall

This commit is contained in:
2024-08-17 07:57:14 +07:00
parent 7bb6a3638e
commit acaf3f7346
4 changed files with 176 additions and 160 deletions

View File

@@ -102,17 +102,17 @@ builder.Services.AddSwaggerGen(options =>
});
builder.WebHost.SetupDiscordBot();
builder.Services.AddHostedService<FeeWorker>();
// builder.Services.AddHostedService<PositionManagerWorker>();
// builder.Services.AddHostedService<PositionFetcher>();
// builder.Services.AddHostedService<PricesFiveMinutesWorker>();
builder.Services.AddHostedService<PricesFifteenMinutesWorker>();
builder.Services.AddHostedService<PricesOneHourWorker>();
// builder.Services.AddHostedService<PricesFourHoursWorker>();
builder.Services.AddHostedService<PricesOneDayWorker>();
// builder.Services.AddHostedService<SpotlightWorker>();
builder.Services.AddHostedService<TraderWatcher>();
builder.Services.AddHostedService<LeaderboardWorker>();
// builder.Services.AddHostedService<FeeWorker>();
// // builder.Services.AddHostedService<PositionManagerWorker>();
// // builder.Services.AddHostedService<PositionFetcher>();
// // builder.Services.AddHostedService<PricesFiveMinutesWorker>();
// builder.Services.AddHostedService<PricesFifteenMinutesWorker>();
// builder.Services.AddHostedService<PricesOneHourWorker>();
// // builder.Services.AddHostedService<PricesFourHoursWorker>();
// builder.Services.AddHostedService<PricesOneDayWorker>();
// // builder.Services.AddHostedService<SpotlightWorker>();
// builder.Services.AddHostedService<TraderWatcher>();
// builder.Services.AddHostedService<LeaderboardWorker>();
builder.Services.AddHostedService<FundingRatesWatcher>();
// App

View File

@@ -24,7 +24,7 @@ public static class DiscordHelpers
var embed = new EmbedBuilder
{
Author = new EmbedAuthorBuilder() { Name = "GMX v2" },
Title = $"{title} {DateTime.UtcNow:d}",
Title = $"{title} {DateTime.UtcNow:g}",
Color = Color.Gold,
Fields = fields,
}.Build();
@@ -36,17 +36,10 @@ public static class DiscordHelpers
{
var fields = new List<EmbedFieldBuilder>();
decimal ratePerYear = fundingRate.Rate; // Rate per year
decimal ratePerDay = ratePerYear / 365; // Rate per day
decimal ratePerMonth = ratePerYear / 12; // Rate per month
decimal ratePerHour = ratePerDay / 24; // Rate per hour
var (ratePerYear, ratePerDay, ratePerMonth, ratePerHour) = GetRates(fundingRate);
if (oldRate != null)
{
var oldRatePerYear = oldRate.Rate; // Rate per year
var oldRatePerDay = oldRatePerYear / 365; // Rate per day
var oldRatePerMonth = oldRatePerYear / 12; // Rate per month
var oldRatePerHour = oldRatePerDay / 24; // Rate per hour
var (oldRatePerYear, oldRatePerDay, oldRatePerMonth, oldRatePerHour) = GetRates(oldRate);
fields.Add(new EmbedFieldBuilder
{
@@ -66,7 +59,7 @@ public static class DiscordHelpers
var embed = new EmbedBuilder
{
Author = new EmbedAuthorBuilder() { Name = "GMX" },
Title = $"{title} {DateTime.UtcNow:d}",
Title = $"{title} {DateTime.UtcNow:g}",
Color = Color.DarkGreen,
Fields = fields,
}.Build();
@@ -115,7 +108,7 @@ public static class DiscordHelpers
var embed = new EmbedBuilder
{
Author = new EmbedAuthorBuilder() { Name = "GMX" },
Title = $"{title} {DateTime.UtcNow:d}",
Title = $"{title} {DateTime.UtcNow:g}",
Color = Color.DarkBlue,
Fields = fields,
}.Build();
@@ -129,11 +122,7 @@ public static class DiscordHelpers
foreach (var fundingRate in fundingRates)
{
decimal ratePerYear = fundingRate.Rate; // Rate per year
decimal ratePerDay = ratePerYear / 365; // Rate per day
decimal ratePerMonth = ratePerYear / 12; // Rate per month
decimal ratePerHour = ratePerDay / 24; // Rate per hour
var (ratePerYear, ratePerDay, ratePerMonth, ratePerHour) = GetRates(fundingRate);
fields.Add(new EmbedFieldBuilder
{
Name = $"{fundingRate.Ticker}",
@@ -145,11 +134,22 @@ public static class DiscordHelpers
var embed = new EmbedBuilder
{
Author = new EmbedAuthorBuilder() { Name = "GMX" },
Title = $"Best Funding Rate {DateTime.UtcNow:d}",
Title = $"Best Funding Rate {DateTime.UtcNow:g}",
Color = Color.DarkGreen,
Fields = fields,
}.Build();
return embed;
}
private static (decimal ratePerYear, decimal ratePerDay, decimal ratePerMonth, decimal ratePerHour) GetRates(
FundingRate fundingRate)
{
decimal ratePerHour = fundingRate.Rate; // Rate per hour
decimal ratePerDay = ratePerHour * 24; // Rate per day
decimal ratePerMonth = ratePerDay * 30; // Rate per month
decimal ratePerYear = ratePerDay * 365; // Rate per year
return (ratePerYear, ratePerDay, ratePerMonth, ratePerHour);
}
}

View File

@@ -99,7 +99,6 @@ namespace Managing.Infrastructure.Messengers.Discord
// Discord started as a game chat service, so it has the option to show what games you are playing
// Here the bot will display "Playing dead" while listening
await _client.SetGameAsync(_settings.BotActivity, "https://moon.com", ActivityType.Playing);
_logger.LogInformation(JsonConvert.SerializeObject(_settings, Formatting.Indented));
if (!_settings.HandleUserAction) return;
List<ApplicationCommandProperties> applicationCommandProperties = new();

View File

@@ -184,6 +184,10 @@ public class GmxV2Service
{
var markets = await GetMarketsAsync(web3);
var readerResult = new List<GmxMarketInfo>();
var readerCalls = new List<Call>();
var datastoreCalls = new List<Call>();
markets = markets.Where(m => !m.IsSpotOnly).ToList();
foreach (var market in markets)
{
var tokensData = await GetTokensData(web3);
@@ -195,6 +199,7 @@ public class GmxV2Service
LongToken = market.LongToken,
ShortToken = market.ShortToken
};
var getMarketInfoCallData = new GetMarketInfoFunction
{
DataStore = Arbitrum.AddressV2.DataStore,
@@ -206,6 +211,7 @@ public class GmxV2Service
Target = Arbitrum.AddressV2.Reader,
CallData = getMarketInfoCallData
};
var getMarketTokenPriceCallData = new GetMarketTokenPriceFunction
{
DataStore = Arbitrum.AddressV2.DataStore,
@@ -221,6 +227,7 @@ public class GmxV2Service
Target = Arbitrum.AddressV2.Reader,
CallData = getMarketTokenPriceCallData
};
var getMarketTokenPriceMinCallData = new GetMarketTokenPriceFunction
{
DataStore = Arbitrum.AddressV2.DataStore,
@@ -237,29 +244,15 @@ public class GmxV2Service
CallData = getMarketTokenPriceMinCallData
};
var readerMulticall = new AggregateFunction();
readerMulticall.Calls = new List<Call>();
readerMulticall.Calls.Add(getMarketInfoCall);
readerMulticall.Calls.Add(getMarketTokenPriceCall);
readerMulticall.Calls.Add(getMarketTokenPriceMinCall);
readerCalls.Add(getMarketInfoCall);
readerCalls.Add(getMarketTokenPriceCall);
readerCalls.Add(getMarketTokenPriceMinCall);
var queryHandler = web3.Eth.GetContractQueryHandler<AggregateFunction>();
var readerCallResults = await queryHandler
.QueryDeserializingToObjectAsync<AggregateOutputDTO>(readerMulticall, Arbitrum.AddressV2.Multicall)
.ConfigureAwait(false);
var marketInfo = new GetMarketInfoOutputDTO().DecodeOutput(readerCallResults.ReturnData[0].ToHex());
var marketTokenPriceMax =
new GetMarketTokenPriceOutputDTO().DecodeOutput(readerCallResults.ReturnData[1].ToHex());
var marketTokenPriceMin =
new GetMarketTokenPriceOutputDTO().DecodeOutput(readerCallResults.ReturnData[2].ToHex());
// Get hashed key to call datastore
var marketKeys = GmxKeysService.GetMarketKeys(market.MarketToken);
if (marketKeys == null)
continue;
var longInterestUsingLongTokenCallData = new GetUintFunction()
var longInterestUsingLongTokenCallData = new GetUintFunction
{
Key = marketKeys.LongInterestUsingLongToken.HexToByteArray()
}.GetCallData();
@@ -268,7 +261,7 @@ public class GmxV2Service
Target = Arbitrum.AddressV2.DataStore,
CallData = longInterestUsingLongTokenCallData
};
var longInterestUsingShortTokenCallData = new GetUintFunction()
var longInterestUsingShortTokenCallData = new GetUintFunction
{
Key = marketKeys.LongInterestUsingShortToken.HexToByteArray()
}.GetCallData();
@@ -277,7 +270,7 @@ public class GmxV2Service
Target = Arbitrum.AddressV2.DataStore,
CallData = longInterestUsingShortTokenCallData
};
var shortInterestUsingLongTokenCallData = new GetUintFunction()
var shortInterestUsingLongTokenCallData = new GetUintFunction
{
Key = marketKeys.ShortInterestUsingLongToken.HexToByteArray()
}.GetCallData();
@@ -286,7 +279,7 @@ public class GmxV2Service
Target = Arbitrum.AddressV2.DataStore,
CallData = shortInterestUsingLongTokenCallData
};
var shortInterestUsingShortTokenCallData = new GetUintFunction()
var shortInterestUsingShortTokenCallData = new GetUintFunction
{
Key = marketKeys.ShortInterestUsingShortToken.HexToByteArray()
}.GetCallData();
@@ -296,24 +289,49 @@ public class GmxV2Service
CallData = shortInterestUsingShortTokenCallData
};
var dataStoreMulticall = new AggregateFunction();
dataStoreMulticall.Calls = new List<Call>();
dataStoreMulticall.Calls.Add(longInterestUsingLongTokenCall);
dataStoreMulticall.Calls.Add(longInterestUsingShortTokenCall);
dataStoreMulticall.Calls.Add(shortInterestUsingLongTokenCall);
dataStoreMulticall.Calls.Add(shortInterestUsingShortTokenCall);
datastoreCalls.Add(longInterestUsingLongTokenCall);
datastoreCalls.Add(longInterestUsingShortTokenCall);
datastoreCalls.Add(shortInterestUsingLongTokenCall);
datastoreCalls.Add(shortInterestUsingShortTokenCall);
}
// Call datastore to get market info
var dataStoreQueryHandler = web3.Eth.GetContractQueryHandler<AggregateFunction>();
var dataStoreCallResults = await dataStoreQueryHandler
.QueryDeserializingToObjectAsync<AggregateOutputDTO>(dataStoreMulticall, Arbitrum.AddressV2.Multicall)
var readerMulticall = new AggregateFunction { Calls = readerCalls };
var datastoreMulticall = new AggregateFunction { Calls = datastoreCalls };
var queryHandler = web3.Eth.GetContractQueryHandler<AggregateFunction>();
var readerCallResults = await queryHandler
.QueryDeserializingToObjectAsync<AggregateOutputDTO>(readerMulticall, Arbitrum.AddressV2.Multicall)
.ConfigureAwait(false);
var datastoreCallResults = await queryHandler
.QueryDeserializingToObjectAsync<AggregateOutputDTO>(datastoreMulticall, Arbitrum.AddressV2.Multicall)
.ConfigureAwait(false);
int readerCallIndex = 0;
int datastoreCallIndex = 0;
foreach (var market in markets)
{
var marketInfo = new GetMarketInfoOutputDTO().DecodeOutput(readerCallResults.ReturnData[readerCallIndex++].ToHex());
var marketTokenPriceMax = new GetMarketTokenPriceOutputDTO().DecodeOutput(readerCallResults.ReturnData[readerCallIndex++].ToHex());
var marketTokenPriceMin = new GetMarketTokenPriceOutputDTO().DecodeOutput(readerCallResults.ReturnData[readerCallIndex++].ToHex());
var marketKeys = GmxKeysService.GetMarketKeys(market.MarketToken);
if (marketKeys == null)
continue;
var longInterestUsingLongToken = new GetUintOutputDTO().DecodeOutput(datastoreCallResults.ReturnData[datastoreCallIndex++].ToHex()).ReturnValue1;
var longInterestUsingShortToken = new GetUintOutputDTO().DecodeOutput(datastoreCallResults.ReturnData[datastoreCallIndex++].ToHex()).ReturnValue1;
var shortInterestUsingLongToken = new GetUintOutputDTO().DecodeOutput(datastoreCallResults.ReturnData[datastoreCallIndex++].ToHex()).ReturnValue1;
var shortInterestUsingShortToken = new GetUintOutputDTO().DecodeOutput(datastoreCallResults.ReturnData[datastoreCallIndex++].ToHex()).ReturnValue1;
var marketInfos = GmxMappers.Map(marketInfo.ReturnValue1);
readerResult.Add(new GmxMarketInfo()
readerResult.Add(new GmxMarketInfo
{
Market = marketInfos,
Infos = DecodeFundingRateOutput(dataStoreCallResults, marketInfos.IsSameCollaterals),
Infos = new GmxMarketInfos
{
LongInterestUsd = longInterestUsingLongToken + longInterestUsingShortToken,
ShortInterestUsd = shortInterestUsingLongToken + shortInterestUsingShortToken
},
MarketTokenPriceMax = GmxMappers.Map(marketTokenPriceMax),
MarketTokenPriceMin = GmxMappers.Map(marketTokenPriceMin)
});
@@ -321,7 +339,6 @@ public class GmxV2Service
return readerResult;
}
private GmxMarketInfos DecodeFundingRateOutput(AggregateOutputDTO results, bool isSameCollaterals)
{
var marketDivisor = new BigInteger(isSameCollaterals ? 2 : 1);