private DistributedProfitsInfo UpdateDistributedProfits(DistributeProfitsInput input, Address profitsReceivingVirtualAddress, long totalShares) { var balance = State.TokenContract.GetBalance.Call(new GetBalanceInput { Owner = profitsReceivingVirtualAddress, Symbol = input.Symbol }).Balance; var distributedProfitsInformation = State.DistributedProfitsMap[profitsReceivingVirtualAddress]; if (distributedProfitsInformation == null) { distributedProfitsInformation = new DistributedProfitsInfo { TotalShares = totalShares, ProfitsAmount = { { input.Symbol, input.Amount.Add(balance) } }, IsReleased = true }; } else { // This means someone used `DistributeProfits` do donate to the specific account period of current profit item. distributedProfitsInformation.TotalShares = totalShares; distributedProfitsInformation.ProfitsAmount[input.Symbol] = balance.Add(input.Amount); distributedProfitsInformation.IsReleased = true; } State.DistributedProfitsMap[profitsReceivingVirtualAddress] = distributedProfitsInformation; return(distributedProfitsInformation); }
/// <summary> /// Just burn balance in general ledger. /// </summary> /// <param name="period"></param> /// <param name="profitsMap"></param> /// <param name="scheme"></param> /// <param name="profitsReceivingVirtualAddress"></param> /// <returns></returns> private Empty BurnProfits(long period, Dictionary <string, long> profitsMap, Scheme scheme, Address profitsReceivingVirtualAddress) { Context.LogDebug(() => "going to Burn Profits."); scheme.CurrentPeriod = period.Add(1); var distributedProfitsInfo = new DistributedProfitsInfo { IsReleased = true }; foreach (var profits in profitsMap) { var symbol = profits.Key; var amount = profits.Value; if (amount > 0) { var balanceOfToken = State.TokenContract.GetBalance.Call(new GetBalanceInput { Owner = scheme.VirtualAddress, Symbol = symbol }); if (balanceOfToken.Balance < amount) { continue; } State.TokenContract.TransferFrom.Send(new TransferFromInput { From = scheme.VirtualAddress, To = Context.Self, Amount = amount, Symbol = symbol }); State.TokenContract.Burn.Send(new BurnInput { Amount = amount, Symbol = symbol }); distributedProfitsInfo.AmountsMap.Add(symbol, -amount); } } State.SchemeInfos[scheme.SchemeId] = scheme; State.DistributedProfitsMap[profitsReceivingVirtualAddress] = distributedProfitsInfo; return(new Empty()); }
public override Empty ContributeProfits(ContributeProfitsInput input) { Assert(input.Symbol != null && input.Symbol.Any(), "Invalid token symbol."); if (input.Symbol == null) { return(new Empty()); // Just to avoid IDE warning. } var scheme = State.SchemeInfos[input.SchemeId]; Assert(scheme != null, "Scheme not found."); if (scheme == null) { return(new Empty()); // Just to avoid IDE warning. } var virtualAddress = Context.ConvertVirtualAddressToContractAddress(input.SchemeId); if (input.Period == 0) { State.TokenContract.TransferFrom.Send(new TransferFromInput { From = Context.Sender, To = virtualAddress, Symbol = input.Symbol, Amount = input.Amount, Memo = $"Add {input.Amount} dividends for {input.SchemeId}." }); if (!scheme.UndistributedProfits.ContainsKey(input.Symbol)) { scheme.UndistributedProfits.Add(input.Symbol, input.Amount); } else { scheme.UndistributedProfits[input.Symbol] = scheme.UndistributedProfits[input.Symbol].Add(input.Amount); } State.SchemeInfos[input.SchemeId] = scheme; } else { var distributedPeriodProfitsVirtualAddress = GetDistributedPeriodProfitsVirtualAddress(virtualAddress, input.Period); var distributedProfitsInformation = State.DistributedProfitsMap[distributedPeriodProfitsVirtualAddress]; if (distributedProfitsInformation == null) { distributedProfitsInformation = new DistributedProfitsInfo { ProfitsAmount = { { input.Symbol, input.Amount } } }; } else { Assert(!distributedProfitsInformation.IsReleased, $"Scheme of period {input.Period} already released."); distributedProfitsInformation.ProfitsAmount[input.Symbol] = distributedProfitsInformation.ProfitsAmount[input.Symbol].Add(input.Amount); } State.TokenContract.TransferFrom.Send(new TransferFromInput { From = Context.Sender, To = distributedPeriodProfitsVirtualAddress, Symbol = input.Symbol, Amount = input.Amount, Memo = $"Add dividends for {input.SchemeId} (period {input.Period})." }); State.DistributedProfitsMap[distributedPeriodProfitsVirtualAddress] = distributedProfitsInformation; } return(new Empty()); }
public override Empty ContributeProfits(ContributeProfitsInput input) { Assert(!string.IsNullOrEmpty(input.Symbol), "Invalid token symbol."); Assert(input.Amount > 0, "Amount need to greater than 0."); var scheme = State.SchemeInfos[input.SchemeId]; Assert(scheme != null, "Scheme not found."); // ReSharper disable once PossibleNullReferenceException var virtualAddress = scheme.VirtualAddress; if (input.Period == 0) { if (State.TokenContract.Value == null) { State.TokenContract.Value = Context.GetContractAddressByName(SmartContractConstants.TokenContractSystemName); } State.TokenContract.TransferFrom.Send(new TransferFromInput { From = Context.Sender, To = virtualAddress, Symbol = input.Symbol, Amount = input.Amount, Memo = $"Add {input.Amount} dividends." }); } else { Assert(input.Period >= scheme.CurrentPeriod, "Invalid contributing period."); var distributedPeriodProfitsVirtualAddress = GetDistributedPeriodProfitsVirtualAddress(virtualAddress, input.Period); var distributedProfitsInformation = State.DistributedProfitsMap[distributedPeriodProfitsVirtualAddress]; if (distributedProfitsInformation == null) { distributedProfitsInformation = new DistributedProfitsInfo { AmountsMap = { { input.Symbol, input.Amount } } }; } else { Assert(!distributedProfitsInformation.IsReleased, $"Scheme of period {input.Period} already released."); distributedProfitsInformation.AmountsMap[input.Symbol] = distributedProfitsInformation.AmountsMap[input.Symbol].Add(input.Amount); } State.TokenContract.TransferFrom.Send(new TransferFromInput { From = Context.Sender, To = distributedPeriodProfitsVirtualAddress, Symbol = input.Symbol, Amount = input.Amount, }); State.DistributedProfitsMap[distributedPeriodProfitsVirtualAddress] = distributedProfitsInformation; } // If someone directly use virtual address to do the contribution, won't sense the token symbol he was using. if (!scheme.ReceivedTokenSymbols.Contains(input.Symbol)) { scheme.ReceivedTokenSymbols.Add(input.Symbol); } State.SchemeInfos[scheme.SchemeId] = scheme; return(new Empty()); }
public override Empty ContributeProfits(ContributeProfitsInput input) { Assert(input.Symbol != null && input.Symbol.Any(), "Invalid token symbol."); Assert(input.Amount > 0, "Amount need to greater than 0."); var scheme = State.SchemeInfos[input.SchemeId]; Assert(scheme != null, "Scheme not found."); var virtualAddress = Context.ConvertVirtualAddressToContractAddress(input.SchemeId); if (input.Period == 0) { State.TokenContract.TransferFrom.Send(new TransferFromInput { From = Context.Sender, To = virtualAddress, Symbol = input.Symbol, Amount = input.Amount, Memo = $"Add {input.Amount} dividends." }); // ReSharper disable once PossibleNullReferenceException // ReSharper disable once AssignNullToNotNullAttribute if (!scheme.UndistributedProfits.ContainsKey(input.Symbol)) { scheme.UndistributedProfits.Add(input.Symbol, input.Amount); } else { scheme.UndistributedProfits[input.Symbol] = scheme.UndistributedProfits[input.Symbol].Add(input.Amount); } State.SchemeInfos[input.SchemeId] = scheme; } else { var distributedPeriodProfitsVirtualAddress = GetDistributedPeriodProfitsVirtualAddress(virtualAddress, input.Period); var distributedProfitsInformation = State.DistributedProfitsMap[distributedPeriodProfitsVirtualAddress]; if (distributedProfitsInformation == null) { distributedProfitsInformation = new DistributedProfitsInfo { ProfitsAmount = { { input.Symbol, input.Amount } } }; } else { Assert(!distributedProfitsInformation.IsReleased, $"Scheme of period {input.Period} already released."); distributedProfitsInformation.ProfitsAmount[input.Symbol] = distributedProfitsInformation.ProfitsAmount[input.Symbol].Add(input.Amount); } State.TokenContract.TransferFrom.Send(new TransferFromInput { From = Context.Sender, To = distributedPeriodProfitsVirtualAddress, Symbol = input.Symbol, Amount = input.Amount, }); State.DistributedProfitsMap[distributedPeriodProfitsVirtualAddress] = distributedProfitsInformation; } return(new Empty()); }