diff --git a/.travis.yml b/.travis.yml index 7f5b70c5..de4df85f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,15 +5,16 @@ os: - linux before_script: - yarn global add surge + - export NODE_ENV=testing after_success: - - yarn build-storybook - - yarn build - | if [ ${TRAVIS_BRANCH} = "master" ]; then export NODE_ENV=production; else export NODE_ENV=development; fi + - yarn build-storybook + - yarn build - cd build_webpack/ && cp index.html 200.html && cd .. - chmod ugo+x ./config/deploy/deploy.sh - ./config/deploy/deploy.sh diff --git a/package.json b/package.json index 576b330b..3acd02cb 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "start": "node scripts/start.js", "build": "node scripts/build.js", "test": "run-with-testrpc -l 40000000 'node scripts/test.js --env=jsdom'", - "test-local": "node scripts/test.js --env=jsdom", + "test-local": "NODE_ENV=test && node scripts/test.js --env=jsdom", "precommit": "./precommit.sh", "flow": "flow", "storybook": "start-storybook -p 6006", @@ -50,6 +50,7 @@ "babel-plugin-dynamic-import-node": "^1.2.0", "babel-plugin-transform-es3-member-expression-literals": "^6.22.0", "babel-plugin-transform-es3-property-literals": "^6.22.0", + "bignumber.js": "^7.2.1", "classnames": "^2.2.5", "css-loader": "^0.28.10", "detect-port": "^1.2.2", diff --git a/safe-contracts/build/contracts/CreateAndAddModules.json b/safe-contracts/build/contracts/CreateAndAddModules.json index ba596baf..1e7d5e36 100644 --- a/safe-contracts/build/contracts/CreateAndAddModules.json +++ b/safe-contracts/build/contracts/CreateAndAddModules.json @@ -1262,10 +1262,22 @@ "1527420696956": { "events": {}, "links": {}, - "address": "0x251be274c3a4580fc02223ee33edfa9a2dc386e5", - "transactionHash": "0x7e0d20efecc34a31abf9e22cedf9e709811549a444d77d4889739930ad68ffb3" + "address": "0x18449f1e7a7397fcc0efb8021e55766f5874d6bb", + "transactionHash": "0x288775644c087eed5e41b96fecebdb23be4e6d40bef5b6fb9a2876c2a3145157" + }, + "1527678155804": { + "events": {}, + "links": {}, + "address": "0x4541a795062934411e9aa7debc9cd288d1ca3c3d", + "transactionHash": "0x1de7d532cd599c2eeb5bd5eed12038de0f6556b5d22a0a4f4f8cc15a68ef552c" + }, + "1528109761438": { + "events": {}, + "links": {}, + "address": "0x5fd674bc2873513f8e5a19d69637d0211e476380", + "transactionHash": "0x288775644c087eed5e41b96fecebdb23be4e6d40bef5b6fb9a2876c2a3145157" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-05-28T13:58:28.822Z" + "updatedAt": "2018-06-04T10:56:37.138Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/DailyLimitModule.json b/safe-contracts/build/contracts/DailyLimitModule.json index 7d5a69ad..e9bcb94c 100644 --- a/safe-contracts/build/contracts/DailyLimitModule.json +++ b/safe-contracts/build/contracts/DailyLimitModule.json @@ -6685,10 +6685,22 @@ "1527420696956": { "events": {}, "links": {}, - "address": "0x904a781310cc19b414bafa5499628cd10173cbad", - "transactionHash": "0x2ec83a0174a651dec98e783aa4e23d0b97e8487f788329f82789da4d5067c614" + "address": "0x7318910138c97bec533269843cac7cc32e30d627", + "transactionHash": "0xf501438a4ec967e2928d922e4af568a2a5365002f8b3f9e32117bbacfaa49331" + }, + "1527678155804": { + "events": {}, + "links": {}, + "address": "0xb3a1d7348482ad2556b7cc56d84e8650e9288cd2", + "transactionHash": "0xd6ea4f9e92e49e53ee69faafc7c7ab1c54d811fd1552351f8ec5cdc6f1795843" + }, + "1528109761438": { + "events": {}, + "links": {}, + "address": "0x3bdceb07fddd50d259a059ca9a75ecda561d4afc", + "transactionHash": "0xf501438a4ec967e2928d922e4af568a2a5365002f8b3f9e32117bbacfaa49331" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-05-28T13:58:28.821Z" + "updatedAt": "2018-06-04T10:56:37.129Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/GnosisSafePersonalEdition.json b/safe-contracts/build/contracts/GnosisSafePersonalEdition.json index 4f153f12..03ba515f 100644 --- a/safe-contracts/build/contracts/GnosisSafePersonalEdition.json +++ b/safe-contracts/build/contracts/GnosisSafePersonalEdition.json @@ -9850,10 +9850,22 @@ "1527420696956": { "events": {}, "links": {}, - "address": "0x5aba3ebfac41cb9be55a7ab67b506c960982e427", - "transactionHash": "0x370c8b71ac770f90d44d7bc1f447930a01806b3d8d7b218b21e4020865c45321" + "address": "0x177c7d89d62a0d8bdab4a0a8a5e7225370fd1486", + "transactionHash": "0x67117c1452ee2f4b904621b6f30790ff998d1f1a72f11c6b71ef47e3dd254724" + }, + "1527678155804": { + "events": {}, + "links": {}, + "address": "0x4dbf7fe3ee192b4ea00005c0a7219e4ca19971d6", + "transactionHash": "0xbbf11bb9369aeb027629ec2279e2be554fee6c522da76160a6b535d25d966b1e" + }, + "1528109761438": { + "events": {}, + "links": {}, + "address": "0x8c55b458a53e8c6e9efa7f54e7be9ca76b43dd9b", + "transactionHash": "0x67117c1452ee2f4b904621b6f30790ff998d1f1a72f11c6b71ef47e3dd254724" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-05-28T13:58:28.830Z" + "updatedAt": "2018-06-04T10:56:37.124Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/GnosisSafeTeamEdition.json b/safe-contracts/build/contracts/GnosisSafeTeamEdition.json index 5332bcd2..14a19442 100644 --- a/safe-contracts/build/contracts/GnosisSafeTeamEdition.json +++ b/safe-contracts/build/contracts/GnosisSafeTeamEdition.json @@ -6862,10 +6862,22 @@ "1527420696956": { "events": {}, "links": {}, - "address": "0xb25140d7a0383c103745ce78d394f13ba4cf05ce", - "transactionHash": "0x6443dda4014bb6968582b264cb829cade880976d4c08e3f3c038cbc7d180f619" + "address": "0xb8d09a68423900f75635ae045562a8338060c9aa", + "transactionHash": "0xa71d3b0b3752acc18733fa881f70c256d63562f28ccca9af910fad3beee9181a" + }, + "1527678155804": { + "events": {}, + "links": {}, + "address": "0x8bec74b923b0d2ac349b920ab7566f9c2de06ed1", + "transactionHash": "0x846890db3c85ef38bf8ee86c789f20fbdf1c6339e44f897e15e80ba166b50de3" + }, + "1528109761438": { + "events": {}, + "links": {}, + "address": "0xd4edae2f2d5718d1798deb48c062b939d6e9d4f4", + "transactionHash": "0xa71d3b0b3752acc18733fa881f70c256d63562f28ccca9af910fad3beee9181a" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-05-28T13:58:28.817Z" + "updatedAt": "2018-06-04T10:56:37.114Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/Migrations.json b/safe-contracts/build/contracts/Migrations.json index 201d1044..d9d7c21a 100644 --- a/safe-contracts/build/contracts/Migrations.json +++ b/safe-contracts/build/contracts/Migrations.json @@ -1384,10 +1384,22 @@ "1527420696956": { "events": {}, "links": {}, - "address": "0x3058a32c81f9e74ace6fa808b1906af0252c7638", - "transactionHash": "0x025b6461e9bfe4546ffada7cbf308b8eb4c12287d93fd6079297fb9c847de4df" + "address": "0x954fe52de6d6d18bef1da4972b7bd26dfae4b90c", + "transactionHash": "0xb6a19a7a679a1474c09c651e4151421f210afa3f47effed019d4c0206144ee5f" + }, + "1527678155804": { + "events": {}, + "links": {}, + "address": "0xad40476dc43dbb9546709731e1112be5817db3d2", + "transactionHash": "0xb329d36a169f7dae30b168e57ae72496354fde3b36d9c285a92da9ff012a6399" + }, + "1528109761438": { + "events": {}, + "links": {}, + "address": "0x2ebea54cbbd4f5491deba7a37605f8f0be3e3c9b", + "transactionHash": "0xb6a19a7a679a1474c09c651e4151421f210afa3f47effed019d4c0206144ee5f" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-05-28T13:58:28.833Z" + "updatedAt": "2018-06-04T10:56:37.139Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/MultiSend.json b/safe-contracts/build/contracts/MultiSend.json index e47d2fe3..79da2b5d 100644 --- a/safe-contracts/build/contracts/MultiSend.json +++ b/safe-contracts/build/contracts/MultiSend.json @@ -346,10 +346,22 @@ "1527420696956": { "events": {}, "links": {}, - "address": "0xe423b2291101fb206218ce4eeb03150e94446086", - "transactionHash": "0xa78e4749df5af5dff57145c85a9c9ca882d3b61e6125da675388fdda421622a2" + "address": "0x8e9d29708810d650d0b43058b41687ea02c0baee", + "transactionHash": "0xd044f1662e339061a8cabf2b06ac94a9f86fcccf3f5d80ebd1bea2a7542d4021" + }, + "1527678155804": { + "events": {}, + "links": {}, + "address": "0x6655c7792ebda0b1dbea3607591995ea391c8a9e", + "transactionHash": "0x70aa0d9af1bc4978d61d3f0c67523717246c4a588a4c1808d45609e0adb04a05" + }, + "1528109761438": { + "events": {}, + "links": {}, + "address": "0x3946fcaaa0ba21aaffc5e06a3cc45debc9e07f7f", + "transactionHash": "0xd044f1662e339061a8cabf2b06ac94a9f86fcccf3f5d80ebd1bea2a7542d4021" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-05-28T13:58:28.823Z" + "updatedAt": "2018-06-04T10:56:37.139Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/ProxyFactory.json b/safe-contracts/build/contracts/ProxyFactory.json index f736d283..5d2b5bed 100644 --- a/safe-contracts/build/contracts/ProxyFactory.json +++ b/safe-contracts/build/contracts/ProxyFactory.json @@ -997,10 +997,22 @@ "1527420696956": { "events": {}, "links": {}, - "address": "0x1f7aea763a0714a857aa537a630aa9c1489a9e8d", - "transactionHash": "0xe6856fb57fd2c5da970b640fe9a5f8ee38444b5dbc381bb11bef2bb9cb80d648" + "address": "0xa16e2ea106b09506111fcd01eb82c9864afa4315", + "transactionHash": "0x75ad1066b44cd801ac66a316dbe4c09e72636d72b70fd62eb647295a0fc5e285" + }, + "1527678155804": { + "events": {}, + "links": {}, + "address": "0xf2bf237dc75c3a466b457a5eff498061dac4c341", + "transactionHash": "0x0a1bf7e8030e9d4d24dd7002f35ece3848830cd266ab089664fd1d44ea95d506" + }, + "1528109761438": { + "events": {}, + "links": {}, + "address": "0xbefd9f4a40b1bec8ec730969a3508d1739fb2742", + "transactionHash": "0x75ad1066b44cd801ac66a316dbe4c09e72636d72b70fd62eb647295a0fc5e285" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-05-28T13:58:28.811Z" + "updatedAt": "2018-06-04T10:56:37.112Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/SocialRecoveryModule.json b/safe-contracts/build/contracts/SocialRecoveryModule.json index 2fa5946a..8f32e0de 100644 --- a/safe-contracts/build/contracts/SocialRecoveryModule.json +++ b/safe-contracts/build/contracts/SocialRecoveryModule.json @@ -7296,10 +7296,22 @@ "1527420696956": { "events": {}, "links": {}, - "address": "0xaba91d2c011e7cc4e8a7b89c7731fc355f5733f4", - "transactionHash": "0x274449b108fc18df74c77e6dcd670fa9c486c1dd6ad7aece13cbedea6a77f75d" + "address": "0x72c57fd020ba5c1e42d7e9a7757dd40d5febc594", + "transactionHash": "0xf0cd95843453bdac02ad8018ef507479ea62989e56d69ad0ac1aad9d3a8515d2" + }, + "1527678155804": { + "events": {}, + "links": {}, + "address": "0xeda62e0821a48445ae6f6f80106e216c6a7f01ef", + "transactionHash": "0x36c8dd7c6308c6c439014348fa486a003b509f6740a3fbb01b00d57958c4eca7" + }, + "1528109761438": { + "events": {}, + "links": {}, + "address": "0xfb1771240bb7edf209c70bd520a5d5424d23b084", + "transactionHash": "0xf0cd95843453bdac02ad8018ef507479ea62989e56d69ad0ac1aad9d3a8515d2" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-05-28T13:58:28.837Z" + "updatedAt": "2018-06-04T10:56:37.135Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/StateChannelModule.json b/safe-contracts/build/contracts/StateChannelModule.json index 5e3d6992..a7ce755f 100644 --- a/safe-contracts/build/contracts/StateChannelModule.json +++ b/safe-contracts/build/contracts/StateChannelModule.json @@ -5867,10 +5867,22 @@ "1527420696956": { "events": {}, "links": {}, - "address": "0x54385cc32f3e1cf1167a00d1031713005b58810d", - "transactionHash": "0x5f41f6fd32694378659292b40446fc88ab574830bb99b43380355fd9b2454ca4" + "address": "0xa3944632cf9b50c805788da58443efdf323e69bd", + "transactionHash": "0x0396e1c9da4fa7bd313286e6033446dbb6e491f267956f8cf13202ce534fd0e6" + }, + "1527678155804": { + "events": {}, + "links": {}, + "address": "0x5b0e6b22a1d89e20256ec666ad2acab10d506258", + "transactionHash": "0x6d60cded3abc0298631da9e4402c536e9c10604d213f4fb215f83795722ccda9" + }, + "1528109761438": { + "events": {}, + "links": {}, + "address": "0x589fd9eea7cca488a80e17a5105befff9616f11d", + "transactionHash": "0x0396e1c9da4fa7bd313286e6033446dbb6e491f267956f8cf13202ce534fd0e6" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-05-28T13:58:28.813Z" + "updatedAt": "2018-06-04T10:56:37.118Z" } \ No newline at end of file diff --git a/safe-contracts/build/contracts/WhitelistModule.json b/safe-contracts/build/contracts/WhitelistModule.json index 60fc9c8b..7eff5a28 100644 --- a/safe-contracts/build/contracts/WhitelistModule.json +++ b/safe-contracts/build/contracts/WhitelistModule.json @@ -4340,10 +4340,22 @@ "1527420696956": { "events": {}, "links": {}, - "address": "0x68493ac3f7b340768f44d3924cbf6f303a104107", - "transactionHash": "0x45669293d5726d8b49af10473522b1c3d6232f5cbded6b626e24d366214501c8" + "address": "0x0f2908be3c687fe9fecdfcd3f87cd7464c229723", + "transactionHash": "0x463374c2fbc7eaff5b87e65c6a8fdc1177ef82c66084df6e7b88b506f99b193c" + }, + "1527678155804": { + "events": {}, + "links": {}, + "address": "0xe6986286e71b3cf130edfecefd140c7b0ef7bdc0", + "transactionHash": "0xf135f6e2d525ab0b8889f2860a2ff124ca2c3b8660bf5352cc05206a71be9a9a" + }, + "1528109761438": { + "events": {}, + "links": {}, + "address": "0xca574a31a4cf1eeabeecaffc555bdc7f91c5caf9", + "transactionHash": "0x463374c2fbc7eaff5b87e65c6a8fdc1177ef82c66084df6e7b88b506f99b193c" } }, "schemaVersion": "2.0.0", - "updatedAt": "2018-05-28T13:58:28.834Z" + "updatedAt": "2018-06-04T10:56:37.132Z" } \ No newline at end of file diff --git a/src/routes/open/components/Layout.test.js b/src/routes/open/components/Layout.test.js index 5d67a410..130bba70 100644 --- a/src/routes/open/components/Layout.test.js +++ b/src/routes/open/components/Layout.test.js @@ -65,10 +65,10 @@ describe('React DOM TESTS > Create Safe form', () => { const deployed = TestUtils.findRenderedDOMComponentWithClass(open, DEPLOYED_COMPONENT_ID) if (deployed) { - const transactionHash = JSON.parse(deployed.getElementsByTagName('pre')[0].innerHTML) - delete transactionHash.logsBloom + const transaction = JSON.parse(deployed.getElementsByTagName('pre')[0].innerHTML) + delete transaction.receipt.logsBloom // eslint-disable-next-line - console.log(transactionHash) + // console.log(transaction) } }) }) diff --git a/src/routes/safe/component/AddTransaction/createTransactions.js b/src/routes/safe/component/AddTransaction/createTransactions.js index aa7fb298..54ca30cd 100644 --- a/src/routes/safe/component/AddTransaction/createTransactions.js +++ b/src/routes/safe/component/AddTransaction/createTransactions.js @@ -8,6 +8,7 @@ import { getGnosisSafeContract } from '~/wallets/safeContracts' import { getWeb3 } from '~/wallets/getWeb3' import { type Safe } from '~/routes/safe/store/model/safe' import { sameAddress } from '~/wallets/ethAddresses' +import executeTransaction from '~/wallets/ethTransactions' export const TX_NAME_PARAM = 'txName' export const TX_DESTINATION_PARAM = 'txDestination' @@ -96,13 +97,15 @@ export const createTransaction = async ( const thresholdIsOne = safe.get('confirmations') === 1 if (hasOneOwner(safe) || thresholdIsOne) { - const txReceipt = await gnosisSafe.execTransactionIfApproved(txDestination, valueInWei, '0x', CALL, nonce, { from: user, gas: '5000000' }) + const txConfirmationData = gnosisSafe.contract.execTransactionIfApproved.getData(txDestination, valueInWei, '0x', CALL, nonce) + const txReceipt = await executeTransaction(txConfirmationData, user, safeAddress) const executedConfirmations: List = buildExecutedConfirmationFrom(safe.get('owners'), user) - return storeTransaction(txName, nonce, txDestination, txValue, user, executedConfirmations, txReceipt.tx, safeAddress, safe.get('confirmations')) + return storeTransaction(txName, nonce, txDestination, txValue, user, executedConfirmations, txReceipt, safeAddress, safe.get('confirmations')) } - const txConfirmationHash = await gnosisSafe.approveTransactionWithParameters(txDestination, valueInWei, '0x', CALL, nonce, { from: user, gas: '5000000' }) - const confirmations: List = buildConfirmationsFrom(safe.get('owners'), user, txConfirmationHash.tx) + const txConfirmationData = gnosisSafe.contract.approveTransactionWithParameters.getData(txDestination, valueInWei, '0x', CALL, nonce) + const txConfirmationReceipt = await executeTransaction(txConfirmationData, user, safeAddress) + const confirmations: List = buildConfirmationsFrom(safe.get('owners'), user, txConfirmationReceipt) return storeTransaction(txName, nonce, txDestination, txValue, user, confirmations, '', safeAddress, safe.get('confirmations')) } diff --git a/src/routes/safe/component/Safe/DailyLimit.jsx b/src/routes/safe/component/Safe/DailyLimit.jsx index 9be98714..c44326c0 100644 --- a/src/routes/safe/component/Safe/DailyLimit.jsx +++ b/src/routes/safe/component/Safe/DailyLimit.jsx @@ -10,14 +10,16 @@ import { type DailyLimit } from '~/routes/safe/store/model/dailyLimit' type Props = { dailyLimit: DailyLimit, onWithdrawn: () => void, + balance: string, } export const WITHDRAWN_BUTTON_TEXT = 'Withdrawn' -const DailyLimitComponent = ({ dailyLimit, onWithdrawn }: Props) => { +const DailyLimitComponent = ({ dailyLimit, balance, onWithdrawn }: Props) => { const limit = dailyLimit.get('value') const spentToday = dailyLimit.get('spentToday') - const disabled = spentToday >= limit + + const disabled = spentToday >= limit || Number(balance) === 0 const text = `${limit} ETH (spent today: ${spentToday} ETH)` return ( diff --git a/src/routes/safe/component/Safe/index.jsx b/src/routes/safe/component/Safe/index.jsx index 6852dc1b..8e88fff2 100644 --- a/src/routes/safe/component/Safe/index.jsx +++ b/src/routes/safe/component/Safe/index.jsx @@ -71,7 +71,7 @@ class GnoSafe extends React.PureComponent {
- + diff --git a/src/routes/safe/component/Transactions/processTransactions.js b/src/routes/safe/component/Transactions/processTransactions.js index f8a611dc..2e866ce2 100644 --- a/src/routes/safe/component/Transactions/processTransactions.js +++ b/src/routes/safe/component/Transactions/processTransactions.js @@ -8,6 +8,7 @@ import { getGnosisSafeContract } from '~/wallets/safeContracts' import { getWeb3 } from '~/wallets/getWeb3' import { sameAddress } from '~/wallets/ethAddresses' import { EXECUTED_CONFIRMATION_HASH } from '~/routes/safe/component/AddTransaction/createTransactions' +import executeTransaction from '~/wallets/ethTransactions' export const updateTransaction = ( name: string, @@ -49,9 +50,9 @@ const execTransaction = async ( const CALL = getOperation() const web3 = getWeb3() const valueInWei = web3.toWei(txValue, 'ether') - const txReceipt = await gnosisSafe.execTransactionIfApproved(destination, valueInWei, data, CALL, nonce, { from: executor, gas: '5000000' }) + const txData = await gnosisSafe.contract.execTransactionIfApproved.getData(destination, valueInWei, data, CALL, nonce) - return txReceipt + return executeTransaction(txData, executor, gnosisSafe.address) } const execConfirmation = async ( @@ -65,9 +66,10 @@ const execConfirmation = async ( const CALL = getOperation() const web3 = getWeb3() const valueInWei = web3.toWei(txValue, 'ether') - const txConfirmationReceipt = await gnosisSafe.approveTransactionWithParameters(txDestination, valueInWei, data, CALL, nonce, { from: executor, gas: '5000000' }) + const txConfirmationData = + await gnosisSafe.contract.approveTransactionWithParameters.getData(txDestination, valueInWei, data, CALL, nonce) - return txConfirmationReceipt + return executeTransaction(txConfirmationData, executor, gnosisSafe.address) } const updateConfirmations = (confirmations: List, userAddress: string, txHash: string) => @@ -103,7 +105,7 @@ export const processTransaction = async ( } const threshold = tx.get('threshold') - const thresholdReached = threshold >= alreadyConfirmed + 1 + const thresholdReached = threshold === alreadyConfirmed + 1 const nonce = tx.get('nonce') const txName = tx.get('name') const txValue = tx.get('value') @@ -113,7 +115,7 @@ export const processTransaction = async ( ? await execTransaction(gnosisSafe, txDestination, txValue, nonce, userAddress) : await execConfirmation(gnosisSafe, txDestination, txValue, nonce, userAddress) - const confirmationHash = thresholdReached ? EXECUTED_CONFIRMATION_HASH : txReceipt.tx + const confirmationHash = thresholdReached ? EXECUTED_CONFIRMATION_HASH : txReceipt const executedConfirmations: List = updateConfirmations(tx.get('confirmations'), userAddress, confirmationHash) return updateTransaction( @@ -123,7 +125,7 @@ export const processTransaction = async ( txValue, userAddress, executedConfirmations, - txReceipt.tx, + thresholdReached ? txReceipt : '', safeAddress, threshold, ) diff --git a/src/routes/safe/component/Withdrawn/withdrawn.js b/src/routes/safe/component/Withdrawn/withdrawn.js index ad734311..d9f066d0 100644 --- a/src/routes/safe/component/Withdrawn/withdrawn.js +++ b/src/routes/safe/component/Withdrawn/withdrawn.js @@ -2,6 +2,7 @@ import { getWeb3 } from '~/wallets/getWeb3' import { getGnosisSafeContract, getCreateDailyLimitExtensionContract } from '~/wallets/safeContracts' import { type DailyLimitProps } from '~/routes/safe/store/model/dailyLimit' +import executeTransaction from '~/wallets/ethTransactions' export const LIMIT_POSITION = 0 export const SPENT_TODAY_POS = 1 @@ -42,12 +43,9 @@ const withdrawn = async (values: Object, safeAddress: string, userAccount: strin const destination = values[DESTINATION_PARAM] const value = web3.toWei(values[VALUE_PARAM], 'ether') - return dailyLimitModule.executeDailyLimit( - 0, - destination, - value, - { from: userAccount, gas: '5000000' }, - ) + const dailyLimitData = dailyLimitModule.contract.executeDailyLimit.getData(0, destination, value) + + return executeTransaction(dailyLimitData, userAccount, dailyLimitModule.address) } export default withdrawn diff --git a/src/routes/safe/store/test/builder/deployedSafe.builder.js b/src/routes/safe/store/test/builder/deployedSafe.builder.js index 0e86b593..e57a3395 100644 --- a/src/routes/safe/store/test/builder/deployedSafe.builder.js +++ b/src/routes/safe/store/test/builder/deployedSafe.builder.js @@ -8,10 +8,11 @@ import { DEPLOYED_COMPONENT_ID } from '~/routes/open/components/FormConfirmation import Open from '~/routes/open/container/Open' import { history, type GlobalState } from '~/store' import { sleep } from '~/utils/timer' -import { getProviderInfo } from '~/wallets/getWeb3' +import { getProviderInfo, getWeb3 } from '~/wallets/getWeb3' import addProvider from '~/wallets/store/actions/addProvider' import { makeProvider } from '~/wallets/store/model/provider' import withdrawn, { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdrawn/withdrawn' +import { promisify } from '~/utils/promisify' export const renderSafe = async (localStore: Store) => { const provider = await getProviderInfo() @@ -29,20 +30,34 @@ export const renderSafe = async (localStore: Store) => { ) } -const deploySafe = async (safe: React$Component<{}>, dailyLimit: string) => { +const deploySafe = async (safe: React$Component<{}>, dailyLimit: string, threshold: number, numOwners: number) => { + expect(threshold).toBeLessThanOrEqual(numOwners) const inputs = TestUtils.scryRenderedDOMComponentsWithTag(safe, 'input') const fieldName = inputs[0] const fieldOwners = inputs[1] const fieldConfirmations = inputs[2] const fieldDailyLimit = inputs[3] - TestUtils.Simulate.change(fieldOwners, { target: { value: '1' } }) + const web3 = getWeb3() + const accounts = await promisify(cb => web3.eth.getAccounts(cb)) + TestUtils.Simulate.change(fieldOwners, { target: { value: `${numOwners}` } }) + await sleep(800) const inputsExpanded = TestUtils.scryRenderedDOMComponentsWithTag(safe, 'input') - const ownerName = inputsExpanded[2] + expect(inputsExpanded.length).toBe((numOwners * 2) + 4) // 2 per owner + name, dailyLimit, confirmations, numOwners + + for (let i = 0; i < numOwners; i += 1) { + const nameIndex = (i * 2) + 2 + const addressIndex = (i * 2) + 3 + const ownerName = inputsExpanded[nameIndex] + const account = inputsExpanded[addressIndex] + + TestUtils.Simulate.change(ownerName, { target: { value: `Adolfo ${i + 1} Eth Account` } }) + TestUtils.Simulate.change(account, { target: { value: accounts[i] } }) + } TestUtils.Simulate.change(fieldName, { target: { value: 'Adolfo Safe' } }) - TestUtils.Simulate.change(fieldConfirmations, { target: { value: '1' } }) - TestUtils.Simulate.change(ownerName, { target: { value: 'Adolfo Eth Account' } }) + TestUtils.Simulate.change(fieldConfirmations, { target: { value: `${threshold}` } }) + TestUtils.Simulate.change(fieldDailyLimit, { target: { value: dailyLimit } }) const form = TestUtils.findRenderedDOMComponentWithTag(safe, 'form') @@ -53,7 +68,7 @@ const deploySafe = async (safe: React$Component<{}>, dailyLimit: string) => { // giving some time to the component for updating its state with safe // before destroying its context - await sleep(3500) + await sleep(9000) // THEN const deployed = TestUtils.findRenderedDOMComponentWithClass(safe, DEPLOYED_COMPONENT_ID) @@ -67,9 +82,14 @@ const deploySafe = async (safe: React$Component<{}>, dailyLimit: string) => { return transactionHash } -export const aDeployedSafe = async (specificStore: Store, dailyLimit?: number = 0.5) => { +export const aDeployedSafe = async ( + specificStore: Store, + dailyLimit?: number = 0.5, + threshold?: number = 1, + numOwners?: number = 1, +) => { const safe: React$Component<{}> = await renderSafe(specificStore) - const deployedSafe = await deploySafe(safe, `${dailyLimit}`) + const deployedSafe = await deploySafe(safe, `${dailyLimit}`, threshold, numOwners) return deployedSafe.logs[1].args.proxy } diff --git a/src/routes/safe/component/Safe.txs.test.js b/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js similarity index 100% rename from src/routes/safe/component/Safe.txs.test.js rename to src/routes/safe/test/Safe.multisig.1owners1threshold.test.js diff --git a/src/routes/safe/test/Safe.multisig.3owners1threshold.test.js b/src/routes/safe/test/Safe.multisig.3owners1threshold.test.js new file mode 100644 index 00000000..6b383e5a --- /dev/null +++ b/src/routes/safe/test/Safe.multisig.3owners1threshold.test.js @@ -0,0 +1,59 @@ +// @flow +import * as React from 'react' +import TestUtils from 'react-dom/test-utils' +import { Provider } from 'react-redux' +import { ConnectedRouter } from 'react-router-redux' +import { aNewStore, history } from '~/store' +import { aDeployedSafe } from '~/routes/safe/store/test/builder/deployedSafe.builder' +import { SAFELIST_ADDRESS } from '~/routes/routes' +import AppRoutes from '~/routes' +import AddTransactionComponent from '~/routes/safe/component/AddTransaction' +import { createMultisigTxFilling, addFundsTo, checkBalanceOf, listTxsOf, getTagFromTransaction, expandTransactionOf, getTransactionFromReduxStore, confirmOwners } from '~/routes/safe/test/testMultisig' + +const renderSafe = localStore => ( + TestUtils.renderIntoDocument(( + + + + + + )) +) + +describe('React DOM TESTS > Multisig transactions from safe [3 owners & 1 threshold] ', () => { + let SafeDom + let store + let address + beforeEach(async () => { + // create store + store = aNewStore() + // deploy safe updating store + address = await aDeployedSafe(store, 10, 1, 3) + // navigate to SAFE route + history.push(`${SAFELIST_ADDRESS}/${address}`) + SafeDom = renderSafe(store) + }) + + it('should execute transaction straight away', async () => { + await addFundsTo(SafeDom, address) + await checkBalanceOf(address, '0.1') + await createMultisigTxFilling(SafeDom, AddTransactionComponent, store) + await checkBalanceOf(address, '0.09') + await listTxsOf(SafeDom) + + await expandTransactionOf(SafeDom, 3, 1) + await confirmOwners(SafeDom, 'Adolfo 1 Eth Account [Confirmed]', 'Adolfo 2 Eth Account [Not confirmed]', 'Adolfo 3 Eth Account [Not confirmed]') + + const paragraphs = getTagFromTransaction(SafeDom, 'p') + + const status = paragraphs[2].innerHTML + expect(status).toBe('Already executed') + + const confirmed = paragraphs[3].innerHTML + const tx = getTransactionFromReduxStore(store, address) + expect(confirmed).toBe(tx.get('tx')) + + const ownerTx = paragraphs[6].innerHTML + expect(ownerTx).toBe('Confirmation hash: EXECUTED') + }) +}) diff --git a/src/routes/safe/test/Safe.multisig.3owners3threshold.test.js b/src/routes/safe/test/Safe.multisig.3owners3threshold.test.js new file mode 100644 index 00000000..f57014f8 --- /dev/null +++ b/src/routes/safe/test/Safe.multisig.3owners3threshold.test.js @@ -0,0 +1,101 @@ +// @flow +import * as React from 'react' +import TestUtils from 'react-dom/test-utils' +import { Provider } from 'react-redux' +import { ConnectedRouter } from 'react-router-redux' +import { aNewStore, history } from '~/store' +import { aDeployedSafe } from '~/routes/safe/store/test/builder/deployedSafe.builder' +import { SAFELIST_ADDRESS } from '~/routes/routes' +import AppRoutes from '~/routes' +import { getWeb3 } from '~/wallets/getWeb3' +import { sleep } from '~/utils/timer' +import { promisify } from '~/utils/promisify' +import AddTransactionComponent from '~/routes/safe/component/AddTransaction' +import { processTransaction } from '~/routes/safe/component/Transactions/processTransactions' +import { confirmationsTransactionSelector } from '~/routes/safe/store/selectors/index' +import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions' +import { createMultisigTxFilling, addFundsTo, checkBalanceOf, listTxsOf, getTagFromTransaction, expandTransactionOf, getTransactionFromReduxStore, confirmOwners } from '~/routes/safe/test/testMultisig' + +const renderSafe = localStore => ( + TestUtils.renderIntoDocument(( + + + + + + )) +) + +describe('React DOM TESTS > Multisig transactions from safe [3 owners & 3 threshold] ', () => { + let SafeDom + let store + let address + let accounts + beforeEach(async () => { + // create store + store = aNewStore() + // deploy safe updating store + address = await aDeployedSafe(store, 10, 3, 3) + // navigate to SAFE route + history.push(`${SAFELIST_ADDRESS}/${address}`) + SafeDom = renderSafe(store) + accounts = await promisify(cb => getWeb3().eth.getAccounts(cb)) + }) + + + const getAlreadyConfirmed = () => { + const tx = getTransactionFromReduxStore(store, address) + const confirmed = confirmationsTransactionSelector(store.getState(), { transaction: tx }) + + return confirmed + } + + const makeConfirmation = async (executor) => { + const alreadyConfirmed = getAlreadyConfirmed() + const tx = getTransactionFromReduxStore(store, address) + await processTransaction(address, tx, alreadyConfirmed, executor) + await sleep(800) + store.dispatch(fetchTransactions()) + sleep(1800) + SafeDom = renderSafe(store) + sleep(1800) + await listTxsOf(SafeDom) + sleep(800) + await expandTransactionOf(SafeDom, 3, 3) + sleep(800) + } + + it('should execute transaction after 2 owners have confirmed and the last one executed correctly', async () => { + await addFundsTo(SafeDom, address) + await createMultisigTxFilling(SafeDom, AddTransactionComponent, store) + + await checkBalanceOf(address, '0.1') + await listTxsOf(SafeDom) + sleep(1400) + const paragraphs = getTagFromTransaction(SafeDom, 'p') + + const status = paragraphs[2].innerHTML + expect(status).toBe('1 of the 3 confirmations needed') + + const confirmed = paragraphs[3].innerHTML + expect(confirmed).toBe('Waiting for the rest of confirmations') + + await expandTransactionOf(SafeDom, 3, 3) + await confirmOwners(SafeDom, 'Adolfo 1 Eth Account [Confirmed]', 'Adolfo 2 Eth Account [Not confirmed]', 'Adolfo 3 Eth Account [Not confirmed]') + + await makeConfirmation(accounts[1]) + await confirmOwners(SafeDom, 'Adolfo 1 Eth Account [Confirmed]', 'Adolfo 2 Eth Account [Confirmed]', 'Adolfo 3 Eth Account [Not confirmed]') + + await makeConfirmation(accounts[2]) + await confirmOwners(SafeDom, 'Adolfo 1 Eth Account [Confirmed]', 'Adolfo 2 Eth Account [Confirmed]', 'Adolfo 3 Eth Account [Confirmed]') + + const paragraphsExecuted = getTagFromTransaction(SafeDom, 'p') + + const statusExecuted = paragraphsExecuted[2].innerHTML + expect(statusExecuted).toBe('Already executed') + + const confirmedExecuted = paragraphsExecuted[3].innerHTML + const tx = getTransactionFromReduxStore(store, address) + expect(confirmedExecuted).toBe(tx.get('tx')) + }) +}) diff --git a/src/routes/safe/component/Safe.withdrawn.test.js b/src/routes/safe/test/Safe.withdrawn.test.js similarity index 88% rename from src/routes/safe/component/Safe.withdrawn.test.js rename to src/routes/safe/test/Safe.withdrawn.test.js index 4dfb8bed..a0803c57 100644 --- a/src/routes/safe/component/Safe.withdrawn.test.js +++ b/src/routes/safe/test/Safe.withdrawn.test.js @@ -41,6 +41,7 @@ describe('React DOM TESTS > Withdrawn funds from safe', () => { it('should withdrawn funds under dailyLimit without needing confirmations', async () => { // add funds to safe await addEtherTo(address, '0.1') + await sleep(3000) const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView) // $FlowFixMe @@ -48,7 +49,7 @@ describe('React DOM TESTS > Withdrawn funds from safe', () => { const withdrawnButton = buttons[0] expect(withdrawnButton.props.children).toEqual(WITHDRAWN_BUTTON_TEXT) TestUtils.Simulate.click(TestUtils.scryRenderedDOMComponentsWithTag(withdrawnButton, 'button')[0]) - + await sleep(4000) const Withdrawn = TestUtils.findRenderedComponentWithType(SafeDom, WithdrawnComponent) // $FlowFixMe @@ -63,7 +64,7 @@ describe('React DOM TESTS > Withdrawn funds from safe', () => { TestUtils.Simulate.submit(form) // fill the form TestUtils.Simulate.submit(form) // confirming data - await sleep(4000) + await sleep(6000) const safeBalance = await getBalanceInEtherOf(address) expect(safeBalance).toBe('0.09') @@ -104,4 +105,18 @@ describe('React DOM TESTS > Withdrawn funds from safe', () => { expect(addTxButton.props.disabled).toBe(false) }) + + it('Withdrawn button disabled when balance is 0', async () => { + const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView) + // $FlowFixMe + const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button) + const addTxButton = buttons[0] + expect(addTxButton.props.children).toEqual(WITHDRAWN_BUTTON_TEXT) + expect(addTxButton.props.disabled).toBe(true) + + await addEtherTo(address, '0.1') + await sleep(1800) + + expect(addTxButton.props.disabled).toBe(false) + }) }) diff --git a/src/routes/safe/test/testMultisig.js b/src/routes/safe/test/testMultisig.js new file mode 100644 index 00000000..c4264cd5 --- /dev/null +++ b/src/routes/safe/test/testMultisig.js @@ -0,0 +1,96 @@ +// @flow +import TestUtils from 'react-dom/test-utils' +import { sleep } from '~/utils/timer' +import { getBalanceInEtherOf } from '~/wallets/getWeb3' +import Button from '~/components/layout/Button' +import { ADD_MULTISIG_BUTTON_TEXT, SEE_MULTISIG_BUTTON_TEXT } from '~/routes/safe/component/Safe/MultisigTx' +import { addEtherTo } from '~/test/addEtherTo' +import SafeView from '~/routes/safe/component/Safe' +import TransactionsComponent from '~/routes/safe/component/Transactions' +import TransactionComponent from '~/routes/safe/component/Transactions/Transaction' +import { safeTransactionsSelector } from '~/routes/safe/store/selectors/index' + +export const createMultisigTxFilling = async (SafeDom, AddTransactionComponent, store) => { + // Get AddTransaction form component + const AddTransaction = TestUtils.findRenderedComponentWithType(SafeDom, AddTransactionComponent) + + // $FlowFixMe + const inputs = TestUtils.scryRenderedDOMComponentsWithTag(AddTransaction, 'input') + const name = inputs[0] + const destination = inputs[1] + const amountInEth = inputs[2] + TestUtils.Simulate.change(name, { target: { value: 'Buying betteries' } }) + TestUtils.Simulate.change(amountInEth, { target: { value: '0.01' } }) + TestUtils.Simulate.change(destination, { target: { value: store.getState().providers.account } }) + + // $FlowFixMe + const form = TestUtils.findRenderedDOMComponentWithTag(AddTransaction, 'form') + + TestUtils.Simulate.submit(form) // fill the form + TestUtils.Simulate.submit(form) // confirming data + return sleep(4000) +} + +export const checkBalanceOf = async (addressToTest: string, value: string) => { + const safeBalance = await getBalanceInEtherOf(addressToTest) + expect(safeBalance).toBe(value) +} + +export const addFundsTo = async (SafeDom, destination: string) => { + // add funds to safe + await addEtherTo(destination, '0.1') + const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView) + + // $FlowFixMe + const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button) + const addTxButton = buttons[1] + expect(addTxButton.props.children).toEqual(ADD_MULTISIG_BUTTON_TEXT) + await sleep(1800) // Give time to enable Add button + TestUtils.Simulate.click(TestUtils.scryRenderedDOMComponentsWithTag(addTxButton, 'button')[0]) +} + +export const listTxsOf = (SafeDom) => { + const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView) + + // $FlowFixMe + const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button) + const seeTx = buttons[2] + expect(seeTx.props.children).toEqual(SEE_MULTISIG_BUTTON_TEXT) + TestUtils.Simulate.click(TestUtils.scryRenderedDOMComponentsWithTag(seeTx, 'button')[0]) +} + +export const getTagFromTransaction = (SafeDom, tag: string) => { + const Transactions = TestUtils.findRenderedComponentWithType(SafeDom, TransactionsComponent) + if (!Transactions) throw new Error() + const Transaction = TestUtils.findRenderedComponentWithType(Transactions, TransactionComponent) + if (!Transaction) throw new Error() + + return TestUtils.scryRenderedDOMComponentsWithTag(Transaction, tag) +} + +export const expandTransactionOf = async (SafeDom, numOwners, safeThreshold) => { + const paragraphs = getTagFromTransaction(SafeDom, 'p') + TestUtils.Simulate.click(paragraphs[2]) // expanded + await sleep(1000) // Time to expand + const paragraphsExpanded = getTagFromTransaction(SafeDom, 'p') + const threshold = paragraphsExpanded[5] + expect(threshold.innerHTML).toContain(`confirmation${safeThreshold === 1 ? '' : 's'} needed`) + TestUtils.Simulate.click(threshold) // expanded + await sleep(1000) // Time to expand + expect(paragraphsExpanded.length).toBe(paragraphs.length + numOwners) +} + +export const getTransactionFromReduxStore = (store, address) => { + const transactions = safeTransactionsSelector(store.getState(), { safeAddress: address }) + + return transactions.get(0) +} + +export const confirmOwners = async (SafeDom, ...statusses: string[]) => { + const paragraphsWithOwners = getTagFromTransaction(SafeDom, 'h3') + for (let i = 0; i < statusses.length; i += 1) { + const ownerIndex = i + 6 + const ownerParagraph = paragraphsWithOwners[ownerIndex].innerHTML + expect(statusses[i]).toEqual(ownerParagraph) + } +} diff --git a/src/wallets/ethTransactions.js b/src/wallets/ethTransactions.js new file mode 100644 index 00000000..47a2dddf --- /dev/null +++ b/src/wallets/ethTransactions.js @@ -0,0 +1,53 @@ +// @flow +import { BigNumber } from 'bignumber.js' +import { getWeb3 } from '~/wallets/getWeb3' +import { promisify } from '~/utils/promisify' + +// const MAINNET_NETWORK = 1 + +export const calculateGasPrice = async () => { +/* + const web3 = getWeb3() + const { network } = web3.version + const isMainnet = MAINNET_NETWORK === network + + const url = isMainnet + ? 'https://safe-relay.staging.gnosisdev.com/api/v1/gas-station/' + : 'https://safe-relay.dev.gnosisdev.com/' +*/ + + const response = await fetch('https://ethgasstation.info/json/ethgasAPI.json', { mode: 'cors' }) + if (!response.ok) { + throw new Error('Error querying gast station') + } + + const json = await response.json() + + return new BigNumber(json.average).multipliedBy(1e8).toString() +} + +export const calculateGasOf = async (data: Object, from: string, to: string) => { + const web3 = getWeb3() + const gas = await promisify(cb => web3.eth.estimateGas({ data, from, to }, cb)) + + return gas * 2 +} + +const executeTransaction = async (data: Object, from: string, to: string) => { + const web3 = getWeb3() + + const gas = await calculateGasOf(data, from, to) + + let gasPrice + try { + gasPrice = await calculateGasPrice() + } catch (err) { + gasPrice = await promisify(cb => web3.eth.getGasPrice(cb)) + } + + return promisify(cb => web3.eth.sendTransaction({ + from, to, data, gas, gasPrice, + }, cb)) +} + +export default executeTransaction diff --git a/src/wallets/getWeb3.js b/src/wallets/getWeb3.js index aa57987b..5e9602c5 100644 --- a/src/wallets/getWeb3.js +++ b/src/wallets/getWeb3.js @@ -28,8 +28,11 @@ export const getProviderInfo: Function = async (): Promise => { // Use MetaMask's provider. web3 = new Web3(window.web3.currentProvider) - // eslint-disable-next-line - console.log('Injected web3 detected.') + + if (process.env.NODE_ENV !== 'test') { + // eslint-disable-next-line + console.log('Injected web3 detected.') + } const name = isMetamask(web3) ? 'METAMASK' : 'UNKNOWN' const account = await getAccountFrom(web3) diff --git a/src/wallets/safeContracts.js b/src/wallets/safeContracts.js index 65a516c3..81399db8 100644 --- a/src/wallets/safeContracts.js +++ b/src/wallets/safeContracts.js @@ -1,12 +1,13 @@ // @flow import contract from 'truffle-contract' -import { promisify } from '~/utils/promisify' import { ensureOnce } from '~/utils/singleton' import { getWeb3 } from '~/wallets/getWeb3' +import { promisify } from '~/utils/promisify' import GnosisSafeSol from '#/GnosisSafeTeamEdition.json' import ProxyFactorySol from '#/ProxyFactory.json' import CreateAndAddModules from '#/CreateAndAddModules.json' import DailyLimitModule from '#/DailyLimitModule.json' +import { calculateGasOf, calculateGasPrice } from '~/wallets/ethTransactions' let proxyFactoryMaster let createAndAddModuleMaster @@ -63,45 +64,46 @@ const getCreateProxyFactoryContract = ensureOnce(createProxyFactoryContract) const getCreateAddExtensionContract = ensureOnce(createAddExtensionContract) export const getCreateDailyLimitExtensionContract = ensureOnce(createDailyLimitExtensionContract) +const instanciateMasterCopies = async () => { + const web3 = getWeb3() + + // Create ProxyFactory Master Copy + const ProxyFactory = getCreateProxyFactoryContract(web3) + proxyFactoryMaster = await ProxyFactory.deployed() + + // Create AddExtension Master Copy + const CreateAndAddExtension = getCreateAddExtensionContract(web3) + createAndAddModuleMaster = await CreateAndAddExtension.deployed() + + // Initialize safe master copy + const GnosisSafe = getGnosisSafeContract(web3) + safeMaster = await GnosisSafe.deployed() + + // Initialize extension master copy + const DailyLimitExtension = getCreateDailyLimitExtensionContract(web3) + dailyLimitMaster = await DailyLimitExtension.deployed() +} + +// ONLY USED IN TEST ENVIRONMENT const createMasterCopies = async () => { const web3 = getWeb3() const accounts = await promisify(cb => web3.eth.getAccounts(cb)) const userAccount = accounts[0] - // Create ProxyFactory Master Copy const ProxyFactory = getCreateProxyFactoryContract(web3) - try { - proxyFactoryMaster = await ProxyFactory.deployed() - } catch (err) { - proxyFactoryMaster = await ProxyFactory.new({ from: userAccount, gas: '5000000' }) - } + proxyFactoryMaster = await ProxyFactory.new({ from: userAccount, gas: '5000000' }) - // Create AddExtension Master Copy const CreateAndAddExtension = getCreateAddExtensionContract(web3) - try { - createAndAddModuleMaster = await CreateAndAddExtension.deployed() - } catch (err) { - createAndAddModuleMaster = await CreateAndAddExtension.new({ from: userAccount, gas: '5000000' }) - } + createAndAddModuleMaster = await CreateAndAddExtension.new({ from: userAccount, gas: '5000000' }) - // Initialize safe master copy const GnosisSafe = getGnosisSafeContract(web3) - try { - safeMaster = await GnosisSafe.deployed() - } catch (err) { - safeMaster = await GnosisSafe.new([userAccount], 1, 0, 0, { from: userAccount, gas: '5000000' }) - } + safeMaster = await GnosisSafe.new([userAccount], 1, 0, 0, { from: userAccount, gas: '5000000' }) - // Initialize extension master copy const DailyLimitExtension = getCreateDailyLimitExtensionContract(web3) - try { - dailyLimitMaster = await DailyLimitExtension.deployed() - } catch (err) { - dailyLimitMaster = await DailyLimitExtension.new([], [], { from: userAccount, gas: '5000000' }) - } + dailyLimitMaster = await DailyLimitExtension.new([], [], { from: userAccount, gas: '5000000' }) } -export const initContracts = ensureOnce(createMasterCopies) +export const initContracts = ensureOnce(process.env.NODE_ENV === 'test' ? createMasterCopies : instanciateMasterCopies) const getSafeDataBasedOn = async (accounts, numConfirmations, dailyLimitInEth) => { const web3 = getWeb3() @@ -128,5 +130,9 @@ export const deploySafeContract = async ( userAccount: string, ) => { const gnosisSafeData = await getSafeDataBasedOn(safeAccounts, numConfirmations, dailyLimit) - return proxyFactoryMaster.createProxy(safeMaster.address, gnosisSafeData, { from: userAccount, gas: '5000000' }) + const proxyFactoryData = proxyFactoryMaster.contract.createProxy.getData(safeMaster.address, gnosisSafeData) + const gas = await calculateGasOf(proxyFactoryData, userAccount, proxyFactoryMaster.address) + const gasPrice = await calculateGasPrice() + + return proxyFactoryMaster.createProxy(safeMaster.address, gnosisSafeData, { from: userAccount, gas, gasPrice }) } diff --git a/yarn.lock b/yarn.lock index 704bc4b6..d6761ce8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2474,6 +2474,10 @@ bignumber.js@^2.1.4: version "2.4.0" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-2.4.0.tgz#838a992da9f9d737e0f4b2db0be62bb09dd0c5e8" +bignumber.js@^7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f" + "bignumber.js@git+https://github.com/debris/bignumber.js#master": version "2.0.7" resolved "git+https://github.com/debris/bignumber.js#c7a38de919ed75e6fb6ba38051986e294b328df9"