public CampaignSettingsHistoryItemEntity(ICampaignSettings campaignSettings, string username)
 {
     TransactionQueueSasUrl = campaignSettings.TransactionQueueSasUrl;
     EmailBlackList         = campaignSettings.EmailBlackList;
     Smtp     = campaignSettings.Smtp;
     Username = username;
 }
Ejemplo n.º 2
0
        private async Task<bool> IsTxValid(TransactionMessage msg, ICampaignSettings settings, decimal soldTokensAmount)
        {
            var preSalePhase = settings.IsPreSale(msg.CreatedUtc);
            var crowdSalePhase = settings.IsCrowdSale(msg.CreatedUtc);
            var amountInvestedUsd = await GetInvestedUsdAmount();

            if (!preSalePhase && !crowdSalePhase)
            {
                await _log.WriteInfoAsync(nameof(Process),
                    $"msg: {msg}, settings: {settings.ToJson()}",
                    $"Transaction is out of campaign dates");

                await _investorRefundRepository.SaveAsync(msg.Email, 
                    InvestorRefundReason.OutOfDates, 
                    msg.ToJson());

                return false;
            }
            if (preSalePhase && soldTokensAmount > settings.PreSaleTotalTokensAmount)
            {
                await _log.WriteInfoAsync(nameof(Process),
                    $"soldTokensAmount: {soldTokensAmount}, settings: {settings.ToJson()}, msg: {msg.ToJson()}",
                    $"All presale tokens were sold out");

                await _investorRefundRepository.SaveAsync(msg.Email, 
                    InvestorRefundReason.PreSaleTokensSoldOut, 
                    msg.ToJson());

                return false;
            }
            if (crowdSalePhase && soldTokensAmount > settings.GetTotalTokensAmount())
            {
                await _log.WriteInfoAsync(nameof(Process),
                    $"soldTokensAmount: {soldTokensAmount}, totalTokensAmount: {settings.GetTotalTokensAmount()}, " +
                    $"settings: {settings.ToJson()}, msg: {msg.ToJson()}",
                    $"All tokens were sold out");

                await _investorRefundRepository.SaveAsync(msg.Email,
                    InvestorRefundReason.TokensSoldOut,
                    msg.ToJson());

                return false;
            }
            if (crowdSalePhase && amountInvestedUsd > settings.HardCapUsd)
            {
                await _log.WriteInfoAsync(nameof(Process),
                    $"amountInvestedUsd: {amountInvestedUsd}, hardCapUsd: {settings.HardCapUsd}, " +
                    $"settings: {settings.ToJson()}, msg: {msg.ToJson()}",
                    $"HardCapUsd was exceeded");

                await _investorRefundRepository.SaveAsync(msg.Email,
                    InvestorRefundReason.HardCapUsdExceeded,
                    msg.ToJson());

                return false;
            }

            return true;
        }
        public override void FixtureSetup()
        {
            base.FixtureSetup();

            _campaignSettingsService = MerchelloContext.Current.Services.CampaignSettingsService;

            var allSettings = _campaignSettingsService.GetAll();
            _campaignSettingsService.Delete(allSettings);

            _campaignSettings = _campaignSettingsService.CreateCampaignSettingsWithKey("Campaign 1", "campaign1");
        }
Ejemplo n.º 4
0
        public override void FixtureSetup()
        {
            base.FixtureSetup();

            _campaignSettingsService = MerchelloContext.Current.Services.CampaignSettingsService;

            var allSettings = _campaignSettingsService.GetAll();

            _campaignSettingsService.Delete(allSettings);

            _campaignSettings = _campaignSettingsService.CreateCampaignSettingsWithKey("Campaign 1", "campaign1");
        }
Ejemplo n.º 5
0
        public static CampaignSettingsModel Create(ICampaignSettings settings)
        {
            if (settings == null)
            {
                return(null);
            }

            return(new CampaignSettingsModel
            {
                TransactionQueueSasUrl = settings.TransactionQueueSasUrl,
                EmailBlackList = settings.EmailBlackList,
                Smtp = settings.Smtp
            });
        }
