difftreelog
Merge pull request #745 from UniqueNetwork/tests/eth-helpers
in: master
9 files changed
tests/src/eth/collectionAdmin.test.tsdiffbeforeafterboth--- a/tests/src/eth/collectionAdmin.test.ts
+++ b/tests/src/eth/collectionAdmin.test.ts
@@ -239,19 +239,29 @@
const owner = await helper.eth.createAccountWithBalance(donor);
const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
- const [newAdmin] = await helper.arrange.createAccounts([10n], donor);
- const newAdminCross = helper.ethCrossAccount.fromKeyringPair(newAdmin);
+ const [adminSub] = await helper.arrange.createAccounts([10n], donor);
+ const adminEth = (await helper.eth.createAccountWithBalance(donor)).toLowerCase();
+ const adminCrossSub = helper.ethCrossAccount.fromKeyringPair(adminSub);
+ const adminCrossEth = helper.ethCrossAccount.fromAddress(adminEth);
+
const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
- await collectionEvm.methods.addCollectionAdminCross(newAdminCross).send();
+ await collectionEvm.methods.addCollectionAdminCross(adminCrossSub).send();
+ await collectionEvm.methods.addCollectionAdminCross(adminCrossEth).send();
+
{
- const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);
- expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())
- .to.be.eq(newAdmin.address.toLocaleLowerCase());
+ const adminList = await helper.collection.getAdmins(collectionId);
+ expect(adminList).to.deep.include({Substrate: adminSub.address});
+ expect(adminList).to.deep.include({Ethereum: adminEth});
}
- await collectionEvm.methods.removeCollectionAdminCross(newAdminCross).send();
- const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);
+ await collectionEvm.methods.removeCollectionAdminCross(adminCrossSub).send();
+ await collectionEvm.methods.removeCollectionAdminCross(adminCrossEth).send();
+ const adminList = await helper.collection.getAdmins(collectionId);
expect(adminList.length).to.be.eq(0);
+
+ // Non admin cannot mint:
+ await expect(helper.nft.mintToken(adminSub, {collectionId, owner: {Substrate: adminSub.address}})).to.be.rejectedWith(/common.PublicMintingNotAllowed/);
+ await expect(collectionEvm.methods.mint(adminEth).send({from: adminEth})).to.be.rejected;
});
// Soft-deprecated
@@ -395,16 +405,27 @@
itEth('Change owner [cross]', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
- const [newOwner] = await helper.arrange.createAccounts([10n], donor);
- const newOwnerCross = helper.ethCrossAccount.fromKeyringPair(newOwner);
- const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
- const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
+ const ownerEth = await helper.eth.createAccountWithBalance(donor);
+ const ownerCrossEth = helper.ethCrossAccount.fromAddress(ownerEth);
+ const [ownerSub] = await helper.arrange.createAccounts([10n], donor);
+ const ownerCrossSub = helper.ethCrossAccount.fromKeyringPair(ownerSub);
- expect(await collectionEvm.methods.isOwnerOrAdminCross(newOwnerCross).call()).to.be.false;
+ const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
- await collectionEvm.methods.changeCollectionOwnerCross(newOwnerCross).send();
+ expect(await collectionEvm.methods.isOwnerOrAdminCross(ownerCrossSub).call()).to.be.false;
- expect(await collectionEvm.methods.isOwnerOrAdminCross(newOwnerCross).call()).to.be.true;
+ // Can set ethereum owner:
+ await collectionEvm.methods.changeCollectionOwnerCross(ownerCrossEth).send({from: owner});
+ expect(await collectionEvm.methods.isOwnerOrAdminCross(ownerCrossEth).call()).to.be.true;
+ expect(await helper.collection.getData(collectionId))
+ .to.have.property('normalizedOwner').that.is.eq(helper.address.ethToSubstrate(ownerEth));
+
+ // Can set Substrate owner:
+ await collectionEvm.methods.changeCollectionOwnerCross(ownerCrossSub).send({from: ownerEth});
+ expect(await collectionEvm.methods.isOwnerOrAdminCross(ownerCrossSub).call()).to.be.true;
+ expect(await helper.collection.getData(collectionId))
+ .to.have.property('normalizedOwner').that.is.eq(helper.address.normalizeSubstrate(ownerSub.address));
});
itEth.skip('change owner call fee', async ({helper}) => {
tests/src/eth/createFTCollection.test.tsdiffbeforeafterboth--- a/tests/src/eth/createFTCollection.test.ts
+++ b/tests/src/eth/createFTCollection.test.ts
@@ -144,7 +144,7 @@
itEth('destroyCollection', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
- const {collectionAddress} = await helper.eth.createFungibleCollection(owner, 'Exister', DECIMALS, 'absolutely anything', 'WIWT');
+ const {collectionAddress, collectionId} = await helper.eth.createFungibleCollection(owner, 'Exister', DECIMALS, 'absolutely anything', 'WIWT');
const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);
const result = await collectionHelper.methods
@@ -166,6 +166,7 @@
expect(await collectionHelper.methods
.isCollectionExist(collectionAddress)
.call()).to.be.false;
+ expect(await helper.collection.getData(collectionId)).to.be.null;
});
});
@@ -214,12 +215,15 @@
}
});
- itEth('(!negative test!) Create collection (no funds)', async ({helper}) => {
+ itEth('(!negative test!) cannot create collection if value !== 2', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);
- await expect(collectionHelper.methods
- .createFTCollection('Peasantry', DECIMALS, 'absolutely anything', 'TWIW')
- .call({value: Number(1n * nominal)})).to.be.rejectedWith('Sent amount not equals to collection creation price (2000000000000000000)');
+ const expects = [0n, 1n, 30n].map(async value => {
+ await expect(collectionHelper.methods
+ .createFTCollection('Peasantry', DECIMALS, 'absolutely anything', 'TWIW')
+ .call({value: Number(value * nominal)})).to.be.rejectedWith('Sent amount not equals to collection creation price (2000000000000000000)');
+ });
+ await Promise.all(expects);
});
// Soft-deprecated
tests/src/eth/createNFTCollection.test.tsdiffbeforeafterboth--- a/tests/src/eth/createNFTCollection.test.ts
+++ b/tests/src/eth/createNFTCollection.test.ts
@@ -308,7 +308,7 @@
itEth('destroyCollection', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
- const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'Limits', 'absolutely anything', 'OLF');
+ const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'Limits', 'absolutely anything', 'OLF');
const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);
@@ -331,5 +331,6 @@
expect(await collectionHelper.methods
.isCollectionExist(collectionAddress)
.call()).to.be.false;
+ expect(await helper.collection.getData(collectionId)).to.be.null;
});
});
\ No newline at end of file
tests/src/eth/createRFTCollection.test.tsdiffbeforeafterboth--- a/tests/src/eth/createRFTCollection.test.ts
+++ b/tests/src/eth/createRFTCollection.test.ts
@@ -340,7 +340,7 @@
itEth('destroyCollection', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
- const {collectionAddress} = await helper.eth.createRFTCollection(owner, 'Limits', 'absolutely anything', 'OLF');
+ const {collectionAddress, collectionId} = await helper.eth.createRFTCollection(owner, 'Limits', 'absolutely anything', 'OLF');
const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);
await expect(collectionHelper.methods
@@ -349,6 +349,7 @@
expect(await collectionHelper.methods
.isCollectionExist(collectionAddress)
- .call()).to.be.false;
+ .call()).to.be.false;
+ expect(await helper.collection.getData(collectionId)).to.be.null;
});
});
tests/src/eth/destroyCollection.test.tsdiffbeforeafterboth--- a/tests/src/eth/destroyCollection.test.ts
+++ b/tests/src/eth/destroyCollection.test.ts
@@ -15,62 +15,48 @@
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
import {IKeyringPair} from '@polkadot/types/types';
-import {Pallets, requirePalletsOrSkip} from '../util';
+import {Pallets} from '../util';
import {expect, itEth, usingEthPlaygrounds} from './util';
-
-describe('Destroy Collection from EVM', () => {
+describe('Destroy Collection from EVM', function() {
let donor: IKeyringPair;
+ const testCases = [
+ {method: 'createRFTCollection' as const, params: ['Limits', 'absolutely anything', 'OLF'], requiredPallets: [Pallets.ReFungible]},
+ {method: 'createNFTCollection' as const, params: ['Limits', 'absolutely anything', 'OLF'], requiredPallets: [Pallets.NFT]},
+ {method: 'createFTCollection' as const, params: ['Limits', 'absolutely anything', 'OLF', 18], requiredPallets: [Pallets.Fungible]},
+ ];
before(async function() {
- await usingEthPlaygrounds(async (helper, privateKey) => {
- requirePalletsOrSkip(this, helper, [Pallets.ReFungible, Pallets.NFT]);
+ await usingEthPlaygrounds(async (_, privateKey) => {
donor = await privateKey({filename: __filename});
});
});
-
- itEth('(!negative test!) RFT', async ({helper}) => {
- const owner = await helper.eth.createAccountWithBalance(donor);
- const signer = await helper.eth.createAccountWithBalance(donor);
-
- const unexistedCollection = helper.ethAddress.fromCollectionId(1000000);
-
- const {collectionAddress} = await helper.eth.createRFTCollection(owner, 'Limits', 'absolutely anything', 'OLF');
- const collectionHelper = helper.ethNativeContract.collectionHelpers(signer);
-
- await expect(collectionHelper.methods
- .destroyCollection(collectionAddress)
- .send({from: signer})).to.be.rejected;
-
- await expect(collectionHelper.methods
- .destroyCollection(unexistedCollection)
- .send({from: signer})).to.be.rejected;
-
- expect(await collectionHelper.methods
- .isCollectionExist(unexistedCollection)
- .call()).to.be.false;
- });
-
- itEth('(!negative test!) NFT', async ({helper}) => {
- const owner = await helper.eth.createAccountWithBalance(donor);
- const signer = await helper.eth.createAccountWithBalance(donor);
-
- const unexistedCollection = helper.ethAddress.fromCollectionId(1000000);
-
- const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'Limits', 'absolutely anything', 'OLF');
- const collectionHelper = helper.ethNativeContract.collectionHelpers(signer);
-
- await expect(collectionHelper.methods
- .destroyCollection(collectionAddress)
- .send({from: signer})).to.be.rejected;
-
- await expect(collectionHelper.methods
- .destroyCollection(unexistedCollection)
- .send({from: signer})).to.be.rejected;
-
- expect(await collectionHelper.methods
- .isCollectionExist(unexistedCollection)
- .call()).to.be.false;
- });
+ testCases.map((testCase) =>
+ itEth.ifWithPallets(`Cannot burn non-owned or non-existing collection ${testCase.method}`, testCase.requiredPallets, async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const signer = await helper.eth.createAccountWithBalance(donor);
+
+ const unexistedCollection = helper.ethAddress.fromCollectionId(1000000);
+
+ const collectionHelpers = helper.ethNativeContract.collectionHelpers(signer);
+ const {collectionAddress} = await helper.eth.createCollecion(testCase.method, owner, ...testCase.params as [string, string, string, number?]);
+
+ // cannot burn collec
+ await expect(collectionHelpers.methods
+ .destroyCollection(collectionAddress)
+ .send({from: signer})).to.be.rejected;
+
+ await expect(collectionHelpers.methods
+ .destroyCollection(unexistedCollection)
+ .send({from: signer})).to.be.rejected;
+
+ expect(await collectionHelpers.methods
+ .isCollectionExist(unexistedCollection)
+ .call()).to.be.false;
+
+ expect(await collectionHelpers.methods
+ .isCollectionExist(collectionAddress)
+ .call()).to.be.true;
+ }));
});
tests/src/eth/fungible.test.tsdiffbeforeafterboth--- a/tests/src/eth/fungible.test.ts
+++ b/tests/src/eth/fungible.test.ts
@@ -232,56 +232,64 @@
});
itEth('Can perform transferCross()', async ({helper}) => {
- const owner = await helper.eth.createAccountWithBalance(donor);
- const receiver = await helper.eth.createAccountWithBalance(donor);
- const to = helper.ethCrossAccount.fromAddress(receiver);
- const toSubstrate = helper.ethCrossAccount.fromKeyringPair(donor);
+ const sender = await helper.eth.createAccountWithBalance(donor);
+ const receiverEth = await helper.eth.createAccountWithBalance(donor);
+ const receiverCrossEth = helper.ethCrossAccount.fromAddress(receiverEth);
+ const receiverCrossSub = helper.ethCrossAccount.fromKeyringPair(donor);
const collection = await helper.ft.mintCollection(alice);
- await collection.mint(alice, 200n, {Ethereum: owner});
+ await collection.mint(alice, 200n, {Ethereum: sender});
const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
- const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'ft', sender);
{
- const result = await contract.methods.transferCross(to, 50).send({from: owner});
-
+ // Can transferCross to ethereum address:
+ const result = await collectionEvm.methods.transferCross(receiverCrossEth, 50).send({from: sender});
+ // Check events:
const event = result.events.Transfer;
expect(event.address).to.be.equal(collectionAddress);
- expect(event.returnValues.from).to.be.equal(owner);
- expect(event.returnValues.to).to.be.equal(receiver);
+ expect(event.returnValues.from).to.be.equal(sender);
+ expect(event.returnValues.to).to.be.equal(receiverEth);
expect(event.returnValues.value).to.be.equal('50');
- }
-
- {
- const balance = await contract.methods.balanceOf(owner).call();
- expect(+balance).to.equal(150);
- }
-
- {
- const balance = await contract.methods.balanceOf(receiver).call();
- expect(+balance).to.equal(50);
+ // Sender's balance decreased:
+ const ownerBalance = await collectionEvm.methods.balanceOf(sender).call();
+ expect(+ownerBalance).to.equal(150);
+ // Receiver's balance increased:
+ const receiverBalance = await collectionEvm.methods.balanceOf(receiverEth).call();
+ expect(+receiverBalance).to.equal(50);
}
{
- const result = await contract.methods.transferCross(toSubstrate, 50).send({from: owner});
-
+ // Can transferCross to substrate address:
+ const result = await collectionEvm.methods.transferCross(receiverCrossSub, 50).send({from: sender});
+ // Check events:
const event = result.events.Transfer;
expect(event.address).to.be.equal(collectionAddress);
- expect(event.returnValues.from).to.be.equal(owner);
+ expect(event.returnValues.from).to.be.equal(sender);
expect(event.returnValues.to).to.be.equal(helper.address.substrateToEth(donor.address));
expect(event.returnValues.value).to.be.equal('50');
+ // Sender's balance decreased:
+ const senderBalance = await collection.getBalance({Ethereum: sender});
+ expect(senderBalance).to.equal(100n);
+ // Receiver's balance increased:
+ const balance = await collection.getBalance({Substrate: donor.address});
+ expect(balance).to.equal(50n);
}
+ });
+
+ itEth('Cannot transferCross() more than have', async ({helper}) => {
+ const sender = await helper.eth.createAccountWithBalance(donor);
+ const receiverEth = await helper.eth.createAccountWithBalance(donor);
+ const receiverCrossEth = helper.ethCrossAccount.fromAddress(receiverEth);
+ const BALANCE = 200n;
+ const BALANCE_TO_TRANSFER = BALANCE + 100n;
- {
- const balance = await collection.getBalance({Ethereum: owner});
- expect(balance).to.equal(100n);
- }
+ const collection = await helper.ft.mintCollection(alice);
+ await collection.mint(alice, BALANCE, {Ethereum: sender});
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'ft', sender);
- {
- const balance = await collection.getBalance({Substrate: donor.address});
- expect(balance).to.equal(50n);
- }
-
+ await expect(collectionEvm.methods.transferCross(receiverCrossEth, BALANCE_TO_TRANSFER).send({from: sender})).to.be.rejected;
});
itEth('Can perform transfer()', async ({helper}) => {
tests/src/eth/nonFungible.test.tsdiffbeforeafterboth252 itEth('Can perform burnFromCross()', async ({helper}) => {252 itEth('Can perform burnFromCross()', async ({helper}) => {253 const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});253 const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});254255 const owner = bob;254 const ownerSub = bob;255 const ownerCrossSub = helper.ethCrossAccount.fromKeyringPair(ownerSub);256 const spender = await helper.eth.createAccountWithBalance(donor, 100n);256 const ownerEth = await helper.eth.createAccountWithBalance(donor, 100n);257 const ownerCrossEth = helper.ethCrossAccount.fromAddress(ownerEth);258259 const burnerEth = await helper.eth.createAccountWithBalance(donor, 100n);260 const burnerCrossEth = helper.ethCrossAccount.fromAddress(burnerEth);257261258 const token = await collection.mintToken(minter, {Substrate: owner.address});262 const token1 = await collection.mintToken(minter, {Substrate: ownerSub.address});263 const token2 = await collection.mintToken(minter, {Ethereum: ownerEth});259264260 const address = helper.ethAddress.fromCollectionId(collection.collectionId);265 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);261 const contract = helper.ethNativeContract.collection(address, 'nft');266 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft');262267263 {268 // Approve tokens from substrate and ethereum:264 await token.approve(owner, {Ethereum: spender});269 await token1.approve(ownerSub, {Ethereum: burnerEth});270 await collectionEvm.methods.approveCross(burnerCrossEth, token2.tokenId).send({from: ownerEth});271272 // can burnFromCross:265 const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);273 const result1 = await collectionEvm.methods.burnFromCross(ownerCrossSub, token1.tokenId).send({from: burnerEth});266 const result = await contract.methods.burnFromCross(ownerCross, token.tokenId).send({from: spender});274 const result2 = await collectionEvm.methods.burnFromCross(ownerCrossEth, token2.tokenId).send({from: burnerEth});267 const events = result.events.Transfer;275 const events1 = result1.events.Transfer;268276 const events2 = result2.events.Transfer;277278 // Check events for burnFromCross (substrate and ethereum):279 [269 expect(events).to.be.like({280 [events1, token1, helper.address.substrateToEth(ownerSub.address)], 281 [events2, token2, ownerEth],282 ].map(burnData => {283 expect(burnData[0]).to.be.like({270 address,284 address: collectionAddress,271 event: 'Transfer',285 event: 'Transfer',272 returnValues: {286 returnValues: {273 from: helper.address.substrateToEth(owner.address),287 from: burnData[2],274 to: '0x0000000000000000000000000000000000000000',288 to: '0x0000000000000000000000000000000000000000',275 tokenId: token.tokenId.toString(),289 tokenId: burnData[1].tokenId.toString(),276 },290 },277 });291 });278 }292 });293294 expect(await token1.doesExist()).to.be.false;295 expect(await token2.doesExist()).to.be.false;279 });296 });280297281 itEth('Can perform approveCross()', async ({helper}) => {298 itEth('Can perform approveCross()', async ({helper}) => {326 expect(await helper.nft.getTokenOwner(collection.collectionId, token2.tokenId)).to.deep.eq({Ethereum: receiverEth.toLowerCase()});343 expect(await helper.nft.getTokenOwner(collection.collectionId, token2.tokenId)).to.deep.eq({Ethereum: receiverEth.toLowerCase()});327 });344 });345346 itEth('Can reaffirm approved address', async ({helper}) => {347 const owner = await helper.eth.createAccountWithBalance(donor, 100n);348 const ownerCrossEth = helper.ethCrossAccount.fromAddress(owner);349 const [receiver1, receiver2] = await helper.arrange.createAccounts([100n, 100n], donor);350 const receiver1Cross = helper.ethCrossAccount.fromKeyringPair(receiver1);351 const receiver2Cross = helper.ethCrossAccount.fromKeyringPair(receiver2);352 const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});353 const token1 = await collection.mintToken(minter, {Ethereum: owner});354 const token2 = await collection.mintToken(minter, {Ethereum: owner});355 const collectionEvm = helper.ethNativeContract.collection(helper.ethAddress.fromCollectionId(collection.collectionId), 'nft');356357 // Can approve and reaffirm approved address:358 await collectionEvm.methods.approveCross(receiver1Cross, token1.tokenId).send({from: owner});359 await collectionEvm.methods.approveCross(receiver2Cross, token1.tokenId).send({from: owner});360361 // receiver1 cannot transferFrom:362 await expect(helper.nft.transferTokenFrom(receiver1, collection.collectionId, token1.tokenId, {Ethereum: owner}, {Substrate: receiver1.address})).to.be.rejected;363 // receiver2 can transferFrom:364 await helper.nft.transferTokenFrom(receiver2, collection.collectionId, token1.tokenId, {Ethereum: owner}, {Substrate: receiver2.address});365366 // can set approved address to self address to remove approval:367 await collectionEvm.methods.approveCross(receiver1Cross, token2.tokenId).send({from: owner});368 await collectionEvm.methods.approveCross(ownerCrossEth, token2.tokenId).send({from: owner});369370 // receiver1 cannot transfer token anymore:371 await expect(helper.nft.transferTokenFrom(receiver1, collection.collectionId, token2.tokenId, {Ethereum: owner}, {Substrate: receiver1.address})).to.be.rejected;372 });328373329 itEth('Can perform transferFrom()', async ({helper}) => {374 itEth('Can perform transferFrom()', async ({helper}) => {330 const owner = await helper.eth.createAccountWithBalance(donor);375 const owner = await helper.eth.createAccountWithBalance(donor);426 itEth('Can perform transferCross()', async ({helper}) => {471 itEth('Can perform transferCross()', async ({helper}) => {427 const collection = await helper.nft.mintCollection(minter, {});472 const collection = await helper.nft.mintCollection(minter, {});428 const owner = await helper.eth.createAccountWithBalance(donor);473 const owner = await helper.eth.createAccountWithBalance(donor);429 const receiver = await helper.eth.createAccountWithBalance(donor);474 const receiverEth = await helper.eth.createAccountWithBalance(donor);430 const to = helper.ethCrossAccount.fromAddress(receiver);475 const receiverCrossEth = helper.ethCrossAccount.fromAddress(receiverEth);431 const toSubstrate = helper.ethCrossAccount.fromKeyringPair(minter);476 const receiverCrossSub = helper.ethCrossAccount.fromKeyringPair(minter);432 477 433 const {tokenId} = await collection.mintToken(minter, {Ethereum: owner});478 const {tokenId} = await collection.mintToken(minter, {Ethereum: owner});434479435 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);480 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);436 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);481 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);437482438 {483 {439 const result = await contract.methods.transferCross(to, tokenId).send({from: owner});484 // Can transferCross to ethereum address:440485 const result = await collectionEvm.methods.transferCross(receiverCrossEth, tokenId).send({from: owner});486 // Check events:441 const event = result.events.Transfer;487 const event = result.events.Transfer;442 expect(event.address).to.be.equal(collectionAddress);488 expect(event.address).to.be.equal(collectionAddress);443 expect(event.returnValues.from).to.be.equal(owner);489 expect(event.returnValues.from).to.be.equal(owner);444 expect(event.returnValues.to).to.be.equal(receiver);490 expect(event.returnValues.to).to.be.equal(receiverEth);445 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);491 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);446 }492 447493 // owner has balance = 0:448 {449 const balance = await contract.methods.balanceOf(owner).call();494 const ownerBalance = await collectionEvm.methods.balanceOf(owner).call();450 expect(+balance).to.equal(0);495 expect(+ownerBalance).to.equal(0);451 }496 // receiver owns token:452453 {454 const balance = await contract.methods.balanceOf(receiver).call();497 const receiverBalance = await collectionEvm.methods.balanceOf(receiverEth).call();455 expect(+balance).to.equal(1);498 expect(+receiverBalance).to.equal(1);456 }457 458 {459 const substrateResult = await contract.methods.transferCross(toSubstrate, tokenId).send({from: receiver});499 expect(await helper.nft.getTokenOwner(collection.collectionId, tokenId)).to.deep.eq({Ethereum: receiverEth.toLowerCase()});460 500 }461501 502 {503 // Can transferCross to substrate address:504 const substrateResult = await collectionEvm.methods.transferCross(receiverCrossSub, tokenId).send({from: receiverEth});505 // Check events:462 const event = substrateResult.events.Transfer;506 const event = substrateResult.events.Transfer;463 expect(event.address).to.be.equal(collectionAddress);507 expect(event.address).to.be.equal(collectionAddress);464 expect(event.returnValues.from).to.be.equal(receiver);508 expect(event.returnValues.from).to.be.equal(receiverEth);465 expect(event.returnValues.to).to.be.equal(helper.address.substrateToEth(minter.address));509 expect(event.returnValues.to).to.be.equal(helper.address.substrateToEth(minter.address));466 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);510 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);467 }511 468512 // owner has balance = 0:469 {470 const balance = await contract.methods.balanceOf(receiver).call();513 const ownerBalance = await collectionEvm.methods.balanceOf(receiverEth).call();471 expect(+balance).to.equal(0);514 expect(+ownerBalance).to.equal(0);472 }515 // receiver owns token:473474 {475 const balance = await helper.nft.getTokensByAddress(collection.collectionId, {Substrate: minter.address});516 const receiverBalance = await helper.nft.getTokensByAddress(collection.collectionId, {Substrate: minter.address});476 expect(balance).to.be.contain(tokenId);517 expect(receiverBalance).to.contain(tokenId);477 }518 }478 });519 });479});520});480521tests/src/eth/reFungible.test.tsdiffbeforeafterboth--- a/tests/src/eth/reFungible.test.ts
+++ b/tests/src/eth/reFungible.test.ts
@@ -363,56 +363,71 @@
});
itEth('Can perform transferCross()', async ({helper}) => {
- const caller = await helper.eth.createAccountWithBalance(donor);
- const receiver = await helper.eth.createAccountWithBalance(donor);
- const to = helper.ethCrossAccount.fromAddress(receiver);
- const toSubstrate = helper.ethCrossAccount.fromKeyringPair(minter);
+ const sender = await helper.eth.createAccountWithBalance(donor);
+ const receiverEth = await helper.eth.createAccountWithBalance(donor);
+ const receiverCrossEth = helper.ethCrossAccount.fromAddress(receiverEth);
+ const receiverCrossSub = helper.ethCrossAccount.fromKeyringPair(minter);
+
const collection = await helper.rft.mintCollection(minter, {});
const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
- const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', sender);
- const {tokenId} = await collection.mintToken(minter, 1n, {Ethereum: caller});
+ const token = await collection.mintToken(minter, 50n, {Ethereum: sender});
{
- const result = await contract.methods.transferCross(to, tokenId).send({from: caller});
-
+ // Can transferCross to ethereum address:
+ const result = await collectionEvm.methods.transferCross(receiverCrossEth, token.tokenId).send({from: sender});
+ // Check events:
const event = result.events.Transfer;
expect(event.address).to.equal(collectionAddress);
- expect(event.returnValues.from).to.equal(caller);
- expect(event.returnValues.to).to.equal(receiver);
- expect(event.returnValues.tokenId).to.equal(tokenId.toString());
- }
-
- {
- const balance = await contract.methods.balanceOf(caller).call();
- expect(+balance).to.equal(0);
- }
-
- {
- const balance = await contract.methods.balanceOf(receiver).call();
- expect(+balance).to.equal(1);
+ expect(event.returnValues.from).to.equal(sender);
+ expect(event.returnValues.to).to.equal(receiverEth);
+ expect(event.returnValues.tokenId).to.equal(token.tokenId.toString());
+ // Sender's balance decreased:
+ const senderBalance = await collectionEvm.methods.balanceOf(sender).call();
+ expect(+senderBalance).to.equal(0);
+ expect(await token.getBalance({Ethereum: sender})).to.eq(0n);
+ // Receiver's balance increased:
+ const receiverBalance = await collectionEvm.methods.balanceOf(receiverEth).call();
+ expect(+receiverBalance).to.equal(1);
+ expect(await token.getBalance({Ethereum: receiverEth})).to.eq(50n);
}
{
- const substrateResult = await contract.methods.transferCross(toSubstrate, tokenId).send({from: receiver});
-
-
+ // Can transferCross to substrate address:
+ const substrateResult = await collectionEvm.methods.transferCross(receiverCrossSub, token.tokenId).send({from: receiverEth});
+ // Check events:
const event = substrateResult.events.Transfer;
expect(event.address).to.be.equal(collectionAddress);
- expect(event.returnValues.from).to.be.equal(receiver);
+ expect(event.returnValues.from).to.be.equal(receiverEth);
expect(event.returnValues.to).to.be.equal(helper.address.substrateToEth(minter.address));
- expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);
+ expect(event.returnValues.tokenId).to.be.equal(`${token.tokenId}`);
+ // Sender's balance decreased:
+ const senderBalance = await collectionEvm.methods.balanceOf(receiverEth).call();
+ expect(+senderBalance).to.equal(0);
+ expect(await token.getBalance({Ethereum: receiverEth})).to.eq(0n);
+ // Receiver's balance increased:
+ const receiverBalance = await helper.nft.getTokensByAddress(collection.collectionId, {Substrate: minter.address});
+ expect(receiverBalance).to.contain(token.tokenId);
+ expect(await token.getBalance({Substrate: minter.address})).to.eq(50n);
}
+ });
+
+ itEth.skip('Cannot transferCross with invalid params', async ({helper}) => {
+ const sender = await helper.eth.createAccountWithBalance(donor);
+ const tokenOwner = await helper.eth.createAccountWithBalance(donor);
+ const receiverCrossSub = helper.ethCrossAccount.fromKeyringPair(minter);
- {
- const balance = await contract.methods.balanceOf(receiver).call();
- expect(+balance).to.equal(0);
- }
+ const collection = await helper.rft.mintCollection(minter, {});
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', sender);
- {
- const balance = await helper.nft.getTokensByAddress(collection.collectionId, {Substrate: minter.address});
- expect(balance).to.be.contain(tokenId);
- }
+ await collection.mintToken(minter, 50n, {Ethereum: sender});
+ const notSendersToken = await collection.mintToken(minter, 50n, {Ethereum: tokenOwner});
+ // Cannot transferCross someone else's token:
+ await expect(collectionEvm.methods.transferCross(receiverCrossSub, notSendersToken.tokenId).send({from: sender})).to.be.rejected;
+ // FIXME: (transaction successful): Cannot transfer token if it does not exist:
+ await expect(collectionEvm.methods.transferCross(receiverCrossSub, 999999).send({from: sender})).to.be.rejected;
});
itEth('transfer event on transfer from partial ownership to full ownership', async ({helper}) => {
tests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth--- a/tests/src/eth/util/playgrounds/unique.dev.ts
+++ b/tests/src/eth/util/playgrounds/unique.dev.ts
@@ -186,11 +186,12 @@
return await this.helper.callRpc('api.rpc.eth.call', [{from: signer, to: contractAddress, data: abi}]);
}
- async createCollecion(functionName: string, signer: string, name: string, description: string, tokenPrefix: string): Promise<{ collectionId: number, collectionAddress: string, events: NormalizedEvent[] }> {
+ async createCollecion(functionName: 'createNFTCollection' | 'createRFTCollection' | 'createFTCollection', signer: string, name: string, description: string, tokenPrefix: string, decimals?: number): Promise<{ collectionId: number, collectionAddress: string, events: NormalizedEvent[] }> {
const collectionCreationPrice = this.helper.balance.getCollectionCreationPrice();
const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);
- const result = await collectionHelper.methods[functionName](name, description, tokenPrefix).send({value: Number(collectionCreationPrice)});
+ const functionParams = functionName === 'createFTCollection' ? [name, decimals, description, tokenPrefix] : [name, description, tokenPrefix];
+ const result = await collectionHelper.methods[functionName](...functionParams).send({value: Number(collectionCreationPrice)});
const collectionAddress = this.helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);
const collectionId = this.helper.ethAddress.extractCollectionId(collectionAddress);
@@ -217,17 +218,8 @@
return this.createCollecion('createRFTCollection', signer, name, description, tokenPrefix);
}
- async createFungibleCollection(signer: string, name: string, decimals: number, description: string, tokenPrefix: string): Promise<{ collectionId: number, collectionAddress: string, events: NormalizedEvent[]}> {
- const collectionCreationPrice = this.helper.balance.getCollectionCreationPrice();
- const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);
-
- const result = await collectionHelper.methods.createFTCollection(name, decimals, description, tokenPrefix).send({value: Number(collectionCreationPrice)});
- const collectionAddress = this.helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);
- const collectionId = this.helper.ethAddress.extractCollectionId(collectionAddress);
-
- const events = this.helper.eth.normalizeEvents(result.events);
-
- return {collectionId, collectionAddress, events};
+ createFungibleCollection(signer: string, name: string, decimals: number, description: string, tokenPrefix: string): Promise<{ collectionId: number, collectionAddress: string, events: NormalizedEvent[]}> {
+ return this.createCollecion('createFTCollection', signer, name, description, tokenPrefix, decimals);
}
async createERC721MetadataCompatibleRFTCollection(signer: string, name: string, description: string, tokenPrefix: string, baseUri: string): Promise<{collectionId: number, collectionAddress: string, events: NormalizedEvent[] }> {