Compare commits
3 Commits
6130c46d90
...
ed107528a2
Author | SHA1 | Date | |
---|---|---|---|
ed107528a2 | |||
590c0651cb | |||
311f6ebc85 |
10
package.json
10
package.json
@ -23,6 +23,9 @@
|
||||
"@apollo/client": "^3.3.20",
|
||||
"@metamask/onboarding": "^1.0.0",
|
||||
"@nuxtjs/moment": "^1.6.0",
|
||||
"@tornado/gas-price-oracle": "^0.5.2-p1",
|
||||
"@tornado/snarkjs": "0.1.20-p2",
|
||||
"@tornado/websnark": "0.0.4-p1",
|
||||
"@walletconnect/web3-provider": "1.7.8",
|
||||
"ajv": "^6.10.2",
|
||||
"arraybuffer-loader": "^1.0.8",
|
||||
@ -30,6 +33,7 @@
|
||||
"bignumber.js": "^9.0.0",
|
||||
"bloomfilter.js": "^1.0.2",
|
||||
"circomlibjs": "0.1.2",
|
||||
"cross-env": "7.0.3",
|
||||
"crypto": "^1.0.1",
|
||||
"dotenv": "^8.2.0",
|
||||
"eth-ens-namehash": "^2.0.8",
|
||||
@ -37,7 +41,6 @@
|
||||
"file-saver": "^2.0.5",
|
||||
"fixed-merkle-tree": "^0.7.3",
|
||||
"form-data": "^3.0.0",
|
||||
"gas-price-oracle": "^0.5.0",
|
||||
"graphql": "^15.5.1",
|
||||
"idb": "^6.0.0",
|
||||
"jspdf": "^1.5.3",
|
||||
@ -53,10 +56,7 @@
|
||||
"vue-clipboard2": "^0.3.1",
|
||||
"vue-i18n": "^8.15.4",
|
||||
"vuex-persistedstate": "^2.7.0",
|
||||
"web3": "1.5.2",
|
||||
"cross-env": "7.0.3",
|
||||
"@tornado/snarkjs": "0.1.20-p2",
|
||||
"@tornado/websnark": "0.0.4-p1"
|
||||
"web3": "1.5.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxtjs/eslint-config": "^1.1.2",
|
||||
|
@ -63,7 +63,8 @@ const state = () => {
|
||||
withdrawType: 'relayer',
|
||||
ethToReceive: '20000000000000000',
|
||||
defaultEthToReceive: '20000000000000000',
|
||||
withdrawNote: ''
|
||||
withdrawNote: '',
|
||||
relayerWithdrawGasLimit: null
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,6 +105,9 @@ const mutations = {
|
||||
},
|
||||
SET_WITHDRAW_NOTE(state, withdrawNote) {
|
||||
state.withdrawNote = withdrawNote
|
||||
},
|
||||
SET_RELAYER_WITHDRAW_GAS_LIMIT(state, { relayerWithdrawGasLimit }) {
|
||||
this._vm.$set(state, 'relayerWithdrawGasLimit', relayerWithdrawGasLimit)
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,7 +146,7 @@ const getters = {
|
||||
currentContract: (state, getters) => (params) => {
|
||||
return getters.tornadoProxyContract(params)
|
||||
},
|
||||
withdrawGas: (state, getters) => {
|
||||
defaultWithdrawGas: (state, getters) => {
|
||||
let action = ACTION.WITHDRAW_WITH_EXTRA
|
||||
|
||||
if (getters.hasEnabledLightProxy) {
|
||||
@ -162,7 +166,7 @@ const getters = {
|
||||
networkFee: (state, getters, rootState, rootGetters) => {
|
||||
const gasPrice = rootGetters['gasPrices/gasPrice']
|
||||
|
||||
const networkFee = toBN(gasPrice).mul(toBN(getters.withdrawGas))
|
||||
const networkFee = toBN(gasPrice).mul(toBN(state.relayerWithdrawGasLimit || getters.defaultWithdrawGas))
|
||||
|
||||
if (getters.isOptimismConnected) {
|
||||
const l1Fee = rootGetters['gasPrices/l1Fee']
|
||||
@ -636,6 +640,30 @@ const actions = {
|
||||
return false
|
||||
}
|
||||
},
|
||||
async estimateRelayerWithdrawGasLimit(
|
||||
{ getters, rootState, commit },
|
||||
{ currency, amount, netId, proof, withdrawCallArgs }
|
||||
) {
|
||||
const tornadoProxy = getters.tornadoProxyContract({ netId })
|
||||
const tornadoInstance = getters.instanceContract({ currency, amount, netId })
|
||||
const relayer = rootState.relayer.selectedRelayer.address
|
||||
|
||||
let gasLimit
|
||||
try {
|
||||
const fetchedGasLimit = await tornadoProxy.methods
|
||||
.withdraw(tornadoInstance._address, proof, ...withdrawCallArgs)
|
||||
.estimateGas({
|
||||
from: relayer,
|
||||
to: tornadoProxy._address,
|
||||
value: withdrawCallArgs[5] || 0
|
||||
})
|
||||
gasLimit = Math.floor(fetchedGasLimit * 1.3)
|
||||
} catch (e) {
|
||||
gasLimit = getters.defaultWithdrawGas
|
||||
console.error(`Cannot fetch gas limit for relayer withdrawal, using default: ${gasLimit}`)
|
||||
}
|
||||
commit('SET_RELAYER_WITHDRAW_GAS_LIMIT', { relayerWithdrawGasLimit: gasLimit })
|
||||
},
|
||||
async checkSpentEventFromNullifier({ getters, dispatch }, parsedNote) {
|
||||
try {
|
||||
const isSpent = await dispatch('loadEvent', {
|
||||
@ -695,7 +723,7 @@ const actions = {
|
||||
return { tree, root }
|
||||
},
|
||||
async createSnarkProof(
|
||||
{ rootGetters, rootState, state, getters },
|
||||
{ rootGetters, rootState, state, getters, dispatch },
|
||||
{ root, note, tree, recipient, leafIndex }
|
||||
) {
|
||||
const { pathElements, pathIndices } = tree.path(leafIndex)
|
||||
@ -708,55 +736,71 @@ const actions = {
|
||||
let fee = BigInt(0)
|
||||
let refund = BigInt(0)
|
||||
|
||||
if (withdrawType === 'relayer') {
|
||||
let totalRelayerFee = getters.relayerFee
|
||||
relayer = BigInt(rootState.relayer.selectedRelayer.address)
|
||||
|
||||
if (note.currency !== nativeCurrency) {
|
||||
refund = BigInt(state.ethToReceive.toString())
|
||||
totalRelayerFee = totalRelayerFee.add(getters.ethToReceiveInToken)
|
||||
async function calculateSnarkProof() {
|
||||
const input = {
|
||||
// public
|
||||
fee,
|
||||
root,
|
||||
refund,
|
||||
relayer,
|
||||
recipient: BigInt(recipient),
|
||||
nullifierHash: note.nullifierHash,
|
||||
// private
|
||||
pathIndices,
|
||||
pathElements,
|
||||
secret: note.secret,
|
||||
nullifier: note.nullifier
|
||||
}
|
||||
|
||||
fee = BigInt(totalRelayerFee.toString())
|
||||
const { circuit, provingKey } = await getTornadoKeys()
|
||||
|
||||
if (!groth16) {
|
||||
groth16 = await buildGroth16()
|
||||
}
|
||||
|
||||
console.log('Start generating SNARK proof', input)
|
||||
console.time('SNARK proof time')
|
||||
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, provingKey)
|
||||
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
||||
|
||||
const args = [
|
||||
toFixedHex(input.root),
|
||||
toFixedHex(input.nullifierHash),
|
||||
toFixedHex(input.recipient, 20),
|
||||
toFixedHex(input.relayer, 20),
|
||||
toFixedHex(input.fee),
|
||||
toFixedHex(input.refund)
|
||||
]
|
||||
console.timeEnd('SNARK proof time')
|
||||
return { args, proof }
|
||||
}
|
||||
|
||||
const input = {
|
||||
// public
|
||||
fee,
|
||||
root,
|
||||
refund,
|
||||
relayer,
|
||||
recipient: BigInt(recipient),
|
||||
nullifierHash: note.nullifierHash,
|
||||
// private
|
||||
pathIndices,
|
||||
pathElements,
|
||||
secret: note.secret,
|
||||
nullifier: note.nullifier
|
||||
// Don't need to calculate or estimate relayer fee, so, return proof immediately
|
||||
if (withdrawType !== 'relayer') return calculateSnarkProof()
|
||||
|
||||
relayer = BigInt(rootState.relayer.selectedRelayer.address)
|
||||
const { proof: dummyProof, args: dummyArgs } = await calculateSnarkProof()
|
||||
const { netId, amount, currency } = note
|
||||
await dispatch('estimateRelayerWithdrawGasLimit', {
|
||||
netId,
|
||||
amount,
|
||||
currency,
|
||||
proof: dummyProof,
|
||||
withdrawCallArgs: dummyArgs
|
||||
})
|
||||
let totalRelayerFee = getters.relayerFee
|
||||
|
||||
if (note.currency !== nativeCurrency) {
|
||||
refund = BigInt(state.ethToReceive.toString())
|
||||
totalRelayerFee = totalRelayerFee.add(getters.ethToReceiveInToken)
|
||||
}
|
||||
|
||||
const { circuit, provingKey } = await getTornadoKeys()
|
||||
fee = BigInt(totalRelayerFee.toString())
|
||||
|
||||
if (!groth16) {
|
||||
groth16 = await buildGroth16()
|
||||
}
|
||||
|
||||
console.log('Start generating SNARK proof', input)
|
||||
console.time('SNARK proof time')
|
||||
const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, provingKey)
|
||||
const { proof } = websnarkUtils.toSolidityInput(proofData)
|
||||
|
||||
const args = [
|
||||
toFixedHex(input.root),
|
||||
toFixedHex(input.nullifierHash),
|
||||
toFixedHex(input.recipient, 20),
|
||||
toFixedHex(input.relayer, 20),
|
||||
toFixedHex(input.fee),
|
||||
toFixedHex(input.refund)
|
||||
]
|
||||
return { args, proof }
|
||||
// Recalculate proof with actual fee and refund
|
||||
return calculateSnarkProof()
|
||||
},
|
||||
async prepareWithdraw({ dispatch, getters, commit }, { note, recipient }) {
|
||||
async prepareWithdraw({ dispatch, commit }, { note, recipient }) {
|
||||
commit('REMOVE_PROOF', { note })
|
||||
try {
|
||||
const parsedNote = parseNote(note)
|
||||
@ -776,7 +820,6 @@ const actions = {
|
||||
note: parsedNote,
|
||||
leafIndex: tree.indexOf(parsedNote.commitmentHex)
|
||||
})
|
||||
console.timeEnd('SNARK proof time')
|
||||
commit('SAVE_PROOF', { proof, args, note })
|
||||
} catch (e) {
|
||||
console.error('prepareWithdraw', e)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* eslint-disable no-console */
|
||||
import Web3 from 'web3'
|
||||
import { toHex, fromWei } from 'web3-utils'
|
||||
import { GasPriceOracle } from 'gas-price-oracle'
|
||||
import { toHex, toWei, fromWei, toBN } from 'web3-utils'
|
||||
import { GasPriceOracle } from '@tornado/gas-price-oracle'
|
||||
import { serialize } from '@ethersproject/transactions'
|
||||
|
||||
import networkConfig from '@/networkConfig'
|
||||
@ -10,7 +10,7 @@ import { DUMMY_NONCE, DUMMY_WITHDRAW_DATA } from '@/constants/variables'
|
||||
|
||||
export const state = () => {
|
||||
return {
|
||||
gasParams: { gasPrice: 50 },
|
||||
gasParams: { gasPrice: toWei(toBN(50), 'gwei') },
|
||||
l1Fee: '0'
|
||||
}
|
||||
}
|
||||
@ -23,6 +23,9 @@ export const getters = {
|
||||
return new GasPriceOracle({
|
||||
chainId: netId,
|
||||
defaultRpc: rootGetters['settings/currentRpc'].url,
|
||||
minPriority: netId === 1 ? 2 : 0.05,
|
||||
percentile: 5,
|
||||
blocksCount: 20,
|
||||
defaultFallbackGasPrices: gasPrices
|
||||
})
|
||||
},
|
||||
@ -63,14 +66,25 @@ export const mutations = {
|
||||
}
|
||||
|
||||
export const actions = {
|
||||
async fetchGasPrice({ getters, dispatch, commit, rootGetters }) {
|
||||
const netId = rootGetters['metamask/netId']
|
||||
async fetchGasPrice({ getters, dispatch, commit, rootGetters, rootState }) {
|
||||
const { pollInterval } = rootGetters['metamask/networkConfig']
|
||||
|
||||
const isLegacy = netId === 137
|
||||
const netId = Number(rootGetters['metamask/netId'])
|
||||
const { url: rpcUrl } = rootState.settings[`netId${netId}`].rpc
|
||||
|
||||
try {
|
||||
const txGasParams = await getters.oracle.getTxGasParams({ isLegacy })
|
||||
// Bump more for Polygon (MATIC) and for Goerli, because minPriority for this sidechains don't affect correctly
|
||||
const bumpPercent = netId === 137 || netId === 5 ? 30 : 10
|
||||
let txGasParams = {}
|
||||
try {
|
||||
// Use maxFeePerGas if eip1599 gas support by chain, use fast if legacy gas fetched
|
||||
txGasParams = await getters.oracle.getTxGasParams({ legacySpeed: 'fast', bumpPercent }) // in wei
|
||||
} catch (e) {
|
||||
const web3 = new Web3(rpcUrl)
|
||||
const wei = toBN(await web3.eth.getGasPrice())
|
||||
const bumped = wei.add(wei.mul(toBN(bumpPercent)).div(toBN(100)))
|
||||
txGasParams = { gasPrice: toHex(bumped) }
|
||||
}
|
||||
|
||||
commit('SAVE_GAS_PARAMS', txGasParams)
|
||||
await dispatch('fetchL1Fee')
|
||||
} catch (e) {
|
||||
@ -81,7 +95,7 @@ export const actions = {
|
||||
},
|
||||
setDefault({ commit, rootGetters }) {
|
||||
const { gasPrices } = rootGetters['metamask/networkConfig']
|
||||
commit('SAVE_GAS_PARAMS', { gasPrice: gasPrices?.fast })
|
||||
commit('SAVE_GAS_PARAMS', { gasPrice: toWei(gasPrices?.fast?.toFixed(9) || 0, 'gwei') })
|
||||
},
|
||||
async fetchL1Fee({ commit, getters, rootGetters }) {
|
||||
const netId = rootGetters['metamask/netId']
|
||||
|
24
yarn.lock
24
yarn.lock
@ -2109,6 +2109,15 @@
|
||||
dependencies:
|
||||
defer-to-connect "^1.0.1"
|
||||
|
||||
"@tornado/gas-price-oracle@^0.5.2-p1":
|
||||
version "0.5.2-p1"
|
||||
resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Fgas-price-oracle/-/0.5.2-p1/gas-price-oracle-0.5.2-p1.tgz#310fed9b481383ffeaa4c1bd105c934a71a9513c"
|
||||
integrity sha512-FbkhDQMD/aEBogdG6IdSXmlraG9LdEhaO+8aeNXZA0Tgp5P4PJ8pgZXxTK2rpVXBMpXrFiFg4IDkpRGrx67d4g==
|
||||
dependencies:
|
||||
axios "^0.21.2"
|
||||
bignumber.js "^9.0.0"
|
||||
node-cache "^5.1.2"
|
||||
|
||||
"@tornado/snarkjs@0.1.20-p2":
|
||||
version "0.1.20-p2"
|
||||
resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Fsnarkjs/-/0.1.20-p2/snarkjs-0.1.20-p2.tgz#e25a1d4ca8305887202d02cb38077795108f1ec3"
|
||||
@ -7800,14 +7809,6 @@ functional-red-black-tree@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
|
||||
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
|
||||
|
||||
gas-price-oracle@^0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/gas-price-oracle/-/gas-price-oracle-0.5.0.tgz#b29f83c97bb4b091a08da7c10e2d1e5888bbade4"
|
||||
integrity sha512-um0cmd9qxGkDHirV1HcrjQ4vedVxK7u+uMeJIjo2yUMYe6T46ihbMnRncF5tfP9deU5hPHJ8FvVRZY1Y/CKkLQ==
|
||||
dependencies:
|
||||
axios "^0.21.2"
|
||||
bignumber.js "^9.0.0"
|
||||
|
||||
gauge@~2.7.3:
|
||||
version "2.7.4"
|
||||
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
|
||||
@ -11039,6 +11040,13 @@ node-cache@^4.1.1:
|
||||
clone "2.x"
|
||||
lodash "^4.17.15"
|
||||
|
||||
node-cache@^5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/node-cache/-/node-cache-5.1.2.tgz#f264dc2ccad0a780e76253a694e9fd0ed19c398d"
|
||||
integrity sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==
|
||||
dependencies:
|
||||
clone "2.x"
|
||||
|
||||
node-fetch@2.6.1, node-fetch@^2.6.1:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||
|
Loading…
x
Reference in New Issue
Block a user