From 534f4f28c3dc732e1455e1a73edc96fbe99802e4 Mon Sep 17 00:00:00 2001 From: Agustin Pane Date: Wed, 18 Nov 2020 11:36:50 -0300 Subject: [PATCH 1/4] Replaces createProxy with createProxyWithNonce method no safe creation --- src/logic/contracts/safeContracts.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/logic/contracts/safeContracts.ts b/src/logic/contracts/safeContracts.ts index b9673cf9be..cf6d332923 100644 --- a/src/logic/contracts/safeContracts.ts +++ b/src/logic/contracts/safeContracts.ts @@ -74,12 +74,13 @@ export const getSafeMasterContract = async () => { return safeMaster } -export const getSafeDeploymentTransaction = (safeAccounts, numConfirmations) => { +export const getSafeDeploymentTransaction = (safeAccounts: string[], numConfirmations: number) => { const gnosisSafeData = safeMaster.methods .setup(safeAccounts, numConfirmations, ZERO_ADDRESS, '0x', DEFAULT_FALLBACK_HANDLER_ADDRESS, ZERO_ADDRESS, 0, ZERO_ADDRESS) .encodeABI() - return proxyFactoryMaster.methods.createProxy(safeMaster.options.address, gnosisSafeData) + const randomSalt = new Date().getTime() + return proxyFactoryMaster.methods.createProxyWithNonce(safeMaster.options.address, gnosisSafeData, randomSalt) } export const estimateGasForDeployingSafe = async ( From 1f262f3f2ffd1cf19113871a8c28fdc0ecbc46dc Mon Sep 17 00:00:00 2001 From: Agustin Pane Date: Wed, 18 Nov 2020 11:47:15 -0300 Subject: [PATCH 2/4] Updates estimationGas method --- src/logic/contracts/safeContracts.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logic/contracts/safeContracts.ts b/src/logic/contracts/safeContracts.ts index cf6d332923..683e7c5274 100644 --- a/src/logic/contracts/safeContracts.ts +++ b/src/logic/contracts/safeContracts.ts @@ -92,7 +92,7 @@ export const estimateGasForDeployingSafe = async ( .setup(safeAccounts, numConfirmations, ZERO_ADDRESS, '0x', DEFAULT_FALLBACK_HANDLER_ADDRESS, ZERO_ADDRESS, 0, ZERO_ADDRESS) .encodeABI() const proxyFactoryData = proxyFactoryMaster.methods - .createProxy(safeMaster.options.address, gnosisSafeData) + .createProxyWithNonce(safeMaster.options.address, gnosisSafeData, new Date().getTime()) .encodeABI() const gas = await calculateGasOf(proxyFactoryData, userAccount, proxyFactoryMaster.options.address) const gasPrice = await calculateGasPrice() From e9d2b1ae2e5446527ac93b4231e87b006f136748 Mon Sep 17 00:00:00 2001 From: Agustin Pane Date: Wed, 18 Nov 2020 13:20:29 -0300 Subject: [PATCH 3/4] Moves safeCreationSalt as a parameter --- src/logic/contracts/safeContracts.ts | 14 +++++++------- src/routes/open/components/Layout.tsx | 10 ++++++---- .../open/components/ReviewInformation/index.tsx | 13 +++++++------ src/routes/open/components/fields.ts | 1 + src/routes/open/container/Open.tsx | 10 +++++----- src/routes/open/utils/safeDataExtractor.ts | 2 ++ src/test/safe.dom.create.tsx | 4 ++-- 7 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/logic/contracts/safeContracts.ts b/src/logic/contracts/safeContracts.ts index 683e7c5274..cc85b84617 100644 --- a/src/logic/contracts/safeContracts.ts +++ b/src/logic/contracts/safeContracts.ts @@ -74,25 +74,25 @@ export const getSafeMasterContract = async () => { return safeMaster } -export const getSafeDeploymentTransaction = (safeAccounts: string[], numConfirmations: number) => { +export const getSafeDeploymentTransaction = (safeAccounts: string[], numConfirmations: number, safeCreationSalt: number) => { const gnosisSafeData = safeMaster.methods .setup(safeAccounts, numConfirmations, ZERO_ADDRESS, '0x', DEFAULT_FALLBACK_HANDLER_ADDRESS, ZERO_ADDRESS, 0, ZERO_ADDRESS) .encodeABI() - const randomSalt = new Date().getTime() - return proxyFactoryMaster.methods.createProxyWithNonce(safeMaster.options.address, gnosisSafeData, randomSalt) + return proxyFactoryMaster.methods.createProxyWithNonce(safeMaster.options.address, gnosisSafeData, safeCreationSalt) } export const estimateGasForDeployingSafe = async ( - safeAccounts, - numConfirmations, - userAccount, + safeAccounts: string[], + numConfirmations: number, + userAccount: string, + safeCreationSalt: number ) => { const gnosisSafeData = await safeMaster.methods .setup(safeAccounts, numConfirmations, ZERO_ADDRESS, '0x', DEFAULT_FALLBACK_HANDLER_ADDRESS, ZERO_ADDRESS, 0, ZERO_ADDRESS) .encodeABI() const proxyFactoryData = proxyFactoryMaster.methods - .createProxyWithNonce(safeMaster.options.address, gnosisSafeData, new Date().getTime()) + .createProxyWithNonce(safeMaster.options.address, gnosisSafeData, safeCreationSalt) .encodeABI() const gas = await calculateGasOf(proxyFactoryData, userAccount, proxyFactoryMaster.options.address) const gasPrice = await calculateGasPrice() diff --git a/src/routes/open/components/Layout.tsx b/src/routes/open/components/Layout.tsx index 6ad2a29f49..728276ad4f 100644 --- a/src/routes/open/components/Layout.tsx +++ b/src/routes/open/components/Layout.tsx @@ -7,11 +7,12 @@ import Block from 'src/components/layout/Block' import Heading from 'src/components/layout/Heading' import Row from 'src/components/layout/Row' import { initContracts } from 'src/logic/contracts/safeContracts' -import Review from 'src/routes/open/components/ReviewInformation' +import { Review } from 'src/routes/open/components/ReviewInformation' import SafeNameField from 'src/routes/open/components/SafeNameForm' import { SafeOwnersPage } from 'src/routes/open/components/SafeOwnersConfirmationsForm' import { FIELD_CONFIRMATIONS, + FIELD_CREATION_PROXY_SALT, FIELD_SAFE_NAME, getOwnerAddressBy, getOwnerNameBy, @@ -40,6 +41,7 @@ type InitialValuesForm = { owner0Name?: string confirmations: string safeName?: string + safeCreationSalt: number } const useInitialValuesFrom = (userAccount: string, safeProps?: SafeProps): InitialValuesForm => { @@ -51,6 +53,7 @@ const useInitialValuesFrom = (userAccount: string, safeProps?: SafeProps): Initi [getOwnerNameBy(0)]: ownerName || 'My Wallet', [getOwnerAddressBy(0)]: userAccount, [FIELD_CONFIRMATIONS]: '1', + [FIELD_CREATION_PROXY_SALT]: Date.now(), } } let obj = {} @@ -68,6 +71,7 @@ const useInitialValuesFrom = (userAccount: string, safeProps?: SafeProps): Initi ...obj, [FIELD_CONFIRMATIONS]: threshold || '1', [FIELD_SAFE_NAME]: name, + [FIELD_CREATION_PROXY_SALT]: Date.now(), } } @@ -92,7 +96,7 @@ type LayoutProps = { safeProps?: SafeProps } -const Layout = (props: LayoutProps): React.ReactElement => { +export const Layout = (props: LayoutProps): React.ReactElement => { const { onCallSafeContractSubmit, safeProps } = props const provider = useSelector(providerNameSelector) @@ -139,5 +143,3 @@ const Layout = (props: LayoutProps): React.ReactElement => { ) } - -export default Layout diff --git a/src/routes/open/components/ReviewInformation/index.tsx b/src/routes/open/components/ReviewInformation/index.tsx index 1efc00571a..4f08ff61b8 100644 --- a/src/routes/open/components/ReviewInformation/index.tsx +++ b/src/routes/open/components/ReviewInformation/index.tsx @@ -13,7 +13,7 @@ import Row from 'src/components/layout/Row' import OpenPaper from 'src/components/Stepper/OpenPaper' import { estimateGasForDeployingSafe } from 'src/logic/contracts/safeContracts' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' -import { getAccountsFrom, getNamesFrom } from 'src/routes/open/utils/safeDataExtractor' +import { getAccountsFrom, getNamesFrom, getSafeCreationSaltFrom } from 'src/routes/open/utils/safeDataExtractor' import { FIELD_CONFIRMATIONS, FIELD_NAME, getNumOwnersFrom } from '../fields' import { useStyles } from './styles' @@ -33,20 +33,23 @@ const ReviewComponent = ({ userAccount, values }: ReviewComponentProps) => { const names = getNamesFrom(values) const addresses = getAccountsFrom(values) const numOwners = getNumOwnersFrom(values) + const safeCreationSalt = getSafeCreationSaltFrom(values) useEffect(() => { const estimateGas = async () => { if (!addresses.length || !numOwners || !userAccount) { return } - const estimatedGasCosts = (await estimateGasForDeployingSafe(addresses, numOwners, userAccount)).toString() + const estimatedGasCosts = ( + await estimateGasForDeployingSafe(addresses, numOwners, userAccount, safeCreationSalt) + ).toString() const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) const formattedGasCosts = formatAmount(gasCosts) setGasCosts(formattedGasCosts) } estimateGas() - }, [addresses, numOwners, userAccount]) + }, [addresses, numOwners, safeCreationSalt, userAccount]) return ( <> @@ -140,7 +143,7 @@ const ReviewComponent = ({ userAccount, values }: ReviewComponentProps) => { ) } -const Review = () => +export const Review = () => function ReviewPage(controls, props): React.ReactElement { return ( <> @@ -150,5 +153,3 @@ const Review = () => ) } - -export default Review diff --git a/src/routes/open/components/fields.ts b/src/routes/open/components/fields.ts index 3816297791..4df7b36e8b 100644 --- a/src/routes/open/components/fields.ts +++ b/src/routes/open/components/fields.ts @@ -2,6 +2,7 @@ export const FIELD_NAME = 'name' export const FIELD_CONFIRMATIONS = 'confirmations' export const FIELD_OWNERS = 'owners' export const FIELD_SAFE_NAME = 'safeName' +export const FIELD_CREATION_PROXY_SALT = 'safeCreationSalt' export const getOwnerNameBy = (index) => `owner${index}Name` export const getOwnerAddressBy = (index) => `owner${index}Address` diff --git a/src/routes/open/container/Open.tsx b/src/routes/open/container/Open.tsx index d6f043a368..6cf5dca3ab 100644 --- a/src/routes/open/container/Open.tsx +++ b/src/routes/open/container/Open.tsx @@ -4,7 +4,7 @@ import React, { useEffect, useState } from 'react' import ReactGA from 'react-ga' import { useDispatch, useSelector } from 'react-redux' import Opening from 'src/routes/opening' -import Layout from 'src/routes/open/components/Layout' +import { Layout } from 'src/routes/open/components/Layout' import Page from 'src/components/layout/Page' import { getSafeDeploymentTransaction } from 'src/logic/contracts/safeContracts' import { checkReceiptStatus } from 'src/logic/wallets/ethTransactions' @@ -12,6 +12,7 @@ import { getAccountsFrom, getNamesFrom, getOwnersFrom, + getSafeCreationSaltFrom, getSafeNameFrom, getThresholdFrom, } from 'src/routes/open/utils/safeDataExtractor' @@ -58,8 +59,9 @@ export const createSafe = (values, userAccount) => { const name = getSafeNameFrom(values) const ownersNames = getNamesFrom(values) const ownerAddresses = getAccountsFrom(values) + const safeCreationSalt = getSafeCreationSaltFrom(values) - const deploymentTx = getSafeDeploymentTransaction(ownerAddresses, confirmations) + const deploymentTx = getSafeDeploymentTransaction(ownerAddresses, confirmations, safeCreationSalt) const promiEvent = deploymentTx.send({ from: userAccount }) @@ -81,7 +83,7 @@ export const createSafe = (values, userAccount) => { return promiEvent } -const Open = (): React.ReactElement => { +export const Open = (): React.ReactElement => { const [loading, setLoading] = useState(false) const [showProgress, setShowProgress] = useState(false) const [creationTxPromise, setCreationTxPromise] = useState>() @@ -199,5 +201,3 @@ const Open = (): React.ReactElement => { ) } - -export default Open diff --git a/src/routes/open/utils/safeDataExtractor.ts b/src/routes/open/utils/safeDataExtractor.ts index 08baa20783..fd3802288e 100644 --- a/src/routes/open/utils/safeDataExtractor.ts +++ b/src/routes/open/utils/safeDataExtractor.ts @@ -28,3 +28,5 @@ export const getOwnersFrom = (names, addresses): List => { export const getThresholdFrom = (values) => Number(values.confirmations) export const getSafeNameFrom = (values) => values.name + +export const getSafeCreationSaltFrom = (values) => values.safeCreationSalt diff --git a/src/test/safe.dom.create.tsx b/src/test/safe.dom.create.tsx index 032ebbf3de..81eff56708 100644 --- a/src/test/safe.dom.create.tsx +++ b/src/test/safe.dom.create.tsx @@ -1,4 +1,4 @@ -// +// import * as React from 'react' import { } from 'redux' import { render, fireEvent, act } from '@testing-library/react' @@ -6,7 +6,7 @@ import { Provider } from 'react-redux' import { ConnectedRouter } from 'connected-react-router' import { sleep } from 'src/utils/timer' import { ADD_OWNER_BUTTON } from 'src/routes/open/components/SafeOwnersConfirmationsForm' -import Open from 'src/routes/open/container/Open' +import { Open } from 'src/routes/open/container/Open' import { aNewStore, history, } from 'src/store' import { getProviderInfo, getWeb3 } from 'src/logic/wallets/getWeb3' import addProvider from 'src/logic/wallets/store/actions/addProvider' From 25cfa93b113a747b34e6567d424e4ee843c6cbea Mon Sep 17 00:00:00 2001 From: Agustin Pane Date: Wed, 18 Nov 2020 13:25:38 -0300 Subject: [PATCH 4/4] Fix default export --- src/routes/open/container/Open.tsx | 4 +++- src/test/safe.dom.create.tsx | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/routes/open/container/Open.tsx b/src/routes/open/container/Open.tsx index 6cf5dca3ab..7161c4e787 100644 --- a/src/routes/open/container/Open.tsx +++ b/src/routes/open/container/Open.tsx @@ -83,7 +83,7 @@ export const createSafe = (values, userAccount) => { return promiEvent } -export const Open = (): React.ReactElement => { +const Open = (): React.ReactElement => { const [loading, setLoading] = useState(false) const [showProgress, setShowProgress] = useState(false) const [creationTxPromise, setCreationTxPromise] = useState>() @@ -201,3 +201,5 @@ export const Open = (): React.ReactElement => { ) } + +export default Open diff --git a/src/test/safe.dom.create.tsx b/src/test/safe.dom.create.tsx index 81eff56708..d686009f16 100644 --- a/src/test/safe.dom.create.tsx +++ b/src/test/safe.dom.create.tsx @@ -6,7 +6,7 @@ import { Provider } from 'react-redux' import { ConnectedRouter } from 'connected-react-router' import { sleep } from 'src/utils/timer' import { ADD_OWNER_BUTTON } from 'src/routes/open/components/SafeOwnersConfirmationsForm' -import { Open } from 'src/routes/open/container/Open' +import Open from 'src/routes/open/container/Open' import { aNewStore, history, } from 'src/store' import { getProviderInfo, getWeb3 } from 'src/logic/wallets/getWeb3' import addProvider from 'src/logic/wallets/store/actions/addProvider'