Example #1
0
    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);
    }
Example #2
0
    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);
    }
Example #3
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);
    }
Example #5
0
    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 ^^^^
    }