public void Transfer_WhenPassedValidAmount_TransfersTokensCorrectly( int mintAmount, int transferAmount) { Address from = this.addresses[0]; Address to = this.addresses[1]; this.MintTokens(mintAmount, from); this.MintTokens(mintAmount, to); BigInteger balanceFromBeforeTransfer = this.GetBalanceOf(from).TotalBalance; BigInteger balanceToBeforeTransfer = this.GetBalanceOf(to).TotalBalance; this.TransferTokens(transferAmount, from, to); IReadOnlyTaggedTokens balanceFromAfterTransfer = this.GetBalanceOf(from); IReadOnlyTaggedTokens balanceOfToAfterTransfer = this.GetBalanceOf(to); Assert.Equal( balanceFromBeforeTransfer - transferAmount, balanceFromAfterTransfer.TotalBalance); Assert.Equal( balanceToBeforeTransfer + transferAmount, balanceOfToAfterTransfer.TotalBalance); }
public void Pick_WhenRequestedLessThanOwnedTokens_ReturnsCorrectAmount(int mintAmount, int pickAmount) { IReadOnlyTaggedTokens tokens = this.fungibleTagger.Tag(this.defaultAddress, mintAmount); IReadOnlyTaggedTokens pickedTokens = this.fungiblePicker.Pick(tokens, pickAmount); Assert.Equal(pickAmount, pickedTokens.TotalBalanceByTag(FungibleTokenTagger.TokenTag)); }
public void RemoveFromBalance(IReadOnlyTaggedTokens tokens) { foreach ((string tag, BigInteger amount) in tokens) { this.RemoveFromBalance(tag, amount); } }
private void RemoveFromBalances(IReadOnlyTaggedTokens tokens, Address holder) { this.Balances[holder].RemoveFromBalance(tokens); if (this.Balances[holder].TotalBalance == 0) { this.Balances.Remove(holder); } }
private void AddToBalances(IReadOnlyTaggedTokens tokens, Address holder) { if (!this.Balances.ContainsKey(holder)) { this.Balances[holder] = new TaggedTokens(); } this.Balances[holder].AddToBalance(tokens); }
private void NotifyReceived(IReadOnlyTaggedTokens tokens, Address from, Address to) { this.SendMessage(to, TokensReceivedEvent.Type, new Dictionary <string, object>() { { TokensReceivedEvent.TokensTransfered, tokens.GetState() }, { TokensReceivedEvent.TokensTotal, this.GetBalances(to).GetState() }, { TokensReceivedEvent.From, from?.ToString() }, }); }
public void TaggedBalance_WhenTokenManagerHasBeenInstantiated_ShouldHaveAllBalancesToZero() { IDictionary <string, object> balances = this.registry.GetContract(this.tokenManager).GetState().GetDictionary("Balances"); Assert.Equal(0, balances.Count); this.addresses.ForEach(address => { IReadOnlyTaggedTokens balance = this.GetBalanceOf(address); Assert.Equal(0, balance.TotalBalance); }); }
private void Mint(BigInteger amount, Address to) { if (amount <= 0) { throw new NonPositiveTokenAmountException(nameof(amount), amount); } IReadOnlyTaggedTokens newTokens = this.TokenTagger.Tag(to, amount); this.AddToBalances(newTokens, to); this.NotifyReceived(newTokens, null, to); }
public void Burn_WhenPassedValidArguments_BurnsCorrectly(int mintAmount, int burnAmount) { Address address = this.addresses[0]; this.MintTokens(mintAmount, address); BigInteger balanceBeforeBurn = this.GetBalanceOf(address).TotalBalance; this.BurnTokens(burnAmount, address); IReadOnlyTaggedTokens balanceAfterBurn = this.GetBalanceOf(address); Assert.Equal(balanceBeforeBurn - burnAmount, balanceAfterBurn.TotalBalance); }
private void Burn(BigInteger amount, Address from, ITokenPicker customPicker = null) { if (amount <= 0) { throw new NonPositiveTokenAmountException(nameof(amount), amount); } customPicker = customPicker ?? this.DefaultTokenPicker; IReadOnlyTaggedTokens tokensToBurn = customPicker.Pick(this.GetBalances(from), amount); this.RemoveFromBalances(tokensToBurn, from); }
protected override void Split(Address tokenManager, IReadOnlyTaggedTokens availableTokens) { if (tokenManager.Equals(this.BurnTokenManager)) { this.SendMessage(this.Exchanger, ExchangeAction.Type, new Dictionary <string, object>() { { ExchangeAction.Amount, availableTokens.TotalBalance.ToString() }, { ExchangeAction.FromTokenManager, this.BurnTokenManager.ToString() }, { ExchangeAction.ToTokenManager, this.MintTokenManager.ToString() }, }); } else { base.Split(tokenManager, availableTokens); } }
private void Transfer(BigInteger amount, Address from, Address to, ITokenPicker customPicker = null) { if (from.Equals(to)) { throw new ArgumentException("Addresses can't transfer to themselves"); } if (amount <= 0) { throw new NonPositiveTokenAmountException(nameof(amount), amount); } customPicker = customPicker ?? this.DefaultTokenPicker; IReadOnlyTaggedTokens tokensToTransfer = customPicker.Pick(this.GetBalances(from), amount); this.RemoveFromBalances(tokensToTransfer, from); this.AddToBalances(tokensToTransfer, to); this.NotifyReceived(tokensToTransfer, from, to); }
public IReadOnlyTaggedTokens Pick(IReadOnlyTaggedTokens tokens, BigInteger amount) { if (amount < 0) { throw new NonPositiveTokenAmountException(nameof(amount), amount); } BigInteger availableTokens = tokens.TotalBalanceByTag(TokenTag); if (availableTokens < amount) { throw new InsufficientTokenAmountException(nameof(amount), availableTokens, amount); } var pickedTokens = new ReadOnlyTaggedTokens(new SortedDictionary <string, BigInteger> { [TokenTag] = amount, }); return(pickedTokens); }
protected override void Split(Address tokenManager, IReadOnlyTaggedTokens availableTokens) { if (this.Recipients.Count <= 0) { return; } BigInteger splitAmount = availableTokens.TotalBalance / this.Recipients.Count; if (splitAmount <= 0) { return; } foreach (Address recipient in this.Recipients) { this.SendMessage(tokenManager, TransferAction.Type, new Dictionary <string, object>() { { TransferAction.To, recipient.ToString() }, { TransferAction.Amount, splitAmount.ToString() }, }); } }
protected override void Split(IReadOnlyTaggedTokens receivedTokens, object recipients) { var employeesToHours = (SortedDictionary <Address, decimal>)recipients; decimal hours = employeesToHours.Sum(x => x.Value); BigInteger splitBase = receivedTokens.TotalBalance / (BigInteger)hours; if (splitBase <= 0) { return; } foreach ((Address employee, var employeeHours) in employeesToHours) { BigInteger amount = splitBase * (BigInteger)employeeHours; var transferAction = new TransferAction( string.Empty, this.TokenManager, amount, this.Address, employee); this.OnSend(transferAction); } }
public ReadOnlyTaggedTokens(IReadOnlyTaggedTokens tokens) { this.Copy(tokens); }
public TaggedTokens(IReadOnlyTaggedTokens tokens) : base(tokens) { }
protected abstract void Split(Address tokenManager, IReadOnlyTaggedTokens availableTokens);
public void Pick_WhenPassedNegativeAmount_Throws(int mintAmount, int pickAmount) { IReadOnlyTaggedTokens tokens = this.fungibleTagger.Tag(this.defaultAddress, mintAmount); Assert.Throws <NonPositiveTokenAmountException>(() => this.fungiblePicker.Pick(tokens, pickAmount)); }
public void Pick_WhenRequestedMoreThanOwnedTokens_Throws(int mintAmount, int pickAmount) { IReadOnlyTaggedTokens tokens = this.fungibleTagger.Tag(this.defaultAddress, mintAmount); Assert.Throws <InsufficientTokenAmountException>(() => this.fungiblePicker.Pick(tokens, pickAmount)); }
public void Tag_WhenPassedValidAddressAndAmount_TagsTokensEvenly(int amount) { IReadOnlyTaggedTokens tokens = this.fungibleTagger.Tag(this.defaultAddress, amount); Assert.Equal(amount, tokens.TotalBalanceByTag(FungibleTokenTagger.TokenTag)); }