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

difftreelog

chore fix code review requests

Grigoriy Simonov2022-12-23parent: #39a2c66.patch.diff
in: master

3 files changed

modifiedruntime/common/ethereum/sponsoring/refungible.rsdiffbeforeafterboth
--- a/runtime/common/ethereum/sponsoring/refungible.rs
+++ b/runtime/common/ethereum/sponsoring/refungible.rs
@@ -233,15 +233,22 @@
 			| TokenContractAddress { .. } => None,
 
 			// Not sponsored
-			TransferCross { .. }
-			| TransferFromCross { .. }
 			| BurnFrom { .. }
-			| BurnFromCross { .. }
-			| MintCross { .. }
+			| BurnFromCross { .. } => None,
+			
+			MintCross { .. }
 			| MintBulk { .. }
-			| MintBulkWithTokenUri { .. } => None,
+			| MintBulkWithTokenUri { .. } => {
+				withdraw_create_item::<T>(
+					&collection,
+					&who,
+					&CreateItemData::NFT(CreateNftData::default()),
+				)
+			}
 
-			Transfer { token_id, .. } => {
+			TransferCross { token_id, .. }
+			| TransferFromCross { token_id, .. }
+			| Transfer { token_id, .. } => {
 				let token_id = TokenId::try_from(token_id).ok()?;
 				withdraw_transfer::<T>(&collection, &who, &token_id)
 			}
@@ -321,8 +328,8 @@
 
 	pub fn unique_extensions_call_sponsor<T>(
 		call: ERC20UniqueExtensionsCall<T>,
-		_token: RefungibleTokenHandle<T>,
-		_who: &T::CrossAccountId,
+		token: RefungibleTokenHandle<T>,
+		who: &T::CrossAccountId,
 	) -> Option<()>
 	where
 		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,
@@ -336,10 +343,20 @@
 			// Not sponsored
 			BurnFrom { .. }
 			| BurnFromCross { .. }
-			| ApproveCross { .. }
-			| TransferCross { .. }
-			| TransferFromCross { .. }
 			| Repartition { .. } => None,
+			
+			TransferCross { .. }
+			| TransferFromCross { .. } => {
+				let RefungibleTokenHandle(handle, token_id) = token;
+				let token_id = token_id.try_into().ok()?;
+				withdraw_transfer::<T>(&handle, &who, &token_id)
+			}
+
+			ApproveCross { .. } => {
+				let RefungibleTokenHandle(handle, token_id) = token;
+				let token_id = token_id.try_into().ok()?;
+				withdraw_approve::<T>(&handle, who.as_sub(), &token_id)
+			}
 		}
 	}
 }
modifiedtests/src/eth/abi/reFungibleDeprecated.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/reFungibleDeprecated.json
+++ b/tests/src/eth/abi/reFungibleDeprecated.json
@@ -98,5 +98,33 @@
     "outputs": [],
     "stateMutability": "nonpayable",
     "type": "function"
+  },
+  {
+    "inputs": [
+      { "internalType": "address", "name": "to", "type": "address" },
+      { "internalType": "uint256[]", "name": "tokenIds", "type": "uint256[]" }
+    ],
+    "name": "mintBulk",
+    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+    "stateMutability": "nonpayable",
+    "type": "function"
+  },
+  {
+    "inputs": [
+      { "internalType": "address", "name": "to", "type": "address" },
+      {
+        "components": [
+          { "internalType": "uint256", "name": "field_0", "type": "uint256" },
+          { "internalType": "string", "name": "field_1", "type": "string" }
+        ],
+        "internalType": "struct Tuple0[]",
+        "name": "tokens",
+        "type": "tuple[]"
+      }
+    ],
+    "name": "mintBulkWithTokenURI",
+    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+    "stateMutability": "nonpayable",
+    "type": "function"
   }
 ]
