コード例 #1
0
        public async Task <ReferralStakesStatusUpdateErrorCode> TokensBurnAndReleaseAsync(string referralId, decimal?releaseBurnRatio = null)
        {
            if (string.IsNullOrEmpty(referralId))
            {
                throw new ArgumentNullException(nameof(referralId));
            }

            var newStatus = StakeStatus.TokensBurnAndReleaseStarted;

            var transactionError = await _transactionRunner.RunWithTransactionAsync(async txContext =>
            {
                var referralStake = await _referralStakesRepository.GetByReferralIdAsync(referralId, txContext);

                if (referralStake == null)
                {
                    return(ReferralStakesStatusUpdateErrorCode.DoesNotExist);
                }

                if (referralStake.Status != StakeStatus.TokensReservationSucceeded)
                {
                    return(ReferralStakesStatusUpdateErrorCode.InvalidStatus);
                }

                var customerWalletAddress =
                    await _pbfClient.CustomersApi.GetWalletAddress(Guid.Parse(referralStake.CustomerId));

                if (customerWalletAddress.Error == CustomerWalletAddressError.CustomerWalletMissing)
                {
                    return(ReferralStakesStatusUpdateErrorCode.CustomerWalletIsMissing);
                }

                var walletBlockStatus =
                    await _walletManagementClient.Api.GetCustomerWalletBlockStateAsync(referralStake.CustomerId);

                if (walletBlockStatus.Status == CustomerWalletActivityStatus.Blocked)
                {
                    return(ReferralStakesStatusUpdateErrorCode.CustomerWalletBlocked);
                }

                referralStake.Status           = newStatus;
                referralStake.ReleaseBurnRatio = releaseBurnRatio;

                var burnRatio = releaseBurnRatio ?? referralStake.ExpirationBurnRatio;

                var(amountToBurn, amountToRelease) =
                    CalculateAmountToBurnAndRelease(referralStake.Amount, burnRatio);

                var encodedData =
                    _blockchainEncodingService.EncodeDecreaseRequestData(customerWalletAddress.WalletAddress,
                                                                         amountToBurn, amountToRelease);

                var operationId = await AddBlockchainOperation(encodedData);

                await _stakesBlockchainDataRepository.UpsertAsync(referralId, operationId, txContext);

                await _referralStakesRepository.UpdateReferralStakeAsync(referralStake, txContext);

                return(ReferralStakesStatusUpdateErrorCode.None);
            });

            if (transactionError == ReferralStakesStatusUpdateErrorCode.None)
            {
                await PublishStatusUpdatedEvent(referralId, newStatus);
            }

            return(transactionError);
        }
コード例 #2
0
        public async Task <ReferralStakeRequestErrorCode> ReferralStakeAsync(ReferralStakeModel model)
        {
            #region Validation

            if (string.IsNullOrEmpty(model.CustomerId))
            {
                throw new ArgumentNullException(nameof(model.CustomerId));
            }

            if (string.IsNullOrEmpty(model.CampaignId))
            {
                throw new ArgumentNullException(nameof(model.CampaignId));
            }

            if (string.IsNullOrEmpty(model.ReferralId))
            {
                throw new ArgumentNullException(nameof(model.ReferralId));
            }

            if (model.Amount <= 0)
            {
                return(ReferralStakeRequestErrorCode.InvalidAmount);
            }

            if (model.WarningPeriodInDays < 0)
            {
                return(ReferralStakeRequestErrorCode.InvalidWarningPeriodInDays);
            }

            if (model.StakingPeriodInDays <= 0)
            {
                return(ReferralStakeRequestErrorCode.InvalidStakingPeriodInDays);
            }

            if (model.StakingPeriodInDays <= model.WarningPeriodInDays)
            {
                return(ReferralStakeRequestErrorCode.WarningPeriodShouldSmallerThanStakingPeriod);
            }

            if (model.ExpirationBurnRatio < 0 || model.ExpirationBurnRatio > 100)
            {
                return(ReferralStakeRequestErrorCode.InvalidBurnRatio);
            }

            var existingStake = await _referralStakesRepository.GetByReferralIdAsync(model.ReferralId);

            if (existingStake != null)
            {
                return(ReferralStakeRequestErrorCode.StakeAlreadyExist);
            }

            var customerProfile = await _customerProfileClient.CustomerProfiles.GetByCustomerIdAsync(model.CustomerId);

            if (customerProfile.ErrorCode == CustomerProfileErrorCodes.CustomerProfileDoesNotExist)
            {
                return(ReferralStakeRequestErrorCode.CustomerDoesNotExist);
            }

            var campaign = await _campaignClient.Campaigns.GetByIdAsync(model.CampaignId);

            if (campaign.ErrorCode == CampaignServiceErrorCodes.EntityNotFound)
            {
                return(ReferralStakeRequestErrorCode.CampaignDoesNotExist);
            }

            var walletBlockStatus =
                await _walletManagementClient.Api.GetCustomerWalletBlockStateAsync(model.CustomerId);

            if (walletBlockStatus.Status == CustomerWalletActivityStatus.Blocked)
            {
                return(ReferralStakeRequestErrorCode.CustomerWalletBlocked);
            }

            var isCustomerIdValidGuid = Guid.TryParse(model.CustomerId, out var customerIdGuid);

            if (!isCustomerIdValidGuid)
            {
                return(ReferralStakeRequestErrorCode.InvalidCustomerId);
            }

            var customerWalletAddress = await _pbfClient.CustomersApi.GetWalletAddress(customerIdGuid);

            if (customerWalletAddress.Error == CustomerWalletAddressError.CustomerWalletMissing)
            {
                return(ReferralStakeRequestErrorCode.CustomerWalletIsMissing);
            }

            var balance = await _pbfClient.CustomersApi.GetBalanceAsync(customerIdGuid);

            if (balance.Total < model.Amount)
            {
                return(ReferralStakeRequestErrorCode.NotEnoughBalance);
            }

            #endregion

            model.Status    = StakeStatus.TokensReservationStarted;
            model.Timestamp = DateTime.UtcNow;

            var encodedData =
                _blockchainEncodingService.EncodeStakeRequestData(customerWalletAddress.WalletAddress, model.Amount);

            var blockchainOperationId = await _pbfClient.OperationsApi.AddGenericOperationAsync(new GenericOperationRequest
            {
                Data          = encodedData,
                SourceAddress = _settingsService.GetMasterWalletAddress(),
                TargetAddress = _settingsService.GetTokenContractAddress()
            });

            return(await _transactionRunner.RunWithTransactionAsync(async txContext =>
            {
                await _referralStakesRepository.AddAsync(model, txContext);
                await _stakesBlockchainDataRepository.UpsertAsync(model.ReferralId, blockchainOperationId.OperationId.ToString(),
                                                                  txContext);

                return ReferralStakeRequestErrorCode.None;
            }));
        }