123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- /* eslint-disable no-console */
- /* eslint-disable import/order */
- import Web3 from 'web3'
- import networkConfig from '@/networkConfig'
- import ERC20ABI from '@/abis/ERC20.abi.json'
- const { numberToHex, toBN, toWei } = require('web3-utils')
- const BN = require('bn.js')
- const zero = new BN(0)
- const negative1 = new BN(-1)
- export const state = () => {
- return {
- approvalAmount: 'unlimited',
- allowance: '',
- balance: ''
- }
- }
- export const getters = {
- tokenContract: (state, getters, rootState, rootGetters) => ({ currency, netId }) => {
- const config = networkConfig[`netId${netId}`]
- const { url } = rootState.settings[`netId${netId}`].rpc
- const address = config.tokens[currency].tokenAddress
- const web3 = new Web3(url)
- return new web3.eth.Contract(ERC20ABI, address)
- },
- // similar to fromWei from web3
- toDecimals: (state, getters, rootState, rootGetters) => (value, decimals, fixed) => {
- const { currency } = rootState.application.selectedStatistic
- decimals = decimals || rootGetters['metamask/networkConfig'].tokens[currency].decimals
- fixed = fixed || 2
- value = new BN(value)
- const negative = value.lt(zero)
- const base = new BN('10').pow(new BN(decimals))
- const baseLength = base.toString(10).length - 1 || 1
- if (negative) {
- value = value.mul(negative1)
- }
- let fraction = value.mod(base).toString(10)
- while (fraction.length < baseLength) {
- fraction = `0${fraction}`
- }
- fraction = fraction.match(/^([0-9]*[1-9]|0)(0*)/)[1]
- const whole = value.div(base).toString(10)
- if (fixed && fraction !== '0') {
- fraction = fraction.slice(0, fixed)
- }
- value = `${whole}${fraction === '0' ? '' : `.${fraction}`}`
- if (negative) {
- value = `-${value}`
- }
- return value
- },
- // similar to toWei from web3
- fromDecimals: (state, getters, rootState, rootGetters) => (value, decimals) => {
- const { currency } = rootState.application.selectedStatistic
- decimals = decimals || rootGetters['metamask/networkConfig'].tokens[currency].decimals
- value = value.toString()
- let ether = value.toString()
- const base = new BN('10').pow(new BN(decimals))
- const baseLength = base.toString(10).length - 1 || 1
- const negative = ether.substring(0, 1) === '-'
- if (negative) {
- ether = ether.substring(1)
- }
- if (ether === '.') {
- throw new Error(this.app.i18n.t('unitInvalidValue', { value }))
- }
- // Split it into a whole and fractional part
- const comps = ether.split('.')
- if (comps.length > 2) {
- throw new Error(this.app.i18n.t('tooManyDecimalPoints', { value }))
- }
- let whole = comps[0]
- let fraction = comps[1]
- if (!whole) {
- whole = '0'
- }
- if (!fraction) {
- fraction = '0'
- }
- if (fraction.length > baseLength) {
- throw new Error(this.app.i18n.t('tooManyDecimalPlaces', { value }))
- }
- while (fraction.length < baseLength) {
- fraction += '0'
- }
- whole = new BN(whole)
- fraction = new BN(fraction)
- let wei = whole.mul(base).add(fraction)
- if (negative) {
- wei = wei.mul(negative)
- }
- return new BN(wei.toString(10), 10)
- },
- isSufficientAllowance: (state, getters, rootState, rootGetters) => {
- const { currency, amount } = rootState.application.selectedInstance
- const { decimals } = rootGetters['metamask/networkConfig'].tokens[currency]
- return toBN(state.allowance).gte(toBN(getters.fromDecimals(amount, decimals)))
- },
- isSufficientBalance: (state, getters, rootState, rootGetters) => {
- const ethBalance = rootState.metamask.ethBalance
- const { currency, amount } = rootState.application.selectedInstance
- const { decimals } = rootGetters['metamask/networkConfig'].tokens[currency]
- const nativeCurrency = rootGetters['metamask/nativeCurrency']
- if (currency === nativeCurrency) {
- return toBN(ethBalance).gte(toBN(toWei(amount.toString())))
- } else {
- return toBN(state.balance).gte(toBN(getters.fromDecimals(amount, decimals)))
- }
- },
- getSymbol: (state, getters, rootState, rootGetters) => (currency) => {
- const tokens = rootGetters['metamask/networkConfig'].tokens
- if (tokens[currency]) {
- return tokens[currency].symbol
- }
- return currency.toUpperCase()
- }
- }
- export const mutations = {
- SET_APPROVAL_AMOUNT(state, { approvalAmount }) {
- state.approvalAmount = approvalAmount
- },
- SAVE_ALLOWANCE(state, { allowance }) {
- this._vm.$set(state, 'allowance', allowance)
- },
- SAVE_BALANCE(state, { balance }) {
- this._vm.$set(state, 'balance', balance)
- }
- }
- export const actions = {
- async approve({ rootState, getters, dispatch, rootGetters, state }) {
- try {
- const netId = rootGetters['metamask/netId']
- const { currency } = rootState.application.selectedInstance
- const { decimals } = rootGetters['metamask/networkConfig'].tokens[currency]
- const tokenInstance = getters.tokenContract({ currency, netId })
- const tornadoProxy = rootGetters['application/tornadoProxyContract']({ netId })
- const { ethAccount } = rootState.metamask
- const amountToApprove =
- state.approvalAmount === 'unlimited'
- ? toBN('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff')
- : toBN(getters.fromDecimals(state.approvalAmount, decimals))
- const data = tokenInstance.methods
- .approve(tornadoProxy._address, amountToApprove.toString())
- .encodeABI()
- const gas = await tokenInstance.methods
- .approve(tornadoProxy._address, amountToApprove.toString())
- .estimateGas({
- from: ethAccount
- })
- const callParams = {
- method: 'eth_sendTransaction',
- params: {
- to: tokenInstance._address,
- gas: numberToHex(gas + 30000),
- data
- },
- watcherParams: {
- title: 'approve',
- successTitle: 'approved'
- },
- isSaving: false
- }
- await dispatch('metamask/sendTransaction', callParams, { root: true })
- } catch (e) {
- console.error('approve action', e)
- throw new Error(e.message)
- }
- },
- async fetchTokenAllowance({ getters, rootGetters, commit, rootState }) {
- const netId = rootGetters['metamask/netId']
- const { currency } = rootState.application.selectedInstance
- const { ethAccount } = rootState.metamask
- try {
- const tornadoInstance = rootGetters['application/tornadoProxyContract']({ netId })
- const nativeCurrency = rootGetters['metamask/nativeCurrency']
- if (currency !== nativeCurrency && ethAccount) {
- const tokenInstance = getters.tokenContract({ currency, netId })
- const allowance = await tokenInstance.methods.allowance(ethAccount, tornadoInstance._address).call()
- commit('SAVE_ALLOWANCE', { allowance })
- }
- } catch (e) {
- console.error('fetchTokenAllowance', e.message)
- }
- },
- async fetchTokenBalance({ state, getters, rootGetters, commit, rootState }) {
- try {
- const netId = rootGetters['metamask/netId']
- const { currency } = rootState.application.selectedInstance
- const { ethAccount } = rootState.metamask
- const nativeCurrency = rootGetters['metamask/nativeCurrency']
- if (currency !== nativeCurrency && ethAccount) {
- const tokenInstance = getters.tokenContract({ currency, netId })
- const balance = await tokenInstance.methods.balanceOf(ethAccount).call()
- commit('SAVE_BALANCE', { balance })
- }
- } catch (e) {
- console.error('fetchTokenBalance', e.message)
- }
- }
- }
|