Refact multicall
This commit is contained in:
@@ -102,17 +102,17 @@ builder.Services.AddSwaggerGen(options =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
builder.WebHost.SetupDiscordBot();
|
builder.WebHost.SetupDiscordBot();
|
||||||
builder.Services.AddHostedService<FeeWorker>();
|
// builder.Services.AddHostedService<FeeWorker>();
|
||||||
// builder.Services.AddHostedService<PositionManagerWorker>();
|
// // builder.Services.AddHostedService<PositionManagerWorker>();
|
||||||
// builder.Services.AddHostedService<PositionFetcher>();
|
// // builder.Services.AddHostedService<PositionFetcher>();
|
||||||
// builder.Services.AddHostedService<PricesFiveMinutesWorker>();
|
// // builder.Services.AddHostedService<PricesFiveMinutesWorker>();
|
||||||
builder.Services.AddHostedService<PricesFifteenMinutesWorker>();
|
// builder.Services.AddHostedService<PricesFifteenMinutesWorker>();
|
||||||
builder.Services.AddHostedService<PricesOneHourWorker>();
|
// builder.Services.AddHostedService<PricesOneHourWorker>();
|
||||||
// builder.Services.AddHostedService<PricesFourHoursWorker>();
|
// // builder.Services.AddHostedService<PricesFourHoursWorker>();
|
||||||
builder.Services.AddHostedService<PricesOneDayWorker>();
|
// builder.Services.AddHostedService<PricesOneDayWorker>();
|
||||||
// builder.Services.AddHostedService<SpotlightWorker>();
|
// // builder.Services.AddHostedService<SpotlightWorker>();
|
||||||
builder.Services.AddHostedService<TraderWatcher>();
|
// builder.Services.AddHostedService<TraderWatcher>();
|
||||||
builder.Services.AddHostedService<LeaderboardWorker>();
|
// builder.Services.AddHostedService<LeaderboardWorker>();
|
||||||
builder.Services.AddHostedService<FundingRatesWatcher>();
|
builder.Services.AddHostedService<FundingRatesWatcher>();
|
||||||
|
|
||||||
// App
|
// App
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public static class DiscordHelpers
|
|||||||
var embed = new EmbedBuilder
|
var embed = new EmbedBuilder
|
||||||
{
|
{
|
||||||
Author = new EmbedAuthorBuilder() { Name = "GMX v2" },
|
Author = new EmbedAuthorBuilder() { Name = "GMX v2" },
|
||||||
Title = $"{title} {DateTime.UtcNow:d}",
|
Title = $"{title} {DateTime.UtcNow:g}",
|
||||||
Color = Color.Gold,
|
Color = Color.Gold,
|
||||||
Fields = fields,
|
Fields = fields,
|
||||||
}.Build();
|
}.Build();
|
||||||
@@ -36,17 +36,10 @@ public static class DiscordHelpers
|
|||||||
{
|
{
|
||||||
var fields = new List<EmbedFieldBuilder>();
|
var fields = new List<EmbedFieldBuilder>();
|
||||||
|
|
||||||
decimal ratePerYear = fundingRate.Rate; // Rate per year
|
var (ratePerYear, ratePerDay, ratePerMonth, ratePerHour) = GetRates(fundingRate);
|
||||||
decimal ratePerDay = ratePerYear / 365; // Rate per day
|
|
||||||
decimal ratePerMonth = ratePerYear / 12; // Rate per month
|
|
||||||
decimal ratePerHour = ratePerDay / 24; // Rate per hour
|
|
||||||
|
|
||||||
if (oldRate != null)
|
if (oldRate != null)
|
||||||
{
|
{
|
||||||
var oldRatePerYear = oldRate.Rate; // Rate per year
|
var (oldRatePerYear, oldRatePerDay, oldRatePerMonth, oldRatePerHour) = GetRates(oldRate);
|
||||||
var oldRatePerDay = oldRatePerYear / 365; // Rate per day
|
|
||||||
var oldRatePerMonth = oldRatePerYear / 12; // Rate per month
|
|
||||||
var oldRatePerHour = oldRatePerDay / 24; // Rate per hour
|
|
||||||
|
|
||||||
fields.Add(new EmbedFieldBuilder
|
fields.Add(new EmbedFieldBuilder
|
||||||
{
|
{
|
||||||
@@ -66,7 +59,7 @@ public static class DiscordHelpers
|
|||||||
var embed = new EmbedBuilder
|
var embed = new EmbedBuilder
|
||||||
{
|
{
|
||||||
Author = new EmbedAuthorBuilder() { Name = "GMX" },
|
Author = new EmbedAuthorBuilder() { Name = "GMX" },
|
||||||
Title = $"{title} {DateTime.UtcNow:d}",
|
Title = $"{title} {DateTime.UtcNow:g}",
|
||||||
Color = Color.DarkGreen,
|
Color = Color.DarkGreen,
|
||||||
Fields = fields,
|
Fields = fields,
|
||||||
}.Build();
|
}.Build();
|
||||||
@@ -115,7 +108,7 @@ public static class DiscordHelpers
|
|||||||
var embed = new EmbedBuilder
|
var embed = new EmbedBuilder
|
||||||
{
|
{
|
||||||
Author = new EmbedAuthorBuilder() { Name = "GMX" },
|
Author = new EmbedAuthorBuilder() { Name = "GMX" },
|
||||||
Title = $"{title} {DateTime.UtcNow:d}",
|
Title = $"{title} {DateTime.UtcNow:g}",
|
||||||
Color = Color.DarkBlue,
|
Color = Color.DarkBlue,
|
||||||
Fields = fields,
|
Fields = fields,
|
||||||
}.Build();
|
}.Build();
|
||||||
@@ -129,11 +122,7 @@ public static class DiscordHelpers
|
|||||||
|
|
||||||
foreach (var fundingRate in fundingRates)
|
foreach (var fundingRate in fundingRates)
|
||||||
{
|
{
|
||||||
decimal ratePerYear = fundingRate.Rate; // Rate per year
|
var (ratePerYear, ratePerDay, ratePerMonth, ratePerHour) = GetRates(fundingRate);
|
||||||
decimal ratePerDay = ratePerYear / 365; // Rate per day
|
|
||||||
decimal ratePerMonth = ratePerYear / 12; // Rate per month
|
|
||||||
decimal ratePerHour = ratePerDay / 24; // Rate per hour
|
|
||||||
|
|
||||||
fields.Add(new EmbedFieldBuilder
|
fields.Add(new EmbedFieldBuilder
|
||||||
{
|
{
|
||||||
Name = $"{fundingRate.Ticker}",
|
Name = $"{fundingRate.Ticker}",
|
||||||
@@ -145,11 +134,22 @@ public static class DiscordHelpers
|
|||||||
var embed = new EmbedBuilder
|
var embed = new EmbedBuilder
|
||||||
{
|
{
|
||||||
Author = new EmbedAuthorBuilder() { Name = "GMX" },
|
Author = new EmbedAuthorBuilder() { Name = "GMX" },
|
||||||
Title = $"Best Funding Rate {DateTime.UtcNow:d}",
|
Title = $"Best Funding Rate {DateTime.UtcNow:g}",
|
||||||
Color = Color.DarkGreen,
|
Color = Color.DarkGreen,
|
||||||
Fields = fields,
|
Fields = fields,
|
||||||
}.Build();
|
}.Build();
|
||||||
|
|
||||||
return embed;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
// 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
|
// Here the bot will display "Playing dead" while listening
|
||||||
await _client.SetGameAsync(_settings.BotActivity, "https://moon.com", ActivityType.Playing);
|
await _client.SetGameAsync(_settings.BotActivity, "https://moon.com", ActivityType.Playing);
|
||||||
_logger.LogInformation(JsonConvert.SerializeObject(_settings, Formatting.Indented));
|
|
||||||
if (!_settings.HandleUserAction) return;
|
if (!_settings.HandleUserAction) return;
|
||||||
|
|
||||||
List<ApplicationCommandProperties> applicationCommandProperties = new();
|
List<ApplicationCommandProperties> applicationCommandProperties = new();
|
||||||
|
|||||||
@@ -181,9 +181,13 @@ public class GmxV2Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<GmxMarketInfo>> GetMarketInfosAsync(Web3 web3)
|
public async Task<List<GmxMarketInfo>> GetMarketInfosAsync(Web3 web3)
|
||||||
{
|
{
|
||||||
var markets = await GetMarketsAsync(web3);
|
var markets = await GetMarketsAsync(web3);
|
||||||
var readerResult = new List<GmxMarketInfo>();
|
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)
|
foreach (var market in markets)
|
||||||
{
|
{
|
||||||
var tokensData = await GetTokensData(web3);
|
var tokensData = await GetTokensData(web3);
|
||||||
@@ -195,6 +199,7 @@ public class GmxV2Service
|
|||||||
LongToken = market.LongToken,
|
LongToken = market.LongToken,
|
||||||
ShortToken = market.ShortToken
|
ShortToken = market.ShortToken
|
||||||
};
|
};
|
||||||
|
|
||||||
var getMarketInfoCallData = new GetMarketInfoFunction
|
var getMarketInfoCallData = new GetMarketInfoFunction
|
||||||
{
|
{
|
||||||
DataStore = Arbitrum.AddressV2.DataStore,
|
DataStore = Arbitrum.AddressV2.DataStore,
|
||||||
@@ -206,6 +211,7 @@ public class GmxV2Service
|
|||||||
Target = Arbitrum.AddressV2.Reader,
|
Target = Arbitrum.AddressV2.Reader,
|
||||||
CallData = getMarketInfoCallData
|
CallData = getMarketInfoCallData
|
||||||
};
|
};
|
||||||
|
|
||||||
var getMarketTokenPriceCallData = new GetMarketTokenPriceFunction
|
var getMarketTokenPriceCallData = new GetMarketTokenPriceFunction
|
||||||
{
|
{
|
||||||
DataStore = Arbitrum.AddressV2.DataStore,
|
DataStore = Arbitrum.AddressV2.DataStore,
|
||||||
@@ -221,6 +227,7 @@ public class GmxV2Service
|
|||||||
Target = Arbitrum.AddressV2.Reader,
|
Target = Arbitrum.AddressV2.Reader,
|
||||||
CallData = getMarketTokenPriceCallData
|
CallData = getMarketTokenPriceCallData
|
||||||
};
|
};
|
||||||
|
|
||||||
var getMarketTokenPriceMinCallData = new GetMarketTokenPriceFunction
|
var getMarketTokenPriceMinCallData = new GetMarketTokenPriceFunction
|
||||||
{
|
{
|
||||||
DataStore = Arbitrum.AddressV2.DataStore,
|
DataStore = Arbitrum.AddressV2.DataStore,
|
||||||
@@ -237,29 +244,15 @@ public class GmxV2Service
|
|||||||
CallData = getMarketTokenPriceMinCallData
|
CallData = getMarketTokenPriceMinCallData
|
||||||
};
|
};
|
||||||
|
|
||||||
var readerMulticall = new AggregateFunction();
|
readerCalls.Add(getMarketInfoCall);
|
||||||
readerMulticall.Calls = new List<Call>();
|
readerCalls.Add(getMarketTokenPriceCall);
|
||||||
readerMulticall.Calls.Add(getMarketInfoCall);
|
readerCalls.Add(getMarketTokenPriceMinCall);
|
||||||
readerMulticall.Calls.Add(getMarketTokenPriceCall);
|
|
||||||
readerMulticall.Calls.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);
|
var marketKeys = GmxKeysService.GetMarketKeys(market.MarketToken);
|
||||||
if (marketKeys == null)
|
if (marketKeys == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var longInterestUsingLongTokenCallData = new GetUintFunction()
|
var longInterestUsingLongTokenCallData = new GetUintFunction
|
||||||
{
|
{
|
||||||
Key = marketKeys.LongInterestUsingLongToken.HexToByteArray()
|
Key = marketKeys.LongInterestUsingLongToken.HexToByteArray()
|
||||||
}.GetCallData();
|
}.GetCallData();
|
||||||
@@ -268,7 +261,7 @@ public class GmxV2Service
|
|||||||
Target = Arbitrum.AddressV2.DataStore,
|
Target = Arbitrum.AddressV2.DataStore,
|
||||||
CallData = longInterestUsingLongTokenCallData
|
CallData = longInterestUsingLongTokenCallData
|
||||||
};
|
};
|
||||||
var longInterestUsingShortTokenCallData = new GetUintFunction()
|
var longInterestUsingShortTokenCallData = new GetUintFunction
|
||||||
{
|
{
|
||||||
Key = marketKeys.LongInterestUsingShortToken.HexToByteArray()
|
Key = marketKeys.LongInterestUsingShortToken.HexToByteArray()
|
||||||
}.GetCallData();
|
}.GetCallData();
|
||||||
@@ -277,7 +270,7 @@ public class GmxV2Service
|
|||||||
Target = Arbitrum.AddressV2.DataStore,
|
Target = Arbitrum.AddressV2.DataStore,
|
||||||
CallData = longInterestUsingShortTokenCallData
|
CallData = longInterestUsingShortTokenCallData
|
||||||
};
|
};
|
||||||
var shortInterestUsingLongTokenCallData = new GetUintFunction()
|
var shortInterestUsingLongTokenCallData = new GetUintFunction
|
||||||
{
|
{
|
||||||
Key = marketKeys.ShortInterestUsingLongToken.HexToByteArray()
|
Key = marketKeys.ShortInterestUsingLongToken.HexToByteArray()
|
||||||
}.GetCallData();
|
}.GetCallData();
|
||||||
@@ -286,7 +279,7 @@ public class GmxV2Service
|
|||||||
Target = Arbitrum.AddressV2.DataStore,
|
Target = Arbitrum.AddressV2.DataStore,
|
||||||
CallData = shortInterestUsingLongTokenCallData
|
CallData = shortInterestUsingLongTokenCallData
|
||||||
};
|
};
|
||||||
var shortInterestUsingShortTokenCallData = new GetUintFunction()
|
var shortInterestUsingShortTokenCallData = new GetUintFunction
|
||||||
{
|
{
|
||||||
Key = marketKeys.ShortInterestUsingShortToken.HexToByteArray()
|
Key = marketKeys.ShortInterestUsingShortToken.HexToByteArray()
|
||||||
}.GetCallData();
|
}.GetCallData();
|
||||||
@@ -296,32 +289,56 @@ public class GmxV2Service
|
|||||||
CallData = shortInterestUsingShortTokenCallData
|
CallData = shortInterestUsingShortTokenCallData
|
||||||
};
|
};
|
||||||
|
|
||||||
var dataStoreMulticall = new AggregateFunction();
|
datastoreCalls.Add(longInterestUsingLongTokenCall);
|
||||||
dataStoreMulticall.Calls = new List<Call>();
|
datastoreCalls.Add(longInterestUsingShortTokenCall);
|
||||||
dataStoreMulticall.Calls.Add(longInterestUsingLongTokenCall);
|
datastoreCalls.Add(shortInterestUsingLongTokenCall);
|
||||||
dataStoreMulticall.Calls.Add(longInterestUsingShortTokenCall);
|
datastoreCalls.Add(shortInterestUsingShortTokenCall);
|
||||||
dataStoreMulticall.Calls.Add(shortInterestUsingLongTokenCall);
|
}
|
||||||
dataStoreMulticall.Calls.Add(shortInterestUsingShortTokenCall);
|
|
||||||
|
|
||||||
// Call datastore to get market info
|
var readerMulticall = new AggregateFunction { Calls = readerCalls };
|
||||||
var dataStoreQueryHandler = web3.Eth.GetContractQueryHandler<AggregateFunction>();
|
var datastoreMulticall = new AggregateFunction { Calls = datastoreCalls };
|
||||||
var dataStoreCallResults = await dataStoreQueryHandler
|
|
||||||
.QueryDeserializingToObjectAsync<AggregateOutputDTO>(dataStoreMulticall, Arbitrum.AddressV2.Multicall)
|
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);
|
.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);
|
var marketInfos = GmxMappers.Map(marketInfo.ReturnValue1);
|
||||||
readerResult.Add(new GmxMarketInfo()
|
readerResult.Add(new GmxMarketInfo
|
||||||
{
|
{
|
||||||
Market = marketInfos,
|
Market = marketInfos,
|
||||||
Infos = DecodeFundingRateOutput(dataStoreCallResults, marketInfos.IsSameCollaterals),
|
Infos = new GmxMarketInfos
|
||||||
|
{
|
||||||
|
LongInterestUsd = longInterestUsingLongToken + longInterestUsingShortToken,
|
||||||
|
ShortInterestUsd = shortInterestUsingLongToken + shortInterestUsingShortToken
|
||||||
|
},
|
||||||
MarketTokenPriceMax = GmxMappers.Map(marketTokenPriceMax),
|
MarketTokenPriceMax = GmxMappers.Map(marketTokenPriceMax),
|
||||||
MarketTokenPriceMin = GmxMappers.Map(marketTokenPriceMin)
|
MarketTokenPriceMin = GmxMappers.Map(marketTokenPriceMin)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return readerResult;
|
return readerResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GmxMarketInfos DecodeFundingRateOutput(AggregateOutputDTO results, bool isSameCollaterals)
|
private GmxMarketInfos DecodeFundingRateOutput(AggregateOutputDTO results, bool isSameCollaterals)
|
||||||
{
|
{
|
||||||
var marketDivisor = new BigInteger(isSameCollaterals ? 2 : 1);
|
var marketDivisor = new BigInteger(isSameCollaterals ? 2 : 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user