git.delta.rocks / unique-network / refs/commits / 25ce44862797

difftreelog

test fixed and improved tests for ERC721Metadata compatible collections. WIP, 1 test still fails

Alex Saft2022-10-15parent: #49ed2a2.patch.diff
in: master

13 files changed

modifiedtests/src/eth/base.test.tsdiffbeforeafterboth
69describe('ERC165 tests', async () => {74describe('ERC165 tests', async () => {
70 // https://eips.ethereum.org/EIPS/eip-16575 // https://eips.ethereum.org/EIPS/eip-165
7176
72 let collection: number;77 let erc721MetadataCompatibleNftCollectionId: number;
78 let simpleNftCollectionId: number;
73 let minter: string;79 let minter: string;
80
81 const BASE_URI = 'base/';
7482
75 function contract(helper: EthUniqueHelper): Contract {83 async function checkInterface(helper: EthUniqueHelper, interfaceId: string, simpleResult: boolean, compatibleResult: boolean) {
76 return helper.ethNativeContract.collection(helper.ethAddress.fromCollectionId(collection), 'nft', minter);84 const simple = helper.ethNativeContract.collection(helper.ethAddress.fromCollectionId(simpleNftCollectionId), 'nft', minter);
85 const compatible = helper.ethNativeContract.collection(helper.ethAddress.fromCollectionId(erc721MetadataCompatibleNftCollectionId), 'nft', minter);
86
87 expect(await simple.methods.supportsInterface(interfaceId).call()).to.equal(simpleResult, `empty (not ERC721Metadata compatible) NFT collection returns not ${simpleResult}`);
88 expect(await compatible.methods.supportsInterface(interfaceId).call()).to.equal(compatibleResult, `ERC721Metadata compatible NFT collection returns not ${compatibleResult}`);
77 }89 }
7890
79 before(async () => {91 before(async () => {
80 await usingEthPlaygrounds(async (helper, privateKey) => {92 await usingEthPlaygrounds(async (helper, privateKey) => {
81 const donor = privateKey('//Alice');93 const donor = privateKey('//Alice');
82 const [alice] = await helper.arrange.createAccounts([10n], donor);94 minter = await helper.eth.createAccountWithBalance(donor);
95
83 ({collectionId: collection} = await helper.nft.mintCollection(96 simpleNftCollectionId = (await helper.eth.createNFTCollection(minter, 'n', 'd', 'p')).collectionId;
84 alice,
85 {
86 name: 'test',
96 },
97 }],
98 },
99 ));
100 minter = helper.eth.createAccount();97 erc721MetadataCompatibleNftCollectionId = (await helper.eth.createERC721MetadataCompatibleNFTCollection(minter, 'n', 'd', 'p', BASE_URI)).collectionId;
101 });98 });
102 });99 });
103100
104 itEth('interfaceID == 0xffffffff always false', async ({helper}) => {101 itEth('nonexistent interfaceID - 0xffffffff - always false', async ({helper}) => {
105 expect(await contract(helper).methods.supportsInterface('0xffffffff').call()).to.be.false;102 await checkInterface(helper, '0xffffffff', false, false);
106 });103 });
107104
108 itEth('ERC721 support', async ({helper}) => {105 itEth('ERC721 - 0x780e9d63 - support', async ({helper}) => {
109 expect(await contract(helper).methods.supportsInterface('0x780e9d63').call()).to.be.true;106 await checkInterface(helper, '0x780e9d63', true, true);
110 });107 });
111108
112 itEth('ERC721Metadata support', async ({helper}) => {109 itEth('ERC721Metadata - 0x5b5e139f - support', async ({helper}) => {
113 expect(await contract(helper).methods.supportsInterface('0x5b5e139f').call()).to.be.true;110 await checkInterface(helper, '0x5b5e139f', false, true);
114 });111 });
115112
116 itEth('ERC721Mintable support', async ({helper}) => {113 itEth('ERC721UniqueMintable - 0x476ff149 - support', async ({helper}) => {
117 expect(await contract(helper).methods.supportsInterface('0x68ccfe89').call()).to.be.true;114 await checkInterface(helper, '0x476ff149', true, true);
118 });115 });
119116
120 itEth('ERC721Enumerable support', async ({helper}) => {117 itEth('ERC721Enumerable - 0x780e9d63 - support', async ({helper}) => {
121 expect(await contract(helper).methods.supportsInterface('0x780e9d63').call()).to.be.true;118 await checkInterface(helper, '0x780e9d63', true, true);
122 });119 });
123120
124 itEth('ERC721UniqueExtensions support', async ({helper}) => {121 itEth('ERC721UniqueExtensions - 0x4468500d - support', async ({helper}) => {
125 expect(await contract(helper).methods.supportsInterface('0xd74d154f').call()).to.be.true;122 await checkInterface(helper, '0x4468500d', true, true);
126 });123 });
127124
128 itEth('ERC721Burnable support', async ({helper}) => {125 itEth('ERC721Burnable - 0x42966c68 - support', async ({helper}) => {
129 expect(await contract(helper).methods.supportsInterface('0x42966c68').call()).to.be.true;126 await checkInterface(helper, '0x42966c68', true, true);
130 });127 });
131128
132 itEth('ERC165 support', async ({helper}) => {129 itEth('ERC165 - 0x01ffc9a7 - support', async ({helper}) => {
133 expect(await contract(helper).methods.supportsInterface('0x01ffc9a7').call()).to.be.true;130 await checkInterface(helper, '0x01ffc9a7', true, true);
134 });131 });
135});132});
136133
modifiedtests/src/eth/collectionProperties.test.tsdiffbeforeafterboth
1import {itEth, usingEthPlaygrounds, expect} from './util/playgrounds';1import {itEth, usingEthPlaygrounds, expect, EthUniqueHelper} from './util/playgrounds';
2import {IKeyringPair} from '@polkadot/types/types';2import {IKeyringPair} from '@polkadot/types/types';
3import {Pallets} from '../util/playgrounds';3import {Pallets} from '../util/playgrounds';
4import {IProperty, ITokenPropertyPermission} from "../util/playgrounds/types";
45
5describe('EVM collection properties', () => {6describe('EVM collection properties', () => {
6 let donor: IKeyringPair;7 let donor: IKeyringPair;
65 });66 });
66 });67 });
6768
68 itEth('ERC721Metadata property can be set for NFT collection', async({helper}) => {69 const checkERC721Metadata = async (helper: EthUniqueHelper, mode: 'nft' | 'rft') => {
69 const caller = await helper.eth.createAccountWithBalance(donor);70 const caller = await helper.eth.createAccountWithBalance(donor);
70 const tokenPropertyPermissions = [{71 const bruh = await helper.eth.createAccountWithBalance(donor);
71 key: 'URI',72
72 permission: {73 const BASE_URI = 'base/'
73 mutable: true,74 const SUFFIX = 'suffix1'
74 collectionAdmin: true,75 const URI = 'uri1'
75 tokenOwner: false,76
76 },
77 }];
78 const collection = await helper.nft.mintCollection(donor, {name: 'col', description: 'descr', tokenPrefix: 'COL', tokenPropertyPermissions});77 const collectionHelpers = helper.ethNativeContract.collectionHelpers(caller);
78 const creatorMethod = mode === 'rft' ? 'createRFTCollection' : 'createNFTCollection'
7979
80 await collection.addAdmin(donor, {Ethereum: caller});80 const {collectionId, collectionAddress} = await helper.eth[creatorMethod](caller, 'n', 'd', 'p')
81
81 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);82 const contract = helper.ethNativeContract.collectionById(collectionId, mode, caller);
83 await contract.methods.addCollectionAdmin(bruh).send(); // to check that admin will work too
84
85 const collection1 = await helper.nft.getCollectionObject(collectionId);
86 const data1 = await collection1.getData()
87 expect(data1?.raw.flags.erc721metadata).to.be.false;
88 expect(await contract.methods.supportsInterface('0x5b5e139f').call()).to.be.false;
8289
83 await contract.methods.setCollectionProperty('ERC721Metadata', Buffer.from('1')).send({from: caller});90 await collectionHelpers.methods.makeCollectionERC721MetadataCompatible(collectionAddress, BASE_URI)
91 .send({from: bruh});
8492
85 expect(await contract.methods.supportsInterface('0x5b5e139f').call()).to.be.true;93 expect(await contract.methods.supportsInterface('0x5b5e139f').call()).to.be.true;
94
95 const collection2 = await helper.nft.getCollectionObject(collectionId);
96 const data2 = await collection2.getData()
97 expect(data2?.raw.flags.erc721metadata).to.be.true;
98
99 const TPPs = data2?.raw.tokenPropertyPermissions
100 expect(TPPs?.length).to.equal(2);
101
102 expect(TPPs.find((tpp: ITokenPropertyPermission) => {
103 return tpp.key === "URI" && tpp.permission.mutable && tpp.permission.collectionAdmin && !tpp.permission.tokenOwner
104 })).to.be.not.null
105
106 expect(TPPs.find((tpp: ITokenPropertyPermission) => {
107 return tpp.key === "URISuffix" && tpp.permission.mutable && tpp.permission.collectionAdmin && !tpp.permission.tokenOwner
108 })).to.be.not.null
109
110 expect(data2?.raw.properties?.find((property: IProperty) => {
111 return property.key === "baseURI" && property.value === BASE_URI
112 })).to.be.not.null
113
114 const token1Result = await contract.methods.mint(bruh).send();
115 const tokenId1 = token1Result.events.Transfer.returnValues.tokenId;
116
117 expect(await contract.methods.tokenURI(tokenId1).call()).to.equal(BASE_URI);
86118
87 await contract.methods.setCollectionProperty('ERC721Metadata', Buffer.from('0')).send({from: caller});119 await contract.methods.setProperty(tokenId1, "URISuffix", Buffer.from(SUFFIX)).send();
88
89 expect(await contract.methods.supportsInterface('0x5b5e139f').call()).to.be.false;120 expect(await contract.methods.tokenURI(tokenId1).call()).to.equal(BASE_URI + SUFFIX);
121
122 await contract.methods.setProperty(tokenId1, "URI", Buffer.from(URI)).send();
123 expect(await contract.methods.tokenURI(tokenId1).call()).to.equal(URI);
124
125 await contract.methods.deleteProperty(tokenId1, "URI").send();
126 expect(await contract.methods.tokenURI(tokenId1).call()).to.equal(BASE_URI + SUFFIX);
127
128 const token2Result = await contract.methods.mintWithTokenURI(bruh, URI).send();
129 const tokenId2 = token2Result.events.Transfer.returnValues.tokenId;
130
131 expect(await contract.methods.tokenURI(tokenId2).call()).to.equal(URI);
132
133 await contract.methods.deleteProperty(tokenId2, "URI").send();
134 expect(await contract.methods.tokenURI(tokenId2).call()).to.equal(BASE_URI);
135
136 await contract.methods.setProperty(tokenId2, "URISuffix", Buffer.from(SUFFIX)).send();
137 expect(await contract.methods.tokenURI(tokenId2).call()).to.equal(BASE_URI + SUFFIX);
90 });138 }
139
140 itEth('ERC721Metadata property can be set for NFT collection', async({helper}) => {
141 await checkERC721Metadata(helper, 'nft');
142 });
91143
92 itEth.ifWithPallets('ERC721Metadata property can be set for RFT collection', [Pallets.ReFungible], async({helper}) => {144 itEth.ifWithPallets('ERC721Metadata property can be set for RFT collection', [Pallets.ReFungible], async({helper}) => {
93 const caller = await helper.eth.createAccountWithBalance(donor);
94 const tokenPropertyPermissions = [{
95 key: 'URI',
96 permission: {
97 mutable: true,
98 collectionAdmin: true,
99 tokenOwner: false,
100 },
101 }];
102 const collection = await helper.rft.mintCollection(donor, {name: 'col', description: 'descr', tokenPrefix: 'COL', tokenPropertyPermissions});145 await checkERC721Metadata(helper, 'rft');
103
104 await collection.addAdmin(donor, {Ethereum: caller});
105
106 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);
107
108 await contract.methods.setCollectionProperty('ERC721Metadata', Buffer.from('1')).send({from: caller});
109
110 expect(await contract.methods.supportsInterface('0x5b5e139f').call()).to.be.true;
111
112 await contract.methods.setCollectionProperty('ERC721Metadata', Buffer.from('0')).send({from: caller});
113
114 expect(await contract.methods.supportsInterface('0x5b5e139f').call()).to.be.false;
115 });146 });
116});147});
117148
modifiedtests/src/eth/collectionSponsoring.test.tsdiffbeforeafterboth
3333
34 await collection.addToAllowList(alice, {Ethereum: minter});34 await collection.addToAllowList(alice, {Ethereum: minter});
3535
36 const nextTokenId = await contract.methods.nextTokenId().call();
37 expect(nextTokenId).to.equal('1');
38 const result = await contract.methods.mint(minter, nextTokenId).send();36 const result = await contract.methods.mint(minter).send();
37
39 const events = helper.eth.normalizeEvents(result.events);38 const events = helper.eth.normalizeEvents(result.events);
40 expect(events).to.be.deep.equal([39 expect(events).to.be.deep.equal([
44 args: {43 args: {
45 from: '0x0000000000000000000000000000000000000000',44 from: '0x0000000000000000000000000000000000000000',
46 to: minter,45 to: minter,
47 tokenId: nextTokenId,46 tokenId: '1',
48 },47 },
49 },48 },
50 ]);49 ]);
96 itEth('Sponsoring collection from evm address via access list', async ({helper}) => {95 itEth('Sponsoring collection from evm address via access list', async ({helper}) => {
97 const owner = await helper.eth.createAccountWithBalance(donor);96 const owner = await helper.eth.createAccountWithBalance(donor);
97
98 const collectionHelpers = helper.ethNativeContract.collectionHelpers(owner);98 const {collectionId, collectionAddress} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'Sponsor collection', '1', '1', '');
9999
100 let result = await collectionHelpers.methods.createERC721MetadataCompatibleNFTCollection('Sponsor collection', '1', '1', '').send({value: Number(2n * nominal)});
101 const collectionIdAddress = helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);
102 const collectionId = helper.ethAddress.extractCollectionId(collectionIdAddress);
103 const collection = helper.nft.getCollectionObject(collectionId);100 const collection = helper.nft.getCollectionObject(collectionId);
104 const sponsor = await helper.eth.createAccountWithBalance(donor);101 const sponsor = await helper.eth.createAccountWithBalance(donor);
105 const collectionEvm = helper.ethNativeContract.collection(collectionIdAddress, 'nft', owner);102 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
106103
107 result = await collectionEvm.methods.setCollectionSponsor(sponsor).send({from: owner});104 await collectionEvm.methods.setCollectionSponsor(sponsor).send({from: owner});
108 let collectionData = (await collection.getData())!;105 let collectionData = (await collection.getData())!;
109 expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));106 expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
110 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');107 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');
133 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));130 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
134131
135 {132 {
136 const nextTokenId = await collectionEvm.methods.nextTokenId().call();
137 expect(nextTokenId).to.be.equal('1');
138 const result = await collectionEvm.methods.mintWithTokenURI(133 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
139 user,
140 nextTokenId,
141 'Test URI',
142 ).send({from: user});
143 const events = helper.eth.normalizeEvents(result.events);134 const events = helper.eth.normalizeEvents(result.events);
144135
145 expect(events).to.be.deep.equal([136 expect(events).to.be.deep.equal([
146 {137 {
147 address: collectionIdAddress,138 address: collectionAddress,
148 event: 'Transfer',139 event: 'Transfer',
149 args: {140 args: {
150 from: '0x0000000000000000000000000000000000000000',141 from: '0x0000000000000000000000000000000000000000',
151 to: user,142 to: user,
152 tokenId: nextTokenId,143 tokenId: '1',
153 },144 },
154 },145 },
155 ]);146 ]);
222 itEth('Check that transaction via EVM spend money from sponsor address', async ({helper}) => {213 itEth('Check that transaction via EVM spend money from sponsor address', async ({helper}) => {
223 const owner = await helper.eth.createAccountWithBalance(donor);214 const owner = await helper.eth.createAccountWithBalance(donor);
215
224 const collectionHelpers = helper.ethNativeContract.collectionHelpers(owner);216 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner,'Sponsor collection', '1', '1', '');
225
226 let result = await collectionHelpers.methods.createERC721MetadataCompatibleNFTCollection('Sponsor collection', '1', '1', '').send({value: Number(2n * nominal)});
227 const collectionIdAddress = helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);
228 const collectionId = helper.ethAddress.extractCollectionId(collectionIdAddress);
229 const collection = helper.nft.getCollectionObject(collectionId);217 const collection = helper.nft.getCollectionObject(collectionId);
230 const sponsor = await helper.eth.createAccountWithBalance(donor);218 const sponsor = await helper.eth.createAccountWithBalance(donor);
231 const collectionEvm = helper.ethNativeContract.collection(collectionIdAddress, 'nft', owner);219 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
232220
233 result = await collectionEvm.methods.setCollectionSponsor(sponsor).send();221 await collectionEvm.methods.setCollectionSponsor(sponsor).send();
234 let collectionData = (await collection.getData())!;222 let collectionData = (await collection.getData())!;
235 expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));223 expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
236 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');224 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');
237225
238 const sponsorCollection = helper.ethNativeContract.collection(collectionIdAddress, 'nft', sponsor);226 const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'nft', sponsor);
239 await sponsorCollection.methods.confirmCollectionSponsorship().send();227 await sponsorCollection.methods.confirmCollectionSponsorship().send();
240 collectionData = (await collection.getData())!;228 collectionData = (await collection.getData())!;
241 expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));229 expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
246 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));234 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
247 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));235 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
248236
249 const userCollectionEvm = helper.ethNativeContract.collection(collectionIdAddress, 'nft', user);237 const userCollectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', user);
238
250 const nextTokenId = await userCollectionEvm.methods.nextTokenId().call();239 let result = await userCollectionEvm.methods.mintWithTokenURI(user, 'Test URI',).send();
251 expect(nextTokenId).to.be.equal('1');
252 result = await userCollectionEvm.methods.mintWithTokenURI(240 const tokenId = result.events.Transfer.returnValues.tokenId;
253 user,
254 nextTokenId,
255 'Test URI',
256 ).send();
257241
258 const events = helper.eth.normalizeEvents(result.events);242 const events = helper.eth.normalizeEvents(result.events);
259 const address = helper.ethAddress.fromCollectionId(collectionId);243 const address = helper.ethAddress.fromCollectionId(collectionId);
265 args: {249 args: {
266 from: '0x0000000000000000000000000000000000000000',250 from: '0x0000000000000000000000000000000000000000',
267 to: user,251 to: user,
268 tokenId: nextTokenId,252 tokenId: '1',
269 },253 },
270 },254 },
271 ]);255 ]);
272 expect(await userCollectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');256 expect(await userCollectionEvm.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
273 257
274 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));258 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
275 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);259 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);
modifiedtests/src/eth/fractionalizer/Fractionalizer.soldiffbeforeafterboth
124 address rftTokenAddress;124 address rftTokenAddress;
125 UniqueRefungibleToken rftTokenContract;125 UniqueRefungibleToken rftTokenContract;
126 if (nft2rftMapping[_collection][_token] == 0) {126 if (nft2rftMapping[_collection][_token] == 0) {
127 rftTokenId = rftCollectionContract.nextTokenId();
128 rftCollectionContract.mint(address(this), rftTokenId);127 rftTokenId = rftCollectionContract.mint(address(this));
129 rftTokenAddress = rftCollectionContract.tokenContractAddress(rftTokenId);128 rftTokenAddress = rftCollectionContract.tokenContractAddress(rftTokenId);
130 nft2rftMapping[_collection][_token] = rftTokenId;129 nft2rftMapping[_collection][_token] = rftTokenId;
131 rft2nftMapping[rftTokenAddress] = Token(_collection, _token);130 rft2nftMapping[rftTokenAddress] = Token(_collection, _token);
modifiedtests/src/eth/fractionalizer/fractionalizer.test.tsdiffbeforeafterboth
64}> => {64}> => {
65 const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');65 const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');
66 const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);66 const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);
67 const nftTokenId = await nftContract.methods.nextTokenId().call();67 const mintResult = await nftContract.methods.mint(owner).send({from: owner});
68 await nftContract.methods.mint(owner, nftTokenId).send({from: owner});68 const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;
6969
70 await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});70 await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});
71 await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send({from: owner});71 await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send({from: owner});
148148
149 const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');149 const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');
150 const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);150 const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);
151 const nftTokenId = await nftContract.methods.nextTokenId().call();151 const mintResult = await nftContract.methods.mint(owner).send({from: owner});
152 await nftContract.methods.mint(owner, nftTokenId).send({from: owner});152 const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;
153153
154 const {contract: fractionalizer} = await initContract(helper, owner);154 const {contract: fractionalizer} = await initContract(helper, owner);
155155
280280
281 const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');281 const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');
282 const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);282 const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);
283 const nftTokenId = await nftContract.methods.nextTokenId().call();283 const mintResult = await nftContract.methods.mint(owner).send({from: owner});
284 await nftContract.methods.mint(owner, nftTokenId).send({from: owner});284 const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;
285285
286 const fractionalizer = await deployContract(helper, owner);286 const fractionalizer = await deployContract(helper, owner);
287287
295295
296 const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');296 const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');
297 const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);297 const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);
298 const nftTokenId = await nftContract.methods.nextTokenId().call();298 const mintResult = await nftContract.methods.mint(owner).send({from: owner});
299 await nftContract.methods.mint(owner, nftTokenId).send({from: owner});299 const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;
300 await nftContract.methods.transfer(nftOwner, 1).send({from: owner});300 await nftContract.methods.transfer(nftOwner, 1).send({from: owner});
301301
302302
312312
313 const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');313 const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');
314 const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);314 const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);
315 const nftTokenId = await nftContract.methods.nextTokenId().call();315 const mintResult = await nftContract.methods.mint(owner).send({from: owner});
316 await nftContract.methods.mint(owner, nftTokenId).send({from: owner});316 const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;
317317
318 const {contract: fractionalizer} = await initContract(helper, owner);318 const {contract: fractionalizer} = await initContract(helper, owner);
319319
327327
328 const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');328 const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');
329 const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);329 const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);
330 const nftTokenId = await nftContract.methods.nextTokenId().call();330 const mintResult = await nftContract.methods.mint(owner).send({from: owner});
331 await nftContract.methods.mint(owner, nftTokenId).send({from: owner});331 const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;
332332
333 const {contract: fractionalizer} = await initContract(helper, owner);333 const {contract: fractionalizer} = await initContract(helper, owner);
334334
343 const fractionalizer = await deployContract(helper, owner);343 const fractionalizer = await deployContract(helper, owner);
344 const rftCollection = await helper.eth.createRFTCollection(owner, 'rft', 'RFT collection', 'RFT');344 const rftCollection = await helper.eth.createRFTCollection(owner, 'rft', 'RFT collection', 'RFT');
345 const refungibleContract = helper.ethNativeContract.collection(rftCollection.collectionAddress, 'rft', owner);345 const refungibleContract = helper.ethNativeContract.collection(rftCollection.collectionAddress, 'rft', owner);
346 const rftTokenId = await refungibleContract.methods.nextTokenId().call();346 const mintResult = await refungibleContract.methods.mint(owner).send({from: owner});
347 await refungibleContract.methods.mint(owner, rftTokenId).send({from: owner});347 const rftTokenId = mintResult.events.Transfer.returnValues.tokenId;
348 348
349 await expect(fractionalizer.methods.rft2nft(rftCollection.collectionAddress, rftTokenId).call({from: owner}))349 await expect(fractionalizer.methods.rft2nft(rftCollection.collectionAddress, rftTokenId).call({from: owner}))
350 .to.be.rejectedWith(/RFT collection is not set$/g);350 .to.be.rejectedWith(/RFT collection is not set$/g);
356 const {contract: fractionalizer} = await initContract(helper, owner);356 const {contract: fractionalizer} = await initContract(helper, owner);
357 const rftCollection = await helper.eth.createRFTCollection(owner, 'rft', 'RFT collection', 'RFT');357 const rftCollection = await helper.eth.createRFTCollection(owner, 'rft', 'RFT collection', 'RFT');
358 const refungibleContract = helper.ethNativeContract.collection(rftCollection.collectionAddress, 'rft', owner);358 const refungibleContract = helper.ethNativeContract.collection(rftCollection.collectionAddress, 'rft', owner);
359 const rftTokenId = await refungibleContract.methods.nextTokenId().call();359 const mintResult = await refungibleContract.methods.mint(owner).send({from: owner});
360 await refungibleContract.methods.mint(owner, rftTokenId).send({from: owner});360 const rftTokenId = mintResult.events.Transfer.returnValues.tokenId;
361 361
362 await expect(fractionalizer.methods.rft2nft(rftCollection.collectionAddress, rftTokenId).call())362 await expect(fractionalizer.methods.rft2nft(rftCollection.collectionAddress, rftTokenId).call())
363 .to.be.rejectedWith(/Wrong RFT collection$/g);363 .to.be.rejectedWith(/Wrong RFT collection$/g);
373 await refungibleContract.methods.addCollectionAdmin(fractionalizer.options.address).send({from: owner});373 await refungibleContract.methods.addCollectionAdmin(fractionalizer.options.address).send({from: owner});
374 await fractionalizer.methods.setRFTCollection(rftCollection.collectionAddress).send({from: owner});374 await fractionalizer.methods.setRFTCollection(rftCollection.collectionAddress).send({from: owner});
375375
376 const rftTokenId = await refungibleContract.methods.nextTokenId().call();376 const mintResult = await refungibleContract.methods.mint(owner).send({from: owner});
377 await refungibleContract.methods.mint(owner, rftTokenId).send({from: owner});377 const rftTokenId = mintResult.events.Transfer.returnValues.tokenId;
378 378
379 await expect(fractionalizer.methods.rft2nft(rftCollection.collectionAddress, rftTokenId).call())379 await expect(fractionalizer.methods.rft2nft(rftCollection.collectionAddress, rftTokenId).call())
380 .to.be.rejectedWith(/No corresponding NFT token found$/g);380 .to.be.rejectedWith(/No corresponding NFT token found$/g);
434434
435 const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');435 const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');
436 const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);436 const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);
437 const nftTokenId = await nftContract.methods.nextTokenId().call();437 const mintResult = await nftContract.methods.mint(owner).send({from: owner});
438 await nftContract.methods.mint(owner, nftTokenId).send({from: owner});438 const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;
439439
440 await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});440 await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});
441 await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send({from: owner});441 await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send({from: owner});
modifiedtests/src/eth/nesting/nest.test.tsdiffbeforeafterboth
30 const owner = await helper.eth.createAccountWithBalance(donor);30 const owner = await helper.eth.createAccountWithBalance(donor);
31 const {collectionId, contract} = await createNestingCollection(helper, owner);31 const {collectionId, contract} = await createNestingCollection(helper, owner);
32 32
33 // Create a token to be nested33 // Create a token to be nested to
34 const targetNFTTokenId = await contract.methods.nextTokenId().call();34 const mintingTargetNFTTokenIdResult = await contract.methods.mint(owner).send({from: owner});
35 await contract.methods.mint(35 const targetNFTTokenId = mintingTargetNFTTokenIdResult.events.Transfer.returnValues.tokenId;
36 owner,
37 targetNFTTokenId,
38 ).send({from: owner});
39
40 const targetNftTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetNFTTokenId);36 const targetNftTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetNFTTokenId);
41 37
42 // Create a nested token38 // Create a nested token
43 const firstTokenId = await contract.methods.nextTokenId().call();39 const mintingFirstTokenIdResult = await contract.methods.mint(targetNftTokenAddress).send({from: owner});
44 await contract.methods.mint(40 const firstTokenId = mintingFirstTokenIdResult.events.Transfer.returnValues.tokenId;
45 targetNftTokenAddress,
46 firstTokenId,
47 ).send({from: owner});
48
49 expect(await contract.methods.ownerOf(firstTokenId).call()).to.be.equal(targetNftTokenAddress);41 expect(await contract.methods.ownerOf(firstTokenId).call()).to.be.equal(targetNftTokenAddress);
50 42
51 // Create a token to be nested and nest43 // Create a token to be nested and nest
52 const secondTokenId = await contract.methods.nextTokenId().call();44 const mintingSecondTokenIdResult = await contract.methods.mint(owner).send({from: owner});
53 await contract.methods.mint(45 const secondTokenId = mintingSecondTokenIdResult.events.Transfer.returnValues.tokenId;
54 owner,46
55 secondTokenId,
56 ).send({from: owner});
57
58 await contract.methods.transfer(targetNftTokenAddress, secondTokenId).send({from: owner});47 await contract.methods.transfer(targetNftTokenAddress, secondTokenId).send({from: owner});
59
72 await contractA.methods.setCollectionNesting(true, [collectionAddressA, collectionAddressB]).send({from: owner});60 await contractA.methods.setCollectionNesting(true, [collectionAddressA, collectionAddressB]).send({from: owner});
73 61
74 // Create a token to nest into62 // Create a token to nest into
75 const targetNftTokenId = await contractA.methods.nextTokenId().call();63 const mintingtargetNftTokenIdResult = await contractA.methods.mint(owner).send({from: owner});
76 await contractA.methods.mint(64 const targetNftTokenId = mintingtargetNftTokenIdResult.events.Transfer.returnValues.tokenId;
77 owner,
78 targetNftTokenId,
79 ).send({from: owner});
80 const nftTokenAddressA1 = helper.ethAddress.fromTokenId(collectionIdA, targetNftTokenId);65 const nftTokenAddressA1 = helper.ethAddress.fromTokenId(collectionIdA, targetNftTokenId);
81 66
82 // Create a token for nesting in the same collection as the target67 // Create a token for nesting in the same collection as the target
83 const nftTokenIdA = await contractA.methods.nextTokenId().call();68 const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});
84 await contractA.methods.mint(
85 owner,
86 nftTokenIdA,
87 ).send({from: owner});
88
89 // Create a token for nesting in a different collection
90 const nftTokenIdB = await contractB.methods.nextTokenId().call();69 const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;
70
71 // Create a token for nesting in a different collection
91 await contractB.methods.mint(72 const mintingTokenIdBResult = await contractB.methods.mint(owner).send({from: owner});
92 owner,73 const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;
93 nftTokenIdB,74
94 ).send({from: owner});
95
96 // Nest75 // Nest
110 await contract.methods.setCollectionNesting(false).send({from: owner});89 await contract.methods.setCollectionNesting(false).send({from: owner});
111 90
112 // Create a token to nest into91 // Create a token to nest into
113 const targetNftTokenId = await contract.methods.nextTokenId().call();92 const mintingTargetTokenIdResult = await contract.methods.mint(owner).send({from: owner});
114 await contract.methods.mint(93 const targetTokenId = mintingTargetTokenIdResult.events.Transfer.returnValues.tokenId;
115 owner,
116 targetNftTokenId,
117 ).send({from: owner});
118
119 const targetNftTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetNftTokenId);94 const targetNftTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetTokenId);
120 95
121 // Create a token to nest96 // Create a token to nest
122 const nftTokenId = await contract.methods.nextTokenId().call();97 const mintingNftTokenIdResult = await contract.methods.mint(owner).send({from: owner});
123 await contract.methods.mint(98 const nftTokenId = mintingNftTokenIdResult.events.Transfer.returnValues.tokenId;
124 owner,99
125 nftTokenId,
126 ).send({from: owner});
127
128 // Try to nest100 // Try to nest
129 await expect(contract.methods101 await expect(contract.methods
138 const {collectionId, contract} = await createNestingCollection(helper, owner);110 const {collectionId, contract} = await createNestingCollection(helper, owner);
139 111
140 // Mint a token112 // Mint a token
141 const targetTokenId = await contract.methods.nextTokenId().call();113 const mintingTargetTokenIdResult = await contract.methods.mint(owner).send({from: owner});
142 await contract.methods.mint(114 const targetTokenId = mintingTargetTokenIdResult.events.Transfer.returnValues.tokenId;
143 owner,
144 targetTokenId,
145 ).send({from: owner});
146 const targetTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetTokenId);115 const targetTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetTokenId);
147 116
148 // Mint a token belonging to a different account117 // Mint a token belonging to a different account
149 const tokenId = await contract.methods.nextTokenId().call();118 const mintingTokenIdResult = await contract.methods.mint(malignant).send({from: owner});
150 await contract.methods.mint(119 const tokenId = mintingTokenIdResult.events.Transfer.returnValues.tokenId;
151 malignant,120
152 tokenId,
153 ).send({from: owner});
154
155 // Try to nest one token in another as a non-owner account121 // Try to nest one token in another as a non-owner account
156 await expect(contract.methods122 await expect(contract.methods
168 await contractA.methods.setCollectionNesting(true, [collectionAddressA, collectionAddressB]).send({from: owner});134 await contractA.methods.setCollectionNesting(true, [collectionAddressA, collectionAddressB]).send({from: owner});
169 135
170 // Create a token in one collection136 // Create a token in one collection
171 const nftTokenIdA = await contractA.methods.nextTokenId().call();137 const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});
172 await contractA.methods.mint(138 const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;
173 owner,
174 nftTokenIdA,
175 ).send({from: owner});
176 const nftTokenAddressA = helper.ethAddress.fromTokenId(collectionIdA, nftTokenIdA);139 const nftTokenAddressA = helper.ethAddress.fromTokenId(collectionIdA, nftTokenIdA);
177 140
178 // Create a token in another collection belonging to someone else141 // Create a token in another collection
179 const nftTokenIdB = await contractB.methods.nextTokenId().call();142 const mintingTokenIdBResult = await contractB.methods.mint(malignant).send({from: owner});
180 await contractB.methods.mint(143 const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;
181 malignant,144
182 nftTokenIdB,
183 ).send({from: owner});
184
185 // Try to drag someone else's token into the other collection and nest145 // Try to drag someone else's token into the other collection and nest
186 await expect(contractB.methods146 await expect(contractB.methods
197 await contractA.methods.setCollectionNesting(true, [collectionAddressA]).send({from: owner});157 await contractA.methods.setCollectionNesting(true, [collectionAddressA]).send({from: owner});
198 158
199 // Create a token in one collection159 // Create a token in one collection
200 const nftTokenIdA = await contractA.methods.nextTokenId().call();160 const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});
201 await contractA.methods.mint(161 const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;
202 owner,
203 nftTokenIdA,
204 ).send({from: owner});
205 const nftTokenAddressA = helper.ethAddress.fromTokenId(collectionIdA, nftTokenIdA);162 const nftTokenAddressA = helper.ethAddress.fromTokenId(collectionIdA, nftTokenIdA);
206 163
207 // Create a token in another collection164 // Create a token in another collection
208 const nftTokenIdB = await contractB.methods.nextTokenId().call();165 const mintingTokenIdBResult = await contractB.methods.mint(owner).send({from: owner});
209 await contractB.methods.mint(166 const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;
210 owner,167
211 nftTokenIdB,168
212 ).send({from: owner});
213
214 // Try to nest into a token in the other collection, disallowed in the first169 // Try to nest into a token in the other collection, disallowed in the first
215 await expect(contractB.methods170 await expect(contractB.methods
modifiedtests/src/eth/nonFungible.test.tsdiffbeforeafterboth
96 const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'Mint collection', 'a', 'b', baseUri);96 const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'Mint collection', 'a', 'b', baseUri);
97 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);97 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
98 98
99 const nextTokenId = await contract.methods.nextTokenId().call();99 const result = await contract.methods.mint(receiver).send();
100 expect(nextTokenId).to.be.equal('1');100 const tokenId = result.events.Transfer.returnValues.tokenId;
101 const result = await contract.methods.mint(101 expect(tokenId).to.be.equal('1');
102 receiver,
103 nextTokenId,
104 ).send();
105102
106 if (propertyKey && propertyValue) {103 if (propertyKey && propertyValue) {
107 // Set URL or suffix104 // Set URL or suffix
108 await contract.methods.setProperty(nextTokenId, propertyKey, Buffer.from(propertyValue)).send();105 await contract.methods.setProperty(tokenId, propertyKey, Buffer.from(propertyValue)).send();
109 }106 }
110107
111 const event = result.events.Transfer;108 const event = result.events.Transfer;
112 expect(event.address).to.be.equal(collectionAddress);109 expect(event.address).to.be.equal(collectionAddress);
113 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');110 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');
114 expect(event.returnValues.to).to.be.equal(receiver);111 expect(event.returnValues.to).to.be.equal(receiver);
115 expect(event.returnValues.tokenId).to.be.equal(nextTokenId);112 expect(event.returnValues.tokenId).to.be.equal(tokenId);
116113
117 return {contract, nextTokenId};114 return {contract, nextTokenId: tokenId};
118 }115 }
119116
120 itEth('Empty tokenURI', async ({helper}) => {117 itEth('Empty tokenURI', async ({helper}) => {
157 const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'Mint collection', '6', '6', '');154 const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'Mint collection', '6', '6', '');
158 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);155 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
156
159 const nextTokenId = await contract.methods.nextTokenId().call();157 const result = await contract.methods.mintWithTokenURI(receiver, 'Test URI').send();
160
161 expect(nextTokenId).to.be.equal('1');158 const tokenId = result.events.Transfer.returnValues.tokenId;
162 const result = await contract.methods.mintWithTokenURI(159 expect(tokenId).to.be.equal('1');
163 receiver,
164 nextTokenId,
165 'Test URI',
166 ).send();
167160
168 const event = result.events.Transfer;161 const event = result.events.Transfer;
169 expect(event.address).to.be.equal(collectionAddress);162 expect(event.address).to.be.equal(collectionAddress);
170 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');163 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');
171 expect(event.returnValues.to).to.be.equal(receiver);164 expect(event.returnValues.to).to.be.equal(receiver);
172 expect(event.returnValues.tokenId).to.be.equal(nextTokenId);
173165
174 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');166 expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
175167
176 // TODO: this wont work right now, need release 919000 first168 // TODO: this wont work right now, need release 919000 first
177 // await helper.methods.setOffchainSchema(collectionIdAddress, 'https://offchain-service.local/token-info/{id}').send();169 // await helper.methods.setOffchainSchema(collectionIdAddress, 'https://offchain-service.local/token-info/{id}').send();
modifiedtests/src/eth/payable.test.tsdiffbeforeafterboth
200 return await helper.ethContract.deployByCode(200 return await helper.ethContract.deployByCode(
201 deployer,201 deployer,
202 'ProxyContract',202 'ProxyContract',
203 `203 `
204 // SPDX-License-Identifier: UNLICENSED204 // SPDX-License-Identifier: UNLICENSED
205 pragma solidity ^0.8.6;205 pragma solidity ^0.8.6;
206206
207 import {CollectionHelpers} from "../api/CollectionHelpers.sol";207 import {CollectionHelpers} from "../api/CollectionHelpers.sol";
208 import {UniqueNFT} from "../api/UniqueNFT.sol";208 import {UniqueNFT} from "../api/UniqueNFT.sol";
209209
210 error Value(uint256 value);210 error Value(uint256 value);
211211
212 contract ProxyContract {212 contract ProxyContract {
213 bool value = false;213 bool value = false;
214 address innerContract;214 address innerContract;
215215
216 event CollectionCreated(address collection);216 event CollectionCreated(address collection);
217 event TokenMinted(uint256 tokenId);217 event TokenMinted(uint256 tokenId);
218218
219 receive() external payable {}219 receive() external payable {}
220220
221 constructor() {221 constructor() {
222 innerContract = address(new InnerContract());222 innerContract = address(new InnerContract());
223 }223 }
224224
225 function flip() public {225 function flip() public {
226 value = !value;226 value = !value;
227 InnerContract(innerContract).flip();227 InnerContract(innerContract).flip();
228 }228 }
229229
230 function createNFTCollection() external payable {230 function createNFTCollection() external payable {
231 address collectionHelpers = 0x6C4E9fE1AE37a41E93CEE429e8E1881aBdcbb54F;231 address collectionHelpers = 0x6C4E9fE1AE37a41E93CEE429e8E1881aBdcbb54F;
232 address nftCollection = CollectionHelpers(collectionHelpers).createNFTCollection{value: msg.value}("A", "B", "C");232 address nftCollection = CollectionHelpers(collectionHelpers).createNFTCollection{value: msg.value}("A", "B", "C");
233 emit CollectionCreated(nftCollection);233 emit CollectionCreated(nftCollection);
234 }234 }
235235
236 function mintNftToken(address collectionAddress) external {236 function mintNftToken(address collectionAddress) external {
237 UniqueNFT collection = UniqueNFT(collectionAddress);237 UniqueNFT collection = UniqueNFT(collectionAddress);
238 uint256 tokenId = collection.nextTokenId();238 uint256 tokenId = collection.mint(msg.sender);
239 collection.mint(msg.sender, tokenId);239 emit TokenMinted(tokenId);
240 emit TokenMinted(tokenId);240 }
241 }241
242242 function getValue() external view returns (bool) {
243 function getValue() external view returns (bool) {243 return InnerContract(innerContract).getValue();
244 return InnerContract(innerContract).getValue();244 }
245 }245 }
246 }246
247247 contract InnerContract {
248 contract InnerContract {248 bool value = false;
249 bool value = false;249 function flip() external {
250 function flip() external {250 value = !value;
251 value = !value;251 }
252 }252 function getValue() external view returns (bool) {
253 function getValue() external view returns (bool) {253 return value;
254 return value;254 }
255 }255 }
256 }256 `,
257 `,
258 [257 [
259 {258 {
260 solPath: 'api/CollectionHelpers.sol',259 solPath: 'api/CollectionHelpers.sol',
modifiedtests/src/eth/proxy/UniqueNFTProxy.soldiffbeforeafterboth
120 return proxied.mintingFinished();120 return proxied.mintingFinished();
121 }121 }
122122
123 function mint(address to, uint256 tokenId)123 function mint(address to)
124 external124 external
125 override125 override
126 returns (bool)126 returns (uint256)
127 {127 {
128 return proxied.mint(to, tokenId);128 return proxied.mint(to);
129 }129 }
130130
131 function mintWithTokenURI(131 function mintWithTokenURI(
132 address to,132 address to,
133 uint256 tokenId,
134 string memory tokenUri133 string memory tokenUri
135 ) external override returns (bool) {134 ) external override returns (uint256) {
136 return proxied.mintWithTokenURI(to, tokenId, tokenUri);135 return proxied.mintWithTokenURI(to, tokenUri);
137 }136 }
138137
139 function finishMinting() external override returns (bool) {138 function finishMinting() external override returns (bool) {
169 return proxied.mintBulk(to, tokenIds);168 return proxied.mintBulk(to, tokenIds);
170 }169 }
171170
172 function mintBulkWithTokenURI(address to, Tuple0[] memory tokens)171 function mintBulkWithTokenURI(address to, Tuple6[] memory tokens)
173 external172 external
174 override173 override
175 returns (bool)174 returns (bool)
modifiedtests/src/eth/proxy/nonFungibleProxy.test.tsdiffbeforeafterboth
111 await collectionEvmOwned.methods.addCollectionAdmin(contract.options.address).send();111 await collectionEvmOwned.methods.addCollectionAdmin(contract.options.address).send();
112112
113 {113 {
114 const nextTokenId = await contract.methods.nextTokenId().call();114 const result = await contract.methods.mintWithTokenURI(receiver, 'Test URI').send({from: caller});
115 expect(nextTokenId).to.be.equal('1');115 const tokenId = result.events.Transfer.returnValues.tokenId;
116 const result = await contract.methods.mintWithTokenURI(116 expect(tokenId).to.be.equal('1');
117 receiver,117
118 nextTokenId,
119 'Test URI',
120 ).send({from: caller});
121 const events = helper.eth.normalizeEvents(result.events);118 const events = helper.eth.normalizeEvents(result.events);
122 events[0].address = events[0].address.toLocaleLowerCase();119 events[0].address = events[0].address.toLocaleLowerCase();
123120
128 args: {125 args: {
129 from: '0x0000000000000000000000000000000000000000',126 from: '0x0000000000000000000000000000000000000000',
130 to: receiver,127 to: receiver,
131 tokenId: nextTokenId,128 tokenId,
132 },129 },
133 },130 },
134 ]);131 ]);
135132
136 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');133 expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
137 }134 }
138 });135 });
139136
modifiedtests/src/eth/reFungible.test.tsdiffbeforeafterboth
33 const caller = await helper.eth.createAccountWithBalance(donor);33 const caller = await helper.eth.createAccountWithBalance(donor);
34 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'TotalSupply', '6', '6');34 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'TotalSupply', '6', '6');
35 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);35 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
36 const nextTokenId = await contract.methods.nextTokenId().call();36
37 await contract.methods.mint(caller, nextTokenId).send();37 await contract.methods.mint(caller).send();
38
38 const totalSupply = await contract.methods.totalSupply().call();39 const totalSupply = await contract.methods.totalSupply().call();
39 expect(totalSupply).to.equal('1');40 expect(totalSupply).to.equal('1');
44 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'BalanceOf', '6', '6');45 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'BalanceOf', '6', '6');
45 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);46 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
4647
47 {
48 const nextTokenId = await contract.methods.nextTokenId().call();
49 await contract.methods.mint(caller, nextTokenId).send();48 await contract.methods.mint(caller).send();
50 }
51 {
52 const nextTokenId = await contract.methods.nextTokenId().call();
53 await contract.methods.mint(caller, nextTokenId).send();49 await contract.methods.mint(caller).send();
54 }
55 {
56 const nextTokenId = await contract.methods.nextTokenId().call();
57 await contract.methods.mint(caller, nextTokenId).send();50 await contract.methods.mint(caller).send();
58 }
5951
60 const balance = await contract.methods.balanceOf(caller).call();52 const balance = await contract.methods.balanceOf(caller).call();
61 expect(balance).to.equal('3');53 expect(balance).to.equal('3');
66 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'OwnerOf', '6', '6');58 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'OwnerOf', '6', '6');
67 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);59 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
6860
69 const tokenId = await contract.methods.nextTokenId().call();61 const result = await contract.methods.mint(caller).send();
70 await contract.methods.mint(caller, tokenId).send();62 const tokenId = result.events.Transfer.returnValues.tokenId;
7163
72 const owner = await contract.methods.ownerOf(tokenId).call();64 const owner = await contract.methods.ownerOf(tokenId).call();
73 expect(owner).to.equal(caller);65 expect(owner).to.equal(caller);
79 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'OwnerOf-AfterBurn', '6', '6');71 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'OwnerOf-AfterBurn', '6', '6');
80 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);72 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
8173
82 const tokenId = await contract.methods.nextTokenId().call();74 const result = await contract.methods.mint(caller).send();
83 await contract.methods.mint(caller, tokenId).send();75 const tokenId = result.events.Transfer.returnValues.tokenId;
84 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);76 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);
8577
86 await tokenContract.methods.repartition(2).send();78 await tokenContract.methods.repartition(2).send();
98 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'Partial-OwnerOf', '6', '6');90 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'Partial-OwnerOf', '6', '6');
99 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);91 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
10092
101 const tokenId = await contract.methods.nextTokenId().call();93 const result = await contract.methods.mint(caller).send();
102 await contract.methods.mint(caller, tokenId).send();94 const tokenId = result.events.Transfer.returnValues.tokenId;
103 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);95 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);
10496
105 await tokenContract.methods.repartition(2).send();97 await tokenContract.methods.repartition(2).send();
127 const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, 'Minty', '6', '6', '');119 const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, 'Minty', '6', '6', '');
128 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);120 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
129 121
130 const nextTokenId = await contract.methods.nextTokenId().call();
131 expect(nextTokenId).to.be.equal('1');
132 const result = await contract.methods.mintWithTokenURI(122 const result = await contract.methods.mintWithTokenURI(receiver, 'Test URI').send();
133 receiver,
134 nextTokenId,
135 'Test URI',
136 ).send();
137123
138 const event = result.events.Transfer;124 const event = result.events.Transfer;
139 expect(event.address).to.equal(collectionAddress);125 expect(event.address).to.equal(collectionAddress);
140 expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');126 expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');
141 expect(event.returnValues.to).to.equal(receiver);127 expect(event.returnValues.to).to.equal(receiver);
128 const tokenId = event.returnValues.tokenId;
142 expect(event.returnValues.tokenId).to.equal(nextTokenId);129 expect(tokenId).to.be.equal('1');
143130
144 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');131 expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
145 });132 });
146133
147 itEth('Can perform mintBulk()', async ({helper}) => {134 itEth('Can perform mintBulk()', async ({helper}) => {
182 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Burny', '6', '6');169 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Burny', '6', '6');
183 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);170 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
184171
185 const tokenId = await contract.methods.nextTokenId().call();172 const result = await contract.methods.mint(caller).send();
186 await contract.methods.mint(caller, tokenId).send();173 const tokenId = result.events.Transfer.returnValues.tokenId;
187 {174 {
188 const result = await contract.methods.burn(tokenId).send();175 const result = await contract.methods.burn(tokenId).send();
189 const event = result.events.Transfer;176 const event = result.events.Transfer;
200 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'TransferFromy', '6', '6');187 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'TransferFromy', '6', '6');
201 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);188 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
202189
203 const tokenId = await contract.methods.nextTokenId().call();190 const result = await contract.methods.mint(caller).send();
191 const tokenId = result.events.Transfer.returnValues.tokenId;
192
204 const tokenAddress = helper.ethAddress.fromTokenId(collectionId, tokenId);193 const tokenAddress = helper.ethAddress.fromTokenId(collectionId, tokenId);
205 await contract.methods.mint(caller, tokenId).send();
206194
207 const tokenContract = helper.ethNativeContract.rftToken(tokenAddress, caller);195 const tokenContract = helper.ethNativeContract.rftToken(tokenAddress, caller);
208 await tokenContract.methods.repartition(15).send();196 await tokenContract.methods.repartition(15).send();
244 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Transferry', '6', '6');232 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Transferry', '6', '6');
245 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);233 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
246234
247 const tokenId = await contract.methods.nextTokenId().call();235 const result = await contract.methods.mint(caller).send();
248 await contract.methods.mint(caller, tokenId).send();236 const tokenId = result.events.Transfer.returnValues.tokenId;
249237
250 {238 {
251 const result = await contract.methods.transfer(receiver, tokenId).send();239 const result = await contract.methods.transfer(receiver, tokenId).send();
274 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'Transferry-Partial-to-Full', '6', '6');262 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'Transferry-Partial-to-Full', '6', '6');
275 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);263 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
276264
277 const tokenId = await contract.methods.nextTokenId().call();265 const result = await contract.methods.mint(caller).send();
278 await contract.methods.mint(caller, tokenId).send();266 const tokenId = result.events.Transfer.returnValues.tokenId;
279267
280 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);268 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);
281269
301 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'Transferry-Full-to-Partial', '6', '6');289 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'Transferry-Full-to-Partial', '6', '6');
302 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);290 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
303291
304 const tokenId = await contract.methods.nextTokenId().call();292 const result = await contract.methods.mint(caller).send();
305 await contract.methods.mint(caller, tokenId).send();293 const tokenId = result.events.Transfer.returnValues.tokenId;
306294
307 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);295 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);
308296
339 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Feeful-Transfer-From', '6', '6');327 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Feeful-Transfer-From', '6', '6');
340 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);328 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
341329
342 const tokenId = await contract.methods.nextTokenId().call();330 const result = await contract.methods.mint(caller).send();
343 await contract.methods.mint(caller, tokenId).send();331 const tokenId = result.events.Transfer.returnValues.tokenId;
344332
345 const cost = await helper.eth.recordCallFee(caller, () => contract.methods.transferFrom(caller, receiver, tokenId).send());333 const cost = await helper.eth.recordCallFee(caller, () => contract.methods.transferFrom(caller, receiver, tokenId).send());
346 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));334 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
353 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Feeful-Transfer', '6', '6');341 const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Feeful-Transfer', '6', '6');
354 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);342 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
355343
356 const tokenId = await contract.methods.nextTokenId().call();344 const result = await contract.methods.mint(caller).send();
357 await contract.methods.mint(caller, tokenId).send();345 const tokenId = result.events.Transfer.returnValues.tokenId;
358346
359 const cost = await helper.eth.recordCallFee(caller, () => contract.methods.transfer(receiver, tokenId).send());347 const cost = await helper.eth.recordCallFee(caller, () => contract.methods.transfer(receiver, tokenId).send());
360 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));348 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
modifiedtests/src/eth/reFungibleToken.test.tsdiffbeforeafterboth
83 const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, 'Mint collection', 'a', 'b', baseUri);83 const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, 'Mint collection', 'a', 'b', baseUri);
84 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);84 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
85 85
86 const nextTokenId = await contract.methods.nextTokenId().call();
87 expect(nextTokenId).to.be.equal('1');
88 const result = await contract.methods.mint(86 const result = await contract.methods.mint(receiver).send();
89 receiver,
90 nextTokenId,
91 ).send();
92
93 if (propertyKey && propertyValue) {
94 // Set URL or suffix
95 await contract.methods.setProperty(nextTokenId, propertyKey, Buffer.from(propertyValue)).send();
96 }
9787
98 const event = result.events.Transfer;88 const event = result.events.Transfer;
89 const tokenId = event.returnValues.tokenId;
90 expect(tokenId).to.be.equal('1');
99 expect(event.address).to.be.equal(collectionAddress);91 expect(event.address).to.be.equal(collectionAddress);
100 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');92 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');
101 expect(event.returnValues.to).to.be.equal(receiver);93 expect(event.returnValues.to).to.be.equal(receiver);
94
95 if (propertyKey && propertyValue) {
96 // Set URL or suffix
102 expect(event.returnValues.tokenId).to.be.equal(nextTokenId);97 await contract.methods.setProperty(tokenId, propertyKey, Buffer.from(propertyValue)).send();
98 }
10399
104 return {contract, nextTokenId};100 return {contract, nextTokenId: tokenId};
105 }101 }
106102
107 itEth('Empty tokenURI', async ({helper}) => {103 itEth('Empty tokenURI', async ({helper}) => {
295 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'Devastation', '6', '6');291 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'Devastation', '6', '6');
296 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);292 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
297293
298 const tokenId = await contract.methods.nextTokenId().call();294 const result = await contract.methods.mint(caller).send();
299 await contract.methods.mint(caller, tokenId).send();295 const tokenId = result.events.Transfer.returnValues.tokenId;
300 const tokenAddress = helper.ethAddress.fromTokenId(collectionId, tokenId);296 const tokenAddress = helper.ethAddress.fromTokenId(collectionId, tokenId);
301 const tokenContract = helper.ethNativeContract.rftToken(tokenAddress, caller);297 const tokenContract = helper.ethNativeContract.rftToken(tokenAddress, caller);
302298
480 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(owner, 'Sands', '', 'GRAIN');476 const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(owner, 'Sands', '', 'GRAIN');
481 const collectionContract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);477 const collectionContract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
482 478
483 const tokenId = await collectionContract.methods.nextTokenId().call();479 const result = await collectionContract.methods.mint(owner).send();
484 await collectionContract.methods.mint(owner, tokenId).send();480 const tokenId = result.events.Transfer.returnValues.tokenId;
481
485 const tokenAddress = helper.ethAddress.fromTokenId(collectionId, tokenId);482 const tokenAddress = helper.ethAddress.fromTokenId(collectionId, tokenId);
486 const tokenContract = helper.ethNativeContract.rftToken(tokenAddress, owner);483 const tokenContract = helper.ethNativeContract.rftToken(tokenAddress, owner);
modifiedtests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth
187 }187 }
188188
189 async createERC721MetadataCompatibleNFTCollection(signer: string, name: string, description: string, tokenPrefix: string, baseUri: string): Promise<{collectionId: number, collectionAddress: string}> {189 async createERC721MetadataCompatibleNFTCollection(signer: string, name: string, description: string, tokenPrefix: string, baseUri: string): Promise<{collectionId: number, collectionAddress: string}> {
190 const collectionCreationPrice = this.helper.balance.getCollectionCreationPrice();
191 const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);190 const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);
192 191
193 const result = await collectionHelper.methods.createERC721MetadataCompatibleNFTCollection(name, description, tokenPrefix, baseUri).send({value: Number(collectionCreationPrice)});192 const {collectionId, collectionAddress} = await this.createNFTCollection(signer, name, description, tokenPrefix)
194193
195 const collectionAddress = this.helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);194 await collectionHelper.methods.makeCollectionERC721MetadataCompatible(collectionAddress, baseUri).send();
196 const collectionId = this.helper.ethAddress.extractCollectionId(collectionAddress);
197195
198 return {collectionId, collectionAddress};196 return {collectionId, collectionAddress};
199 }197 }
211 }209 }
212210
213 async createERC721MetadataCompatibleRFTCollection(signer: string, name: string, description: string, tokenPrefix: string, baseUri: string): Promise<{collectionId: number, collectionAddress: string}> {211 async createERC721MetadataCompatibleRFTCollection(signer: string, name: string, description: string, tokenPrefix: string, baseUri: string): Promise<{collectionId: number, collectionAddress: string}> {
214 const collectionCreationPrice = this.helper.balance.getCollectionCreationPrice();
215 const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);212 const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);
216 213
217 const result = await collectionHelper.methods.createERC721MetadataCompatibleRFTCollection(name, description, tokenPrefix, baseUri).send({value: Number(collectionCreationPrice)});214 const {collectionId, collectionAddress} = await this.createRFTCollection(signer, name, description, tokenPrefix)
218215
219 const collectionAddress = this.helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);216 await collectionHelper.methods.makeCollectionERC721MetadataCompatible(collectionAddress, baseUri).send();
220 const collectionId = this.helper.ethAddress.extractCollectionId(collectionAddress);
221217
222 return {collectionId, collectionAddress};218 return {collectionId, collectionAddress};
223 }219 }