difftreelog
Merge pull request #410 from UniqueNetwork/fix/admin-transfer
in: master
Fix/admin transfer
7 files changed
pallets/nonfungible/src/lib.rsdiffbeforeafterboth381 <TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;381 <TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;382 ensure!(382 ensure!(&token_data.owner == sender, <CommonError<T>>::NoPermission);383 &token_data.owner == sender384 || (collection.limits.owner_can_transfer() && collection.is_owner_or_admin(sender)),385 <CommonError<T>>::NoPermission386 );387383665661666 let token_data =662 let token_data =667 <TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;663 <TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;668 // TODO: require sender to be token, owner, require admins to go through transfer_from669 ensure!(664 ensure!(&token_data.owner == from, <CommonError<T>>::NoPermission);670 &token_data.owner == from671 || (collection.limits.owner_can_transfer() && collection.is_owner_or_admin(from)),672 <CommonError<T>>::NoPermission673 );674665977 collection.check_allowlist(spender)?;968 collection.check_allowlist(spender)?;978 }969 }970971 if collection.limits.owner_can_transfer() && collection.is_owner_or_admin(spender) {972 return Ok(());973 }974979 if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {975 if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {980 // TODO: should collection owner be allowed to perform this transfer?981 ensure!(976 ensure!(982 <PalletStructure<T>>::check_indirectly_owned(977 <PalletStructure<T>>::check_indirectly_owned(983 spender.clone(),978 spender.clone(),tests/package.jsondiffbeforeafterboth60 "testAddToContractAllowList": "mocha --timeout 9999999 -r ts-node/register ./**/addToContractAllowList.test.ts",60 "testAddToContractAllowList": "mocha --timeout 9999999 -r ts-node/register ./**/addToContractAllowList.test.ts",61 "testTransfer": "mocha --timeout 9999999 -r ts-node/register ./**/transfer.test.ts",61 "testTransfer": "mocha --timeout 9999999 -r ts-node/register ./**/transfer.test.ts",62 "testBurnItem": "mocha --timeout 9999999 -r ts-node/register ./**/burnItem.test.ts",62 "testBurnItem": "mocha --timeout 9999999 -r ts-node/register ./**/burnItem.test.ts",63 "testAdminTransferAndBurn": "mocha --timeout 9999999 -r ts-node/register ./**/adminTransferAndBurn.test.ts",63 "testSetMintPermission": "mocha --timeout 9999999 -r ts-node/register ./**/setMintPermission.test.ts",64 "testSetMintPermission": "mocha --timeout 9999999 -r ts-node/register ./**/setMintPermission.test.ts",64 "testCreditFeesToTreasury": "mocha --timeout 9999999 -r ts-node/register ./**/creditFeesToTreasury.test.ts",65 "testCreditFeesToTreasury": "mocha --timeout 9999999 -r ts-node/register ./**/creditFeesToTreasury.test.ts",65 "testContractSponsoring": "mocha --timeout 9999999 -r ts-node/register ./**/contractSponsoring.test.ts",66 "testContractSponsoring": "mocha --timeout 9999999 -r ts-node/register ./**/contractSponsoring.test.ts",tests/src/adminTransferAndBurn.test.tsdiffbeforeafterbothno changes
tests/src/burnItem.test.tsdiffbeforeafterboth155 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);155 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);156156157 await usingApi(async (api) => {157 await usingApi(async (api) => {158 const tx = api.tx.unique.burnItem(collectionId, tokenId, 1);158 const tx = api.tx.unique.burnFrom(collectionId, {Substrate: alice.address}, tokenId, 1);159 const events = await submitTransactionAsync(bob, tx);159 const events = await submitTransactionAsync(bob, tx);160 const result = getGenericResult(events);160 const result = getGenericResult(events);161161tests/src/nesting/graphs.test.tsdiffbeforeafterboth36 await usingApi(async (api, privateKeyWrapper) => {36 await usingApi(async (api, privateKeyWrapper) => {37 const alice = privateKeyWrapper('//Alice');37 const alice = privateKeyWrapper('//Alice');38 const collection = await buildComplexObjectGraph(api, alice);38 const collection = await buildComplexObjectGraph(api, alice);39 await setCollectionLimitsExpectSuccess(alice, collection, {ownerCanTransfer: true});39 const tokenTwoParent = tokenIdToCross(collection, 1);404041 // to self41 // to self42 await expect(42 await expect(49 'second transaction',49 'second transaction',50 ).to.be.rejectedWith(/structure\.OuroborosDetected/);50 ).to.be.rejectedWith(/structure\.OuroborosDetected/);51 await expect(51 await expect(52 executeTransaction(api, alice, api.tx.unique.transfer(tokenIdToCross(collection, 8), collection, 2, 1)),52 executeTransaction(api, alice, api.tx.unique.transferFrom(tokenTwoParent, tokenIdToCross(collection, 8), collection, 2, 1)),53 'third transaction',53 'third transaction',54 ).to.be.rejectedWith(/structure\.OuroborosDetected/);54 ).to.be.rejectedWith(/structure\.OuroborosDetected/);55 });55 });tests/src/nesting/nest.test.tsdiffbeforeafterboth123 ], 'Children contents check at nesting #2');123 ], 'Children contents check at nesting #2');124124125 // Move token B to a different user outside the nesting tree125 // Move token B to a different user outside the nesting tree126 await transferExpectSuccess(collectionA, tokenB, alice, bob);126 await transferFromExpectSuccess(collectionA, tokenB, alice, targetAddress, bob);127 children = await getTokenChildren(api, collectionA, targetToken);127 children = await getTokenChildren(api, collectionA, targetToken);128 expect(children.length).to.be.equal(1, 'Children length check at unnesting');128 expect(children.length).to.be.equal(1, 'Children length check at unnesting');129 expect(children).to.be.have.deep.members([129 expect(children).to.be.have.deep.members([470 await expect(executeTransaction(470 await expect(executeTransaction(471 api, 471 api, 472 alice, 472 alice, 473 api.tx.unique.transfer(targetAddress, collection, newToken, 1),473 api.tx.unique.transferFrom(targetAddress, {Substrate: bob.address}, collection, newToken, 1),474 ), 'while nesting another\'s token token').to.be.rejectedWith(/common\.AddressNotInAllowlist/);474 ), 'while nesting another\'s token token').to.be.rejectedWith(/common\.AddressNotInAllowlist/);475 expect(await getTokenOwner(api, collection, newToken)).to.be.deep.equal({Substrate: bob.address});475 expect(await getTokenOwner(api, collection, newToken)).to.be.deep.equal({Substrate: bob.address});476476tests/src/util/helpers.tsdiffbeforeafterboth830 });830 });831}831}832833export async function burnItemExpectFailure(sender: IKeyringPair, collectionId: number, tokenId: number, value: number | bigint = 1) {834 await usingApi(async (api) => {835 const tx = api.tx.unique.burnItem(collectionId, tokenId, value);836837 const events = await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;838 const result = getCreateCollectionResult(events);839 // tslint:disable-next-line:no-unused-expression840 expect(result.success).to.be.false;841 });842}843844export async function burnFromExpectSuccess(sender: IKeyringPair, from: IKeyringPair | CrossAccountId, collectionId: number, tokenId: number, value: number | bigint = 1) {845 await usingApi(async (api) => {846 const tx = api.tx.unique.burnFrom(collectionId, normalizeAccountId(from), tokenId, value);847 const events = await submitTransactionAsync(sender, tx);848 return getGenericResult(events).success;849 });850}832851833export async function852export async function834approve(853approve(