git.delta.rocks / unique-network / refs/commits / ef7fe00096da

difftreelog

source

js-packages/tests/transfer.test.ts16.7 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 {itEth, usingEthPlaygrounds} from './eth/util/index.js';19import {itSub, Pallets, usingPlaygrounds, expect} from './util/index.js';20import {NON_EXISTENT_COLLECTION_ID} from '@unique/playgrounds/types.js';2122describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {23  let donor: IKeyringPair;24  let alice: IKeyringPair;25  let bob: IKeyringPair;2627  before(async () => {28    await usingPlaygrounds(async (helper, privateKey) => {29      donor = await privateKey({url: import.meta.url});30      [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);31    });32  });3334  itSub('Balance transfers and check balance', async ({helper}) => {35    const alicesBalanceBefore = await helper.balance.getSubstrate(alice.address);36    const bobsBalanceBefore = await helper.balance.getSubstrate(bob.address);3738    expect(await helper.balance.transferToSubstrate(alice, bob.address, 1n)).to.be.true;3940    const alicesBalanceAfter = await helper.balance.getSubstrate(alice.address);41    const bobsBalanceAfter = await helper.balance.getSubstrate(bob.address);4243    expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;44    expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;45  });4647  itSub('Inability to pay fees error message is correct', async ({helper}) => {48    const [zero] = await helper.arrange.createAccounts([0n], donor);4950    // console.error = () => {};51    // The following operation throws an error into the console and the logs. Pay it no heed as long as the test succeeds.52    await expect(helper.balance.transferToSubstrate(zero, donor.address, 1n))53      .to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');54  });5556  itSub('[nft] User can transfer owned token', async ({helper}) => {57    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-1-NFT', description: '', tokenPrefix: 'T'});58    const nft = await collection.mintToken(alice);5960    await nft.transfer(alice, {Substrate: bob.address});61    expect(await nft.getOwner()).to.be.deep.equal({Substrate: bob.address});62  });6364  itSub('[fungible] User can transfer owned token', async ({helper}) => {65    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-1-FT', description: '', tokenPrefix: 'T'});66    await collection.mint(alice, 10n);6768    await collection.transfer(alice, {Substrate: bob.address}, 9n);69    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);70    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);71  });7273  itSub.ifWithPallets('[refungible] User can transfer owned token', [Pallets.ReFungible], async ({helper}) => {74    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});75    const rft = await collection.mintToken(alice, 10n);7677    await rft.transfer(alice, {Substrate: bob.address}, 9n);78    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);79    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);80  });8182  itSub('[nft] Collection admin can transfer owned token', async ({helper}) => {83    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-2-NFT', description: '', tokenPrefix: 'T'});84    await collection.addAdmin(alice, {Substrate: bob.address});8586    const nft = await collection.mintToken(bob, {Substrate: bob.address});87    await nft.transfer(bob, {Substrate: alice.address});8889    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});90  });9192  itSub('[fungible] Collection admin can transfer owned token', async ({helper}) => {93    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-2-FT', description: '', tokenPrefix: 'T'});94    await collection.addAdmin(alice, {Substrate: bob.address});9596    await collection.mint(bob, 10n, {Substrate: bob.address});97    await collection.transfer(bob, {Substrate: alice.address}, 1n);9899    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);100    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);101  });102103  itSub.ifWithPallets('[refungible] Collection admin can transfer owned token', [Pallets.ReFungible], async ({helper}) => {104    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-2-RFT', description: '', tokenPrefix: 'T'});105    await collection.addAdmin(alice, {Substrate: bob.address});106107    const rft = await collection.mintToken(bob, 10n, {Substrate: bob.address});108    await rft.transfer(bob, {Substrate: alice.address}, 1n);109110    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);111    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);112  });113});114115describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {116  let alice: IKeyringPair;117  let bob: IKeyringPair;118119  before(async () => {120    await usingPlaygrounds(async (helper, privateKey) => {121      const donor = await privateKey({url: import.meta.url});122      [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);123    });124  });125126127  itSub('[nft] Transfer with not existed collection_id', async ({helper}) => {128    await expect(helper.nft.transferToken(alice, NON_EXISTENT_COLLECTION_ID, 1, {Substrate: bob.address}))129      .to.be.rejectedWith(/common\.CollectionNotFound/);130  });131132  itSub('[fungible] Transfer with not existed collection_id', async ({helper}) => {133    await expect(helper.ft.transfer(alice, NON_EXISTENT_COLLECTION_ID, {Substrate: bob.address}))134      .to.be.rejectedWith(/common\.CollectionNotFound/);135  });136137  itSub.ifWithPallets('[refungible] Transfer with not existed collection_id', [Pallets.ReFungible], async ({helper}) => {138    await expect(helper.rft.transferToken(alice, NON_EXISTENT_COLLECTION_ID, 1, {Substrate: bob.address}))139      .to.be.rejectedWith(/common\.CollectionNotFound/);140  });141142  itSub('[nft] Transfer with deleted collection_id', async ({helper}) => {143    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-1-NFT', description: '', tokenPrefix: 'T'});144    const nft = await collection.mintToken(alice);145146    await nft.burn(alice);147    await collection.burn(alice);148149    await expect(nft.transfer(alice, {Substrate: bob.address}))150      .to.be.rejectedWith(/common\.CollectionNotFound/);151  });152153  itSub('[fungible] Transfer with deleted collection_id', async ({helper}) => {154    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-1-FT', description: '', tokenPrefix: 'T'});155    await collection.mint(alice, 10n);156157    await collection.burnTokens(alice, 10n);158    await collection.burn(alice);159160    await expect(collection.transfer(alice, {Substrate: bob.address}))161      .to.be.rejectedWith(/common\.CollectionNotFound/);162  });163164  itSub.ifWithPallets('[refungible] Transfer with deleted collection_id', [Pallets.ReFungible], async ({helper}) => {165    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-1-RFT', description: '', tokenPrefix: 'T'});166    const rft = await collection.mintToken(alice, 10n);167168    await rft.burn(alice, 10n);169    await collection.burn(alice);170171    await expect(rft.transfer(alice, {Substrate: bob.address}))172      .to.be.rejectedWith(/common\.CollectionNotFound/);173  });174175  itSub('[nft] Transfer with not existed item_id', async ({helper}) => {176    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-2-NFT', description: '', tokenPrefix: 'T'});177    await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))178      .to.be.rejectedWith(/common\.TokenNotFound/);179  });180181  itSub('[fungible] Transfer with not existed item_id', async ({helper}) => {182    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-2-FT', description: '', tokenPrefix: 'T'});183    await expect(collection.transfer(alice, {Substrate: bob.address}))184      .to.be.rejectedWith(/common\.TokenValueTooLow/);185  });186187  itSub.ifWithPallets('[refungible] Transfer with not existed item_id', [Pallets.ReFungible], async ({helper}) => {188    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-2-RFT', description: '', tokenPrefix: 'T'});189    await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))190      .to.be.rejectedWith(/common\.TokenValueTooLow/);191  });192193  itSub('Zero transfer NFT', async ({helper}) => {194    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-3-NFT', description: '', tokenPrefix: 'T'});195    const tokenAlice = await collection.mintToken(alice, {Substrate: alice.address});196    const tokenBob = await collection.mintToken(alice, {Substrate: bob.address});197    // 1. Zero transfer of own tokens allowed:198    await helper.executeExtrinsic(alice, 'api.tx.unique.transfer', [{Substrate: bob.address}, collection.collectionId, tokenAlice.tokenId, 0]);199    // 2. Zero transfer of non-owned tokens not allowed:200    await expect(helper.executeExtrinsic(alice, 'api.tx.unique.transfer', [{Substrate: alice.address}, collection.collectionId, tokenBob.tokenId, 0])).to.be.rejectedWith('common.NoPermission');201    // 3. Zero transfer of non-existing tokens not allowed:202    await expect(helper.executeExtrinsic(alice, 'api.tx.unique.transfer', [{Substrate: alice.address}, collection.collectionId, 10, 0])).to.be.rejectedWith('common.TokenNotFound');203    expect(await tokenAlice.getOwner()).to.deep.eq({Substrate: alice.address});204    expect(await tokenBob.getOwner()).to.deep.eq({Substrate: bob.address});205    // 4. Storage is not corrupted:206    await tokenAlice.transfer(alice, {Substrate: bob.address});207    await tokenBob.transfer(bob, {Substrate: alice.address});208    expect(await tokenAlice.getOwner()).to.deep.eq({Substrate: bob.address});209    expect(await tokenBob.getOwner()).to.deep.eq({Substrate: alice.address});210  });211212  itSub('[nft] Transfer with deleted item_id', async ({helper}) => {213    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-3-NFT', description: '', tokenPrefix: 'T'});214    const nft = await collection.mintToken(alice);215216    await nft.burn(alice);217218    await expect(nft.transfer(alice, {Substrate: bob.address}))219      .to.be.rejectedWith(/common\.TokenNotFound/);220  });221222  itSub('[fungible] Transfer with deleted item_id', async ({helper}) => {223    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-3-FT', description: '', tokenPrefix: 'T'});224    await collection.mint(alice, 10n);225226    await collection.burnTokens(alice, 10n);227228    await expect(collection.transfer(alice, {Substrate: bob.address}))229      .to.be.rejectedWith(/common\.TokenValueTooLow/);230  });231232  itSub.ifWithPallets('[refungible] Transfer with deleted item_id', [Pallets.ReFungible], async ({helper}) => {233    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-3-RFT', description: '', tokenPrefix: 'T'});234    const rft = await collection.mintToken(alice, 10n);235236    await rft.burn(alice, 10n);237238    await expect(rft.transfer(alice, {Substrate: bob.address}))239      .to.be.rejectedWith(/common\.TokenValueTooLow/);240  });241242  itSub('[nft] Transfer with recipient that is not owner', async ({helper}) => {243    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-4-NFT', description: '', tokenPrefix: 'T'});244    const nft = await collection.mintToken(alice);245246    await expect(nft.transfer(bob, {Substrate: bob.address}))247      .to.be.rejectedWith(/common\.NoPermission/);248    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});249  });250251  itSub('[fungible] Transfer with recipient that is not owner', async ({helper}) => {252    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-4-FT', description: '', tokenPrefix: 'T'});253    await collection.mint(alice, 10n);254255    await expect(collection.transfer(bob, {Substrate: bob.address}, 9n))256      .to.be.rejectedWith(/common\.TokenValueTooLow/);257    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(0n);258    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(10n);259  });260261  itSub.ifWithPallets('[refungible] Transfer with recipient that is not owner', [Pallets.ReFungible], async ({helper}) => {262    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});263    const rft = await collection.mintToken(alice, 10n);264265    await expect(rft.transfer(bob, {Substrate: bob.address}, 9n))266      .to.be.rejectedWith(/common\.TokenValueTooLow/);267    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(0n);268    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(10n);269  });270});271272describe('Transfers to self (potentially over substrate-evm boundary)', () => {273  let donor: IKeyringPair;274275  before(async function() {276    await usingEthPlaygrounds(async (_, privateKey) => {277      donor = await privateKey({url: import.meta.url});278    });279  });280281  itEth('Transfers to self. In case of same frontend', async ({helper}) => {282    const [owner] = await helper.arrange.createAccounts([10n], donor);283    const collection = await helper.ft.mintCollection(owner, {});284    await collection.mint(owner, 100n);285286    const ownerProxy = helper.address.substrateToEth(owner.address);287288    // transfer to own proxy289    await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);290    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);291    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);292293    // transfer-from own proxy to own proxy again294    await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Ethereum: ownerProxy}, 5n);295    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);296    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);297  });298299  itEth('Transfers to self. In case of substrate-evm boundary', async ({helper}) => {300    const [owner] = await helper.arrange.createAccounts([10n], donor);301    const collection = await helper.ft.mintCollection(owner, {});302    await collection.mint(owner, 100n);303304    const ownerProxy = helper.address.substrateToEth(owner.address);305306    // transfer to own proxy307    await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);308    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);309    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);310311    // transfer-from own proxy to self312    await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Substrate: owner.address}, 5n);313    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(95n);314    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(5n);315  });316317  itEth('Transfers to self. In case of inside substrate-evm', async ({helper}) => {318    const [owner] = await helper.arrange.createAccounts([10n], donor);319    const collection = await helper.ft.mintCollection(owner, {});320    await collection.mint(owner, 100n);321322    // transfer to self again323    await collection.transfer(owner, {Substrate: owner.address}, 10n);324    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);325326    // transfer-from self to self again327    await collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 5n);328    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);329  });330331  itEth('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({helper}) => {332    const [owner] = await helper.arrange.createAccounts([10n], donor);333    const collection = await helper.ft.mintCollection(owner, {});334    await collection.mint(owner, 10n);335336    // transfer to self again337    await expect(collection.transfer(owner, {Substrate: owner.address}, 11n))338      .to.be.rejectedWith(/common\.TokenValueTooLow/);339340    // transfer-from self to self again341    await expect(collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 12n))342      .to.be.rejectedWith(/common\.TokenValueTooLow/);343    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(10n);344  });345});