1234567891011121314151617import {IKeyringPair} from '@polkadot/types/types';18import {expect, itSub, Pallets, requirePalletsOrSkip, usingPlaygrounds} from '../../util';1920describe('Refungible nesting', () => {21 let alice: IKeyringPair;22 let charlie: IKeyringPair;2324 before(async function() {25 await usingPlaygrounds(async (helper, privateKey) => {26 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);27 const donor = await privateKey({filename: __filename});28 [alice, charlie] = await helper.arrange.createAccounts([50n, 10n], donor);29 });30 });3132 [33 {restrictedMode: true},34 {restrictedMode: false},35 ].map(testCase => {36 itSub(`Owner can nest their token${testCase.restrictedMode ? ': Restricted mode' : ''}`, async ({helper}) => {37 const collectionNFT = await helper.nft.mintCollection(alice, {permissions: {access: 'AllowList', mintMode: true, nesting: {tokenOwner: true}}});38 const collectionRFT = await helper.rft.mintCollection(alice);39 const targetToken = await collectionNFT.mintToken(alice, {Substrate: charlie.address});4041 await collectionNFT.setPermissions(alice, {access: 'AllowList', mintMode: true, nesting: {tokenOwner: true, restricted: testCase.restrictedMode ? [collectionRFT.collectionId] : null}});42 await collectionNFT.addToAllowList(alice, {Substrate: charlie.address});43 await collectionNFT.addToAllowList(alice, targetToken.nestingAccount());4445 await collectionRFT.setPermissions(alice, {access: 'AllowList', mintMode: true});46 await collectionRFT.addToAllowList(alice, {Substrate: charlie.address});47 await collectionRFT.addToAllowList(alice, targetToken.nestingAccount());4849 50 const nestedToken = await collectionRFT.mintToken(charlie, 5n, targetToken.nestingAccount());51 expect(await nestedToken.getBalance(targetToken.nestingAccount())).to.be.equal(5n);5253 54 const newToken = await collectionRFT.mintToken(charlie, 5n);55 await newToken.transfer(charlie, targetToken.nestingAccount(), 2n);56 expect(await newToken.getBalance(targetToken.nestingAccount())).to.be.equal(2n);57 expect(await newToken.getBalance({Substrate: charlie.address})).to.be.equal(3n);58 });59 });6061 itSub('Owner can unnest nested token', async ({helper}) => {62 const collection = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});63 const targetToken = await collection.mintToken(alice);6465 66 const collectionRFT = await helper.rft.mintCollection(alice);67 const token = await collectionRFT.mintToken(alice, 10n, targetToken.nestingAccount());6869 70 await token.transferFrom(alice, targetToken.nestingAccount(), {Substrate: alice.address}, 9n);71 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(9n);72 expect(await token.getBalance(targetToken.nestingAccount())).to.be.equal(1n);7374 75 await token.transferFrom(alice, targetToken.nestingAccount(), {Substrate: alice.address}, 1n);76 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(10n);77 expect(await token.getBalance(targetToken.nestingAccount())).to.be.equal(0n);78 });7980 itSub('Owner can burn nested token pieces', async ({helper}) => {81 const collection = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});82 const targetToken = await collection.mintToken(alice);8384 85 const collectionRFT = await helper.rft.mintCollection(alice);86 const token = await collectionRFT.mintToken(alice, 100n, {Substrate: alice.address});87 await token.transfer(alice, targetToken.nestingAccount(), 30n);8889 90 await token.burnFrom(alice, targetToken.nestingAccount(), 10n);91 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(70n);92 expect(await token.getBalance(targetToken.nestingAccount())).to.be.equal(20n);93 expect(await targetToken.getChildren()).to.has.length(1);9495 96 await token.burnFrom(alice, targetToken.nestingAccount(), 20n);97 expect(await token.getBalance(targetToken.nestingAccount())).to.be.equal(0n);98 expect(await targetToken.getChildren()).to.has.length(0);99 expect(await token.doesExist()).to.be.true;100101 102 await targetToken.burn(alice);103 expect(await targetToken.doesExist()).to.be.false;104 });105});106107describe('Refungible nesting negative tests', () => {108 let alice: IKeyringPair;109 let bob: IKeyringPair;110111 before(async function() {112 await usingPlaygrounds(async (helper, privateKey) => {113 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);114 const donor = await privateKey({filename: __filename});115 [alice, bob] = await helper.arrange.createAccounts([100n, 50n], donor);116 });117 });118119 itSub('cannot nest token if nesting is disabled', async ({helper}) => {120 const collectionNFT = await helper.nft.mintCollection(alice);121 const collectionRFT = await helper.rft.mintCollection(alice);122 const targetToken = await collectionNFT.mintToken(alice);123124 125 await expect(collectionRFT.mintToken(alice, 5n, targetToken.nestingAccount()))126 .to.be.rejectedWith(/common\.UserIsNotAllowedToNest/);127128 129 const token = await collectionRFT.mintToken(alice, 5n);130 await expect(token.transfer(alice, targetToken.nestingAccount(), 2n))131 .to.be.rejectedWith(/common\.UserIsNotAllowedToNest/);132 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(5n);133 });134135 [136 {restrictedMode: true},137 {restrictedMode: false},138 ].map(testCase => {139 itSub(`non-Owner cannot nest someone else's token${testCase.restrictedMode ? ': Restricted mode' : ''}`, async ({helper}) => {140 const collectionNFT = await helper.nft.mintCollection(alice);141 const collectionRFT = await helper.rft.mintCollection(alice);142 const targetToken = await collectionNFT.mintToken(alice);143144 await collectionNFT.setPermissions(alice, {access: 'AllowList', mintMode: true, nesting: {tokenOwner: true, restricted: testCase.restrictedMode ? [collectionRFT.collectionId] : null}});145 await collectionNFT.addToAllowList(alice, {Substrate: bob.address});146 await collectionNFT.addToAllowList(alice, targetToken.nestingAccount());147148 149 const newToken = await collectionRFT.mintToken(alice);150 await expect(newToken.transfer(bob, targetToken.nestingAccount())).to.be.rejectedWith(/common\.TokenValueTooLow/);151152 expect(await targetToken.getChildren()).to.be.length(0);153 expect(await newToken.getBalance({Substrate: alice.address})).to.be.equal(1n);154155 156 await newToken.transfer(alice, targetToken.nestingAccount());157158 159 await expect(newToken.transferFrom(bob, targetToken.nestingAccount(), {Substrate: alice.address}, 1n))160 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);161 expect(await newToken.getBalance(targetToken.nestingAccount())).to.be.equal(1n);162 });163 });164165 itSub('ReFungible: disallows to nest token to an unlisted collection', async ({helper}) => {166 const collectionNFT = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true, restricted: []}}});167 const collectionRFT = await helper.rft.mintCollection(alice);168 const targetToken = await collectionNFT.mintToken(alice);169170 171 await expect(collectionRFT.mintToken(alice, 5n, targetToken.nestingAccount()))172 .to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);173174 175 const token = await collectionRFT.mintToken(alice, 5n);176 await expect(token.transfer(alice, targetToken.nestingAccount(), 2n))177 .to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);178 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(5n);179 });180});