WA-238 Adjust createTransaction function to be executed correctly

This commit is contained in:
apanizo 2018-05-24 17:01:23 +02:00
parent ad7157b454
commit 38953cfcb7
2 changed files with 59 additions and 28 deletions

View File

@ -6,7 +6,7 @@ import { sleep } from '~/utils/timer'
import { type Safe } from '~/routes/safe/store/model/safe' import { type Safe } from '~/routes/safe/store/model/safe'
import actions, { type Actions } from './actions' import actions, { type Actions } from './actions'
import selector, { type SelectorProps } from './selector' import selector, { type SelectorProps } from './selector'
import transaction, { storeTransaction, TX_NAME_PARAM, TX_DESTINATION_PARAM, TX_VALUE_PARAM } from './transactions' import { createTransaction, TX_NAME_PARAM, TX_DESTINATION_PARAM, TX_VALUE_PARAM } from './transactions'
import MultisigForm from './MultisigForm' import MultisigForm from './MultisigForm'
import ReviewTx from './ReviewTx' import ReviewTx from './ReviewTx'
@ -37,11 +37,8 @@ class Transactions extends React.Component<Props, State> {
const nonce = Date.now() const nonce = Date.now()
const destination = values[TX_DESTINATION_PARAM] const destination = values[TX_DESTINATION_PARAM]
const value = values[TX_VALUE_PARAM] const value = values[TX_VALUE_PARAM]
const tx = await transaction(safe.get('address'), destination, value, nonce, userAddress) const name = values[TX_NAME_PARAM]
await storeTransaction( await createTransaction(safe, name, destination, value, nonce, userAddress)
values[TX_NAME_PARAM], nonce, destination, value, userAddress,
safe.get('owners'), tx.tx, safe.get('address'), safe.get('confirmations'),
)
await sleep(1500) await sleep(1500)
this.props.fetchTransactions() this.props.fetchTransactions()
this.setState({ done: true }) this.setState({ done: true })

View File

@ -6,22 +6,34 @@ import { type Confirmation, makeConfirmation } from '~/routes/safe/store/model/c
import { makeTransaction, type Transaction, type TransactionProps } from '~/routes/safe/store/model/transaction' import { makeTransaction, type Transaction, type TransactionProps } from '~/routes/safe/store/model/transaction'
import { getGnosisSafeContract } from '~/wallets/safeContracts' import { getGnosisSafeContract } from '~/wallets/safeContracts'
import { getWeb3 } from '~/wallets/getWeb3' import { getWeb3 } from '~/wallets/getWeb3'
import { type Safe } from '~/routes/safe/store/model/safe'
export const TX_NAME_PARAM = 'txName' export const TX_NAME_PARAM = 'txName'
export const TX_DESTINATION_PARAM = 'txDestination' export const TX_DESTINATION_PARAM = 'txDestination'
export const TX_VALUE_PARAM = 'txValue' export const TX_VALUE_PARAM = 'txValue'
const buildConfirmationsFrom = (owners: List<Owner>, creator: string): List<Confirmation> => { export const EXECUTED_CONFIRMATION_HASH = 'EXECUTED'
if (!owners) {
throw new Error('This safe has no owners') // Exported for testing it, should not use it. Use #transactions fnc.
export const buildConfirmationsFrom =
(owners: List<Owner>, creator: string, confirmationHash: string): List<Confirmation> => {
if (!owners) {
throw new Error('This safe has no owners')
}
if (!owners.find((owner: Owner) => owner.get('address') === creator)) {
throw new Error('The creator of the tx is not an owner')
}
return owners.map((owner: Owner) => makeConfirmation({
owner,
status: owner.get('address') === creator,
hash: owner.get('address') === creator ? confirmationHash : undefined,
}))
} }
if (!owners.find((owner: Owner) => owner.get('address') === creator)) { export const buildExecutedConfirmationFrom = (owners: List<Owner>, creator: string): List<Confirmation> =>
throw new Error('The creator of the tx is not an owner') buildConfirmationsFrom(owners, creator, EXECUTED_CONFIRMATION_HASH)
}
return owners.map((owner: Owner) => makeConfirmation({ owner, status: owner.get('address') === creator }))
}
export const storeTransaction = ( export const storeTransaction = (
name: string, name: string,
@ -29,14 +41,12 @@ export const storeTransaction = (
destination: string, destination: string,
value: number, value: number,
creator: string, creator: string,
owners: List<Owner>, confirmations: List<Confirmation>,
tx: string, tx: string,
safeAddress: string, safeAddress: string,
safeThreshold: number, safeThreshold: number,
) => { ) => {
const confirmations: List<Confirmation> = buildConfirmationsFrom(owners, creator) const notMinedWhenOneOwnerSafe = confirmations.count() === 1 && !tx
const notMinedWhenOneOwnerSafe = owners.count() === 1 && !tx
if (notMinedWhenOneOwnerSafe) { if (notMinedWhenOneOwnerSafe) {
throw new Error('The tx should be mined before storing it in safes with one owner') throw new Error('The tx should be mined before storing it in safes with one owner')
} }
@ -58,15 +68,39 @@ export const storeTransaction = (
localStorage.setItem(TX_KEY, JSON.stringify(safeTransactions)) localStorage.setItem(TX_KEY, JSON.stringify(safeTransactions))
} }
const transactions = async (safeAddress: string, destination: string, value: number, nonce: number, user: string) => { const hasOneOwner = (safe: Safe) => {
const web3 = getWeb3() const owners = safe.get('owners')
const GnosisSafe = await getGnosisSafeContract(web3) if (!owners) {
const gnosisSafe = GnosisSafe.at(safeAddress) throw new Error('Received a Safe without owners when creating a tx')
}
const valueInWei = web3.toWei(value, 'ether') return owners.count() === 1
const CALL = 0
return gnosisSafe.approveTransactionWithParameters(destination, valueInWei, '0x', CALL, nonce, { from: user, gas: '5000000' })
} }
export default transactions export const createTransaction = async (
safe: Safe,
txName: string,
txDestination: string,
txValue: number,
nonce: number,
user: string,
) => {
const web3 = getWeb3()
const GnosisSafe = await getGnosisSafeContract(web3)
const safeAddress = safe.get('address')
const gnosisSafe = GnosisSafe.at(safeAddress)
const valueInWei = web3.toWei(txValue, 'ether')
const CALL = 0
if (hasOneOwner(safe)) {
const txHash = await gnosisSafe.execTransactionIfApproved(txDestination, valueInWei, '0x', CALL, nonce, { from: user, gas: '5000000' })
const executedConfirmations: List<Confirmation> = buildExecutedConfirmationFrom(safe.get('owners'), user)
return storeTransaction(txName, nonce, txDestination, txValue, user, executedConfirmations, txHash, safeAddress, safe.get('confirmations'))
}
const txConfirmationHash = await gnosisSafe.approveTransactionWithParameters(txDestination, valueInWei, '0x', CALL, nonce, { from: user, gas: '5000000' })
const confirmations: List<Confirmation> = buildConfirmationsFrom(safe.get('owners'), user, txConfirmationHash)
return storeTransaction(txName, nonce, txDestination, txValue, user, confirmations, '', safeAddress, safe.get('confirmations'))
}