difftreelog
feat configure min gas price
in: master
9 files changed
runtime/src/lib.rsdiffbeforeafterboth243pub 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 transfer246 1.into()247 (1 * MICROUNIQUE).into()247 }248 }248}249}249250tests/src/creditFeesToTreasury.test.tsdiffbeforeafterboth14 createItemExpectSuccess,14 createItemExpectSuccess,15 getGenericResult,15 getGenericResult,16 transferExpectSuccess,16 transferExpectSuccess,17 UNIQUE,17} from './util/helpers';18} from './util/helpers';181919import {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);173174174 // 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 });180180tests/src/eth/base.test.tsdiffbeforeafterboth112import {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';576describe('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 });2425 itWeb3('NFT transfer is close to 0.15 UNQ', async ({web3, api}) => {26 const caller = await createEthAccountWithBalance(api, web3);27 const receiver = createEthAccount(web3);2829 const alice = privateKey('//Alice');30 const collection = await createCollectionExpectSuccess({31 mode: {type: 'NFT'},32 });33 const itemId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});3435 const address = collectionIdToAddress(collection);36 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});3738 const cost = await recordEthFee(api, caller, () => contract.methods.transfer(receiver, itemId).send(caller));3940 const fee = Number(cost) / Number(UNIQUE);41 const expectedFee = 0.15;42 const tolerance = 0.002;4344 expect(Math.abs(fee - expectedFee) < tolerance).to.be.true;45 });22});46});2347tests/src/eth/fungible.test.tsdiffbeforeafterboth95 const alice = privateKey('//Alice');95 const alice = privateKey('//Alice');969697 const owner = createEthAccount(web3);97 const owner = createEthAccount(web3);98 await transferBalanceToEth(api, alice, owner, 999999999999999);98 await transferBalanceToEth(api, alice, owner);9999100 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});100 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});101101102 const spender = createEthAccount(web3);102 const spender = createEthAccount(web3);103 await transferBalanceToEth(api, alice, spender, 999999999999999);103 await transferBalanceToEth(api, alice, spender);104104105 const receiver = createEthAccount(web3);105 const receiver = createEthAccount(web3);106106153 const alice = privateKey('//Alice');153 const alice = privateKey('//Alice');154154155 const owner = createEthAccount(web3);155 const owner = createEthAccount(web3);156 await transferBalanceToEth(api, alice, owner, 999999999999999);156 await transferBalanceToEth(api, alice, owner);157157158 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});158 await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner});159159160 const receiver = createEthAccount(web3);160 const receiver = createEthAccount(web3);161 await transferBalanceToEth(api, alice, receiver, 999999999999999);161 await transferBalanceToEth(api, alice, receiver);162162163 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});tests/src/eth/marketplace/marketplace.test.tsdiffbeforeafterboth383839 // Ask39 // Ask40 {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 }444445 // Token is transferred to matcher45 // Token is transferred to matcher49 {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 signature52 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 }5555959596 // Ask96 // Ask97 {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 }101101102 // Token is transferred to matcher102 // Token is transferred to matcher107 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());109109110 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 signature112 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));114114115 // Approved price is removed from buyer balance, and added to seller115 // Approved price is removed from buyer balance, and added to seller158158159 // Ask159 // Ask160 {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 }164164165 // Token is transferred to matcher165 // Token is transferred to matcher173 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());175175176 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));177177178 // Price is removed from buyer balance, and added to seller178 // Price is removed from buyer balance, and added to seller179 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');tests/src/eth/nonFungible.test.tsdiffbeforeafterboth203 const alice = privateKey('//Alice');203 const alice = privateKey('//Alice');204204205 const owner = createEthAccount(web3);205 const owner = createEthAccount(web3);206 await transferBalanceToEth(api, alice, owner, 999999999999999);206 await transferBalanceToEth(api, alice, owner);207207208 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});208 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});209209213 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);213 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);214214215 {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);218218219 expect(events).to.be.deep.equal([219 expect(events).to.be.deep.equal([237 const alice = privateKey('//Alice');237 const alice = privateKey('//Alice');238238239 const owner = createEthAccount(web3);239 const owner = createEthAccount(web3);240 await transferBalanceToEth(api, alice, owner, 999999999999999);240 await transferBalanceToEth(api, alice, owner);241241242 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});242 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});243243244 const spender = createEthAccount(web3);244 const spender = createEthAccount(web3);245 await transferBalanceToEth(api, alice, spender, 999999999999999);245 await transferBalanceToEth(api, alice, spender);246246247 const receiver = createEthAccount(web3);247 const receiver = createEthAccount(web3);248248285 const alice = privateKey('//Alice');285 const alice = privateKey('//Alice');286286287 const owner = createEthAccount(web3);287 const owner = createEthAccount(web3);288 await transferBalanceToEth(api, alice, owner, 999999999999999);288 await transferBalanceToEth(api, alice, owner);289289290 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});290 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});291291292 const receiver = createEthAccount(web3);292 const receiver = createEthAccount(web3);293 await transferBalanceToEth(api, alice, receiver, 999999999999999);293 await transferBalanceToEth(api, alice, receiver);294294295 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});tests/src/eth/payable.test.tsdiffbeforeafterboth32 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);tests/src/eth/proxy/nonFungibleProxy.test.tsdiffbeforeafterboth224 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});224 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});225225226 {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);229229230 expect(events).to.be.deep.equal([230 expect(events).to.be.deep.equal([tests/src/eth/util/helpers.tsdiffbeforeafterboth12import 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';212122export const GAS_ARGS = {gas: 0x1000000, gasPrice: '0x01'};22export const GAS_ARGS = {gas: 1000000};232324let 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}656566export 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}230230231export 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);