public async Task CanLimitTokenAutoAssociation() { await using var fxAccount = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.AutoAssociationLimit = 1); await using var fxToken1 = await TestToken.CreateAsync(_network, fx => fx.Params.GrantKycEndorsement = null); await using var fxToken2 = await TestToken.CreateAsync(_network, fx => fx.Params.GrantKycEndorsement = null); await AssertHg.TokenNotAssociatedAsync(fxToken1, fxAccount); await AssertHg.TokenNotAssociatedAsync(fxToken2, fxAccount); var xferAmount1 = fxToken1.Params.Circulation / 2; var receipt = await fxToken1.Client.TransferTokensAsync(fxToken1, fxToken1.TreasuryAccount, fxAccount, (long)xferAmount1, fxToken1.TreasuryAccount); Assert.Equal(ResponseCode.Success, receipt.Status); var tex = await Assert.ThrowsAsync <TransactionException>(async() => { var xferAmount2 = fxToken2.Params.Circulation / 2; var receipt2 = await fxToken2.Client.TransferTokensAsync(fxToken2, fxToken2.TreasuryAccount, fxAccount, (long)xferAmount2, fxToken2.TreasuryAccount); }); Assert.Equal(ResponseCode.NoRemainingAutomaticAssociations, tex.Status); Assert.StartsWith("Unable to execute transfers, status: NoRemainingAutomaticAssociations", tex.Message); await AssertHg.TokenIsAssociatedAsync(fxToken1, fxAccount); await AssertHg.TokenNotAssociatedAsync(fxToken2, fxAccount); await AssertHg.TokenBalanceAsync(fxToken1, fxAccount, xferAmount1); }
public async Task CanDeleteAccountHavingTokenBalance() { await using var fxAccount1 = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 120_00_000_000); await using var fxAccount2 = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.InitialBalance = 120_00_000_000); await using var fxToken = await TestToken.CreateAsync(_network, fx => fx.Params.GrantKycEndorsement = null, fxAccount1, fxAccount2); var xferAmount = (long)fxToken.Params.Circulation; await AssertHg.TokenBalanceAsync(fxToken, fxAccount1, 0); await AssertHg.TokenBalanceAsync(fxToken, fxAccount2, 0); await AssertHg.TokenBalanceAsync(fxToken, fxToken.TreasuryAccount, fxToken.Params.Circulation); await fxAccount1.Client.TransferTokensAsync(fxToken, fxToken.TreasuryAccount, fxAccount1, xferAmount, fxToken.TreasuryAccount); await AssertHg.TokenBalanceAsync(fxToken, fxAccount1, fxToken.Params.Circulation); await AssertHg.TokenBalanceAsync(fxToken, fxAccount2, 0); await AssertHg.TokenBalanceAsync(fxToken, fxToken.TreasuryAccount, 0); // Can't delete the account because it has tokens associated with it. var tex = await Assert.ThrowsAsync <TransactionException>(async() => { await fxAccount1.Client.DeleteAccountAsync(fxAccount1, fxAccount2, fxAccount1.PrivateKey); }); Assert.Equal(ResponseCode.TransactionRequiresZeroTokenBalances, tex.Status); Assert.StartsWith("Unable to delete account, status: TransactionRequiresZeroTokenBalances", tex.Message); await AssertHg.TokenBalanceAsync(fxToken, fxAccount1, fxToken.Params.Circulation); await AssertHg.TokenBalanceAsync(fxToken, fxAccount2, 0); await AssertHg.TokenBalanceAsync(fxToken, fxToken.TreasuryAccount, 0); await fxAccount1.Client.TransferTokensAsync(fxToken, fxAccount1, fxAccount2, xferAmount, fxAccount1); await fxAccount1.Client.DeleteAccountAsync(fxAccount1, fxAccount2, fxAccount1.PrivateKey); await AssertHg.TokenBalanceAsync(fxToken, fxAccount2, fxToken.Params.Circulation); await AssertHg.TokenBalanceAsync(fxToken, fxToken.TreasuryAccount, 0); }
public async Task CanRaiseLimitTokenAutoAssociation() { await using var fxAccount = await TestAccount.CreateAsync(_network, fx => fx.CreateParams.AutoAssociationLimit = 1); await using var fxToken1 = await TestToken.CreateAsync(_network, fx => fx.Params.GrantKycEndorsement = null); await using var fxToken2 = await TestToken.CreateAsync(_network, fx => fx.Params.GrantKycEndorsement = null); await AssertHg.TokenNotAssociatedAsync(fxToken1, fxAccount); await AssertHg.TokenNotAssociatedAsync(fxToken2, fxAccount); var xferAmount1 = fxToken1.Params.Circulation / 2; var receipt = await fxToken1.Client.TransferTokensAsync(fxToken1, fxToken1.TreasuryAccount, fxAccount, (long)xferAmount1, fxToken1.TreasuryAccount); Assert.Equal(ResponseCode.Success, receipt.Status); await fxAccount.Client.UpdateAccountAsync(new UpdateAccountParams { Address = fxAccount, AutoAssociationLimit = 2, Signatory = fxAccount }); var xferAmount2 = fxToken2.Params.Circulation / 2; var receipt2 = await fxToken2.Client.TransferTokensAsync(fxToken2, fxToken2.TreasuryAccount, fxAccount, (long)xferAmount2, fxToken2.TreasuryAccount); Assert.Equal(ResponseCode.Success, receipt2.Status); await AssertHg.TokenIsAssociatedAsync(fxToken1, fxAccount); await AssertHg.TokenIsAssociatedAsync(fxToken2, fxAccount); await AssertHg.TokenBalanceAsync(fxToken1, fxAccount, xferAmount1); await AssertHg.TokenBalanceAsync(fxToken2, fxAccount, xferAmount2); }
async Task TransferringAssetAppliesSingleFixedCommision() { await using var fxBuyer = await TestAccount.CreateAsync(_network); await using var fxSeller = await TestAccount.CreateAsync(_network); await using var fxBenefactor = await TestAccount.CreateAsync(_network); await using var fxPaymentToken = await TestToken.CreateAsync(_network, fx => fx.Params.GrantKycEndorsement = null, fxBenefactor, fxBuyer, fxSeller); await using var fxAsset = await TestAsset.CreateAsync(_network, fx => { fx.Params.Royalties = new FixedRoyalty[] { new FixedRoyalty(fxBenefactor, fxPaymentToken, 10) }; fx.Params.GrantKycEndorsement = null; }, fxBuyer, fxSeller); Assert.Equal(ResponseCode.Success, fxAsset.Record.Status); var movedAsset = new Asset(fxAsset, 1); await fxPaymentToken.Client.TransferTokensAsync(fxPaymentToken, fxPaymentToken.TreasuryAccount, fxBuyer, 100, fxPaymentToken.TreasuryAccount); await fxPaymentToken.Client.TransferAssetAsync(movedAsset, fxAsset.TreasuryAccount, fxSeller, fxAsset.TreasuryAccount); await AssertHg.AssetBalanceAsync(fxAsset, fxBuyer, 0); await AssertHg.AssetBalanceAsync(fxAsset, fxSeller, 1); await AssertHg.AssetBalanceAsync(fxAsset, fxBenefactor, 0); await AssertHg.AssetBalanceAsync(fxAsset, fxAsset.TreasuryAccount, fxAsset.Metadata.Length - 1); await AssertHg.AssetBalanceAsync(fxAsset, fxPaymentToken.TreasuryAccount, 0); await AssertHg.TokenBalanceAsync(fxPaymentToken, fxBuyer, 100); await AssertHg.TokenBalanceAsync(fxPaymentToken, fxSeller, 0); await AssertHg.TokenBalanceAsync(fxPaymentToken, fxBenefactor, 0); await AssertHg.TokenBalanceAsync(fxPaymentToken, fxAsset.TreasuryAccount, 0); await AssertHg.TokenBalanceAsync(fxPaymentToken, fxPaymentToken.TreasuryAccount, fxPaymentToken.Params.Circulation - 100); var record = await fxAsset.Client.TransferWithRecordAsync(new TransferParams { AssetTransfers = new[] { new AssetTransfer(movedAsset, fxSeller, fxBuyer) }, TokenTransfers = new[] { new TokenTransfer(fxPaymentToken, fxBuyer, -100), new TokenTransfer(fxPaymentToken, fxSeller, 100), }, Signatory = new Signatory(fxBuyer, fxSeller) }); Assert.Equal(ResponseCode.Success, record.Status); Assert.False(record.Hash.IsEmpty); Assert.NotNull(record.Concensus); Assert.NotNull(record.CurrentExchangeRate); Assert.NotNull(record.NextExchangeRate); Assert.Empty(record.Memo); Assert.InRange(record.Fee, 0UL, ulong.MaxValue); Assert.Equal(_network.Payer, record.Id.Address); Assert.Equal(3, record.TokenTransfers.Count); Assert.Contains(new TokenTransfer(fxPaymentToken, fxBuyer, -100), record.TokenTransfers); Assert.Contains(new TokenTransfer(fxPaymentToken, fxSeller, 90), record.TokenTransfers); Assert.Contains(new TokenTransfer(fxPaymentToken, fxBenefactor, 10), record.TokenTransfers); Assert.Single(record.AssetTransfers); Assert.Contains(new AssetTransfer(movedAsset, fxSeller, fxBuyer), record.AssetTransfers); Assert.Empty(record.Associations); Assert.Single(record.Royalties); AssertHg.ContainsRoyalty(fxPaymentToken, fxSeller, fxBenefactor, 10, record.Royalties); await AssertHg.AssetBalanceAsync(fxAsset, fxBuyer, 1); await AssertHg.AssetBalanceAsync(fxAsset, fxSeller, 0); await AssertHg.AssetBalanceAsync(fxAsset, fxBenefactor, 0); await AssertHg.AssetBalanceAsync(fxAsset, fxAsset.TreasuryAccount, fxAsset.Metadata.Length - 1); await AssertHg.AssetBalanceAsync(fxAsset, fxPaymentToken.TreasuryAccount, 0); await AssertHg.TokenBalanceAsync(fxPaymentToken, fxBuyer, 0); await AssertHg.TokenBalanceAsync(fxPaymentToken, fxSeller, 90); await AssertHg.TokenBalanceAsync(fxPaymentToken, fxBenefactor, 10); await AssertHg.TokenBalanceAsync(fxPaymentToken, fxAsset.TreasuryAccount, 0); await AssertHg.TokenBalanceAsync(fxPaymentToken, fxPaymentToken.TreasuryAccount, fxPaymentToken.Params.Circulation - 100); }
public async Task CanScheduleBurnTokenCoins() { await using var fxPayer = await TestAccount.CreateAsync(_network, ctx => ctx.CreateParams.InitialBalance = 40_00_000_000); await using var fxToken = await TestToken.CreateAsync(_network); var amountToDestory = fxToken.Params.Circulation / 3 + 1; var expectedCirculation = fxToken.Params.Circulation - amountToDestory; var pendingReceipt = await fxToken.Client.BurnTokenAsync( fxToken, amountToDestory, new Signatory( fxToken.SupplyPrivateKey, new PendingParams { PendingPayer = fxPayer })); Assert.Equal(ResponseCode.Success, pendingReceipt.Status); // This should be considered a network bug. Assert.Equal(0UL, pendingReceipt.Circulation); await AssertHg.TokenBalanceAsync(fxToken, fxToken.TreasuryAccount, fxToken.Params.Circulation); var signingReceipt = await fxPayer.Client.SignPendingTransactionAsync(pendingReceipt.Pending.Id, fxPayer.PrivateKey); Assert.Equal(ResponseCode.Success, signingReceipt.Status); var executedReceipt = await fxPayer.Client.GetReceiptAsync(pendingReceipt.Pending.TxId) as TokenReceipt; Assert.Equal(ResponseCode.Success, executedReceipt.Status); Assert.Equal(expectedCirculation, executedReceipt.Circulation); var executedRecord = await fxPayer.Client.GetTransactionRecordAsync(pendingReceipt.Pending.TxId) as TokenRecord; Assert.Equal(ResponseCode.Success, executedRecord.Status); Assert.Equal(expectedCirculation, executedRecord.Circulation); await AssertHg.TokenBalanceAsync(fxToken, fxToken.TreasuryAccount, expectedCirculation); var info = await fxToken.Client.GetTokenInfoAsync(fxToken); Assert.Equal(fxToken.Record.Token, info.Token); Assert.Equal(fxToken.Params.Symbol, info.Symbol); Assert.Equal(fxToken.TreasuryAccount.Record.Address, info.Treasury); Assert.Equal(expectedCirculation, info.Circulation); Assert.Equal(fxToken.Params.Decimals, info.Decimals); Assert.Equal(fxToken.Params.Ceiling, info.Ceiling); Assert.Equal(fxToken.Params.Administrator, info.Administrator); Assert.Equal(fxToken.Params.GrantKycEndorsement, info.GrantKycEndorsement); Assert.Equal(fxToken.Params.SuspendEndorsement, info.SuspendEndorsement); Assert.Equal(fxToken.Params.ConfiscateEndorsement, info.ConfiscateEndorsement); Assert.Equal(fxToken.Params.SupplyEndorsement, info.SupplyEndorsement); Assert.Equal(fxToken.Params.RoyaltiesEndorsement, info.RoyaltiesEndorsement); Assert.Equal(TokenTradableStatus.Tradable, info.TradableStatus); Assert.Equal(TokenTradableStatus.Tradable, info.PauseStatus); Assert.Equal(TokenKycStatus.Revoked, info.KycStatus); Assert.Empty(info.Royalties); Assert.False(info.Deleted); Assert.Equal(fxToken.Params.Memo, info.Memo); // NETWORK V0.21.0 UNSUPPORTED vvvv // NOT IMPLEMENTED YET Assert.Empty(info.Ledger.ToArray()); // NETWORK V0.21.0 UNSUPPORTED ^^^^ }