2023-08-22 19:23:18 +03:00
|
|
|
/* eslint-disable no-console */
|
2024-05-12 23:58:20 +03:00
|
|
|
import { toWei, toBN } from 'web3-utils'
|
|
|
|
import { formatUnits, parseUnits } from 'ethers'
|
|
|
|
import { ChainId, TornadoFeeOracle, getProvider } from '@tornado/tornado-oracles'
|
|
|
|
import { WITHDRAW_GAS_LIMIT } from '@/constants/variables'
|
2023-08-22 19:23:18 +03:00
|
|
|
|
|
|
|
export const state = () => {
|
|
|
|
return {
|
|
|
|
gasPriceParams: { gasPrice: toWei(toBN(50), 'gwei') },
|
2024-05-12 23:58:20 +03:00
|
|
|
l1Fee: toBN(0),
|
2023-08-27 22:30:25 +03:00
|
|
|
withdrawalNetworkFee: toBN(0),
|
|
|
|
withdrawalFeeViaRelayer: toBN(0)
|
2023-08-22 19:23:18 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export const getters = {
|
2024-05-12 23:58:20 +03:00
|
|
|
provider: (state, getters, rootState, rootGetters) => {
|
|
|
|
const netId = Number(rootGetters['metamask/netId'])
|
|
|
|
const { url: rpcUrl } = rootState.settings[`netId${netId}`].rpc
|
|
|
|
const config = rootGetters['metamask/networkConfig']
|
|
|
|
|
|
|
|
return getProvider(netId, rpcUrl, config)
|
|
|
|
},
|
2023-08-22 19:23:18 +03:00
|
|
|
oracle: (state, getters, rootState, rootGetters) => {
|
|
|
|
const netId = Number(rootGetters['metamask/netId'])
|
|
|
|
const { url: rpcUrl } = rootState.settings[`netId${netId}`].rpc
|
2024-05-12 23:58:20 +03:00
|
|
|
const config = rootGetters['metamask/networkConfig']
|
2023-08-22 19:23:18 +03:00
|
|
|
|
2024-05-12 23:58:20 +03:00
|
|
|
return new TornadoFeeOracle(netId, rpcUrl, config)
|
2023-08-22 19:23:18 +03:00
|
|
|
},
|
|
|
|
getGasPriceParams: (state) => {
|
|
|
|
return state.gasPriceParams
|
|
|
|
},
|
2024-05-12 23:58:20 +03:00
|
|
|
getMetamaskGasPriceParams: (state) => {
|
|
|
|
const feeData = state.gasPriceParams
|
|
|
|
|
|
|
|
const gasParams = feeData.maxFeePerGas
|
|
|
|
? {
|
|
|
|
maxFeePerGas: '0x' + feeData.maxFeePerGas.toString(16),
|
|
|
|
maxPriorityFeePerGas: '0x' + feeData.maxPriorityFeePerGas.toString(16)
|
|
|
|
}
|
|
|
|
: {
|
|
|
|
gasPrice: '0x' + feeData.gasPrice.toString(16)
|
|
|
|
}
|
|
|
|
|
|
|
|
return gasParams
|
|
|
|
},
|
|
|
|
l1Fee: (state) => {
|
|
|
|
return state.l1Fee
|
|
|
|
},
|
|
|
|
selectedInstance: (state, getters, rootState, rootGetters) => {
|
|
|
|
const nativeCurrency = rootGetters['metamask/nativeCurrency']
|
|
|
|
const { tokens } = rootGetters['metamask/networkConfig']
|
|
|
|
const { currency, amount } = rootState.application.selectedStatistic
|
|
|
|
|
|
|
|
const {
|
|
|
|
instanceAddress: instanceAddresses,
|
|
|
|
decimals,
|
|
|
|
gasLimit: instanceGasLimit,
|
|
|
|
tokenGasLimit
|
|
|
|
} = tokens[currency]
|
|
|
|
|
|
|
|
const { [amount]: instanceAddress } = instanceAddresses
|
|
|
|
|
|
|
|
const isNativeCurrency = currency.toLowerCase() === nativeCurrency
|
|
|
|
|
|
|
|
const firstAmount = Object.keys(instanceAddresses).sort((a, b) => Number(a) - Number(b))[0]
|
|
|
|
const isFirstAmount = Number(amount) === Number(firstAmount)
|
|
|
|
|
|
|
|
const denomination = parseUnits(String(amount), decimals)
|
|
|
|
|
|
|
|
const tokenPriceInWei = rootState.price.prices[currency.toLowerCase()]
|
|
|
|
|
|
|
|
return {
|
|
|
|
instanceAddress,
|
|
|
|
currency: currency.toLowerCase(),
|
|
|
|
amount: String(amount),
|
|
|
|
decimals,
|
|
|
|
denomination,
|
|
|
|
isNativeCurrency,
|
|
|
|
isFirstAmount,
|
|
|
|
instanceGasLimit,
|
|
|
|
tokenGasLimit,
|
|
|
|
tokenPriceInWei
|
|
|
|
}
|
|
|
|
},
|
|
|
|
gasPrice: (state, getters, rootState, rootGetters) => {
|
|
|
|
const netId = Number(rootGetters['metamask/netId'])
|
|
|
|
const gasPriceParams = getters.getGasPriceParams
|
|
|
|
|
|
|
|
let gasPrice = BigInt(
|
|
|
|
gasPriceParams.maxFeePerGas
|
|
|
|
? gasPriceParams.maxFeePerGas.toString()
|
|
|
|
: gasPriceParams.gasPrice.toString()
|
|
|
|
)
|
|
|
|
|
|
|
|
// to-do: manually bump gas price for BSC, remove this when we are able to check gasPrice from relayer status
|
|
|
|
if (netId === ChainId.BSC && gasPrice < parseUnits('3.3', 'gwei')) {
|
|
|
|
gasPrice = parseUnits('3.3', 'gwei')
|
|
|
|
}
|
|
|
|
|
|
|
|
return gasPrice
|
2023-08-22 19:23:18 +03:00
|
|
|
},
|
|
|
|
gasPriceInGwei: (state, getters) => {
|
2024-05-12 23:58:20 +03:00
|
|
|
return formatUnits(getters.gasPrice, 'gwei')
|
|
|
|
},
|
|
|
|
gasLimit: (state, getters) => ({ gas, gasLimit } = {}) => {
|
|
|
|
const { instanceGasLimit } = getters.selectedInstance
|
|
|
|
return BigInt(gas || gasLimit || instanceGasLimit || WITHDRAW_GAS_LIMIT)
|
|
|
|
},
|
|
|
|
refundGasLimit: (state, getters) => {
|
|
|
|
const { isFirstAmount, tokenGasLimit } = getters.selectedInstance
|
|
|
|
return isFirstAmount && tokenGasLimit ? BigInt(tokenGasLimit) : undefined
|
|
|
|
},
|
|
|
|
ethRefund: (state, getters, rootState) => {
|
|
|
|
return rootState.application.ethToReceive || 0
|
|
|
|
},
|
|
|
|
relayerFeePercent: (state, getters, rootState) => {
|
|
|
|
return rootState.relayer.selectedRelayer.tornadoServiceFee
|
2023-08-22 19:23:18 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export const mutations = {
|
|
|
|
SAVE_GAS_PARAMS(state, payload) {
|
|
|
|
state.gasPriceParams = payload
|
|
|
|
},
|
|
|
|
SAVE_WITHDRAWAL_NETWORK_FEE(state, gasFee) {
|
|
|
|
state.withdrawalNetworkFee = gasFee
|
2023-08-27 22:30:25 +03:00
|
|
|
},
|
|
|
|
SAVE_WITHDRAWAL_FEE_VIA_RELAYER(state, fee) {
|
|
|
|
state.withdrawalFeeViaRelayer = fee
|
2024-05-12 23:58:20 +03:00
|
|
|
},
|
|
|
|
SAVE_L1_FEE(state, fee) {
|
|
|
|
state.l1Fee = fee
|
2023-08-22 19:23:18 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export const actions = {
|
|
|
|
async fetchGasPrice({ getters, dispatch, commit, rootGetters }) {
|
|
|
|
const { pollInterval } = rootGetters['metamask/networkConfig']
|
|
|
|
|
|
|
|
try {
|
2024-05-12 23:58:20 +03:00
|
|
|
const feeData = await getters.provider.getFeeData()
|
|
|
|
|
|
|
|
const gasParams = feeData.maxFeePerGas
|
|
|
|
? {
|
|
|
|
maxFeePerGas: feeData.maxFeePerGas.toString(),
|
|
|
|
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas
|
|
|
|
? feeData.maxPriorityFeePerGas.toString()
|
|
|
|
: null
|
|
|
|
}
|
|
|
|
: {
|
|
|
|
gasPrice: feeData.gasPrice ? feeData.gasPrice.toString() : parseUnits('50', 'gwei').toString()
|
|
|
|
}
|
|
|
|
|
|
|
|
commit('SAVE_GAS_PARAMS', gasParams)
|
2023-08-22 19:23:18 +03:00
|
|
|
} catch (e) {
|
|
|
|
console.error('fetchGasPrice', e)
|
|
|
|
} finally {
|
|
|
|
setTimeout(() => dispatch('fetchGasPrice'), 2000 * pollInterval)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
setDefaultGasPrice({ commit, rootGetters }) {
|
|
|
|
const { gasPrices } = rootGetters['metamask/networkConfig']
|
|
|
|
commit('SAVE_GAS_PARAMS', { gasPrice: toWei(gasPrices?.fast?.toFixed(9) || 0, 'gwei') })
|
|
|
|
},
|
2024-05-12 23:58:20 +03:00
|
|
|
calculateWithdrawalNetworkFee({ getters, commit }, { tx }) {
|
|
|
|
const gasPrice = getters.gasPrice
|
|
|
|
const gasLimit = BigInt(tx?.gas || tx?.gasLimit || WITHDRAW_GAS_LIMIT)
|
|
|
|
|
|
|
|
const gasCost = gasPrice * gasLimit
|
|
|
|
|
|
|
|
commit('SAVE_WITHDRAWAL_NETWORK_FEE', toBN(gasCost.toString()))
|
2023-08-22 19:23:18 +03:00
|
|
|
|
2024-05-12 23:58:20 +03:00
|
|
|
return gasCost
|
2023-08-27 22:30:25 +03:00
|
|
|
},
|
2024-05-12 23:58:20 +03:00
|
|
|
async calculateL1Fee({ commit, getters }, { tx }) {
|
|
|
|
const oracle = getters.oracle
|
|
|
|
|
|
|
|
const l1Fee = await oracle.fetchL1OptimismFee(tx)
|
|
|
|
|
|
|
|
commit('SAVE_L1_FEE', toBN(l1Fee.toString()))
|
|
|
|
},
|
|
|
|
async calculateWithdrawalFeeViaRelayer({ dispatch, getters, commit }, { tx }) {
|
|
|
|
const { decimals, denomination, isNativeCurrency, tokenPriceInWei } = getters.selectedInstance
|
|
|
|
|
|
|
|
const oracle = getters.oracle
|
|
|
|
const gasPrice = getters.gasPrice
|
|
|
|
const gasLimit = getters.gasLimit(tx)
|
|
|
|
const refundGasLimit = getters.refundGasLimit
|
|
|
|
const relayerFeePercent = getters.relayerFeePercent
|
|
|
|
|
|
|
|
await dispatch('calculateL1Fee', { tx })
|
|
|
|
dispatch('calculateWithdrawalNetworkFee', { tx })
|
|
|
|
|
|
|
|
const l1Fee = getters.l1Fee
|
|
|
|
|
|
|
|
if (!isNativeCurrency) {
|
|
|
|
dispatch('application/setDefaultEthToReceive', { gasPrice, refundGasLimit }, { root: true })
|
|
|
|
|
|
|
|
const ethRefund = getters.ethRefund
|
|
|
|
|
|
|
|
const relayerFee = oracle.calculateRelayerFee({
|
|
|
|
gasPrice,
|
|
|
|
gasLimit,
|
|
|
|
l1Fee,
|
|
|
|
denomination,
|
|
|
|
ethRefund,
|
|
|
|
tokenPriceInWei,
|
|
|
|
tokenDecimals: decimals,
|
|
|
|
relayerFeePercent,
|
|
|
|
isEth: isNativeCurrency
|
|
|
|
})
|
|
|
|
|
|
|
|
commit('SAVE_WITHDRAWAL_FEE_VIA_RELAYER', toBN(relayerFee.toString()))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const relayerFee = oracle.calculateRelayerFee({
|
|
|
|
gasPrice,
|
|
|
|
gasLimit,
|
|
|
|
l1Fee,
|
|
|
|
denomination,
|
|
|
|
relayerFeePercent
|
|
|
|
})
|
2023-08-27 22:30:25 +03:00
|
|
|
|
2024-05-12 23:58:20 +03:00
|
|
|
commit('SAVE_WITHDRAWAL_FEE_VIA_RELAYER', toBN(relayerFee.toString()))
|
2023-08-22 19:23:18 +03:00
|
|
|
}
|
|
|
|
}
|