Transactions gas costs wip

This commit is contained in:
Mikhail Mikheev 2019-10-07 18:50:33 +04:00
parent 712fc80b1e
commit 387ea01d5e
4 changed files with 99 additions and 11 deletions

View File

@ -0,0 +1,57 @@
// @flow
import GnosisSafeSol from '@gnosis.pm/safe-contracts/build/contracts/GnosisSafe.json'
import { getWeb3, getAccountFrom } from '~/logic/wallets/getWeb3'
import { type Operation } from '~/logic/safe/transactions'
import { calculateGasOf, calculateGasPrice } from '~/logic/wallets/ethTransactions'
import { ZERO_ADDRESS } from '~/logic/wallets/ethAddresses'
import { CALL } from '.'
export const estimateApprovalTxGasCosts = async (safeAddress: string, to: string, data: string): Promise<number> => {
try {
const web3 = getWeb3()
const from = await getAccountFrom(web3)
const safeInstance = new web3.eth.Contract(GnosisSafeSol.abi, safeAddress)
const nonce = await safeInstance.methods.nonce().call()
const txHash = await safeInstance.methods
.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)
} catch (err) {
console.error(`Error while estimating approval transaction gas costs: ${err}`)
return 1000000000000000
}
}
export const estimateExecuteTxGasCosts = async (
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()
return gas * parseInt(gasPrice, 10)
} catch (err) {
console.error(`Error while estimating transaction execution gas costs: ${err}`)
return 0.001
}
}

View File

@ -64,7 +64,7 @@ const getProviderName: Function = (web3Provider): string => {
return name
}
const getAccountFrom: Function = async (web3Provider): Promise<string | null> => {
export const getAccountFrom: Function = async (web3Provider): Promise<string | null> => {
const accounts = await web3Provider.eth.getAccounts()
if (process.env.NODE_ENV === 'test' && window.testAccountIndex) {

View File

@ -67,7 +67,7 @@ const Routes = ({ defaultSafe, location }: RoutesProps) => {
<Route path={SAFE_ADDRESS} component={Safe} />
<Route exact path={OPENING_ADDRESS} component={Opening} />
<Route exact path={LOAD_ADDRESS} component={Load} />
{/* <Redirect to="/" /> */}
<Redirect to="/" />
</Switch>
)
}

View File

@ -1,5 +1,5 @@
// @flow
import React from 'react'
import React, { useEffect, useState } from 'react'
import { BigNumber } from 'bignumber.js'
import OpenInNew from '@material-ui/icons/OpenInNew'
import { withStyles } from '@material-ui/core/styles'
@ -19,6 +19,7 @@ import Hairline from '~/components/layout/Hairline'
import SafeInfo from '~/routes/safe/components/Balances/SendModal/SafeInfo'
import { setImageToPlaceholder } from '~/routes/safe/components/Balances/utils'
import { getStandardTokenContract, getHumanFriendlyToken } from '~/logic/tokens/store/actions/fetchTokens'
import { estimateApprovalTxGasCosts } from '~/logic/safe/transactions/gasNew'
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
import { getWeb3 } from '~/logic/wallets/getWeb3'
import { TX_NOTIFICATION_TYPES } from '~/logic/safe/transactions'
@ -59,10 +60,42 @@ const ReviewTx = ({
enqueueSnackbar,
closeSnackbar,
}: Props) => {
const submitTx = async () => {
const web3 = getWeb3()
const [gasCosts, setGasCosts] = useState<string>('0.0')
const isSendingETH = isEther(tx.token.symbol)
const txRecipient = isSendingETH ? tx.recipientAddress : tx.token.address
useEffect(() => {
let isCurrent = true
const estimateGas = async () => {
const web3 = getWeb3()
const { fromWei, toBN } = web3.utils
let txData = EMPTY_DATA
if (!isSendingETH) {
const StandardToken = await getStandardTokenContract()
const tokenInstance = await StandardToken.at(tx.token.address)
txData = tokenInstance.contract.methods.transfer(tx.recipientAddress, 0).encodeABI()
}
const estimatedGasCosts = await estimateApprovalTxGasCosts(safeAddress, txRecipient, txData)
console.log({ estimatedGasCosts })
const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether')
const roundedGasCosts = parseFloat(gasCostsAsEth).toFixed(3)
if (isCurrent) {
setGasCosts(roundedGasCosts)
}
}
estimateGas()
return () => {
isCurrent = false
}
}, [])
const submitTx = async () => {
const web3 = getWeb3()
let txData = EMPTY_DATA
let txAmount = web3.utils.toWei(tx.amount, 'ether')
@ -106,12 +139,7 @@ const ReviewTx = ({
</Row>
<Hairline />
<Block className={classes.container}>
<SafeInfo
safeAddress={safeAddress}
etherScanLink={etherScanLink}
safeName={safeName}
ethBalance={ethBalance}
/>
<SafeInfo safeAddress={safeAddress} etherScanLink={etherScanLink} safeName={safeName} ethBalance={ethBalance} />
<Row margin="md">
<Col xs={1}>
<img src={ArrowDown} alt="Arrow Down" style={{ marginLeft: '8px' }} />
@ -152,6 +180,9 @@ const ReviewTx = ({
</Paragraph>
</Row>
</Block>
<Row>
<Paragraph>{`Gas costs: ${gasCosts}`}</Paragraph>
</Row>
<Hairline style={{ position: 'absolute', bottom: 85 }} />
<Row align="center" className={classes.buttonRow}>
<Button minWidth={140} onClick={() => setActiveScreen('sendFunds')}>