git.delta.rocks / unique-network / refs/heads / master

difftreelog

source

js-packages/tests/creditFeesToTreasury.seqtest.ts7.8 KiBsourcehistory
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import type {IKeyringPair} from '@polkadot/types/types';18import {ApiPromise} from '@polkadot/api';19import {usingPlaygrounds, expect, itSub} from '@unique/test-utils/util.js';20import type {u32} from '@polkadot/types-codec';21import { itEth } from '@unique/test-utils/eth/util.js';22import { ITransactionResult } from '@unique-nft/playgrounds/types';2324const TREASURY = '5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z';25const saneMinimumFee = 0.05;26const saneMaximumFee = 0.5;27const createCollectionDeposit = 100;2829// Skip the inflation block pauses if the block is close to inflation block30// until the inflation happens31/*eslint no-async-promise-executor: "off"*/32function skipInflationBlock(api: ApiPromise): Promise<void> {33  const promise = new Promise<void>(async (resolve) => {34    const inflationBlockInterval = api.consts.inflation.inflationBlockInterval as u32;35    const blockInterval = inflationBlockInterval.toNumber();36    const unsubscribe = await api.rpc.chain.subscribeNewHeads(head => {37      const currentBlock = head.number.toNumber();38      if(currentBlock % blockInterval < blockInterval - (blockInterval / 5)) {39        unsubscribe();40        resolve();41      } else {42        console.log(`Skipping inflation block, current block: ${currentBlock}`);43      }44    });45  });4647  return promise;48}4950describe('integration test: Fees must be credited to Treasury:', () => {51  let alice: IKeyringPair;52  let bob: IKeyringPair;5354  before(async () => {55    await usingPlaygrounds(async (helper, privateKey) => {56      const donor = await privateKey({url: import.meta.url});57      [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);58    });59  });6061  itSub('Total issuance does not change', async ({helper}) => {62    const api = helper.getApi();63    await skipInflationBlock(api);64    await helper.wait.newBlocks(1);6566    const totalBefore = (await helper.callRpc('api.query.balances.totalIssuance', [])).toBigInt();6768    await helper.balance.transferToSubstrate(alice, bob.address, 1n);6970    const totalAfter = (await helper.callRpc('api.query.balances.totalIssuance', [])).toBigInt();7172    expect(totalAfter).to.be.equal(totalBefore);73  });7475  itSub('Sender balance decreased by fee+sent amount, Treasury balance increased by fee', async ({helper}) => {76    await skipInflationBlock(helper.getApi());77    await helper.wait.newBlocks(1);7879    const treasuryBalanceBefore = await helper.balance.getSubstrate(TREASURY);80    const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);8182    const amount = 1n;83    await helper.balance.transferToSubstrate(alice, bob.address, amount);8485    const treasuryBalanceAfter = await helper.balance.getSubstrate(TREASURY);86    const aliceBalanceAfter = await helper.balance.getSubstrate(alice.address);8788    const fee = aliceBalanceBefore - aliceBalanceAfter - amount;89    const treasuryIncrease = treasuryBalanceAfter - treasuryBalanceBefore;9091    expect(treasuryIncrease).to.be.equal(fee);92  });9394  itSub('Treasury balance increased by failed tx fee', async ({helper}) => {95    const api = helper.getApi();96    await helper.wait.newBlocks(1);9798    const treasuryBalanceBefore = await helper.balance.getSubstrate(TREASURY);99    const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);100101    await expect(helper.signTransaction(bob, api.tx.balances.forceSetBalance(alice.address, 0))).to.be.rejected;102103    const treasuryBalanceAfter = await helper.balance.getSubstrate(TREASURY);104    const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);105106    const fee = bobBalanceBefore - bobBalanceAfter;107    const treasuryIncrease = treasuryBalanceAfter - treasuryBalanceBefore;108109    expect(treasuryIncrease).to.be.equal(fee);110  });111112  itSub('NFT Transactions also send fees to Treasury', async ({helper}) => {113    await skipInflationBlock(helper.getApi());114    await helper.wait.newBlocks(1);115116    const treasuryBalanceBefore = await helper.balance.getSubstrate(TREASURY);117    const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);118119    await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});120121    const treasuryBalanceAfter = await helper.balance.getSubstrate(TREASURY);122    const aliceBalanceAfter = await helper.balance.getSubstrate(alice.address);123    const fee = aliceBalanceBefore - aliceBalanceAfter;124    const treasuryIncrease = treasuryBalanceAfter - treasuryBalanceBefore;125126    expect(treasuryIncrease).to.be.equal(fee);127  });128129  itSub('Fees are sane', async ({helper}) => {130    const unique = helper.balance.getOneTokenNominal();131    await skipInflationBlock(helper.getApi());132    await helper.wait.newBlocks(1);133134    const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);135136    await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});137138    const aliceBalanceAfter = await helper.balance.getSubstrate(alice.address);139    const fee = aliceBalanceBefore - aliceBalanceAfter;140141    expect(fee / unique < BigInt(Math.ceil(saneMaximumFee + createCollectionDeposit))).to.be.true;142    expect(fee / unique < BigInt(Math.ceil(saneMinimumFee  + createCollectionDeposit))).to.be.true;143  });144145  itSub('NFT Transfer fee is close to 0.1 Unique', async ({helper}) => {146    await skipInflationBlock(helper.getApi());147    await helper.wait.newBlocks(1);148149    const collection = await helper.nft.mintCollection(alice, {150      name: 'test',151      description: 'test',152      tokenPrefix: 'test',153    });154    // const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');155    const token = await collection.mintToken(alice, {Substrate: alice.address});156157    const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);158    await token.transfer(alice, {Substrate: bob.address});159    const aliceBalanceAfter = await helper.balance.getSubstrate(alice.address);160161    const fee = Number(aliceBalanceBefore - aliceBalanceAfter) / Number(helper.balance.getOneTokenNominal());162    const expectedTransferFee = 0.1;163    // fee drifts because of NextFeeMultiplier164    const tolerance = 0.001;165166    expect(Math.abs(fee - expectedTransferFee)).to.be.lessThan(tolerance);167  });168   169  itEth('Evm Transactions send fees to Treasury', async ({helper}) => {170    const value = helper.balance.getOneTokenNominal();171    const gasPrice = await helper.getWeb3().eth.getGasPrice();172    let result = null;173    174    const lambda = async () => {175      result = await helper.executeExtrinsic(alice, 'api.tx.evm.call', [176        helper.address.substrateToEth(alice.address),177        helper.address.substrateToEth(bob.address),178        '0x',179        value,180        25_000,181        gasPrice,182        null,183        null,184        [],185      ]);186    };187    188    const totalPaid = await helper.arrange.calculcateFee({ Substrate: alice.address }, lambda);189    const evmFees = totalPaid - value;190    191    const treasuryDepoosited = (result as unknown as ITransactionResult).result.events192      .filter(({ event: { method, section } }) => section == 'treasury' && method == 'Deposit')193      .map(({ event: { data } }) => data[0].toJSON());194    195    const deposit = BigInt(treasuryDepoosited[0]);196  197    expect(deposit).to.be.equal(evmFees);198  });199  200});