From ec9c78b88bed9e9a4b3eb6eef2fce4b315c40a3d Mon Sep 17 00:00:00 2001 From: apanizo Date: Mon, 30 Apr 2018 14:10:24 +0200 Subject: [PATCH] WA-238 Deploying contracts with Daily limit and ProxyFactory --- src/routes/open/container/Open.jsx | 59 ++++++++++++------- src/routes/safe/store/test/balance.reducer.js | 4 +- .../test/builder/deployedSafe.builder.js | 2 +- src/utils/singleton.js | 3 +- src/wallets/safeContracts.js | 40 +++++++++++++ 5 files changed, 84 insertions(+), 24 deletions(-) create mode 100644 src/wallets/safeContracts.js diff --git a/src/routes/open/container/Open.jsx b/src/routes/open/container/Open.jsx index e3897ef7..cd070ecf 100644 --- a/src/routes/open/container/Open.jsx +++ b/src/routes/open/container/Open.jsx @@ -1,12 +1,16 @@ // @flow import * as React from 'react' import { connect } from 'react-redux' -import contract from 'truffle-contract' + import Page from '~/components/layout/Page' import { getAccountsFrom, getThresholdFrom, getNamesFrom, getSafeNameFrom, getDailyLimitFrom } from '~/routes/open/utils/safeDataExtractor' import { getWeb3 } from '~/wallets/getWeb3' -import { promisify } from '~/utils/promisify' -import Safe from '#/GnosisSafe.json' +import { + getCreateAddExtensionContract, + getCreateDailyLimitExtensionContract, + getCreateProxyFactoryContract, + getGnosisSafeContract, +} from '~/wallets/safeContracts' import selector from './selector' import actions, { type Actions } from './actions' import Layout from '../components/Layout' @@ -21,7 +25,7 @@ type State = { safeTx: string, } -const createSafe = async (safeContract, values, userAccount, addSafe) => { +const createSafe = async (values, userAccount, addSafe): State => { const accounts = getAccountsFrom(values) const numConfirmations = getThresholdFrom(values) const name = getSafeNameFrom(values) @@ -29,11 +33,36 @@ const createSafe = async (safeContract, values, userAccount, addSafe) => { const dailyLimit = getDailyLimitFrom(values) const web3 = getWeb3() - safeContract.setProvider(web3.currentProvider) + const GnosisSafe = getGnosisSafeContract(web3) + const ProxyFactory = getCreateProxyFactoryContract(web3) + const CreateAndAddExtension = getCreateAddExtensionContract(web3) + const DailyLimitExtension = getCreateDailyLimitExtensionContract(web3) - const safe = await safeContract.new(accounts, numConfirmations, 0, 0, { from: userAccount, gas: '5000000' }) - addSafe(name, safe.address, numConfirmations, dailyLimit, owners, accounts) - return safe + // Create Master Copies + const proxyFactory = await ProxyFactory.new({ from: userAccount, gas: '5000000' }) + const createAndAddExtension = await CreateAndAddExtension.new({ from: userAccount, gas: '5000000' }) + + // Initialize safe master copy + const gnosisSafeMasterCopy = await GnosisSafe.new({ from: userAccount, gas: '5000000' }) + gnosisSafeMasterCopy.setup([userAccount], 1, 0, 0, { from: userAccount, gas: '5000000' }) + + // Initialize extension master copy + const dailyLimitExtensionMasterCopy = await DailyLimitExtension.new({ from: userAccount, gas: '5000000' }) + dailyLimitExtensionMasterCopy.setup([], [], { from: userAccount, gas: '5000000' }) + + // Create Gnosis Safe and Daily Limit Extension in one transactions + const extensionData = await dailyLimitExtensionMasterCopy.contract.setup.getData([0], [100], { from: userAccount, gas: '5000000' }) + const proxyFactoryData = await proxyFactory.contract.createProxy.getData(dailyLimitExtensionMasterCopy.address, extensionData, { from: userAccount, gas: '5000000' }) + const createAndAddExtensionData = createAndAddExtension.contract.createAndAddExtension.getData(proxyFactory.address, proxyFactoryData, { from: userAccount, gas: '5000000' }) + const gnosisSafeData = await gnosisSafeMasterCopy.contract.setup.getData(accounts, numConfirmations, createAndAddExtension.address, createAndAddExtensionData, { from: userAccount, gas: '5000000' }) + const safe = await proxyFactory.createProxy(gnosisSafeMasterCopy.address, gnosisSafeData, { from: userAccount, gas: '5000000' }) + + const param = safe.logs[1].args.proxy + const safeContract = GnosisSafe.at(param) + + addSafe(name, safeContract.address, numConfirmations, dailyLimit, owners, accounts) + + return { safeAddress: safeContract.address, safeTx: safe } } class Open extends React.Component { @@ -44,29 +73,19 @@ class Open extends React.Component { safeAddress: '', safeTx: '', } - - this.safe = contract(Safe) } onCallSafeContractSubmit = async (values) => { try { const { userAccount, addSafe } = this.props - const web3 = getWeb3() - - const safeInstance = await createSafe(this.safe, values, userAccount, addSafe) - const { address, transactionHash } = safeInstance - - const transactionReceipt = await promisify(cb => web3.eth.getTransactionReceipt(transactionHash, cb)) - - this.setState({ safeAddress: address, safeTx: transactionReceipt }) + const safeInstance = await createSafe(values, userAccount, addSafe) + this.setState(safeInstance) } catch (error) { // eslint-disable-next-line console.log('Error while creating the Safe' + error) } } - safe: any - render() { const { safeAddress, safeTx } = this.state const { provider, userAccount } = this.props diff --git a/src/routes/safe/store/test/balance.reducer.js b/src/routes/safe/store/test/balance.reducer.js index 923fc449..b10487f5 100644 --- a/src/routes/safe/store/test/balance.reducer.js +++ b/src/routes/safe/store/test/balance.reducer.js @@ -23,7 +23,7 @@ const balanceReducerTests = () => { it('reducer should return 0 to just deployed safe', async () => { // GIVEN const safeTx = await aDeployedSafe(store) - const address = safeTx.contractAddress + const address = safeTx.logs[1].args.proxy // WHEN await store.dispatch(fetchBalance(address)) @@ -37,7 +37,7 @@ const balanceReducerTests = () => { it('reducer should return 1.3456 ETH as funds to safe with 1 ETH', async () => { // GIVEN const safeTx = await aDeployedSafe(store) - const address = safeTx.contractAddress + const address = safeTx.logs[1].args.proxy // WHEN await addEtherTo(address, '1.3456') diff --git a/src/routes/safe/store/test/builder/deployedSafe.builder.js b/src/routes/safe/store/test/builder/deployedSafe.builder.js index 6c9b9dca..43cfd125 100644 --- a/src/routes/safe/store/test/builder/deployedSafe.builder.js +++ b/src/routes/safe/store/test/builder/deployedSafe.builder.js @@ -61,7 +61,7 @@ const deploySafe = async (safe: React$Component<{}>) => { } const transactionHash = JSON.parse(deployed.getElementsByTagName('pre')[0].innerHTML) - delete transactionHash.logsBloom + delete transactionHash.receipt.logsBloom return transactionHash } diff --git a/src/utils/singleton.js b/src/utils/singleton.js index 5517a770..8a685343 100644 --- a/src/utils/singleton.js +++ b/src/utils/singleton.js @@ -7,7 +7,8 @@ export const ensureOnce = (fn: Function): Function => { if (executed) { return response } executed = true - response = fn(args) + // eslint-disable-next-line + response = fn.apply(undefined, args) return response } diff --git a/src/wallets/safeContracts.js b/src/wallets/safeContracts.js new file mode 100644 index 00000000..267d1128 --- /dev/null +++ b/src/wallets/safeContracts.js @@ -0,0 +1,40 @@ +// @flow +import contract from 'truffle-contract' +import { ensureOnce } from '~/utils/singleton' +import GnosisSafeSol from '#/GnosisSafe.json' +import ProxyFactorySol from '#/ProxyFactory.json' +import CreateAndAddExtensionSol from '#/CreateAndAddExtension.json' +import DailyLimitExtensionSol from '#/DailyLimitExtension.json' + +const createGnosisSafeContract = (web3: any) => { + const gnosisSafe = contract(GnosisSafeSol) + gnosisSafe.setProvider(web3.currentProvider) + + return gnosisSafe +} + +const createProxyFactoryContract = (web3: any) => { + const proxyFactory = contract(ProxyFactorySol) + proxyFactory.setProvider(web3.currentProvider) + + return proxyFactory +} + +const createAddExtensionContract = (web3: any) => { + const createAndAddExtension = contract(CreateAndAddExtensionSol) + createAndAddExtension.setProvider(web3.currentProvider) + + return createAndAddExtension +} + +const createDailyLimitExtensionContract = (web3: any) => { + const dailyLimitExtension = contract(DailyLimitExtensionSol) + dailyLimitExtension.setProvider(web3.currentProvider) + + return dailyLimitExtension +} + +export const getGnosisSafeContract = ensureOnce(createGnosisSafeContract) +export const getCreateProxyFactoryContract = ensureOnce(createProxyFactoryContract) +export const getCreateAddExtensionContract = ensureOnce(createAddExtensionContract) +export const getCreateDailyLimitExtensionContract = ensureOnce(createDailyLimitExtensionContract)