diff --git a/abis/OvmGasPriceOracle.abi.json b/abis/OvmGasPriceOracle.abi.json
new file mode 100644
index 0000000..8f239ad
--- /dev/null
+++ b/abis/OvmGasPriceOracle.abi.json
@@ -0,0 +1,151 @@
+[
+ {
+ "inputs": [{ "internalType": "address", "name": "_owner", "type": "address" }],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [{ "indexed": false, "internalType": "uint256", "name": "", "type": "uint256" }],
+ "name": "DecimalsUpdated",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [{ "indexed": false, "internalType": "uint256", "name": "", "type": "uint256" }],
+ "name": "GasPriceUpdated",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [{ "indexed": false, "internalType": "uint256", "name": "", "type": "uint256" }],
+ "name": "L1BaseFeeUpdated",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [{ "indexed": false, "internalType": "uint256", "name": "", "type": "uint256" }],
+ "name": "OverheadUpdated",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ { "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" },
+ { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [{ "indexed": false, "internalType": "uint256", "name": "", "type": "uint256" }],
+ "name": "ScalarUpdated",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "gasPrice",
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [{ "internalType": "bytes", "name": "_data", "type": "bytes" }],
+ "name": "getL1Fee",
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [{ "internalType": "bytes", "name": "_data", "type": "bytes" }],
+ "name": "getL1GasUsed",
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "l1BaseFee",
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "overhead",
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "scalar",
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [{ "internalType": "uint256", "name": "_decimals", "type": "uint256" }],
+ "name": "setDecimals",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [{ "internalType": "uint256", "name": "_gasPrice", "type": "uint256" }],
+ "name": "setGasPrice",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [{ "internalType": "uint256", "name": "_baseFee", "type": "uint256" }],
+ "name": "setL1BaseFee",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [{ "internalType": "uint256", "name": "_overhead", "type": "uint256" }],
+ "name": "setOverhead",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [{ "internalType": "uint256", "name": "_scalar", "type": "uint256" }],
+ "name": "setScalar",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
diff --git a/components/withdraw/WithdrawTotal.vue b/components/withdraw/WithdrawTotal.vue
index c6bcd5f..f14d213 100644
--- a/components/withdraw/WithdrawTotal.vue
+++ b/components/withdraw/WithdrawTotal.vue
@@ -17,7 +17,7 @@
{{ $t('networkFee') }}
- {{ networkFeeInEth }} {{ networkCurrency }}
+ {{ toDecimals(networkFee, null, 6) }} {{ networkCurrency }}
{{ $t('relayerFee') }}
@@ -76,9 +76,6 @@ export default {
...mapGetters('token', ['toDecimals', 'fromDecimals']),
...mapGetters('application', ['networkFee']),
...mapGetters('price', ['tokenRate']),
- networkFeeInEth() {
- return fromWei(this.networkFee)
- },
relayerFee() {
const { amount } = this.selectedStatistic
const total = toBN(this.fromDecimals(amount.toString()))
diff --git a/constants/variables.js b/constants/variables.js
index 5b96108..e2868b0 100644
--- a/constants/variables.js
+++ b/constants/variables.js
@@ -87,3 +87,8 @@ export const trees = {
PARTS_COUNT: 4,
LEVELS: 20 // const from contract
}
+
+export const DUMMY_NONCE = '0x1111111111111111111111111111111111111111111111111111111111111111'
+
+export const DUMMY_WITHDRAW_DATA =
+ '0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111'
diff --git a/networkConfig.js b/networkConfig.js
index 2811513..3364c47 100644
--- a/networkConfig.js
+++ b/networkConfig.js
@@ -249,6 +249,7 @@ export default {
deployedBlock: 2243689,
multicall: '0x35A6Cdb2C9AD4a45112df4a04147EB07dFA01aB7',
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
+ ovmGasPriceOracleContract: '0x420000000000000000000000000000000000000F',
rpcUrls: {
Alchemy: {
name: 'Alchemy',
diff --git a/store/application.js b/store/application.js
index 7529ffb..3475410 100644
--- a/store/application.js
+++ b/store/application.js
@@ -148,19 +148,18 @@ const getters = {
currentContract: (state, getters) => (params) => {
return getters.tornadoProxyContract(params)
},
- withdrawGas: (state, getters, rootState, rootGetters) => {
- const netId = rootGetters['metamask/netId']
+ withdrawGas: (state, getters) => {
let action = ACTION.WITHDRAW_WITH_EXTRA
if (getters.hasEnabledLightProxy) {
action = ACTION.WITHDRAW
}
- if (Number(netId) === 10) {
+ if (getters.isOptimismConnected) {
action = ACTION.OP_WITHDRAW
}
- if (Number(netId) === 42161) {
+ if (getters.isArbitrumConnected) {
action = ACTION.ARB_WITHDRAW
}
@@ -169,7 +168,14 @@ const getters = {
networkFee: (state, getters, rootState, rootGetters) => {
const gasPrice = rootGetters['gasPrices/fastGasPrice']
- return toBN(gasPrice).mul(toBN(getters.withdrawGas))
+ const networkFee = toBN(gasPrice).mul(toBN(getters.withdrawGas))
+
+ if (getters.isOptimismConnected) {
+ const l1Fee = rootGetters['gasPrices/l1Fee']
+ return networkFee.add(toBN(l1Fee))
+ }
+
+ return networkFee
},
relayerFee: (state, getters, rootState, rootGetters) => {
const { currency, amount } = rootState.application.selectedStatistic
@@ -245,6 +251,14 @@ const getters = {
},
hasEnabledLightProxy: (state, getters, rootState, rootGetters) => {
return Boolean(rootGetters['metamask/networkConfig']['tornado-proxy-light.contract.tornadocash.eth'])
+ },
+ isOptimismConnected: (state, getters, rootState, rootGetters) => {
+ const netId = rootGetters['metamask/netId']
+ return Number(netId) === 10
+ },
+ isArbitrumConnected: (state, getters, rootState, rootGetters) => {
+ const netId = rootGetters['metamask/netId']
+ return Number(netId) === 42161
}
}
diff --git a/store/gasPrices.js b/store/gasPrices.js
index cc76e86..025e7cb 100644
--- a/store/gasPrices.js
+++ b/store/gasPrices.js
@@ -1,7 +1,13 @@
/* eslint-disable no-console */
+import Web3 from 'web3'
import { GasPriceOracle } from 'gas-price-oracle'
+import { serialize } from '@ethersproject/transactions'
import { toHex, toWei, toBN, fromWei } from 'web3-utils'
+import networkConfig from '@/networkConfig'
+import OvmGasPriceOracleABI from '@/abis/OvmGasPriceOracle.abi.json'
+import { DUMMY_NONCE, DUMMY_WITHDRAW_DATA } from '@/constants/variables'
+
export const state = () => {
return {
oracle: {
@@ -31,11 +37,26 @@ export const state = () => {
maxFeePerGas: 9,
maxPriorityFeePerGas: 1
}
- }
+ },
+ l1Fee: '0'
}
}
export const getters = {
+ ovmGasPriceOracleContract: (state, getters, rootState) => ({ netId }) => {
+ const config = networkConfig[`netId${netId}`]
+ const { url } = rootState.settings[`netId${netId}`].rpc
+ const address = config.ovmGasPriceOracleContract
+ if (address) {
+ const web3 = new Web3(url)
+ return new web3.eth.Contract(OvmGasPriceOracleABI, address)
+ }
+
+ return null
+ },
+ l1Fee: (state) => {
+ return state.l1Fee
+ },
oracle: (state, getters, rootState, rootGetters) => {
const netId = Number(rootGetters['metamask/netId'])
const { gasPrices } = rootGetters['metamask/networkConfig']
@@ -108,6 +129,9 @@ export const mutations = {
this._vm.$set(state.eip, 'fast', fast)
this._vm.$set(state.eip, 'standard', standard)
this._vm.$set(state.eip, 'low', low)
+ },
+ SAVE_L1_FEE(state, l1Fee) {
+ state.l1Fee = l1Fee
}
}
@@ -124,6 +148,8 @@ export const actions = {
commit('SAVE_ORACLE_GAS_PRICES', gas)
}
+ await dispatch('fetchL1Fee')
+
setTimeout(() => dispatch('fetchGasPrice'), 1000 * pollInterval)
} catch (e) {
console.error('fetchGasPrice', e)
@@ -187,5 +213,36 @@ export const actions = {
setDefault({ commit, rootGetters }) {
const { gasPrices } = rootGetters['metamask/networkConfig']
commit('SAVE_ORACLE_GAS_PRICES', gasPrices)
+ },
+ async fetchL1Fee({ commit, getters, dispatch, rootGetters }) {
+ const netId = rootGetters['metamask/netId']
+ const isOptimismConnected = rootGetters['application/isOptimismConnected']
+
+ const oracleInstance = getters.ovmGasPriceOracleContract({ netId })
+
+ if (isOptimismConnected && oracleInstance) {
+ try {
+ const gasLimit = rootGetters['application/withdrawGas']
+ const tornadoProxyInstance = rootGetters['application/tornadoProxyContract']({ netId })
+
+ const gasPrice = getters.fastGasPrice
+
+ const tx = serialize({
+ type: 0,
+ gasLimit,
+ gasPrice,
+ chainId: netId,
+ nonce: DUMMY_NONCE,
+ data: DUMMY_WITHDRAW_DATA,
+ to: tornadoProxyInstance._address
+ })
+
+ const l1Fee = await oracleInstance.methods.getL1Fee(tx).call()
+
+ commit('SAVE_L1_FEE', l1Fee)
+ } catch (err) {
+ console.error('fetchL1Fee has error:', err.message)
+ }
+ }
}
}