refactor tx gas eestimation method to one functions which supports both execution and approval
This commit is contained in:
parent
ea04ae976e
commit
ee483a98e4
|
@ -1,57 +1,53 @@
|
||||||
// @flow
|
// @flow
|
||||||
import GnosisSafeSol from '@gnosis.pm/safe-contracts/build/contracts/GnosisSafe.json'
|
import GnosisSafeSol from '@gnosis.pm/safe-contracts/build/contracts/GnosisSafe.json'
|
||||||
import { getWeb3, getAccountFrom } from '~/logic/wallets/getWeb3'
|
import { getWeb3, getAccountFrom } from '~/logic/wallets/getWeb3'
|
||||||
import { type Operation } from '~/logic/safe/transactions'
|
|
||||||
import { calculateGasOf, calculateGasPrice } from '~/logic/wallets/ethTransactions'
|
import { calculateGasOf, calculateGasPrice } from '~/logic/wallets/ethTransactions'
|
||||||
import { ZERO_ADDRESS } from '~/logic/wallets/ethAddresses'
|
import { ZERO_ADDRESS } from '~/logic/wallets/ethAddresses'
|
||||||
|
import { type Transaction } from '~/routes/safe/store/models/transaction'
|
||||||
import { CALL } from '.'
|
import { CALL } from '.'
|
||||||
|
|
||||||
export const estimateApprovalTxGasCosts = async (safeAddress: string, to: string, data: string): Promise<number> => {
|
export const estimateTxGasCosts = async (
|
||||||
|
safeAddress: string,
|
||||||
|
to: string,
|
||||||
|
data: string,
|
||||||
|
tx?: Transaction,
|
||||||
|
): Promise<number> => {
|
||||||
try {
|
try {
|
||||||
const web3 = getWeb3()
|
const web3 = getWeb3()
|
||||||
const from = await getAccountFrom(web3)
|
const from = await getAccountFrom(web3)
|
||||||
const safeInstance = new web3.eth.Contract(GnosisSafeSol.abi, safeAddress)
|
const safeInstance = new web3.eth.Contract(GnosisSafeSol.abi, safeAddress)
|
||||||
const nonce = await safeInstance.methods.nonce().call()
|
const nonce = await safeInstance.methods.nonce().call()
|
||||||
|
const threshold = await safeInstance.methods.getThreshold().call()
|
||||||
|
|
||||||
|
const isExecution = (tx && tx.confirmations.size) || threshold === '1'
|
||||||
|
|
||||||
|
let txData
|
||||||
|
if (isExecution) {
|
||||||
|
// https://gnosis-safe.readthedocs.io/en/latest/contracts/signatures.html#pre-validated-signatures
|
||||||
|
const signatures = tx
|
||||||
|
|| `0x000000000000000000000000${from.replace(
|
||||||
|
'0x',
|
||||||
|
'',
|
||||||
|
)}000000000000000000000000000000000000000000000000000000000000000001`
|
||||||
|
txData = await safeInstance.methods
|
||||||
|
.execTransaction(to, 0, data, CALL, 0, 0, 0, ZERO_ADDRESS, ZERO_ADDRESS, signatures)
|
||||||
|
.encodeABI()
|
||||||
|
} else {
|
||||||
const txHash = await safeInstance.methods
|
const txHash = await safeInstance.methods
|
||||||
.getTransactionHash(to, 0, data, CALL, 0, 0, 0, ZERO_ADDRESS, ZERO_ADDRESS, nonce)
|
.getTransactionHash(to, 0, data, CALL, 0, 0, 0, ZERO_ADDRESS, ZERO_ADDRESS, nonce)
|
||||||
.call({
|
.call({
|
||||||
from,
|
from,
|
||||||
})
|
})
|
||||||
const approvalData = await safeInstance.methods.approveHash(txHash).encodeABI()
|
txData = await safeInstance.methods.approveHash(txHash).encodeABI()
|
||||||
const gas = await calculateGasOf(approvalData, from, safeAddress)
|
|
||||||
const gasPrice = await calculateGasPrice()
|
|
||||||
|
|
||||||
return gas * parseInt(gasPrice, 10)
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`Error while estimating approval transaction gas costs: ${err}`)
|
|
||||||
|
|
||||||
return 1000000000000000
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
export const estimateExecuteTxGasCosts = async (
|
const gas = await calculateGasOf(txData, from, safeAddress)
|
||||||
safeInstance: any,
|
|
||||||
to: string,
|
|
||||||
valueInWei: number | string,
|
|
||||||
data: string,
|
|
||||||
operation: Operation,
|
|
||||||
nonce: string | number,
|
|
||||||
sender: string,
|
|
||||||
sigs: string,
|
|
||||||
): Promise<number> => {
|
|
||||||
try {
|
|
||||||
const web3 = getWeb3()
|
|
||||||
const contract = new web3.eth.Contract(GnosisSafeSol.abi, safeInstance.address)
|
|
||||||
const executionData = await contract.methods
|
|
||||||
.execTransaction(to, valueInWei, data, operation, 0, 0, 0, ZERO_ADDRESS, ZERO_ADDRESS)
|
|
||||||
.encodeABI()
|
|
||||||
const gas = await calculateGasOf(executionData, sender, safeInstance.address)
|
|
||||||
const gasPrice = await calculateGasPrice()
|
const gasPrice = await calculateGasPrice()
|
||||||
|
|
||||||
return gas * parseInt(gasPrice, 10)
|
return gas * parseInt(gasPrice, 10)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Error while estimating transaction execution gas costs: ${err}`)
|
console.error(`Error while estimating transaction execution gas costs: ${err}`)
|
||||||
|
|
||||||
return 0.001
|
return 10000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import EtherscanBtn from '~/components/EtherscanBtn'
|
||||||
import CopyBtn from '~/components/CopyBtn'
|
import CopyBtn from '~/components/CopyBtn'
|
||||||
import SafeInfo from '~/routes/safe/components/Balances/SendModal/SafeInfo'
|
import SafeInfo from '~/routes/safe/components/Balances/SendModal/SafeInfo'
|
||||||
import { setImageToPlaceholder } from '~/routes/safe/components/Balances/utils'
|
import { setImageToPlaceholder } from '~/routes/safe/components/Balances/utils'
|
||||||
import { estimateApprovalTxGasCosts } from '~/logic/safe/transactions/gasNew'
|
import { estimateTxGasCosts } from '~/logic/safe/transactions/gasNew'
|
||||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||||
import { TX_NOTIFICATION_TYPES } from '~/logic/safe/transactions'
|
import { TX_NOTIFICATION_TYPES } from '~/logic/safe/transactions'
|
||||||
import { getEthAsToken } from '~/logic/tokens/utils/tokenHelpers'
|
import { getEthAsToken } from '~/logic/tokens/utils/tokenHelpers'
|
||||||
|
@ -57,7 +57,7 @@ const ReviewCustomTx = ({
|
||||||
const web3 = getWeb3()
|
const web3 = getWeb3()
|
||||||
const { fromWei, toBN } = web3.utils
|
const { fromWei, toBN } = web3.utils
|
||||||
|
|
||||||
const estimatedGasCosts = await estimateApprovalTxGasCosts(safeAddress, tx.recipientAddress, tx.data.trim())
|
const estimatedGasCosts = await estimateTxGasCosts(safeAddress, tx.recipientAddress, tx.data.trim())
|
||||||
const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether')
|
const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether')
|
||||||
const formattedGasCosts = formatAmount(gasCostsAsEth)
|
const formattedGasCosts = formatAmount(gasCostsAsEth)
|
||||||
if (isCurrent) {
|
if (isCurrent) {
|
||||||
|
|
|
@ -18,7 +18,7 @@ import Hairline from '~/components/layout/Hairline'
|
||||||
import SafeInfo from '~/routes/safe/components/Balances/SendModal/SafeInfo'
|
import SafeInfo from '~/routes/safe/components/Balances/SendModal/SafeInfo'
|
||||||
import { setImageToPlaceholder } from '~/routes/safe/components/Balances/utils'
|
import { setImageToPlaceholder } from '~/routes/safe/components/Balances/utils'
|
||||||
import { getStandardTokenContract, getHumanFriendlyToken } from '~/logic/tokens/store/actions/fetchTokens'
|
import { getStandardTokenContract, getHumanFriendlyToken } from '~/logic/tokens/store/actions/fetchTokens'
|
||||||
import { estimateApprovalTxGasCosts } from '~/logic/safe/transactions/gasNew'
|
import { estimateTxGasCosts } from '~/logic/safe/transactions/gasNew'
|
||||||
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
||||||
import { formatAmount } from '~/logic/tokens/utils/formatAmount'
|
import { formatAmount } from '~/logic/tokens/utils/formatAmount'
|
||||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||||
|
@ -70,7 +70,7 @@ const ReviewTx = ({
|
||||||
txData = tokenInstance.contract.methods.transfer(tx.recipientAddress, 0).encodeABI()
|
txData = tokenInstance.contract.methods.transfer(tx.recipientAddress, 0).encodeABI()
|
||||||
}
|
}
|
||||||
|
|
||||||
const estimatedGasCosts = await estimateApprovalTxGasCosts(safeAddress, txRecipient, txData)
|
const estimatedGasCosts = await estimateTxGasCosts(safeAddress, txRecipient, txData)
|
||||||
const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether')
|
const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether')
|
||||||
const formattedGasCosts = formatAmount(gasCostsAsEth)
|
const formattedGasCosts = formatAmount(gasCostsAsEth)
|
||||||
if (isCurrent) {
|
if (isCurrent) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ import type { Owner } from '~/routes/safe/store/models/owner'
|
||||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||||
import { formatAmount } from '~/logic/tokens/utils/formatAmount'
|
import { formatAmount } from '~/logic/tokens/utils/formatAmount'
|
||||||
import { getGnosisSafeInstanceAt } from '~/logic/contracts/safeContracts'
|
import { getGnosisSafeInstanceAt } from '~/logic/contracts/safeContracts'
|
||||||
import { estimateApprovalTxGasCosts } from '~/logic/safe/transactions/gasNew'
|
import { estimateTxGasCosts } from '~/logic/safe/transactions/gasNew'
|
||||||
import { styles } from './style'
|
import { styles } from './style'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
@ -48,7 +48,7 @@ const ChangeThreshold = ({
|
||||||
|
|
||||||
const safeInstance = await getGnosisSafeInstanceAt(safeAddress)
|
const safeInstance = await getGnosisSafeInstanceAt(safeAddress)
|
||||||
const txData = safeInstance.contract.methods.changeThreshold('1').encodeABI()
|
const txData = safeInstance.contract.methods.changeThreshold('1').encodeABI()
|
||||||
const estimatedGasCosts = await estimateApprovalTxGasCosts(safeAddress, safeAddress, txData)
|
const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, txData)
|
||||||
const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether')
|
const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether')
|
||||||
const formattedGasCosts = formatAmount(gasCostsAsEth)
|
const formattedGasCosts = formatAmount(gasCostsAsEth)
|
||||||
if (isCurrent) {
|
if (isCurrent) {
|
||||||
|
|
Loading…
Reference in New Issue