refactor tx gas eestimation method to one functions which supports both execution and approval

This commit is contained in:
Mikhail Mikheev 2019-10-10 16:47:21 +04:00
parent ea04ae976e
commit ee483a98e4
4 changed files with 36 additions and 40 deletions

View File

@ -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 txHash = await safeInstance.methods const threshold = await safeInstance.methods.getThreshold().call()
.getTransactionHash(to, 0, data, CALL, 0, 0, 0, ZERO_ADDRESS, ZERO_ADDRESS, nonce)
.call({
from,
})
const approvalData = await safeInstance.methods.approveHash(txHash).encodeABI()
const gas = await calculateGasOf(approvalData, from, safeAddress)
const gasPrice = await calculateGasPrice()
return gas * parseInt(gasPrice, 10) const isExecution = (tx && tx.confirmations.size) || threshold === '1'
} catch (err) {
console.error(`Error while estimating approval transaction gas costs: ${err}`)
return 1000000000000000 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
.getTransactionHash(to, 0, data, CALL, 0, 0, 0, ZERO_ADDRESS, ZERO_ADDRESS, nonce)
.call({
from,
})
txData = await safeInstance.methods.approveHash(txHash).encodeABI()
}
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
} }
} }

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {