Skip to content

Commit a2ce121

Browse files
authored
Merge branch 'development' into issue-123
2 parents e710353 + 37c46f5 commit a2ce121

2 files changed

Lines changed: 41 additions & 16 deletions

File tree

contracts/proxies/ProxyFactory.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ contract ProxyFactory {
5050
assembly {
5151
proxy := create2(0x0, add(0x20, deploymentData), mload(deploymentData), salt)
5252
}
53+
require(address(proxy) != address(0), "Create2 call failed");
5354
}
5455

5556
/// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.

test/gnosisSafeDeploymentViaCreate2.js

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ const abi = require('ethereumjs-abi')
66
const GnosisSafe = artifacts.require("./GnosisSafe.sol")
77
const Proxy = artifacts.require("./Proxy.sol")
88
const ProxyFactory = artifacts.require("./ProxyFactory.sol")
9-
const MockContract = artifacts.require('./MockContract.sol');
10-
const MockToken = artifacts.require('./Token.sol');
9+
const MockContract = artifacts.require('./MockContract.sol')
10+
const MockToken = artifacts.require('./Token.sol')
1111

1212
contract('GnosisSafe via create2', function(accounts) {
1313

@@ -108,7 +108,7 @@ contract('GnosisSafe via create2', function(accounts) {
108108

109109
// User funds safe
110110
token.transfer(creationData.safe, creationData.userCosts, {from: accounts[0]})
111-
assert.equal(await token.balances(creationData.safe), creationData.userCosts);
111+
assert.equal(await token.balances(creationData.safe), creationData.userCosts)
112112
assert.equal(await token.balances(funder), 0)
113113

114114
await deployWithCreationData(creationData)
@@ -144,31 +144,55 @@ contract('GnosisSafe via create2', function(accounts) {
144144
utils.assertRejects(deployWithCreationData(creationData), "Deployment without enough tokens should fail")
145145
assert.equal(await web3.eth.getCode(creationData.safe), '0x')
146146

147-
let mockContract = await MockContract.new();
148-
let mockToken = MockToken.at(mockContract.address);
147+
let mockContract = await MockContract.new()
148+
let mockToken = MockToken.at(mockContract.address)
149149

150-
await mockContract.givenAnyRunOutOfGas();
150+
await mockContract.givenAnyRunOutOfGas()
151151
creationData = await getCreationData(mockToken.address, 1337, nonce)
152152
utils.assertRejects(deployWithCreationData(creationData), "Deployment without enough gas should fail")
153-
assert.equal(await web3.eth.getCode(creationData.safe), '0x');
153+
assert.equal(await web3.eth.getCode(creationData.safe), '0x')
154154

155155

156-
await mockContract.givenAnyRevert();
157-
creationData = await getCreationData(mockToken.address, 1337, nonce);
156+
await mockContract.givenAnyRevert()
157+
creationData = await getCreationData(mockToken.address, 1337, nonce)
158158
utils.assertRejects(deployWithCreationData(creationData), "Deployment when payment fails should fail")
159-
assert.equal(await web3.eth.getCode(creationData.safe), '0x');
159+
assert.equal(await web3.eth.getCode(creationData.safe), '0x')
160160

161161

162-
await mockContract.givenAnyReturnBool(false);
163-
creationData = await getCreationData(mockToken.address, 1337, nonce);
162+
await mockContract.givenAnyReturnBool(false)
163+
creationData = await getCreationData(mockToken.address, 1337, nonce)
164164
utils.assertRejects(deployWithCreationData(creationData), "Deployment when payment transfer returns false should fail")
165-
assert.equal(await web3.eth.getCode(creationData.safe), '0x');
165+
assert.equal(await web3.eth.getCode(creationData.safe), '0x')
166166

167167
// We deploy a proxy to the same predicted address to make sure that even after a failure we could deploy a successfull one
168-
await mockContract.givenAnyReturnBool(true);
169-
creationData = await getCreationData(mockToken.address, 1337, nonce);
168+
await mockContract.givenAnyReturnBool(true)
169+
creationData = await getCreationData(mockToken.address, 1337, nonce)
170+
await deployWithCreationData(creationData)
171+
assert.equal(await web3.eth.getCode(creationData.safe), await proxyFactory.proxyRuntimeCode())
172+
173+
})
174+
175+
it('should fail when creating the same proxy twice', async () => {
176+
// Estimate safe creation costs
177+
let gnosisSafeData = await gnosisSafeMasterCopy.contract.setup.getData([lw.accounts[0], lw.accounts[1], lw.accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
178+
let creationNonce = new Date().getTime()
179+
let estimate = (await proxyFactory.createProxyWithNonce.estimateGas(gnosisSafeMasterCopy.address, gnosisSafeData, creationNonce)) + 9000
180+
let creationData = await getCreationData(0, estimate * gasPrice, creationNonce)
181+
182+
// User funds safe
183+
await web3.eth.sendTransaction({from: accounts[1], to: creationData.safe, value: creationData.userCosts})
184+
assert.equal(await web3.eth.getBalance(creationData.safe).toNumber(), creationData.userCosts)
185+
let funderBalance = await web3.eth.getBalance(funder).toNumber()
186+
170187
await deployWithCreationData(creationData)
171188
assert.equal(await web3.eth.getCode(creationData.safe), await proxyFactory.proxyRuntimeCode())
172189

173-
});
190+
utils.assertRejects(deployWithCreationData(creationData), "Deployment fails as same proxy with same params (and address) was already deployed")
191+
192+
let estimatedAddressData = proxyFactory.contract.calculateCreateProxyWithNonceAddress.getData(gnosisSafeMasterCopy.address, creationData.data, creationData.creationNonce)
193+
let estimatedAddressResponse = await web3.eth.call({to: proxyFactory.address, from: funder, data: estimatedAddressData, gasPrice: 0})
194+
let errorMessage = await utils.getErrorMessage(proxyFactory.address, 0, estimatedAddressData, funder)
195+
assert.equal(errorMessage, 'Create2 call failed')
196+
})
197+
174198
})

0 commit comments

Comments
 (0)