git.delta.rocks / unique-network / refs/commits / 1d30029fd67b

difftreelog

test market evm tests to playgrounds

Maksandre2022-10-04parent: #d3b796f.patch.diff
in: master

2 files changed

modifiedtests/src/eth/marketplace/marketplace.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {usingPlaygrounds} from './../../util/playgrounds/index';
18import {IKeyringPair} from '@polkadot/types/types';
17import {readFile} from 'fs/promises';19import {readFile} from 'fs/promises';
18import {getBalanceSingle} from '../../substrate/get-balance';20import {collectionIdToAddress, contractHelpers, GAS_ARGS, SponsoringMode} from '../util/helpers';
19import {
20 addToAllowListExpectSuccess,
21 confirmSponsorshipExpectSuccess,
22 createCollectionExpectSuccess,
23 createItemExpectSuccess,
24 getTokenOwner,
25 setCollectionLimitsExpectSuccess,
26 setCollectionSponsorExpectSuccess,
27 transferExpectSuccess,
28 transferFromExpectSuccess,
29 transferBalanceTo,
30} from '../../util/helpers';
31import {collectionIdToAddress, contractHelpers, createEthAccountWithBalance, executeEthTxOnSub, GAS_ARGS, itWeb3, SponsoringMode, subToEth, subToEthLowercase, transferBalanceToEth} from '../util/helpers';
32import {evmToAddress} from '@polkadot/util-crypto';
33import nonFungibleAbi from '../nonFungibleAbi.json';21import nonFungibleAbi from '../nonFungibleAbi.json';
3422
35import {expect} from 'chai';23import {itEth, expect} from '../util/playgrounds';
3624
37const PRICE = 2000n;25const PRICE = 2000n;
3826
39describe('Matcher contract usage', () => {27describe('Matcher contract usage', () => {
40 itWeb3('With UNQ', async ({api, web3, privateKeyWrapper}) => {28 let donor: IKeyringPair;
29 let alice: IKeyringPair;
30 let aliceMirror: string;
31 let aliceDoubleMirror: string;
32 let seller: IKeyringPair;
33 let sellerMirror: string;
34
35 before(async () => {
36 await usingPlaygrounds(async (_helper, privateKey) => {
41 const alice = privateKeyWrapper('//Alice');37 donor = privateKey('//Alice');
42 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);38 });
39 });
40
41 beforeEach(async () => {
42 await usingPlaygrounds(async (helper, privateKey) => {
43 [alice] = await helper.arrange.createAccounts([10000n], donor);
43 const matcherOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);44 aliceMirror = helper.address.substrateToEth(alice.address).toLowerCase();
45 aliceDoubleMirror = helper.address.ethToSubstrate(aliceMirror);
46 seller = privateKey(`//Seller/${Date.now()}`);
47 sellerMirror = helper.address.substrateToEth(seller.address).toLowerCase();
48
49 await helper.balance.transferToSubstrate(donor, aliceDoubleMirror, 10_000_000_000_000_000_000n);
50 });
51 });
52
53 itEth('With UNQ', async ({helper}) => {
54 const web3 = helper.web3!;
55
56 const sponsor = await helper.eth.createAccountWithBalance(donor);
57 const matcherOwner = await helper.eth.createAccountWithBalance(donor);
44 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {58 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {
45 from: matcherOwner,59 from: matcherOwner,
46 ...GAS_ARGS,60 ...GAS_ARGS,
53 await helpers.methods.setSponsor(matcher.options.address, sponsor).send({from: matcherOwner});67 await helpers.methods.setSponsor(matcher.options.address, sponsor).send({from: matcherOwner});
54 await helpers.methods.confirmSponsorship(matcher.options.address).send({from: sponsor});68 await helpers.methods.confirmSponsorship(matcher.options.address).send({from: sponsor});
5569
56 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});70 const collection = await helper.nft.mintCollection(alice, {limits: {sponsorApproveTimeout: 1}, pendingSponsor: alice.address});
57 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorApproveTimeout: 1});71 await collection.confirmSponsorship(alice);
72 await collection.addToAllowList(alice, {Substrate: aliceDoubleMirror});
58 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner});73 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collection.collectionId), {from: matcherOwner});
59 await setCollectionSponsorExpectSuccess(collectionId, alice.address);74 await helper.eth.transferBalanceFromSubstrate(donor, aliceMirror);
60 await transferBalanceToEth(api, alice, subToEth(alice.address));
61 await confirmSponsorshipExpectSuccess(collectionId);
6275
63 await helpers.methods.toggleAllowed(matcher.options.address, subToEth(alice.address), true).send({from: matcherOwner});76 await helpers.methods.toggleAllowed(matcher.options.address, aliceMirror, true).send({from: matcherOwner});
64 await addToAllowListExpectSuccess(alice, collectionId, evmToAddress(subToEth(alice.address)));77 await helpers.methods.toggleAllowed(matcher.options.address, sellerMirror, true).send({from: matcherOwner});
6578
66 const seller = privateKeyWrapper(`//Seller/${Date.now()}`);79 const token = await collection.mintToken(alice, {Ethereum: sellerMirror});
67 await helpers.methods.toggleAllowed(matcher.options.address, subToEth(seller.address), true).send({from: matcherOwner});
6880
69 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);
70
71 // To transfer item to matcher it first needs to be transfered to EVM account of bob
72 await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)});
73
74 // Token is owned by seller initially81 // Token is owned by seller initially
75 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)});82 expect(await token.getOwner()).to.be.deep.equal({Ethereum: sellerMirror});
7683
77 // Ask84 // Ask
78 {85 {
79 await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));86 await helper.eth.sendEVM(seller, evmCollection.options.address, evmCollection.methods.approve(matcher.options.address, token.tokenId).encodeABI(), '0');
80 await executeEthTxOnSub(web3, api, seller, matcher, m => m.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, tokenId));87 await helper.eth.sendEVM(seller, matcher.options.address, matcher.methods.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, token.tokenId).encodeABI(), '0');
81 }88 }
8289
83 // Token is transferred to matcher90 // Token is transferred to matcher
84 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});91 expect(await token.getOwner()).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});
8592
86 // Buy93 // Buy
87 {94 {
88 const sellerBalanceBeforePurchase = await getBalanceSingle(api, seller.address);95 const sellerBalanceBeforePurchase = await helper.balance.getSubstrate(seller.address);
89 await executeEthTxOnSub(web3, api, alice, matcher, m => m.buy(evmCollection.options.address, tokenId), {value: PRICE});96 await helper.eth.sendEVM(alice, matcher.options.address, matcher.methods.buy(evmCollection.options.address, token.tokenId).encodeABI(), PRICE.toString());
90 expect(await getBalanceSingle(api, seller.address) - sellerBalanceBeforePurchase === PRICE);97 expect(await helper.balance.getSubstrate(seller.address) - sellerBalanceBeforePurchase === PRICE);
91 }98 }
9299
93 // Token is transferred to evm account of alice100 // Token is transferred to evm account of alice
94 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)});101 expect(await token.getOwner()).to.be.deep.equal({Ethereum: aliceMirror});
95102
96 // Transfer token to substrate side of alice103 // Transfer token to substrate side of alice
97 await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address});104 await token.transferFrom(alice, {Ethereum: aliceMirror}, {Substrate: alice.address});
98105
99 // Token is transferred to substrate account of alice, seller received funds106 // Token is transferred to substrate account of alice, seller received funds
100 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address});107 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});
101 });108 });
102109
110 itEth('With escrow', async ({helper}) => {
111 const web3 = helper.web3!;
103112
104 itWeb3('With escrow', async ({api, web3, privateKeyWrapper}) => {113 const sponsor = await helper.eth.createAccountWithBalance(donor);
105 const alice = privateKeyWrapper('//Alice');
106 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
107 const matcherOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);114 const matcherOwner = await helper.eth.createAccountWithBalance(donor);
108 const escrow = await createEthAccountWithBalance(api, web3, privateKeyWrapper);115 const escrow = await helper.eth.createAccountWithBalance(donor);
109 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {116 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {
110 from: matcherOwner,117 from: matcherOwner,
111 ...GAS_ARGS,118 ...GAS_ARGS,
119 await helpers.methods.setSponsor(matcher.options.address, sponsor).send({from: matcherOwner});126 await helpers.methods.setSponsor(matcher.options.address, sponsor).send({from: matcherOwner});
120 await helpers.methods.confirmSponsorship(matcher.options.address).send({from: sponsor});127 await helpers.methods.confirmSponsorship(matcher.options.address).send({from: sponsor});
121128
122 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});129 const collection = await helper.nft.mintCollection(alice, {limits: {sponsorApproveTimeout: 1}, pendingSponsor: alice.address});
123 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorApproveTimeout: 1});130 await collection.confirmSponsorship(alice);
131 await collection.addToAllowList(alice, {Substrate: aliceDoubleMirror});
124 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner});132 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collection.collectionId), {from: matcherOwner});
125 await setCollectionSponsorExpectSuccess(collectionId, alice.address);133 await helper.eth.transferBalanceFromSubstrate(donor, aliceMirror);
126 await transferBalanceToEth(api, alice, subToEth(alice.address));
127 await confirmSponsorshipExpectSuccess(collectionId);
128134
129 await helpers.methods.toggleAllowed(matcher.options.address, subToEth(alice.address), true).send({from: matcherOwner});
130 await addToAllowListExpectSuccess(alice, collectionId, evmToAddress(subToEth(alice.address)));
131135
132 const seller = privateKeyWrapper(`//Seller/${Date.now()}`);136 await helpers.methods.toggleAllowed(matcher.options.address, aliceMirror, true).send({from: matcherOwner});
133 await helpers.methods.toggleAllowed(matcher.options.address, subToEth(seller.address), true).send({from: matcherOwner});
134137
135 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);138 await helpers.methods.toggleAllowed(matcher.options.address, sellerMirror, true).send({from: matcherOwner});
136139
137 // To transfer item to matcher it first needs to be transfered to EVM account of bob140 const token = await collection.mintToken(alice, {Ethereum: sellerMirror});
138 await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)});
139141
140 // Token is owned by seller initially142 // Token is owned by seller initially
141 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)});143 expect(await token.getOwner()).to.be.deep.equal({Ethereum: sellerMirror});
142144
143 // Ask145 // Ask
144 {146 {
145 await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));147 await helper.eth.sendEVM(seller, evmCollection.options.address, evmCollection.methods.approve(matcher.options.address, token.tokenId).encodeABI(), '0');
146 await executeEthTxOnSub(web3, api, seller, matcher, m => m.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, tokenId));148 await helper.eth.sendEVM(seller, matcher.options.address, matcher.methods.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, token.tokenId).encodeABI(), '0');
147 }149 }
148150
149 // Token is transferred to matcher151 // Token is transferred to matcher
150 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});152 expect(await token.getOwner()).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});
151153
152 // Give buyer KSM154 // Give buyer KSM
153 await matcher.methods.depositKSM(PRICE, subToEth(alice.address)).send({from: escrow});155 await matcher.methods.depositKSM(PRICE, aliceMirror).send({from: escrow});
154156
155 // Buy157 // Buy
156 {158 {
157 expect(await matcher.methods.balanceKSM(subToEth(seller.address)).call()).to.be.equal('0');159 expect(await matcher.methods.balanceKSM(sellerMirror).call()).to.be.equal('0');
158 expect(await matcher.methods.balanceKSM(subToEth(alice.address)).call()).to.be.equal(PRICE.toString());160 expect(await matcher.methods.balanceKSM(aliceMirror).call()).to.be.equal(PRICE.toString());
159161
160 await executeEthTxOnSub(web3, api, alice, matcher, m => m.buyKSM(evmCollection.options.address, tokenId, subToEth(alice.address), subToEth(alice.address)));162 await helper.eth.sendEVM(alice, matcher.options.address, matcher.methods.buyKSM(evmCollection.options.address, token.tokenId, aliceMirror, aliceMirror).encodeABI(), '0');
161163
162 // Price is removed from buyer balance, and added to seller164 // Price is removed from buyer balance, and added to seller
163 expect(await matcher.methods.balanceKSM(subToEth(alice.address)).call()).to.be.equal('0');165 expect(await matcher.methods.balanceKSM(aliceMirror).call()).to.be.equal('0');
164 expect(await matcher.methods.balanceKSM(subToEth(seller.address)).call()).to.be.equal(PRICE.toString());166 expect(await matcher.methods.balanceKSM(sellerMirror).call()).to.be.equal(PRICE.toString());
165 }167 }
166168
167 // Token is transferred to evm account of alice169 // Token is transferred to evm account of alice
168 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)});170 expect(await token.getOwner()).to.be.deep.equal({Ethereum: aliceMirror});
169171
170 // Transfer token to substrate side of alice172 // Transfer token to substrate side of alice
171 await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address});173 await token.transferFrom(alice, {Ethereum: aliceMirror}, {Substrate: alice.address});
172174
173 // Token is transferred to substrate account of alice, seller received funds175 // Token is transferred to substrate account of alice, seller received funds
174 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address});176 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});
175 });177 });
176178
179 itEth('Sell tokens from substrate user via EVM contract', async ({helper, privateKey}) => {
180 const web3 = helper.web3!;
177181
178 itWeb3('Sell tokens from substrate user via EVM contract', async ({api, web3, privateKeyWrapper}) => {182 const matcherOwner = await helper.eth.createAccountWithBalance(donor);
179 const alice = privateKeyWrapper('//Alice');
180 const matcherOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
181 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {183 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {
182 from: matcherOwner,184 from: matcherOwner,
183 ...GAS_ARGS,185 ...GAS_ARGS,
184 });186 });
185 const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments:[matcherOwner]}).send({from: matcherOwner});187 const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments:[matcherOwner]}).send({from: matcherOwner});
186 await transferBalanceToEth(api, alice, matcher.options.address);188 await helper.eth.transferBalanceFromSubstrate(donor, matcher.options.address);
187189
188 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});190 const collection = await helper.nft.mintCollection(alice, {limits: {sponsorApproveTimeout: 1}});
189 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorApproveTimeout: 1});
190 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner});191 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collection.collectionId), {from: matcherOwner});
191192
192 const seller = privateKeyWrapper(`//Seller/${Date.now()}`);193 await helper.balance.transferToSubstrate(donor, seller.address, 100_000_000_000_000_000_000n);
193 await transferBalanceTo(api, alice, seller.address);
194 194
195 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);195 const token = await collection.mintToken(alice, {Ethereum: sellerMirror});
196
197 // To transfer item to matcher it first needs to be transfered to EVM account of bob
198 await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)});
199196
200 // Token is owned by seller initially197 // Token is owned by seller initially
201 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)});198 expect(await token.getOwner()).to.be.deep.equal({Ethereum: sellerMirror});
202199
203 // Ask200 // Ask
204 {201 {
205 await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));202 await helper.eth.sendEVM(seller, evmCollection.options.address, evmCollection.methods.approve(matcher.options.address, token.tokenId).encodeABI(), '0');
206 await executeEthTxOnSub(web3, api, seller, matcher, m => m.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, tokenId));203 await helper.eth.sendEVM(seller, matcher.options.address, matcher.methods.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, token.tokenId).encodeABI(), '0');
207 }204 }
208205
209 // Token is transferred to matcher206 // Token is transferred to matcher
210 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});207 expect(await token.getOwner()).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});
211208
212 // Buy209 // Buy
213 {210 {
214 const sellerBalanceBeforePurchase = await getBalanceSingle(api, seller.address);211 const sellerBalanceBeforePurchase = await helper.balance.getSubstrate(seller.address);
215 await executeEthTxOnSub(web3, api, alice, matcher, m => m.buy(evmCollection.options.address, tokenId), {value: PRICE});212 await helper.eth.sendEVM(alice, matcher.options.address, matcher.methods.buy(evmCollection.options.address, token.tokenId).encodeABI(), PRICE.toString());
216 expect(await getBalanceSingle(api, seller.address) - sellerBalanceBeforePurchase === PRICE);213 expect(await helper.balance.getSubstrate(seller.address) - sellerBalanceBeforePurchase === PRICE);
217 }214 }
218215
219 // Token is transferred to evm account of alice216 // Token is transferred to evm account of alice
220 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)});217 expect(await token.getOwner()).to.be.deep.equal({Ethereum: aliceMirror});
221218
222 // Transfer token to substrate side of alice219 // Transfer token to substrate side of alice
223 await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address});220 await token.transferFrom(alice, {Ethereum: aliceMirror}, {Substrate: alice.address});
224221
225 // Token is transferred to substrate account of alice, seller received funds222 // Token is transferred to substrate account of alice, seller received funds
226 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address});223 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});
227 });224 });
228});225});
229226
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/unique.ts
+++ b/tests/src/util/playgrounds/unique.ts
@@ -275,6 +275,7 @@
   }
   
   private static extractData(data: any, type: any): any {
+    if(!type) return data.toHuman();
     if (['u16', 'u32'].indexOf(type.type) > -1) return data.toNumber();
     if (['u64', 'u128', 'u256'].indexOf(type.type) > -1) return data.toBigInt();
     if(type.hasOwnProperty('sub')) return this.extractSub(data, type.sub);