modifiedtests/src/eth/collectionSponsoring.test.tsdiffbeforeafterboth
1616
17import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
18import {Pallets, requirePalletsOrSkip, usingPlaygrounds} from '../util/index';18import {Pallets, requirePalletsOrSkip, usingPlaygrounds} from '../util/index';
19import { CrossAccountId } from '../util/playgrounds/unique';
19import {itEth, expect} from './util';20import {itEth, expect} from './util';
2021
21describe('evm nft collection sponsoring', () => {22describe('evm nft collection sponsoring', () => {
158159
159 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));160 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
160 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));161 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));
162 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
161163
162 // User can mint token without balance:164 // User can mint token without balance:
163 {165 {
181183
182 expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');184 expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
183 expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);185 expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);
184 expect(userBalanceAfter).to.be.eq(0n);186 expect(userBalanceAfter).to.be.eq(userBalanceBefore);
185 expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;187 expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;
186 }188 }
187 }));189 }));
332 });334 });
333 });335 });
334 336
337 [
338 'mintCross',
339 'mintWithTokenURI',
340 'mintBulk',
341 'mintBulkWithTokenUri',
342 ].map(testCase =>
335 itEth('sponsors mint transactions', async ({helper}) => {343 itEth(`[${testCase}] sponsors mint transactions`, async ({helper}) => {
336 const collection = await helper.rft.mintCollection(alice, {tokenPrefix: 'spnr', permissions: {mintMode: true}});344 const collection = await helper.rft.mintCollection(alice, {tokenPrefix: 'spnr', permissions: {mintMode: true}, tokenPropertyPermissions: [
345 {key: 'URI', permission: {tokenOwner: true, mutable: true, collectionAdmin: true}},
346 ]});
347
348 const owner = await helper.eth.createAccountWithBalance(donor);
337 await collection.setSponsor(alice, alice.address);349 await collection.setSponsor(alice, alice.address);
338 await collection.confirmSponsorship(alice);350 await collection.confirmSponsorship(alice);
339351
340 const minter = helper.eth.createAccount();352 const minter = helper.eth.createAccount();
353 const minterCross = helper.ethCrossAccount.fromAddress(minter);
341 expect(await helper.balance.getEthereum(minter)).to.equal(0n);354 expect(await helper.balance.getEthereum(minter)).to.equal(0n);
342355
343 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);356 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
344 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', minter);357 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', minter, true);
345358
346 await collection.addToAllowList(alice, {Ethereum: minter});359 await collection.addToAllowList(alice, {Ethereum: minter});
347360 helper.collection.addAdmin(alice, collection.collectionId, {Ethereum: owner});
361 const collectionHelpers = helper.ethNativeContract.collectionHelpers(owner);
362 await collectionHelpers.methods.makeCollectionERC721MetadataCompatible(collectionAddress, 'base/')
363 .send();
364
365 let mintingResult;
366 let tokenId;
367 const nextTokenId = await contract.methods.nextTokenId().call();
368 switch (testCase) {
369 case 'mintCross':
370 mintingResult = await contract.methods.mintCross(minterCross, []).send();
371 break;
372 case 'mintWithTokenURI':
348 const result = await contract.methods.mint(minter).send();373 mintingResult = await contract.methods.mintWithTokenURI(minter, 'Test URI').send();
374 tokenId = mintingResult.events.Transfer.returnValues.tokenId;
375 expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
376 break;
377 case 'mintBulk':
378 mintingResult = await contract.methods.mintBulk(minter, [nextTokenId]).send();
379 break;
380 case 'mintBulkWithTokenUri':
381 mintingResult = await contract.methods.mintBulkWithTokenURI(minter, [[nextTokenId, 'Test URI']]).send();
382 tokenId = mintingResult.events.Transfer.returnValues.tokenId;
383 expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
384 break;
385 }
349386
350 const events = helper.eth.normalizeEvents(result.events);387 const events = helper.eth.normalizeEvents(mintingResult.events);
351 expect(events).to.deep.include({388 expect(events).to.deep.include({
352 address: collectionAddress,389 address: collectionAddress,
353 event: 'Transfer',390 event: 'Transfer',
357 tokenId: '1',394 tokenId: '1',
358 },395 },
359 });396 });
360 });397 }));
361398
362 [399 [
363 'setCollectionSponsorCross',400 'setCollectionSponsorCross',
405 let sponsorship = (await collectionSub.getData())!.raw.sponsorship;442 let sponsorship = (await collectionSub.getData())!.raw.sponsorship;
406 expect(sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsorEth, true));443 expect(sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsorEth, true));
407 // Account cannot confirm sponsorship if it is not set as a sponsor444 // Account cannot confirm sponsorship if it is not set as a sponsor
408 //await collectionEvm.methods.confirmCollectionSponsorship().call();
409 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');445 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');
410 446
411 // Sponsor can confirm sponsorship:447 // Sponsor can confirm sponsorship:
434 470
435 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));471 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
436 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));472 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));
473 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
437474
438 // User can mint token without balance:475 // User can mint token without balance:
439 {476 {
456 493
457 expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');494 expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
458 expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);495 expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);
459 expect(userBalanceAfter).to.be.eq(0n);496 expect(userBalanceAfter).to.be.eq(userBalanceBefore);
460 expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;497 expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;
461 }498 }
462 }));499 }));
465 'setCollectionSponsorCross',502 'setCollectionSponsorCross',
466 'setCollectionSponsor', // Soft-deprecated503 'setCollectionSponsor', // Soft-deprecated
467 ].map(testCase => 504 ].map(testCase =>
468 itEth(`[${testCase}] Check that transaction via EVM spend money from sponsor address`, async ({helper}) => {505 itEth(`[${testCase}] Check that collection admin EVM transaction spend money from sponsor eth address`, async ({helper}) => {
469 const owner = await helper.eth.createAccountWithBalance(donor);506 const owner = await helper.eth.createAccountWithBalance(donor);
470 const sponsor = await helper.eth.createAccountWithBalance(donor);507 const sponsor = await helper.eth.createAccountWithBalance(donor);
471 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);508 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
475 const collectionSub = helper.rft.getCollectionObject(collectionId);512 const collectionSub = helper.rft.getCollectionObject(collectionId);
476 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner, testCase === 'setCollectionSponsor');513 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner, testCase === 'setCollectionSponsor');
477 // Set collection sponsor:514 // Set collection sponsor:
515 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.false;
478 await collectionEvm.methods[testCase](testCase === 'setCollectionSponsor' ? sponsor : sponsorCross).send();516 await collectionEvm.methods[testCase](testCase === 'setCollectionSponsor' ? sponsor : sponsorCross).send();
517 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.true;
479 let collectionData = (await collectionSub.getData())!;518 let collectionData = (await collectionSub.getData())!;
480 expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));519 expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
481 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');520 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');
482 521 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.true;
522
483 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});523 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
484 collectionData = (await collectionSub.getData())!;524 collectionData = (await collectionSub.getData())!;
485 expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));525 expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
486 526 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.false;
527 const sponsorTuple = await collectionEvm.methods.collectionSponsor().call({from: owner});
528 expect(helper.address.restoreCrossAccountFromBigInt(BigInt(sponsorTuple.sub))).to.be.equal(helper.address.ethToSubstrate(sponsor));
529
487 const user = helper.eth.createAccount();530 const user = helper.eth.createAccount();
488 const userCross = helper.ethCrossAccount.fromAddress(user);531 const userCross = helper.ethCrossAccount.fromAddress(user);
514 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;557 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
515 }));558 }));
516559
517 itEth('Check that transaction via EVM spend money from substrate sponsor address', async ({helper}) => {560 itEth('Check that collection admin EVM transaction spend money from sponsor sub address', async ({helper}) => {
518 const owner = await helper.eth.createAccountWithBalance(donor);561 const owner = await helper.eth.createAccountWithBalance(donor);
519 const sponsor = alice;562 const sponsor = alice;
520 const sponsorCross = helper.ethCrossAccount.fromKeyringPair(sponsor);563 const sponsorCross = helper.ethCrossAccount.fromKeyringPair(sponsor);
527 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.false;570 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.false;
528 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();571 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();
529 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.true;572 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.true;
573 let collectionData = (await collectionSub.getData())!;
574 expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(sponsor.address);
575 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');
530576
531 await collectionSub.confirmSponsorship(sponsor);577 await collectionSub.confirmSponsorship(sponsor);
578 collectionData = (await collectionSub.getData())!;
579 expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(sponsor.address);
532 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.false;580 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call()).to.be.false;
581 const sponsorTuple = await collectionEvm.methods.collectionSponsor().call({from: owner});
582 expect(BigInt(sponsorTuple.sub)).to.be.equal(BigInt('0x' + Buffer.from(sponsor.addressRaw).toString('hex')));
533583
534 const user = helper.eth.createAccount();584 const user = helper.eth.createAccount();
535 const userCross = helper.ethCrossAccount.fromAddress(user);585 const userCross = helper.ethCrossAccount.fromAddress(user);
585635
586 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));636 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
587 const sponsorBalanceBefore = await helper.balance.getSubstrate(sponsor.address);637 const sponsorBalanceBefore = await helper.balance.getSubstrate(sponsor.address);
638 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
588639
589 {640 {
590 const nextTokenId = await collectionEvm.methods.nextTokenId().call();641 const nextTokenId = await collectionEvm.methods.nextTokenId().call();
609660
610 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));661 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
611 const sponsorBalanceAfter = await helper.balance.getSubstrate(sponsor.address);662 const sponsorBalanceAfter = await helper.balance.getSubstrate(sponsor.address);
663 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
612664
613 expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');665 expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
614 expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);666 expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);
667 expect(userBalanceAfter).to.be.eq(userBalanceBefore);
615 expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;668 expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;
616 }669 }
617 });670 });
637 expect(collectionSponsor).to.deep.eq({Unconfirmed: sponsorSub.address});690 expect(collectionSponsor).to.deep.eq({Unconfirmed: sponsorSub.address});
638 });691 });
692
693 [
694 'transfer',
695 'transferCross',
696 'transferFrom',
697 'transferFromCross',
698 ].map(testCase =>
699 itEth(`[${testCase}] Check that transfer via EVM spend money from sponsor address`, async ({helper}) => {
700 const owner = await helper.eth.createAccountWithBalance(donor);
701
702 const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');
703 const sponsor = await helper.eth.createAccountWithBalance(donor);
704 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
705 const receiver = await helper.eth.createAccountWithBalance(donor);
706 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
707
708 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();
709 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
710
711 const user = await helper.eth.createAccountWithBalance(donor);
712 const userCross = helper.ethCrossAccount.fromAddress(user);
713 await collectionEvm.methods.addCollectionAdminCross(userCross).send();
714
715 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
716 const tokenId = result.events.Transfer.returnValues.tokenId;
717
718 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
719 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
720 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
721
722 switch (testCase) {
723 case 'transfer':
724 await collectionEvm.methods.transfer(receiver, tokenId).send({from: user});
725 break;
726 case 'transferCross':
727 await collectionEvm.methods.transferCross(helper.ethCrossAccount.fromAddress(receiver), tokenId).send({from: user});
728 break;
729 case 'transferFrom':
730 await collectionEvm.methods.transferFrom(user, receiver, tokenId).send({from: user});
731 break;
732 case 'transferFromCross':
733 await collectionEvm.methods.transferFromCross(helper.ethCrossAccount.fromAddress(user), helper.ethCrossAccount.fromAddress(receiver), tokenId).send({from: user});
734 break;
735 }
736
737 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
738 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);
739 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
740 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
741 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
742 expect(userBalanceAfter).to.be.eq(userBalanceBefore);
743 }));
639});744});
640745
641describe('evm RFT token sponsoring', () => {746describe('evm RFT token sponsoring', () => {
648 });753 });
649 });754 });
650755
756 [
757 'transfer',
758 'transferCross',
759 'transferFrom',
760 'transferFromCross',
761 ].map(testCase =>
651 itEth('[cross] Check that transfer via EVM spend money from sponsor address', async ({helper}) => {762 itEth(`[${testCase}] Check that token piece transfer via EVM spend money from sponsor address`, async ({helper}) => {
652 const owner = await helper.eth.createAccountWithBalance(donor);763 const owner = await helper.eth.createAccountWithBalance(donor);
653764
654 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');765 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');
674 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));785 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
675 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));786 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
676787
788 switch (testCase) {
789 case 'transfer':
677 await tokenContract.methods.transfer(receiver, 1).send();790 await tokenContract.methods.transfer(receiver, 1).send();
791 break;
792 case 'transferCross':
793 await tokenContract.methods.transferCross(helper.ethCrossAccount.fromAddress(receiver), 1).send();
794 break;
795 case 'transferFrom':
796 await tokenContract.methods.transferFrom(user, receiver, 1).send();
797 break;
798 case 'transferFromCross':
799 await tokenContract.methods.transferFromCross(helper.ethCrossAccount.fromAddress(user), helper.ethCrossAccount.fromAddress(receiver), 1).send();
800 break;
801 }
678802
679 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));803 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
680 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);804 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);
681 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));805 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
682 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;806 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
683 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));807 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
684 expect(userBalanceAfter).to.be.eq(userBalanceBefore);808 expect(userBalanceAfter).to.be.eq(userBalanceBefore);
685 });809 }));
686810
687 itEth('[cross] Check that approve via EVM spend money from sponsor address', async ({helper}) => {811 [
688 const owner = await helper.eth.createAccountWithBalance(donor);812 'approve',
689813 'approveCross',
690 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');814 ].map(testCase =>
691 const sponsor = await helper.eth.createAccountWithBalance(donor);
692 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
693 const receiver = await helper.eth.createAccountWithBalance(donor);
694 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
695
696 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();
697 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
698
699 const user = await helper.eth.createAccountWithBalance(donor);
700 const userCross = helper.ethCrossAccount.fromAddress(user);
701 await collectionEvm.methods.addCollectionAdminCross(userCross).send();
702
703 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
704 const tokenId = result.events.Transfer.returnValues.tokenId;
705
706 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, user);
707 await tokenContract.methods.repartition(2).send();
708
709 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
710 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
711 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
712
713 await tokenContract.methods.approve(receiver, 1).send();
714
715 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
716 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);
717 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
718 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
719 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
720 expect(userBalanceAfter).to.be.eq(userBalanceBefore);
721 });
722
723
724 itEth('[cross] Check that transferFrom via EVM spend money from sponsor address', async ({helper}) => {815 itEth(`[${testCase}] Check that approve via EVM spend money from sponsor address`, async ({helper}) => {
725 const owner = await helper.eth.createAccountWithBalance(donor);816 const owner = await helper.eth.createAccountWithBalance(donor);
726817
727 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');818 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');
742833
743 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, user); 834 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, user);
744 await tokenContract.methods.repartition(2).send();835 await tokenContract.methods.repartition(2).send();
745 await tokenContract.methods.approve(receiver, 1).send();836
746
747 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));837 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
748 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));838 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
749 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));839 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
840
750 const receiverBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(receiver));841 switch (testCase) {
751842 case 'approve':
752 const receiverTokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, receiver);
753 await receiverTokenContract.methods.transferFrom(user, receiver, 1).send();843 await tokenContract.methods.approve(receiver, 1).send();
754844 break;
845 case 'approveCross':
755 const receiverBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(receiver));846 await tokenContract.methods.approveCross(helper.ethCrossAccount.fromAddress(receiver), 1).send();
756 expect(receiverBalanceAfter).to.be.eq(receiverBalanceBefore);847 break;
848 }
849
757 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));850 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
758 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);851 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);
759 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));852 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
760 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;853 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
761 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));854 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
762 expect(userBalanceAfter).to.be.eq(userBalanceBefore);855 expect(userBalanceAfter).to.be.eq(userBalanceBefore);
763 });856 }));
764});857});
765858
859