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

difftreelog

source

tests/src/confirmSponsorship.test.ts13.3 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 chai from 'chai';18import chaiAsPromised from 'chai-as-promised';19import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync} from './substrate/substrate-api';20import {21  createCollectionExpectSuccess,22  setCollectionSponsorExpectSuccess,23  destroyCollectionExpectSuccess,24  confirmSponsorshipExpectSuccess,25  confirmSponsorshipExpectFailure,26  createItemExpectSuccess,27  findUnusedAddress,28  getGenericResult,29  enableAllowListExpectSuccess,30  enablePublicMintingExpectSuccess,31  addToAllowListExpectSuccess,32  normalizeAccountId,33  addCollectionAdminExpectSuccess,34  getCreatedCollectionCount,35  UNIQUE,36  requirePallets,37  Pallets,38} from './util/helpers';39import {IKeyringPair} from '@polkadot/types/types';40import {usingPlaygrounds} from './util/playgrounds';4142chai.use(chaiAsPromised);43const expect = chai.expect;4445let donor: IKeyringPair;4647before(async () => {48  await usingPlaygrounds(async (_, privateKey) => {49    donor = privateKey('//Alice');50  });51});5253let alice: IKeyringPair;54let bob: IKeyringPair;55let charlie: IKeyringPair;5657describe('integration test: ext. confirmSponsorship():', () => {5859  before(async () => {60    await usingPlaygrounds(async (helper) => {61      [alice, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 0n], donor);62    });63  });6465  it('Confirm collection sponsorship', async () => {66    await usingPlaygrounds(async (helper) => {67      const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});68      await collection.setSponsor(alice, bob.address);69      await collection.confirmSponsorship(bob);70    });71  });7273  it('Add sponsor to a collection after the same sponsor was already added and confirmed', async () => {74    await usingPlaygrounds(async (helper) => {75      const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});76      await collection.setSponsor(alice, bob.address);77      await collection.confirmSponsorship(bob);78      await collection.setSponsor(alice, bob.address);79    });80  });81  it('Add new sponsor to a collection after another sponsor was already added and confirmed', async () => {82    await usingPlaygrounds(async (helper) => {83      const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});84      await collection.setSponsor(alice, bob.address);85      await collection.confirmSponsorship(charlie);86    });87  });8889  it('NFT: Transfer fees are paid by the sponsor after confirmation', async () => {90    await usingPlaygrounds(async (helper) => {91      const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});92      await collection.setSponsor(alice, bob.address);93      await collection.confirmSponsorship(bob);94      const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);95      const token = await collection.mintToken(alice, {Substrate: charlie.address});96      await token.transfer(charlie, {Substrate: alice.address});97      const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);98      expect(bobBalanceAfter < bobBalanceBefore).to.be.true;99    });100  });101102  it('Fungible: Transfer fees are paid by the sponsor after confirmation', async () => {103    await usingPlaygrounds(async (helper) => {104      const collection = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'}, 0);105      await collection.setSponsor(alice, bob.address);106      await collection.confirmSponsorship(bob);107      const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);108      await collection.mint(alice, {Substrate: charlie.address}, 100n);109      await collection.transfer(charlie, {Substrate: alice.address}, 1n);110      const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);111      expect(bobBalanceAfter < bobBalanceBefore).to.be.true;112    });113  });114115  it('ReFungible: Transfer fees are paid by the sponsor after confirmation', async function() {116    await usingPlaygrounds(async (helper) => {117      const collection = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});118      await collection.setSponsor(alice, bob.address);119      await collection.confirmSponsorship(bob);120      const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);121      const token = await collection.mintToken(alice, {Substrate: charlie.address}, 100n);122      await token.transfer(charlie, {Substrate: alice.address}, 1n);123      const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);124      expect(bobBalanceAfter < bobBalanceBefore).to.be.true;125    });126  });127128  it('CreateItem fees are paid by the sponsor after confirmation', async () => {129    await usingPlaygrounds(async (helper) => {130      const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});131      await collection.setSponsor(alice, bob.address);132      await collection.confirmSponsorship(bob);133      await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});134      await collection.addToAllowList(alice, {Substrate: charlie.address});135136      const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);137      await collection.mintToken(charlie, {Substrate: charlie.address});138      const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);139140      expect(bobBalanceAfter < bobBalanceBefore).to.be.true;141    });142  });143144  it('NFT: Sponsoring of transfers is rate limited', async () => {145    await usingPlaygrounds(async (helper) => {146      const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});147      await collection.setSponsor(alice, bob.address);148      await collection.confirmSponsorship(bob);149150      const token = await collection.mintToken(alice, {Substrate: alice.address});151      await token.transfer(alice, {Substrate: charlie.address});152      const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);153154      const transferTx = async () => token.transfer(charlie, {Substrate: alice.address});155      await expect(transferTx()).to.be.rejectedWith('Inability to pay some fees');156      const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);157158      expect(bobBalanceAfter === bobBalanceBefore).to.be.true;159    });160  });161162  it('Fungible: Sponsoring is rate limited', async () => {163    await usingPlaygrounds(async (helper) => {164      const collection = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});165      await collection.setSponsor(alice, bob.address);166      await collection.confirmSponsorship(bob);167168      await collection.mint(alice, {Substrate: charlie.address}, 100n);169      await collection.transfer(charlie, {Substrate: charlie.address}, 1n);170      const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);171172      const transferTx = async () => collection.transfer(charlie, {Substrate: charlie.address});173      await expect(transferTx()).to.be.rejected;174      const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);175176      expect(bobBalanceAfter === bobBalanceBefore).to.be.true;177    });178  });179180  it('ReFungible: Sponsoring is rate limited', async function() {181    await usingPlaygrounds(async (helper) => {182      const collection = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});183      await collection.setSponsor(alice, bob.address);184      await collection.confirmSponsorship(bob);185186      const token = await collection.mintToken(alice, {Substrate: charlie.address}, 100n);187      await token.transfer(charlie, {Substrate: alice.address});188189      const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);190      const transferTx = async () => token.transfer(charlie, {Substrate: alice.address});191      await expect(transferTx()).to.be.rejectedWith('Inability to pay some fees');192      const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);193194      expect(bobBalanceAfter === bobBalanceBefore).to.be.true;195    });196  });197198  it('NFT: Sponsoring of createItem is rate limited', async () => {199    await usingPlaygrounds(async (helper) => {200      const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});201      await collection.setSponsor(alice, bob.address);202      await collection.confirmSponsorship(bob);203      await collection.setPermissions(alice, {mintMode: true, access: 'AllowList'});204      await collection.addToAllowList(alice, {Substrate: charlie.address});205206      await collection.mintToken(charlie, {Substrate: charlie.address});207208      const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);209      const mintTx = async () => collection.mintToken(charlie, {Substrate: charlie.address});210      await expect(mintTx()).to.be.rejectedWith('Inability to pay some fees');211      const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);212213      expect(bobBalanceAfter === bobBalanceBefore).to.be.true;214    });215  });216});217218describe('(!negative test!) integration test: ext. confirmSponsorship():', () => {219  before(async () => {220    await usingApi(async (api, privateKeyWrapper) => {221      alice = privateKeyWrapper('//Alice');222      bob = privateKeyWrapper('//Bob');223      charlie = privateKeyWrapper('//Charlie');224    });225  });226227  it('(!negative test!) Confirm sponsorship for a collection that never existed', async () => {228    // Find the collection that never existed229    let collectionId = 0;230    await usingApi(async (api) => {231      collectionId = await getCreatedCollectionCount(api) + 1;232    });233234    await confirmSponsorshipExpectFailure(collectionId, '//Bob');235  });236237  it('(!negative test!) Confirm sponsorship using a non-sponsor address', async () => {238    const collectionId = await createCollectionExpectSuccess();239    await setCollectionSponsorExpectSuccess(collectionId, bob.address);240241    await usingApi(async (api) => {242      const transfer = api.tx.balances.transfer(charlie.address, 1e15);243      await submitTransactionAsync(alice, transfer);244    });245246    await confirmSponsorshipExpectFailure(collectionId, '//Charlie');247  });248249  it('(!negative test!) Confirm sponsorship using owner address', async () => {250    const collectionId = await createCollectionExpectSuccess();251    await setCollectionSponsorExpectSuccess(collectionId, bob.address);252    await confirmSponsorshipExpectFailure(collectionId, '//Alice');253  });254255  it('(!negative test!) Confirm sponsorship by collection admin', async () => {256    const collectionId = await createCollectionExpectSuccess();257    await setCollectionSponsorExpectSuccess(collectionId, bob.address);258    await addCollectionAdminExpectSuccess(alice, collectionId, charlie.address);259    await confirmSponsorshipExpectFailure(collectionId, '//Charlie');260  });261262  it('(!negative test!) Confirm sponsorship without sponsor being set with setCollectionSponsor', async () => {263    const collectionId = await createCollectionExpectSuccess();264    await confirmSponsorshipExpectFailure(collectionId, '//Bob');265  });266267  it('(!negative test!) Confirm sponsorship in a collection that was destroyed', async () => {268    const collectionId = await createCollectionExpectSuccess();269    await destroyCollectionExpectSuccess(collectionId);270    await confirmSponsorshipExpectFailure(collectionId, '//Bob');271  });272273  it('(!negative test!) Transfer fees are not paid by the sponsor if the transfer failed', async () => {274    const collectionId = await createCollectionExpectSuccess();275    await setCollectionSponsorExpectSuccess(collectionId, bob.address);276    await confirmSponsorshipExpectSuccess(collectionId, '//Bob');277278    await usingApi(async (api, privateKeyWrapper) => {279      // Find unused address280      const ownerZeroBalance = await findUnusedAddress(api, privateKeyWrapper);281282      // Find another unused address283      const senderZeroBalance = await findUnusedAddress(api, privateKeyWrapper);284285      // Mint token for an unused address286      const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', ownerZeroBalance.address);287288      const sponsorBalanceBeforeTx = (await api.query.system.account(bob.address)).data.free.toBigInt();289290      // Try to transfer this token from an unsponsored unused adress to Alice291      const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(alice.address), collectionId, itemId, 0);292      await expect(submitTransactionExpectFailAsync(senderZeroBalance, zeroToAlice)).to.be.rejected;293294      const sponsorBalanceAfterTx = (await api.query.system.account(bob.address)).data.free.toBigInt();295296      expect(sponsorBalanceAfterTx).to.equal(sponsorBalanceBeforeTx);297    });298  });299});