private async Task <IStakeEvent> GetStakeLockupAsync(IFundSettings fundSettings, IStakeSettings stakeSettings, ITransaction transaction) { var stakeData = await etherClient.GetDataAsync <StakeFunction>(stakeSettings.StakingAddress, transaction.Input); if (stakeData != null) { var seconds = (double)Web3.Convert.FromWei(stakeData.Length, 0); var quantity = Web3.Convert.FromWei(stakeData.Quantity, fundSettings.Decimals); return(new BusinessStakeEvent() { Hash = transaction.Hash, ConfirmedAt = transaction.ConfirmedAt, UserAddress = transaction.Sender, StakeAddress = stakeSettings.ContractAddress, ContractAddress = fundSettings.ContractAddress, Type = StakeEventType.Lockup, Lock = new BusinessStakeLock() { Duration = TimeSpan.FromSeconds(seconds), ExpiresAt = transaction.ConfirmedAt.AddSeconds(seconds), Quantity = quantity, } }); } return(null); }
private async Task <IStakeEvent> GetStakeReleaseAsync(IFundSettings fundSettings, IStakeSettings stakeSettings, ITransaction transaction) { var stakingAddress = stakeSettings.GetStakingAddress(fundSettings.Symbol); var operations = await Operations .ListOperationsAsync(transaction.Hash) .ToListAsync(CancellationToken); var feeOperation = operations.SingleOrDefault(x => x.Type == OperationTypes.Transfer && x.Sender.Equals(stakingAddress, StringComparison.OrdinalIgnoreCase) && stakeSettings.FeeAddresses.Select(x => x.Address.ToLower()).Contains(x.Recipient.ToLower())); var releaseOperation = operations.LastOrDefault(x => x.Type == OperationTypes.Transfer && x.Sender.Equals(stakingAddress, StringComparison.OrdinalIgnoreCase) && (feeOperation == null || x.Order != feeOperation.Order)); if (releaseOperation != null) { return(new BusinessStakeEvent() { Hash = transaction.Hash, ConfirmedAt = transaction.ConfirmedAt, UserAddress = new EthereumAddress(releaseOperation.Recipient), StakeAddress = stakeSettings.ContractAddress, ContractAddress = fundSettings.ContractAddress, Type = feeOperation != null ? StakeEventType.EarlyWithdrawal : StakeEventType.Release, Release = new BusinessStakeRelease() { Quantity = Web3.Convert.FromWei(BigInteger.Parse(releaseOperation.Value), fundSettings.Decimals), FeeQuantity = feeOperation != null ? Web3.Convert.FromWei(BigInteger.Parse(feeOperation.Value), fundSettings.Decimals) : default(decimal?) } }); } return(null); }
private async Task <IFund> GetFundAsync(IFundSettings settings, IInvictusFund fund, CurrencyCode currencyCode) { var now = DateTime.UtcNow; var priceData = settings.Tradable ? await ethplorerClient.GetTokenInfoAsync(new EthereumAddress(settings.DataKey)) : null; var navData = await ListPerformanceAsync(settings.Symbol, PriceMode.Close, now.AddDays(-29), now, currencyCode) .ToListAsync(CancellationToken); return(await MapFundAsync( fund, navData .Select(x => x.NetAssetValuePerToken) .ToList(), priceData?.Price, settings.Symbol, currencyCode)); }
private async Task SyncPerformanceAsync( ICoinGeckoClient coinGeckoClient, IInvictusClient invictusClient, IFundPerformanceRepository repository, IFundSettings fund, DateTimeOffset startDate, DateTimeOffset endDate, CancellationToken cancellationToken) { var start = new DateTimeOffset(startDate.Date, TimeSpan.Zero); while (!cancellationToken.IsCancellationRequested) { if (start >= DateTimeOffset.UtcNow) { break; } var end = start.AddDays(MaxDays).Round(); Console.WriteLine($"[{fund.ContractAddress}] Processing Batch: {start} -> {end}"); var invictusNavs = await invictusClient .ListPerformanceAsync(fund.Symbol, start, end) .ToListAsync(cancellationToken); if (invictusNavs.Any()) { var marketPrices = fund.Tradable ? await coinGeckoClient .ListCoinPerformanceAsync(fund.CoinGeckoId, start.AddDays(-1), end.AddDays(1)) .ToListAsync(cancellationToken) : new List <CoinGeckoCoinPerformance>(); foreach (var nav in invictusNavs) { var closestPrice = marketPrices .OrderBy(i => Math.Abs(i.Date.ToUnixTimeSeconds() - new DateTimeOffset(nav.Date, TimeSpan.Zero).ToUnixTimeSeconds())) .FirstOrDefault(); var perf = new DataFundPerformance() { Address = fund.ContractAddress, Date = nav.Date, Nav = nav.NetAssetValuePerToken, Price = closestPrice?.Price ?? -1, MarketCap = closestPrice?.MarketCap ?? -1, Volume = closestPrice?.Volume ?? -1 }; await repository.UploadItemsAsync(perf); } } Console.WriteLine($"[{fund.ContractAddress}] Finished Batch: {start} -> {end}"); if (end >= endDate) { break; } else { start = end; } } }