Ejemplo n.º 6
0
        private async Task UpdateInvestorReferralCode(InvestorTransaction tx, ICampaignSettings settings)
        {
            try
            {
                if (settings.EnableReferralProgram)
                {
                    var investor = await _investorRepository.GetAsync(tx.Email);

                    if (string.IsNullOrEmpty(investor.ReferralCode) && 
                        investor.AmountUsd >= settings.MinInvestAmountUsd)
                    {
                        if (!settings.ReferralCodeLength.HasValue)
                        {
                            throw new Exception("settings.ReferralCodeLength does not have value");
                        }

                        var code = await _referralCodeService.GetReferralCode(settings.ReferralCodeLength.Value);

                        await _investorRepository.SaveReferralCode(investor.Email, code);
                        await _investorAttributeRepository.SaveAsync(InvestorAttributeType.ReferralCode,
                            investor.Email, code);

                        await _log.WriteInfoAsync(nameof(UpdateInvestorReferralCode),
                            $"email: {investor.Email}, code: {code}",
                            $"Update investor referral code");
                    }

                    if (!string.IsNullOrEmpty(investor.ReferralCodeApplied) && 
                        investor.AmountUsd >= settings.MinInvestAmountUsd)
                    {
                        var referralOwnerEmail = await _investorAttributeRepository.GetInvestorEmailAsync(
                            InvestorAttributeType.ReferralCode, investor.ReferralCodeApplied);
                        if (referralOwnerEmail != null)
                        {
                            await _investorRepository.IncrementReferrals(referralOwnerEmail);

                            await _log.WriteInfoAsync(nameof(UpdateInvestorReferralCode),
                                $"referralEmail: {referralOwnerEmail}",
                                $"Increment referrals number");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                await _log.WriteErrorAsync(nameof(UpdateInvestorReferralCode),
                    $"Tx: {tx.ToJson()}, settings: {settings.ToJson()}",
                    ex);
            }
        }
Ejemplo n.º 7
0
        private async Task<InvestorTransaction> SaveTransaction(TransactionMessage msg, 
            ICampaignSettings settings, decimal soldTokensAmount)
        {
            var investor = await _investorRepository.GetAsync(msg.Email);
            var exchangeRate = await GetExchangeRate(msg);
            var avgExchangeRate = Convert.ToDecimal(exchangeRate.AverageRate);
            var amountUsd = msg.Amount * avgExchangeRate;
            var tokenPriceList = TokenPrice.GetPriceList(settings, investor, msg.CreatedUtc, 
                amountUsd, soldTokensAmount);
            var amountToken = tokenPriceList.Sum(p => p.Count);
            var tokenPrice = tokenPriceList.Count == 1 ? tokenPriceList[0].Price : (amountUsd / amountToken);

            var tx = new InvestorTransaction
            {
                Email = msg.Email,
                UniqueId = msg.UniqueId,
                CreatedUtc = msg.CreatedUtc,
                Currency = msg.Currency,
                TransactionId = msg.TransactionId,
                BlockId = msg.BlockId,
                PayInAddress = msg.PayInAddress,
                Amount = msg.Amount,
                AmountUsd = amountUsd,
                AmountToken = amountToken,
                Fee = msg.Fee,
                TokenPrice = tokenPrice,
                TokenPriceContext = tokenPriceList.ToJson(),
                ExchangeRate = avgExchangeRate,
                ExchangeRateContext = exchangeRate.Rates.ToJson()
            };

            await _log.WriteInfoAsync(nameof(SaveTransaction),
                $"tx: {tx.ToJson()}", $"Save transaction");

            await _investorTransactionRepository.SaveAsync(tx);

            return tx;
        }
Ejemplo n.º 8
0
        public async Task UpsertAsync(string campaignId, ICampaignSettings campaignSettings, string username)
        {
            var partitionKey = GetPartitionKey(campaignId);
            var rowKey       = GetRowKey();
            var entity       = new CampaignSettingsEntity(campaignSettings)
            {
                PartitionKey = partitionKey,
                RowKey       = rowKey
            };

            await _table.InsertOrReplaceAsync(entity);

            _cache.Set(CacheKey(campaignId), entity);

            var historyPartitionKey = GetHistoryPartitionKey(campaignId);
            var historyRowKey       = GetHistoryRowKey(DateTime.UtcNow);
            var historyEntity       = new CampaignSettingsHistoryItemEntity(campaignSettings, username)
            {
                PartitionKey = historyPartitionKey,
                RowKey       = historyRowKey
            };

            await _history.InsertAsync(historyEntity);
        }
 public DemoOptinProcessService(IServiceClientFactory serviceClientFactory, ICacheService cacheService, ICampaignSettings campaignConfig, IAuthenticationService authenticationService)
     : base(serviceClientFactory, cacheService, campaignConfig, authenticationService)
 {
 }
 public CampaignToken(ICampaignSettings campaignSettings)
 {
     _campaignSettings = campaignSettings;
     _tokenDateTime    = DateTime.MinValue;
 }
Ejemplo n.º 11
0
 public MailingImpl(IAuthenticationService authenticationService, ICampaignSettings campaignSettings)
 {
     _authenticationService = authenticationService;
     _campaignSettings      = campaignSettings;
 }
        private TransactionService Init(string investorEmail = "*****@*****.**", double exchangeRate = 1.0)
        {
            _log = new LogToMemory();

            _campaignInfoRepository = new Mock <ICampaignInfoRepository>();

            _campaignInfoRepository
            .Setup(m => m.IncrementValue(It.Is <CampaignInfoType>(t => t == CampaignInfoType.AmountInvestedUsd), It.IsAny <decimal>()))
            .Callback((CampaignInfoType t, decimal v) => _usdAmount += v)
            .Returns(() => Task.CompletedTask);

            _campaignInfoRepository
            .Setup(m => m.SaveLatestTransactionsAsync(It.IsAny <string>(), It.IsAny <string>()))
            .Returns(() => Task.CompletedTask);

            _campaignSettings = new CampaignSettings
            {
                PreSaleStartDateTimeUtc    = DateTime.UtcNow.AddDays(-15),
                PreSaleEndDateTimeUtc      = DateTime.UtcNow,
                PreSaleTotalTokensAmount   = 100000000,
                CrowdSaleStartDateTimeUtc  = DateTime.UtcNow,
                CrowdSaleEndDateTimeUtc    = DateTime.UtcNow.AddDays(21),
                CrowdSaleTotalTokensAmount = 360000000,
                TokenDecimals         = 4,
                MinInvestAmountUsd    = 1000,
                TokenBasePriceUsd     = 0.064M,
                HardCapUsd            = 1000000,
                EnableReferralProgram = true,
                ReferralCodeLength    = 6
            };

            _campaignSettingsRepository = new Mock <ICampaignSettingsRepository>();

            _campaignSettingsRepository
            .Setup(m => m.GetAsync())
            .Returns(() => Task.FromResult(_campaignSettings));

            _exRateClient = new Mock <IIcoExRateClient>();

            _exRateClient
            .Setup(m => m.GetAverageRate(It.IsAny <Pair>(), It.IsAny <DateTime>()))
            .Returns(() => Task.FromResult(new AverageRateResponse {
                AverageRate = exchangeRate
            }));

            _investor = new Investor()
            {
                Email             = investorEmail,
                ConfirmationToken = Guid.NewGuid(),
                AmountUsd         = _campaignSettings.MinInvestAmountUsd + 10
            };

            _investorRepository = new Mock <IInvestorRepository>();

            _investorRepository
            .Setup(m => m.GetAsync(It.Is <string>(v => !string.IsNullOrWhiteSpace(v) && v == investorEmail)))
            .Returns(() => Task.FromResult(_investor));

            _investorRepository
            .Setup(m => m.SaveReferralCode(It.IsAny <string>(), It.IsAny <string>()))
            .Returns(() => Task.CompletedTask);

            _investorAttributeRepository = new Mock <IInvestorAttributeRepository>();

            _investorAttributeRepository
            .Setup(m => m.SaveAsync(It.IsAny <InvestorAttributeType>(), It.IsAny <string>(), It.IsAny <string>()))
            .Returns(() => Task.CompletedTask);

            _investorAttributeRepository
            .Setup(m => m.GetInvestorEmailAsync(
                       It.IsIn(new InvestorAttributeType[] { InvestorAttributeType.PayInBtcAddress, InvestorAttributeType.PayInEthAddress }),
                       It.IsAny <string>()))
            .Returns(() => Task.FromResult(investorEmail));

            _investorAttributeRepository
            .Setup(m => m.GetInvestorEmailAsync(
                       It.IsIn(new InvestorAttributeType[] { InvestorAttributeType.ReferralCode }),
                       It.IsAny <string>()))
            .Returns(() => Task.FromResult(""));

            _privateInvestorAttributeRepository = new Mock <IPrivateInvestorAttributeRepository>();

            _privateInvestorAttributeRepository
            .Setup(m => m.GetInvestorEmailAsync(
                       It.IsIn(new PrivateInvestorAttributeType[] { PrivateInvestorAttributeType.ReferralCode }),
                       It.IsAny <string>()))
            .Returns(() => Task.FromResult(""));

            _investorTransaction = new InvestorTransaction {
            };

            _investorTransactionRepository = new Mock <IInvestorTransactionRepository>();

            _investorTransactionRepository
            .Setup(m => m.GetAsync(
                       It.Is <string>(v => !string.IsNullOrWhiteSpace(v) && v == "*****@*****.**"),
                       It.IsAny <string>()))
            .Returns(() => Task.FromResult(_investorTransaction));

            _investorTransactionRepository
            .Setup(m => m.SaveAsync(It.IsAny <IInvestorTransaction>()))
            .Returns(() => Task.CompletedTask);

            _investorRefundRepository = new Mock <IInvestorRefundRepository>();

            _investorRefundRepository
            .Setup(m => m.SaveAsync(It.IsAny <string>(), It.IsAny <InvestorRefundReason>(), It.IsAny <string>()))
            .Returns(() => Task.CompletedTask);

            _investmentMailSender = new Mock <IQueuePublisher <InvestorNewTransactionMessage> >();

            _investmentMailSender
            .Setup(m => m.SendAsync(It.IsAny <InvestorNewTransactionMessage>()))
            .Returns(() => Task.CompletedTask);

            _urlEncryptionService = new UrlEncryptionService("E546C8DF278CD5931069B522E695D4F2", "1234567890123456");
            _kycService           = new KycService(_campaignSettingsRepository.Object, _urlEncryptionService);

            _referralCodeService = new ReferralCodeService(_investorAttributeRepository.Object,
                                                           _privateInvestorAttributeRepository.Object);

            return(new TransactionService(
                       _log,
                       _exRateClient.Object,
                       _investorAttributeRepository.Object,
                       _campaignInfoRepository.Object,
                       _campaignSettingsRepository.Object,
                       _investorTransactionRepository.Object,
                       _investorRefundRepository.Object,
                       _investorRepository.Object,
                       _investmentMailSender.Object,
                       _kycService,
                       _referralCodeService,
                       "http://test-ito.valid.global/summary/{token}/overview"));
        }
        public static IList <TokenPrice> GetPriceList(ICampaignSettings settings, IInvestor investor,
                                                      DateTime txDateTimeUtc, decimal amountUsd, decimal currentTotal)
        {
            var tokenInfo = settings.GetTokenInfo(currentTotal, txDateTimeUtc);

            if (tokenInfo == null)
            {
                return(null);
            }

            var priceList  = new List <TokenPrice>();
            var tokenPhase = Enum.GetName(typeof(TokenPricePhase), tokenInfo.Phase);
            var tokens     = (amountUsd / tokenInfo.Price).RoundDown(settings.TokenDecimals);

            if (tokenInfo.Phase == TokenPricePhase.CrowdSaleInitial)
            {
                var tokensBelow = Consts.CrowdSale.InitialAmount - currentTotal;
                if (tokensBelow > 0M)
                {
                    if (tokens > tokensBelow)
                    {
                        // tokens below threshold
                        priceList.Add(new TokenPrice(tokensBelow, tokenInfo.Price, tokenPhase));

                        // tokens above threshold
                        var amountUsdAbove = amountUsd - (tokensBelow * tokenInfo.Price);
                        var priceAbove     = settings.GetTokenPrice(TokenPricePhase.CrowdSaleFirstDay);
                        var tokensAbove    = (amountUsdAbove / priceAbove).RoundDown(settings.TokenDecimals);

                        priceList.Add(new TokenPrice(tokensAbove, priceAbove, nameof(TokenPricePhase.CrowdSaleFirstDay)));

                        return(priceList);
                    }
                }
            }

            if (settings.EnableReferralProgram &&
                (tokenInfo.Phase == TokenPricePhase.CrowdSaleSecondWeek ||
                 tokenInfo.Phase == TokenPricePhase.CrowdSaleLastWeek))
            {
                if (settings.ReferralDiscount.HasValue && !string.IsNullOrEmpty(investor.ReferralCodeApplied))
                {
                    var tokenPriceReferral = settings.TokenBasePriceUsd * ((100 - settings.ReferralDiscount.Value) / 100);
                    var takenPhaseReferral = "ReferralDiscount";
                    var tokensReferral     = (amountUsd / tokenPriceReferral).RoundDown(settings.TokenDecimals);

                    priceList.Add(new TokenPrice(tokensReferral, tokenPriceReferral, takenPhaseReferral));

                    return(priceList);
                }

                if (settings.ReferralOwnerDiscount.HasValue && investor.ReferralsNumber > 0)
                {
                    var tokenPriceReferral = settings.TokenBasePriceUsd * ((100 - settings.ReferralOwnerDiscount.Value) / 100);
                    var takenPhaseReferral = "ReferralOwnerDiscount";
                    var tokensReferral     = (amountUsd / tokenPriceReferral).RoundDown(settings.TokenDecimals);

                    priceList.Add(new TokenPrice(tokensReferral, tokenPriceReferral, takenPhaseReferral));

                    return(priceList);
                }
            }

            priceList.Add(new TokenPrice(tokens, tokenInfo.Price, tokenPhase));

            return(priceList);
        }
 public CampaignToken(IAuthenticationService authenticationService, ICampaignSettings campaignSettings)
 {
     _authenticationService = authenticationService;
     _campaignSettings      = campaignSettings;
 }
Ejemplo n.º 15
0
 public CampaignSettingsEntity(ICampaignSettings campaignSettings)
 {
     TransactionQueueSasUrl = campaignSettings.TransactionQueueSasUrl;
     EmailBlackList         = campaignSettings.EmailBlackList;
     Smtp = campaignSettings.Smtp;
 }
 public ExtendedRecipientListService(IServiceClientFactory serviceClientFactory, IAuthenticationService authenticationService, ICacheService cacheService, ICampaignSettings campaignConfig)
     : base(serviceClientFactory, authenticationService, cacheService, campaignConfig)
 {
 }
Ejemplo n.º 17
0
        private async Task SendConfirmationEmail(InvestorTransaction tx, string link, ICampaignSettings settings)
        {
            try
            {
                var investor = await _investorRepository.GetAsync(tx.Email);

                var message = new InvestorNewTransactionMessage
                {
                    EmailTo = tx.Email,
                    InvestedAmountUsd = investor.AmountUsd.RoundDown(2),
                    InvestedAmountToken = investor.AmountToken.RoundDown(4),
                    TransactionAmount = tx.Amount,
                    TransactionAmountUsd = tx.AmountUsd.RoundDown(2),
                    TransactionAmountToken = tx.AmountToken.RoundDown(4),
                    TransactionFee = tx.Fee,
                    TransactionAsset = tx.Currency.ToAssetName(),
                    LinkToSummaryPage = _siteSummaryPageUrl.Replace("{token}", investor.ConfirmationToken.Value.ToString()),
                    LinkTransactionDetails = link,
                    MinAmount = settings.MinInvestAmountUsd,
                    MoreInvestmentRequired = investor.AmountUsd < settings.MinInvestAmountUsd
                };

                if (settings.KycEnableRequestSending &&
                    investor.KycRequestedUtc == null &&
                    investor.AmountUsd >= settings.MinInvestAmountUsd)
                {
                    var kycId = await SaveInvestorKyc(investor.Email);
                    var kycLink = await _kycService.GetKycLink(tx.Email, kycId);

                    message.KycRequired = true;
                    message.KycLink = kycLink;
                }

                await _log.WriteInfoAsync(nameof(SendConfirmationEmail),
                    $"message: {message.ToJson()}",
                    $"Send transaction confirmation message to queue");

                await _investmentMailSender.SendAsync(message);
            }
            catch (Exception ex)
            {
                await _log.WriteErrorAsync(nameof(SendConfirmationEmail),
                    $"Tx: {tx.ToJson()}, TxLink: {link}",
                    ex);
            }
        }