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

difftreelog

source

tests/src/nesting/unnest.test.ts7.2 KiBsourcehistory
1import {expect} from 'chai';2import {tokenIdToAddress} from '../eth/util/helpers';3import privateKey from '../substrate/privateKey';4import usingApi, {executeTransaction} from '../substrate/substrate-api';5import {6  createCollectionExpectSuccess,7  createItemExpectSuccess,8  getBalance,9  getTokenOwner,10  normalizeAccountId,11  setCollectionLimitsExpectSuccess,12  transferExpectSuccess,13  transferFromExpectSuccess,14} from '../util/helpers';15import {IKeyringPair} from '@polkadot/types/types';1617let alice: IKeyringPair;18let bob: IKeyringPair;1920describe('Integration Test: Unnesting', () => {21  before(async () => {22    await usingApi(async () => {23      alice = privateKey('//Alice');24      bob = privateKey('//Bob');25    });26  });2728  it('NFT: allows the owner to successfully unnest a token', async () => {29    await usingApi(async api => {30      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});31      await setCollectionLimitsExpectSuccess(alice, collection, {nestingRule: 'Owner'});32      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');33      const targetAddress = {Ethereum: tokenIdToAddress(collection, targetToken)};3435      // Create a nested token36      const nestedToken = await createItemExpectSuccess(alice, collection, 'NFT', targetAddress);3738      // Unnest39      await expect(executeTransaction(40        api,41        alice,42        api.tx.unique.transferFrom(normalizeAccountId(targetAddress), normalizeAccountId(alice), collection, nestedToken, 1),43      ), 'while unnesting').to.not.be.rejected;44      expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Substrate: alice.address});4546      // Nest and burn47      await transferExpectSuccess(collection, nestedToken, alice, targetAddress);48      await expect(executeTransaction(49        api,50        alice,51        api.tx.unique.burnFrom(collection, normalizeAccountId(targetAddress), nestedToken, 1),52      ), 'while burning').to.not.be.rejected;53      await expect(getTokenOwner(api, collection, nestedToken)).to.be.rejected;54    });55  });5657  it('Fungible: allows the owner to successfully unnest a token', async () => {58    await usingApi(async api => {59      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});60      await setCollectionLimitsExpectSuccess(alice, collection, {nestingRule: 'Owner'});61      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');62      const targetAddress = {Ethereum: tokenIdToAddress(collection, targetToken)};6364      const collectionFT = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});65      const nestedToken = await createItemExpectSuccess(alice, collectionFT, 'Fungible');6667      // Nest and unnest68      await transferExpectSuccess(collectionFT, nestedToken, alice, targetAddress, 1, 'Fungible');69      await transferFromExpectSuccess(collectionFT, nestedToken, alice, targetAddress, alice, 1, 'Fungible');7071      // Nest and burn72      await transferExpectSuccess(collectionFT, nestedToken, alice, targetAddress, 1, 'Fungible');73      const balanceBefore = await getBalance(api, collectionFT, normalizeAccountId(targetAddress), nestedToken);74      await expect(executeTransaction(75        api,76        alice,77        api.tx.unique.burnFrom(collectionFT, normalizeAccountId(targetAddress), nestedToken, 1),78      ), 'while burning').to.not.be.rejected;79      const balanceAfter = await getBalance(api, collectionFT, normalizeAccountId(targetAddress), nestedToken);80      expect(balanceAfter + BigInt(1)).to.be.equal(balanceBefore);81    });82  });8384  it('ReFungible: allows the owner to successfully unnest a token', async () => {85    await usingApi(async api => {86      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});87      await setCollectionLimitsExpectSuccess(alice, collection, {nestingRule: 'Owner'});88      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');89      const targetAddress = {Ethereum: tokenIdToAddress(collection, targetToken)};9091      const collectionRFT = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});92      const nestedToken = await createItemExpectSuccess(alice, collectionRFT, 'ReFungible');9394      // Nest and unnest95      await transferExpectSuccess(collectionRFT, nestedToken, alice, targetAddress, 1, 'ReFungible');96      await transferFromExpectSuccess(collectionRFT, nestedToken, alice, targetAddress, alice, 1, 'ReFungible');9798      // Nest and burn99      await transferExpectSuccess(collectionRFT, nestedToken, alice, targetAddress, 1, 'ReFungible');100      await expect(executeTransaction(101        api,102        alice,103        api.tx.unique.burnFrom(collectionRFT, normalizeAccountId(targetAddress), nestedToken, 1),104      ), 'while burning').to.not.be.rejected;105      const balance = await getBalance(api, collectionRFT, normalizeAccountId(targetAddress), nestedToken);106      expect(balance).to.be.equal(0n);107    });108  });109});110111describe('Negative Test: Unnesting', () => {112  before(async () => {113    await usingApi(async () => {114      alice = privateKey('//Alice');115      bob = privateKey('//Bob');116    });117  });118119  it('Disallows a non-owner to unnest/burn a token', async () => {120    await usingApi(async api => {121      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});122      await setCollectionLimitsExpectSuccess(alice, collection, {nestingRule: 'Owner'});123      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');124      const targetAddress = {Ethereum: tokenIdToAddress(collection, targetToken)};125126      // Create a nested token127      const nestedToken = await createItemExpectSuccess(alice, collection, 'NFT', targetAddress);128129      // Try to unnest130      await expect(executeTransaction(131        api,132        bob,133        api.tx.unique.transferFrom(normalizeAccountId(targetAddress), normalizeAccountId(bob), collection, nestedToken, 1),134      ), 'while unnesting').to.be.rejectedWith(/^common\.ApprovedValueTooLow$/);135      expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, targetToken).toLowerCase()});136137      // Try to burn138      await expect(executeTransaction(139        api,140        bob,141        api.tx.unique.burnFrom(collection, normalizeAccountId(bob.address), nestedToken, 1),142      ), 'while burning').to.not.be.rejectedWith(/^common\.ApprovedValueTooLow$/);143      expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, targetToken).toLowerCase()});144    });145  });146147  // todo another test for creating excessive depth matryoshka with Ethereum?148149  // Recursive nesting150  it('Prevents Ouroboros creation', async () => {151    const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});152    await setCollectionLimitsExpectSuccess(alice, collection, {nestingRule: 'Owner'});153    const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');154155    // Create a nested token ouroboros156    const nestedToken = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: tokenIdToAddress(collection, targetToken)});157    expect(transferExpectSuccess(collection, targetToken, alice, {Ethereum: tokenIdToAddress(collection, nestedToken)})).to.be.rejectedWith(/^structure\.OuroborosDetected$/);158  });159});