git.delta.rocks / unique-network / refs/commits / 26f0d33cfa5a

difftreelog

chore fix code review requests

Grigoriy Simonov2022-12-23parent: #0b44e9f.patch.diff
in: master

2 files changed

modifiedruntime/common/ethereum/sponsoring/refungible.rsdiffbeforeafterboth
93 value,93 value,
94 ..94 ..
95 } => {95 } => {
96 let token_id: TokenId = token_id.try_into().ok()?;96 let token_id = TokenId::try_from(token_id).ok()?;
97 withdraw_set_token_property::<T>(&collection, &who, &token_id, key.len() + value.len())97 withdraw_set_token_property::<T>(&collection, &who, &token_id, key.len() + value.len())
98 }98 }
99 }99 }
125 pub fn call_sponsor<T>(125 pub fn call_sponsor<T>(
126 call: ERC721Call<T>,126 call: ERC721Call<T>,
127 collection: CollectionHandle<T>,127 collection: CollectionHandle<T>,
128 who: &T::CrossAccountId,128 _who: &T::CrossAccountId,
129 ) -> Option<()>129 ) -> Option<()>
130 where130 where
131 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,131 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,
147 | SetApprovalForAll { .. } => None,147 | SetApprovalForAll { .. } => None,
148148
149 TransferFrom { token_id, from, .. } => {149 TransferFrom { token_id, from, .. } => {
150 let token_id: TokenId = token_id.try_into().ok()?;150 let token_id = TokenId::try_from(token_id).ok()?;
151 let from = T::CrossAccountId::from_eth(from);151 let from = T::CrossAccountId::from_eth(from);
152 withdraw_transfer::<T>(&collection, &from, &token_id)152 withdraw_transfer::<T>(&collection, &from, &token_id)
153 }153 }
154
155 // Not supported
154 Approve { _token_id, .. } => {156 Approve { .. } => None,
155 let token_id: TokenId = _token_id.try_into().ok()?;
156 withdraw_approve::<T>(&collection, who.as_sub(), &token_id)
157 }
158 }157 }
159 }158 }
160159
241 | MintBulkWithTokenUri { .. } => None,240 | MintBulkWithTokenUri { .. } => None,
242241
243 Transfer { token_id, .. } => {242 Transfer { token_id, .. } => {
244 let token_id: TokenId = token_id.try_into().ok()?;243 let token_id = TokenId::try_from(token_id).ok()?;
245 withdraw_transfer::<T>(&collection, &who, &token_id)244 withdraw_transfer::<T>(&collection, &who, &token_id)
246 }245 }
247 }246 }
modifiedtests/src/eth/collectionSponsoring.test.tsdiffbeforeafterboth
144 expect(nextTokenId).to.be.equal('1');144 expect(nextTokenId).to.be.equal('1');
145145
146 // Set collection permissions:146 // Set collection permissions:
147 const oldPermissions = (await collectionSub.getData())!.raw.permissions; // (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman();147 const oldPermissions = (await collectionSub.getData())!.raw.permissions;
148 expect(oldPermissions.mintMode).to.be.false;148 expect(oldPermissions.mintMode).to.be.false;
149 expect(oldPermissions.access).to.be.equal('Normal');149 expect(oldPermissions.access).to.be.equal('Normal');
150150
151 await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner});151 await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner});
152 await collectionEvm.methods.addToCollectionAllowListCross(userCross).send({from: owner});152 await collectionEvm.methods.addToCollectionAllowListCross(userCross).send({from: owner});
153 await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});153 await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});
154154
155 const newPermissions = (await collectionSub.getData())!.raw.permissions; // (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman();155 const newPermissions = (await collectionSub.getData())!.raw.permissions;
156 expect(newPermissions.mintMode).to.be.true;156 expect(newPermissions.mintMode).to.be.true;
157 expect(newPermissions.access).to.be.equal('AllowList');157 expect(newPermissions.access).to.be.equal('AllowList');
158158
380 // expect(bigIntToSub(api, BigInt(sponsorTuple[1]))).to.be.eq(sponsor.address);380 // expect(bigIntToSub(api, BigInt(sponsorTuple[1]))).to.be.eq(sponsor.address);
381 // });381 // });
382382
383 // Soft-deprecated383 [
384 'setCollectionSponsorCross',
385 'setCollectionSponsor', // Soft-deprecated
384 itEth('[eth] Remove sponsor', async ({helper}) => {386 ].map(testCase =>
387 itEth(`[${testCase}] can remove collection sponsor`, async ({helper}) => {
385 const owner = await helper.eth.createAccountWithBalance(donor);388 const owner = await helper.eth.createAccountWithBalance(donor);
386 const collectionHelpers = helper.ethNativeContract.collectionHelpers(owner);389 const collectionHelpers = helper.ethNativeContract.collectionHelpers(owner);
390
391 let result = await collectionHelpers.methods.createRFTCollection('Sponsor collection', '1', '1').send({value: Number(2n * nominal)});
392 const collectionIdAddress = helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);
393 const sponsor = await helper.eth.createAccountWithBalance(donor);
394 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
395 const collectionEvm = helper.ethNativeContract.collection(collectionIdAddress, 'rft', owner, testCase === 'setCollectionSponsor');
396
397 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;
398 result = await collectionEvm.methods[testCase](testCase === 'setCollectionSponsor' ? sponsor : sponsorCross).send({from: owner});
399 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.true;
400
401 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
402 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;
403
404 await collectionEvm.methods.removeCollectionSponsor().send({from: owner});
405
406 const sponsorTuple = await collectionEvm.methods.collectionSponsor().call({from: owner});
407 expect(sponsorTuple.field_0).to.be.eq('0x0000000000000000000000000000000000000000');
408 }));
387409
388 let result = await collectionHelpers.methods.createRFTCollection('Sponsor collection', '1', '1').send({value: Number(2n * nominal)});410 [
411 'setCollectionSponsorCross',
412 'setCollectionSponsor', // Soft-deprecated
413 ].map(testCase =>
414 itEth(`[${testCase}] Can sponsor from evm address via access list`, async ({helper}) => {
415 const owner = await helper.eth.createAccountWithBalance(donor);
416 const sponsorEth = await helper.eth.createAccountWithBalance(donor);
417 const sponsorCrossEth = helper.ethCrossAccount.fromAddress(sponsorEth);
418
419 const {collectionId, collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, 'Sponsor collection', '1', '1', '');
420
421 const collectionSub = helper.rft.getCollectionObject(collectionId);
422 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner, testCase === 'setCollectionSponsor');
423
424 // Set collection sponsor:
425 await collectionEvm.methods[testCase](testCase === 'setCollectionSponsor' ? sponsorEth : sponsorCrossEth).send({from: owner});
389 const collectionIdAddress = helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);426 let sponsorship = (await collectionSub.getData())!.raw.sponsorship;
427 expect(sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsorEth, true));
390 const sponsor = await helper.eth.createAccountWithBalance(donor);428 // Account cannot confirm sponsorship if it is not set as a sponsor
429 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');
430
431 // Sponsor can confirm sponsorship:
432 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsorEth});
433 sponsorship = (await collectionSub.getData())!.raw.sponsorship;
434 expect(sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsorEth, true));
435
436 // Create user with no balance:
437 const user = helper.eth.createAccount();
391 const collectionEvm = helper.ethNativeContract.collection(collectionIdAddress, 'rft', owner, true);438 const userCross = helper.ethCrossAccount.fromAddress(user);
439 const nextTokenId = await collectionEvm.methods.nextTokenId().call();
440 expect(nextTokenId).to.be.equal('1');
441
442 // Set collection permissions:
443 const oldPermissions = (await collectionSub.getData())!.raw.permissions;
444 expect(oldPermissions.mintMode).to.be.false;
445 expect(oldPermissions.access).to.be.equal('Normal');
392446
393 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;447 await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner});
394 result = await collectionEvm.methods.setCollectionSponsor(sponsor).send({from: owner});448 await collectionEvm.methods.addToCollectionAllowListCross(userCross).send({from: owner});
395 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.true;449 await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});
450
451 const newPermissions = (await collectionSub.getData())!.raw.permissions;
452 expect(newPermissions.mintMode).to.be.true;
453 expect(newPermissions.access).to.be.equal('AllowList');
454
455 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
456 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));
396457
397 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});458 // User can mint token without balance:
459 {
460 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
398 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;461 const events = helper.eth.normalizeEvents(result.events);
399462
400 await collectionEvm.methods.removeCollectionSponsor().send({from: owner});463 expect(events).to.deep.include({
464 address: collectionAddress,
465 event: 'Transfer',
466 args: {
467 from: '0x0000000000000000000000000000000000000000',
468 to: user,
469 tokenId: '1',
470 },
471 });
472
473 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
474 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));
475 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));
476
477 expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
478 expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);
479 expect(userBalanceAfter).to.be.eq(0n);
480 expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;
481 }
482 }));
401483
402 const sponsorTuple = await collectionEvm.methods.collectionSponsor().call({from: owner});
403 expect(sponsorTuple.field_0).to.be.eq('0x0000000000000000000000000000000000000000');
404 });
405
406 itEth('[cross] Remove sponsor', async ({helper}) => {
407 const owner = await helper.eth.createAccountWithBalance(donor);
408 const collectionHelpers = helper.ethNativeContract.collectionHelpers(owner);
409
410 let result = await collectionHelpers.methods.createRFTCollection('Sponsor collection', '1', '1').send({value: Number(2n * nominal)});
411 const collectionIdAddress = helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);
412 const sponsor = await helper.eth.createAccountWithBalance(donor);
413 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
414 const collectionEvm = helper.ethNativeContract.collection(collectionIdAddress, 'rft', owner);
415
416 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;
417 result = await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send({from: owner});
418 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.true;
419
420 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
421 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;
422
423 await collectionEvm.methods.removeCollectionSponsor().send({from: owner});
424
425 const sponsorTuple = await collectionEvm.methods.collectionSponsor().call({from: owner});
426 expect(sponsorTuple.field_0).to.be.eq('0x0000000000000000000000000000000000000000');
427 });
428
429 // Soft-deprecated
430 itEth('[eth] Sponsoring collection from evm address via access list', async ({helper}) => {
431 const owner = await helper.eth.createAccountWithBalance(donor);
432
433 const {collectionId, collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, 'Sponsor collection', '1', '1', '');
434
435 const collection = helper.rft.getCollectionObject(collectionId);
436 const sponsor = await helper.eth.createAccountWithBalance(donor);
437 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner, true);
438
439 await collectionEvm.methods.setCollectionSponsor(sponsor).send({from: owner});
440 let collectionData = (await collection.getData())!;
441 expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
442 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');
443
444 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
445 collectionData = (await collection.getData())!;
446 expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
447
448 const user = helper.eth.createAccount();
449 const nextTokenId = await collectionEvm.methods.nextTokenId().call();
450 expect(nextTokenId).to.be.equal('1');
451
452 const oldPermissions = (await collection.getData())!.raw.permissions; // (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman();
453 expect(oldPermissions.mintMode).to.be.false;
454 expect(oldPermissions.access).to.be.equal('Normal');
455
456 await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner});
457 await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner});
458 await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});
459
460 const newPermissions = (await collection.getData())!.raw.permissions; // (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman();
461 expect(newPermissions.mintMode).to.be.true;
462 expect(newPermissions.access).to.be.equal('AllowList');
463
464 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
465 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
466
467 {
468 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
469 const events = helper.eth.normalizeEvents(result.events);
470
471 expect(events).to.deep.include({
472 address: collectionAddress,
473 event: 'Transfer',
474 args: {
475 from: '0x0000000000000000000000000000000000000000',
476 to: user,
477 tokenId: '1',
478 },
479 });
480
481 const ownerBalanceAfter = await helper.balance.getSubstrate(await helper.address.ethToSubstrate(owner));
482 const sponsorBalanceAfter = await helper.balance.getSubstrate(await helper.address.ethToSubstrate(sponsor));
483
484 expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
485 expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);
486 expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;
487 }
488 });
489
490 itEth('[cross] Sponsoring collection from evm address via access list', async ({helper}) => {
491 const owner = await helper.eth.createAccountWithBalance(donor);
492
493 const {collectionId, collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, 'Sponsor collection', '1', '1', '');
494
495 const collection = helper.rft.getCollectionObject(collectionId);
496 const sponsor = await helper.eth.createAccountWithBalance(donor);
497 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
498 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
499
500 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send({from: owner});
501 let collectionData = (await collection.getData())!;
502 expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
503 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');
504
505 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
506 collectionData = (await collection.getData())!;
507 expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
508
509 const user = helper.eth.createAccount();
510 const userCross = helper.ethCrossAccount.fromAddress(user);
511 const nextTokenId = await collectionEvm.methods.nextTokenId().call();
512 expect(nextTokenId).to.be.equal('1');
513
514 const oldPermissions = (await collection.getData())!.raw.permissions; // (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman();
515 expect(oldPermissions.mintMode).to.be.false;
516 expect(oldPermissions.access).to.be.equal('Normal');
517
518 await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner});
519 await collectionEvm.methods.addToCollectionAllowListCross(userCross).send({from: owner});
520 await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});
521
522 const newPermissions = (await collection.getData())!.raw.permissions; // (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman();
523 expect(newPermissions.mintMode).to.be.true;
524 expect(newPermissions.access).to.be.equal('AllowList');
525
526 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
527 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
528
529 {
530 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
531 const events = helper.eth.normalizeEvents(result.events);
532
533 expect(events).to.deep.include({
534 address: collectionAddress,
535 event: 'Transfer',
536 args: {
537 from: '0x0000000000000000000000000000000000000000',
538 to: user,
539 tokenId: '1',
540 },
541 });
542
543 const ownerBalanceAfter = await helper.balance.getSubstrate(await helper.address.ethToSubstrate(owner));
544 const sponsorBalanceAfter = await helper.balance.getSubstrate(await helper.address.ethToSubstrate(sponsor));
545
546 expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
547 expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);
548 expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;
549 }
550 });
551
552 // TODO: Temprorary off. Need refactor484 // TODO: Temprorary off. Need refactor
553 // itWeb3('Sponsoring collection from substrate address via access list', async ({api, web3, privateKeyWrapper}) => {485 // itWeb3('Sponsoring collection from substrate address via access list', async ({api, web3, privateKeyWrapper}) => {
605 // }537 // }
606 // });538 // });
607539
608 // Soft-deprecated540 [
609 itEth('[eth] Check that transaction via EVM spend money from sponsor address', async ({helper}) => {541 'setCollectionSponsorCross',
542 'setCollectionSponsor', // Soft-deprecated
543 ].map(testCase =>
544 itEth(`[${testCase}] Check that transaction via EVM spend money from sponsor address`, async ({helper}) => {
545 const owner = await helper.eth.createAccountWithBalance(donor);
546 const sponsor = await helper.eth.createAccountWithBalance(donor);
547 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
548
549 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');
550
551 const collectionSub = helper.rft.getCollectionObject(collectionId);
552 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner, testCase === 'setCollectionSponsor');
553 // Set collection sponsor:
554 await collectionEvm.methods[testCase](testCase === 'setCollectionSponsor' ? sponsor : sponsorCross).send();
555 let collectionData = (await collectionSub.getData())!;
556 expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
557 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');
558
559 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
560 collectionData = (await collectionSub.getData())!;
561 expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
562
563 const user = helper.eth.createAccount();
564 const userCross = helper.ethCrossAccount.fromAddress(user);
565 await collectionEvm.methods.addCollectionAdminCross(userCross).send();
566
567 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
568 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
569
570 const mintingResult = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
571 const tokenId = mintingResult.events.Transfer.returnValues.tokenId;
572
573 const events = helper.eth.normalizeEvents(mintingResult.events);
574 const address = helper.ethAddress.fromCollectionId(collectionId);
575
576 expect(events).to.deep.include({
577 address,
578 event: 'Transfer',
579 args: {
580 from: '0x0000000000000000000000000000000000000000',
581 to: user,
582 tokenId: '1',
583 },
584 });
585 expect(await collectionEvm.methods.tokenURI(tokenId).call({from: user})).to.be.equal('Test URI');
586
587 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
588 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);
589 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
590 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
591 }));
592
593 itEth('Check that transaction via EVM spend money from substrate sponsor address', async ({helper}) => {
610 const owner = await helper.eth.createAccountWithBalance(donor);594 const owner = await helper.eth.createAccountWithBalance(donor);
595 const sponsor = alice;
596 const sponsorCross = helper.ethCrossAccount.fromKeyringPair(sponsor);
611597
612 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');598 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');
613 const collection = helper.rft.getCollectionObject(collectionId);
614 const sponsor = await helper.eth.createAccountWithBalance(donor);
615 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner, true);
616599
617 await collectionEvm.methods.setCollectionSponsor(sponsor).send();600 const collectionSub = helper.rft.getCollectionObject(collectionId);
618 let collectionData = (await collection.getData())!;601 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner, false);
619 expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));602 // Set collection sponsor:
620 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');603 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();
621604
622 const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor, true);605 await collectionSub.confirmSponsorship(sponsor);
623 await sponsorCollection.methods.confirmCollectionSponsorship().send();
624 collectionData = (await collection.getData())!;
625 expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
626606
627 const user = helper.eth.createAccount();607 const user = helper.eth.createAccount();
628 await collectionEvm.methods.addCollectionAdmin(user).send();608 const userCross = helper.ethCrossAccount.fromAddress(user);
609 await collectionEvm.methods.addCollectionAdminCross(userCross).send();
629610
630 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));611 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
631 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));612 const sponsorBalanceBefore = await helper.balance.getSubstrate(sponsor.address);
613
614 const mintingResult = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
615 const tokenId = mintingResult.events.Transfer.returnValues.tokenId;
632616
633 const userCollectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', user, true);617 const events = helper.eth.normalizeEvents(mintingResult.events);
634
635 const result = await userCollectionEvm.methods.mintWithTokenURI(user, 'Test URI').send();
636 const tokenId = result.events.Transfer.returnValues.tokenId;
637
638 const events = helper.eth.normalizeEvents(result.events);
639 const address = helper.ethAddress.fromCollectionId(collectionId);618 const address = helper.ethAddress.fromCollectionId(collectionId);
640619
641 expect(events).to.deep.include({620 expect(events).to.deep.include({
647 tokenId: '1',626 tokenId: '1',
648 },627 },
649 });628 });
650 expect(await userCollectionEvm.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');629 expect(await collectionEvm.methods.tokenURI(tokenId).call({from: user})).to.be.equal('Test URI');
651630
652 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));631 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
653 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);632 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);
654 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));633 const sponsorBalanceAfter = await helper.balance.getSubstrate(sponsor.address);
655 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;634 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
656 });635 });
657636
658 itEth('[cross] Check that transaction via EVM spend money from sponsor address', async ({helper}) => {637 itEth('Can reassign collection sponsor', async ({helper}) => {
659 const owner = await helper.eth.createAccountWithBalance(donor);638 const owner = await helper.eth.createAccountWithBalance(donor);
639 const sponsorEth = await helper.eth.createAccountWithBalance(donor);
640 const sponsorCrossEth = helper.ethCrossAccount.fromAddress(sponsorEth);
641 const [sponsorSub] = await helper.arrange.createAccounts([100n], donor);
642 const sponsorCrossSub = helper.ethCrossAccount.fromKeyringPair(sponsorSub);
660643
661 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');644 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');
662 const collection = helper.rft.getCollectionObject(collectionId);645 const collectionSub = helper.rft.getCollectionObject(collectionId);
663 const sponsor = await helper.eth.createAccountWithBalance(donor);
664 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
665 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);646 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
666647
667 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();648 // Set and confirm sponsor:
668 let collectionData = (await collection.getData())!;649 await collectionEvm.methods.setCollectionSponsorCross(sponsorCrossEth).send({from: owner});
669 expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
670 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');650 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsorEth});
671651
672 const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor);652 // Can reassign sponsor:
673 await sponsorCollection.methods.confirmCollectionSponsorship().send();653 await collectionEvm.methods.setCollectionSponsorCross(sponsorCrossSub).send({from: owner});
674 collectionData = (await collection.getData())!;
675 expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
676
677 const user = helper.eth.createAccount();
678 const userCross = helper.ethCrossAccount.fromAddress(user);
679 await collectionEvm.methods.addCollectionAdminCross(userCross).send();
680
681 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
682 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));654 const collectionSponsor = (await collectionSub.getData())?.raw.sponsorship;
683
684 const userCollectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', user);
685
686 const result = await userCollectionEvm.methods.mintWithTokenURI(user, 'Test URI').send();
687 const tokenId = result.events.Transfer.returnValues.tokenId;
688
689 const events = helper.eth.normalizeEvents(result.events);655 expect(collectionSponsor).to.deep.eq({Unconfirmed: sponsorSub.address});
690 const address = helper.ethAddress.fromCollectionId(collectionId);
691
692 expect(events).to.deep.include({
693 address,
694 event: 'Transfer',
695 args: {
696 from: '0x0000000000000000000000000000000000000000',
697 to: user,
698 tokenId: '1',
699 },
700 });
701 expect(await userCollectionEvm.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
702
703 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
704 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);
705 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
706 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;
707 });656 });
708});657});
709658
727 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);676 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
728677
729 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();678 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();
679 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
730680
731 const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor);
732 await sponsorCollection.methods.confirmCollectionSponsorship().send();
733
734 const user = await helper.eth.createAccountWithBalance(donor);681 const user = await helper.eth.createAccountWithBalance(donor);
735 const userCross = helper.ethCrossAccount.fromAddress(user);682 const userCross = helper.ethCrossAccount.fromAddress(user);
736 await collectionEvm.methods.addCollectionAdminCross(userCross).send();683 await collectionEvm.methods.addCollectionAdminCross(userCross).send();
737684
738 const userCollectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', user);685 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
739
740 const result = await userCollectionEvm.methods.mintWithTokenURI(user, 'Test URI').send();
741 const tokenId = result.events.Transfer.returnValues.tokenId;686 const tokenId = result.events.Transfer.returnValues.tokenId;
742687
743 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, user); 688 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, user);
767 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);712 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
768713
769 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();714 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();
715 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
770716
771 const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor);
772 await sponsorCollection.methods.confirmCollectionSponsorship().send();
773
774 const user = await helper.eth.createAccountWithBalance(donor);717 const user = await helper.eth.createAccountWithBalance(donor);
775 const userCross = helper.ethCrossAccount.fromAddress(user);718 const userCross = helper.ethCrossAccount.fromAddress(user);
776 await collectionEvm.methods.addCollectionAdminCross(userCross).send();719 await collectionEvm.methods.addCollectionAdminCross(userCross).send();
777720
778 const userCollectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', user);721 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
779
780 const result = await userCollectionEvm.methods.mintWithTokenURI(user, 'Test URI').send();
781 const tokenId = result.events.Transfer.returnValues.tokenId;722 const tokenId = result.events.Transfer.returnValues.tokenId;
782723
783 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, user); 724 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, user);
808 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);749 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
809750
810 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();751 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();
752 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
811753
812 const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor);
813 await sponsorCollection.methods.confirmCollectionSponsorship().send();
814
815 const user = await helper.eth.createAccountWithBalance(donor);754 const user = await helper.eth.createAccountWithBalance(donor);
816 const userCross = helper.ethCrossAccount.fromAddress(user);755 const userCross = helper.ethCrossAccount.fromAddress(user);
817 await collectionEvm.methods.addCollectionAdminCross(userCross).send();756 await collectionEvm.methods.addCollectionAdminCross(userCross).send();
818
819 const userCollectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', user);
820757
821 const result = await userCollectionEvm.methods.mintWithTokenURI(user, 'Test URI').send();758 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
822 const tokenId = result.events.Transfer.returnValues.tokenId;759 const tokenId = result.events.Transfer.returnValues.tokenId;
823760
824 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, user); 761 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, user);