git.delta.rocks / unique-network / refs/commits / 2e1cabd3ad66

difftreelog

feat configure min gas price

Yaroslav Bolyukin2021-11-05parent: #540e85d.patch.diff
in: master

9 files changed

modifiedruntime/src/lib.rsdiffbeforeafterboth
243pub struct FixedFee;243pub struct FixedFee;
244impl FeeCalculator for FixedFee {244impl FeeCalculator for FixedFee {
245 fn min_gas_price() -> U256 {245 fn min_gas_price() -> U256 {
246 // Targeting 0.15 UNQ per transfer
246 1.into()247 (1 * MICROUNIQUE).into()
247 }248 }
248}249}
249250
modifiedtests/src/creditFeesToTreasury.test.tsdiffbeforeafterboth
14 createItemExpectSuccess,14 createItemExpectSuccess,
15 getGenericResult,15 getGenericResult,
16 transferExpectSuccess,16 transferExpectSuccess,
17 UNIQUE,
17} from './util/helpers';18} from './util/helpers';
1819
19import {default as waitNewBlocks} from './substrate/wait-new-blocks';20import {default as waitNewBlocks} from './substrate/wait-new-blocks';
169 const aliceBalanceBefore: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();170 const aliceBalanceBefore: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
170 await transferExpectSuccess(collectionId, tokenId, alice, bob, 1, 'NFT');171 await transferExpectSuccess(collectionId, tokenId, alice, bob, 1, 'NFT');
171 const aliceBalanceAfter: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();172 const aliceBalanceAfter: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt();
172 const fee = aliceBalanceBefore - aliceBalanceAfter;173 const fee = Number(aliceBalanceBefore - aliceBalanceAfter) / Number(UNIQUE);
173174
174 // console.log(fee.toString());
175 const expectedTransferFee = 0.1;175 const expectedTransferFee = 0.1;
176 const tolerance = 0.001;176 const tolerance = 0.001;
177 expect(Number(fee) / 1e15 - expectedTransferFee).to.be.lessThan(tolerance);177 expect(Number(fee) / Number(UNIQUE) - expectedTransferFee).to.be.lessThan(tolerance);
178 });178 });
179 });179 });
180180
modifiedtests/src/eth/base.test.tsdiffbeforeafterboth
11
2import {createEthAccount, createEthAccountWithBalance, deployFlipper, ethBalanceViaSub, GAS_ARGS, itWeb3, recordEthFee} from './util/helpers';2import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, deployFlipper, ethBalanceViaSub, GAS_ARGS, itWeb3, recordEthFee} from './util/helpers';
3import {expect} from 'chai';3import {expect} from 'chai';
4import {UNIQUE} from '../util/helpers';4import {createCollectionExpectSuccess, createItemExpectSuccess, UNIQUE} from '../util/helpers';
5import nonFungibleAbi from './nonFungibleAbi.json';
6import privateKey from '../substrate/privateKey';
57
6describe('Contract calls', () => {8describe('Contract calls', () => {
7 itWeb3('Call of simple contract fee is less than 0.2 UNQ', async ({web3, api}) => {9 itWeb3('Call of simple contract fee is less than 0.2 UNQ', async ({web3, api}) => {
20 expect(cost - await ethBalanceViaSub(api, userB) < BigInt(0.2 * Number(UNIQUE))).to.be.true;22 expect(cost - await ethBalanceViaSub(api, userB) < BigInt(0.2 * Number(UNIQUE))).to.be.true;
21 });23 });
24
25 itWeb3('NFT transfer is close to 0.15 UNQ', async ({web3, api}) => {
26 const caller = await createEthAccountWithBalance(api, web3);
27 const receiver = createEthAccount(web3);
28
29 const alice = privateKey('//Alice');
30 const collection = await createCollectionExpectSuccess({
31 mode: {type: 'NFT'},
32 });
33 const itemId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});
34
35 const address = collectionIdToAddress(collection);
36 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
37
38 const cost = await recordEthFee(api, caller, () => contract.methods.transfer(receiver, itemId).send(caller));
39
40 const fee = Number(cost) / Number(UNIQUE);
41 const expectedFee = 0.15;
42 const tolerance = 0.002;
43
44 expect(Math.abs(fee - expectedFee) < tolerance).to.be.true;
45 });
22});46});
2347
modifiedtests/src/eth/fungible.test.tsdiffbeforeafterboth
95 const alice = privateKey('//Alice');95 const alice = privateKey('//Alice');
9696
97 const owner = createEthAccount(web3);97 const owner = createEthAccount(web3);
98 await transferBalanceToEth(api, alice, owner, 999999999999999);98 await transferBalanceToEth(api, alice, owner);
9999
100 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});100 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
101101
102 const spender = createEthAccount(web3);102 const spender = createEthAccount(web3);
103 await transferBalanceToEth(api, alice, spender, 999999999999999);103 await transferBalanceToEth(api, alice, spender);
104104
105 const receiver = createEthAccount(web3);105 const receiver = createEthAccount(web3);
106106
153 const alice = privateKey('//Alice');153 const alice = privateKey('//Alice');
154154
155 const owner = createEthAccount(web3);155 const owner = createEthAccount(web3);
156 await transferBalanceToEth(api, alice, owner, 999999999999999);156 await transferBalanceToEth(api, alice, owner);
157157
158 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});158 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});
159159
160 const receiver = createEthAccount(web3);160 const receiver = createEthAccount(web3);
161 await transferBalanceToEth(api, alice, receiver, 999999999999999);161 await transferBalanceToEth(api, alice, receiver);
162162
163 const address = collectionIdToAddress(collection);163 const address = collectionIdToAddress(collection);
164 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});164 const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS});
modifiedtests/src/eth/marketplace/marketplace.test.tsdiffbeforeafterboth
3838
39 // Ask39 // Ask
40 {40 {
41 await executeEthTxOnSub(api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));41 await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));
42 await executeEthTxOnSub(api, seller, matcher, m => m.setAsk(PRICE, '0x0000000000000000000000000000000000000000', evmCollection.options.address, tokenId, 1));42 await executeEthTxOnSub(web3, api, seller, matcher, m => m.setAsk(PRICE, '0x0000000000000000000000000000000000000000', evmCollection.options.address, tokenId, 1));
43 }43 }
4444
45 // Token is transferred to matcher45 // Token is transferred to matcher
49 {49 {
50 const sellerBalanceBeforePurchase = await getBalanceSingle(api, seller.address);50 const sellerBalanceBeforePurchase = await getBalanceSingle(api, seller.address);
51 // There is two functions named 'buy', so we should provide full signature51 // There is two functions named 'buy', so we should provide full signature
52 await executeEthTxOnSub(api, alice, matcher, m => m['buy(address,uint256)'](evmCollection.options.address, tokenId), {value: PRICE});52 await executeEthTxOnSub(web3, api, alice, matcher, m => m['buy(address,uint256)'](evmCollection.options.address, tokenId), {value: PRICE});
53 expect(await getBalanceSingle(api, seller.address) - sellerBalanceBeforePurchase === PRICE);53 expect(await getBalanceSingle(api, seller.address) - sellerBalanceBeforePurchase === PRICE);
54 }54 }
5555
9595
96 // Ask96 // Ask
97 {97 {
98 await executeEthTxOnSub(api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));98 await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));
99 await executeEthTxOnSub(api, seller, matcher, m => m.setAsk(PRICE, evmFungible.options.address, evmCollection.options.address, tokenId, 1));99 await executeEthTxOnSub(web3, api, seller, matcher, m => m.setAsk(PRICE, evmFungible.options.address, evmCollection.options.address, tokenId, 1));
100 }100 }
101101
102 // Token is transferred to matcher102 // Token is transferred to matcher
107 const sellerBalanceBeforePurchase = BigInt(await evmFungible.methods.balanceOf(subToEth(seller.address)).call());107 const sellerBalanceBeforePurchase = BigInt(await evmFungible.methods.balanceOf(subToEth(seller.address)).call());
108 const buyerBalanceBeforePurchase = BigInt(await evmFungible.methods.balanceOf(subToEth(alice.address)).call());108 const buyerBalanceBeforePurchase = BigInt(await evmFungible.methods.balanceOf(subToEth(alice.address)).call());
109109
110 await executeEthTxOnSub(api, alice, evmFungible, m => m.approve(matcher.options.address, PRICE));110 await executeEthTxOnSub(web3, api, alice, evmFungible, m => m.approve(matcher.options.address, PRICE));
111 // There is two functions named 'buy', so we should provide full signature111 // There is two functions named 'buy', so we should provide full signature
112 await executeEthTxOnSub(api, alice, matcher, m =>112 await executeEthTxOnSub(web3, api, alice, matcher, m =>
113 m['buy(address,uint256,address,uint256)'](evmCollection.options.address, tokenId, evmFungible.options.address, PRICE));113 m['buy(address,uint256,address,uint256)'](evmCollection.options.address, tokenId, evmFungible.options.address, PRICE));
114114
115 // Approved price is removed from buyer balance, and added to seller115 // Approved price is removed from buyer balance, and added to seller
158158
159 // Ask159 // Ask
160 {160 {
161 await executeEthTxOnSub(api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));161 await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));
162 await executeEthTxOnSub(api, seller, matcher, m => m.setAsk(PRICE, ksmToken, evmCollection.options.address, tokenId, 1));162 await executeEthTxOnSub(web3, api, seller, matcher, m => m.setAsk(PRICE, ksmToken, evmCollection.options.address, tokenId, 1));
163 }163 }
164164
165 // Token is transferred to matcher165 // Token is transferred to matcher
173 expect(await matcher.methods.escrowBalance(ksmToken, subToEth(seller.address)).call()).to.be.equal('0');173 expect(await matcher.methods.escrowBalance(ksmToken, subToEth(seller.address)).call()).to.be.equal('0');
174 expect(await matcher.methods.escrowBalance(ksmToken, subToEth(alice.address)).call()).to.be.equal(PRICE.toString());174 expect(await matcher.methods.escrowBalance(ksmToken, subToEth(alice.address)).call()).to.be.equal(PRICE.toString());
175175
176 await executeEthTxOnSub(api, alice, matcher, m => m.buy(evmCollection.options.address, tokenId));176 await executeEthTxOnSub(web3, api, alice, matcher, m => m.buy(evmCollection.options.address, tokenId));
177177
178 // Price is removed from buyer balance, and added to seller178 // Price is removed from buyer balance, and added to seller
179 expect(await matcher.methods.escrowBalance(ksmToken, subToEth(alice.address)).call()).to.be.equal('0');179 expect(await matcher.methods.escrowBalance(ksmToken, subToEth(alice.address)).call()).to.be.equal('0');
modifiedtests/src/eth/nonFungible.test.tsdiffbeforeafterboth
203 const alice = privateKey('//Alice');203 const alice = privateKey('//Alice');
204204
205 const owner = createEthAccount(web3);205 const owner = createEthAccount(web3);
206 await transferBalanceToEth(api, alice, owner, 999999999999999);206 await transferBalanceToEth(api, alice, owner);
207207
208 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});208 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
209209
213 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);213 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);
214214
215 {215 {
216 const result = await contract.methods.approve(spender, tokenId).send({from: owner, gas: '0x1000000', gasPrice: '0x01'});216 const result = await contract.methods.approve(spender, tokenId).send({from: owner, ...GAS_ARGS});
217 const events = normalizeEvents(result.events);217 const events = normalizeEvents(result.events);
218218
219 expect(events).to.be.deep.equal([219 expect(events).to.be.deep.equal([
237 const alice = privateKey('//Alice');237 const alice = privateKey('//Alice');
238238
239 const owner = createEthAccount(web3);239 const owner = createEthAccount(web3);
240 await transferBalanceToEth(api, alice, owner, 999999999999999);240 await transferBalanceToEth(api, alice, owner);
241241
242 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});242 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
243243
244 const spender = createEthAccount(web3);244 const spender = createEthAccount(web3);
245 await transferBalanceToEth(api, alice, spender, 999999999999999);245 await transferBalanceToEth(api, alice, spender);
246246
247 const receiver = createEthAccount(web3);247 const receiver = createEthAccount(web3);
248248
285 const alice = privateKey('//Alice');285 const alice = privateKey('//Alice');
286286
287 const owner = createEthAccount(web3);287 const owner = createEthAccount(web3);
288 await transferBalanceToEth(api, alice, owner, 999999999999999);288 await transferBalanceToEth(api, alice, owner);
289289
290 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});290 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
291291
292 const receiver = createEthAccount(web3);292 const receiver = createEthAccount(web3);
293 await transferBalanceToEth(api, alice, receiver, 999999999999999);293 await transferBalanceToEth(api, alice, receiver);
294294
295 const address = collectionIdToAddress(collection);295 const address = collectionIdToAddress(collection);
296 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});296 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
modifiedtests/src/eth/payable.test.tsdiffbeforeafterboth
32 contract.methods.giveMoney().encodeABI(),32 contract.methods.giveMoney().encodeABI(),
33 '10000',33 '10000',
34 GAS_ARGS.gas,34 GAS_ARGS.gas,
35 GAS_ARGS.gasPrice,35 await web3.eth.getGasPrice(),
36 null,36 null,
37 );37 );
38 const events = await submitTransactionAsync(alice, tx);38 const events = await submitTransactionAsync(alice, tx);
modifiedtests/src/eth/proxy/nonFungibleProxy.test.tsdiffbeforeafterboth
224 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});224 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});
225225
226 {226 {
227 const result = await contract.methods.approve(spender, tokenId).send({from: caller, gas: '0x1000000', gasPrice: '0x01'});227 const result = await contract.methods.approve(spender, tokenId).send({from: caller, ...GAS_ARGS});
228 const events = normalizeEvents(result.events);228 const events = normalizeEvents(result.events);
229229
230 expect(events).to.be.deep.equal([230 expect(events).to.be.deep.equal([
modifiedtests/src/eth/util/helpers.tsdiffbeforeafterboth
12import usingApi, {submitTransactionAsync} from '../../substrate/substrate-api';12import usingApi, {submitTransactionAsync} from '../../substrate/substrate-api';
13import {IKeyringPair} from '@polkadot/types/types';13import {IKeyringPair} from '@polkadot/types/types';
14import {expect} from 'chai';14import {expect} from 'chai';
15import {getGenericResult} from '../../util/helpers';15import {getGenericResult, UNIQUE} from '../../util/helpers';
16import * as solc from 'solc';16import * as solc from 'solc';
17import config from '../../config';17import config from '../../config';
18import privateKey from '../../substrate/privateKey';18import privateKey from '../../substrate/privateKey';
19import contractHelpersAbi from './contractHelpersAbi.json';19import contractHelpersAbi from './contractHelpersAbi.json';
20import getBalance from '../../substrate/get-balance';20import getBalance from '../../substrate/get-balance';
2121
22export const GAS_ARGS = {gas: 0x1000000, gasPrice: '0x01'};22export const GAS_ARGS = {gas: 1000000};
2323
24let web3Connected = false;24let web3Connected = false;
25export async function usingWeb3<T>(cb: (web3: Web3) => Promise<T> | T): Promise<T> {25export async function usingWeb3<T>(cb: (web3: Web3) => Promise<T> | T): Promise<T> {
63 return account;63 return account;
64}64}
6565
66export async function transferBalanceToEth(api: ApiPromise, source: IKeyringPair, target: string, amount = 999999999999999) {66export async function transferBalanceToEth(api: ApiPromise, source: IKeyringPair, target: string, amount = 10000n * UNIQUE) {
67 const tx = api.tx.balances.transfer(evmToAddress(target), amount);67 const tx = api.tx.balances.transfer(evmToAddress(target), amount);
68 const events = await submitTransactionAsync(source, tx);68 const events = await submitTransactionAsync(source, tx);
69 const result = getGenericResult(events);69 const result = getGenericResult(events);
228 return new web3.eth.Contract(contractHelpersAbi as any, '0x842899ECF380553E8a4de75bF534cdf6fBF64049', {from: caller, ...GAS_ARGS});228 return new web3.eth.Contract(contractHelpersAbi as any, '0x842899ECF380553E8a4de75bF534cdf6fBF64049', {from: caller, ...GAS_ARGS});
229}229}
230230
231export async function executeEthTxOnSub(api: ApiPromise, from: IKeyringPair, to: any, mkTx: (methods: any) => any, {value = 0}: {value?: bigint | number} = { }) {231export async function executeEthTxOnSub(web3: Web3, api: ApiPromise, from: IKeyringPair, to: any, mkTx: (methods: any) => any, {value = 0}: {value?: bigint | number} = { }) {
232 const tx = api.tx.evm.call(232 const tx = api.tx.evm.call(
233 subToEth(from.address),233 subToEth(from.address),
234 to.options.address,234 to.options.address,
235 mkTx(to.methods).encodeABI(),235 mkTx(to.methods).encodeABI(),
236 value,236 value,
237 GAS_ARGS.gas,237 GAS_ARGS.gas,
238 GAS_ARGS.gasPrice,238 await web3.eth.getGasPrice(),
239 null,239 null,
240 );240 );
241 const events = await submitTransactionAsync(from, tx);241 const events = await submitTransactionAsync(from, tx);