public override Empty ReceiveProfits(ReceiveProfitsInput input)
        {
            var profitReceivingInformation = State.ProfitReceivingInfos[input.ContractAddress];

            Assert(profitReceivingInformation.ProfitReceiverAddress == Context.Sender,
                   "Only profit receiver can perform this action.");
            foreach (var symbol in input.Symbols.Except(TokenContractConstants.ResourceTokenSymbols))
            {
                var profits = State.Balances[input.ContractAddress][symbol];
                State.Balances[input.ContractAddress][symbol] = 0;
                var donates = profits.Mul(profitReceivingInformation.DonationPartsPerHundred).Div(100);
                State.Balances[Context.Self][symbol] = State.Balances[Context.Self][symbol].Add(donates);
                if (State.TreasuryContract.Value != null)
                {
                    // Main Chain.
                    State.TreasuryContract.Donate.Send(new DonateInput
                    {
                        Symbol = symbol,
                        Amount = donates
                    });
                }
                else
                {
                    // Side Chain.
                    Transfer(new TransferInput
                    {
                        To     = Context.GetContractAddressByName(SmartContractConstants.ConsensusContractSystemName),
                        Amount = donates,
                        Symbol = symbol
                    });
                }

                State.Balances[profitReceivingInformation.ProfitReceiverAddress][symbol] =
                    State.Balances[profitReceivingInformation.ProfitReceiverAddress][symbol].Add(profits.Sub(donates));
            }

            return(new Empty());
        }
        public override Empty ReceiveProfits(ReceiveProfitsInput input)
        {
            var profitReceivingInformation = State.ProfitReceivingInfos[input.ContractAddress];

            Assert(profitReceivingInformation.ProfitReceiverAddress == Context.Sender,
                   "Only profit Beneficiary can perform this action.");
            foreach (var symbol in input.Symbols.Except(TokenContractConstants.ResourceTokenSymbols))
            {
                var profits = State.Balances[input.ContractAddress][symbol];
                State.Balances[input.ContractAddress][symbol] = 0;
                var donates = profits.Mul(profitReceivingInformation.DonationPartsPerHundred).Div(100);
                State.Balances[Context.Self][symbol] = State.Balances[Context.Self][symbol].Add(donates);
                State.TreasuryContract.Donate.Send(new DonateInput
                {
                    Symbol = symbol,
                    Amount = donates
                });
                State.Balances[profitReceivingInformation.ProfitReceiverAddress][symbol] =
                    State.Balances[profitReceivingInformation.ProfitReceiverAddress][symbol].Add(profits.Sub(donates));
            }

            return(new Empty());
        }
        public override Empty ReceiveProfits(ReceiveProfitsInput input)
        {
            var profitReceivingInformation = State.ProfitReceivingInfos[input.ContractAddress];

            Assert(profitReceivingInformation.ProfitReceiverAddress == Context.Sender,
                   "Only profit receiver can perform this action.");
            Assert(
                !Context.Variables.GetStringArray(TokenContractConstants.PayRentalSymbolListName)
                .Union(Context.Variables.GetStringArray(TokenContractConstants.PayTxFeeSymbolListName))
                .Contains(input.Symbol), "Invalid token symbol.");
            var contractBalance = GetBalance(input.ContractAddress, input.Symbol);

            Assert(input.Amount <= contractBalance, "Invalid profit amount.");
            var profits = input.Amount == 0 ? contractBalance : input.Amount;

            ModifyBalance(input.ContractAddress, input.Symbol, -profits);
            var donates = profits.Mul(profitReceivingInformation.DonationPartsPerHundred).Div(100);

            if (State.TreasuryContract.Value != null)
            {
                // Main Chain.
                // Increase balance of Token Contract then distribute donates.
                ModifyBalance(Context.Self, input.Symbol, donates);
                State.TreasuryContract.Donate.Send(new DonateInput
                {
                    Symbol = input.Symbol,
                    Amount = donates
                });
            }
            else
            {
                // Side Chain.
                var consensusContractAddress =
                    Context.GetContractAddressByName(SmartContractConstants.ConsensusContractSystemName);
                ModifyBalance(consensusContractAddress, input.Symbol, donates);
            }

            var actualProfits = profits.Sub(donates);

            ModifyBalance(profitReceivingInformation.ProfitReceiverAddress, input.Symbol, actualProfits);

            if (State.TokenHolderContract.Value == null)
            {
                var tokenHolderContractAddress =
                    Context.GetContractAddressByName(SmartContractConstants.TokenHolderContractSystemName);
                if (tokenHolderContractAddress == null)
                {
                    return(new Empty());
                }

                State.TokenHolderContract.Value = tokenHolderContractAddress;
            }

            // Distribute token holders profits.
            State.TokenHolderContract.DistributeProfits.Send(new DistributeProfitsInput
            {
                SchemeManager = input.ContractAddress,
            });

            return(new Empty());
        }