Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add master copy constructor #157

Merged
merged 2 commits into from
Dec 9, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions contracts/GnosisSafe.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ contract GnosisSafe
// Mapping to keep track of all hashes (message or transaction) that have been approve by ANY owners
mapping(address => mapping(bytes32 => uint256)) public approvedHashes;

// This constructor ensures that this contract can only be used as a master copy for Proxy contracts
constructor() public {
// By setting the threshold it is not possible to call setup anymore,
// so we create a Safe with 0 owners and threshold 1.
// This is an unusable Safe, perfect for the mastercopy
threshold = 1;
}

/// @dev Setup function sets initial storage of contract.
/// @param _owners List of Safe owners.
/// @param _threshold Number of required confirmations for a Safe transaction.
Expand Down
1 change: 0 additions & 1 deletion migrations/4_deploy_master_copies.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ const notOwnedAddress2 = "0x0000000000000000000000000000000000000003"

module.exports = function(deployer) {
deployer.deploy(GnosisSafe).then(function (safe) {
safe.setup([notOwnedAddress], 1, 0, 0, 0, 0, 0, 0)
return safe
});
deployer.deploy(StateChannelModule).then(function (module) {
Expand Down
3 changes: 0 additions & 3 deletions scripts/deploy_safe_contracts_oz.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ shell.exec(`npx oz push --network ${network} --skip-compile`)
shell.exec(`npx oz add DefaultCallbackHandler --skip-compile`)
shell.exec(`npx oz push --network ${network} --skip-compile`)

// Init master copies
shell.exec(`npx truffle --network ${network} exec scripts/init_contracts.js`)

// Publish zos package
shell.exec(`npx oz publish --network ${network}`)

Expand Down
2 changes: 0 additions & 2 deletions scripts/init_contracts.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const fs = require('fs');
const GnosisSafe = artifacts.require("./GnosisSafe.sol");
const StateChannelModule = artifacts.require("./StateChannelModule.sol");
const DailyLimitModule = artifacts.require("./DailyLimitModule.sol")
const SocialRecoveryModule = artifacts.require("./SocialRecoveryModule.sol");
Expand Down Expand Up @@ -30,7 +29,6 @@ module.exports = function(callback) {
});
var oz = JSON.parse(fs.readFileSync('./.openzeppelin/' + network + '.json'));
Promise.all([
ignoreErrors(GnosisSafe.at(oz.contracts['GnosisSafe'].address).setup([notOwnedAddress, notOwnedAddress2], 2, 0, 0, 0, 0, 0, 0)),
//ignoreErrors(StateChannelModule.at(oz.contracts['StateChannelModule'].address).setup()),
//ignoreErrors(DailyLimitModule.at(oz.contracts['DailyLimitModule'].address).setup([],[])),
//ignoreErrors(SocialRecoveryModule.at(oz.contracts['SocialRecoveryModule'].address).setup([notOwnedAddress, notOwnedAddress2], 2)),
Expand Down
1 change: 0 additions & 1 deletion test/createAndAddModules.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ contract('CreateAndAddModules', function(accounts) {
// Create Master Copies
let proxyFactory = await ProxyFactory.new()
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
gnosisSafeMasterCopy.setup([lw.accounts[0], lw.accounts[1], lw.accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
let stateChannelModuleMasterCopy = await StateChannelModule.new()
stateChannelModuleMasterCopy.setup()
let socialRecoveryModuleMasterCopy = await SocialRecoveryModule.new()
Expand Down
1 change: 0 additions & 1 deletion test/createCall.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ contract('CreateCall', function(accounts) {
// Create Master Copies
let proxyFactory = await ProxyFactory.new()
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
gnosisSafeMasterCopy.setup([lw.accounts[0], lw.accounts[1], lw.accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
// Create Gnosis Safe
let gnosisSafeData = await gnosisSafeMasterCopy.contract.setup.getData([lw.accounts[0], lw.accounts[1], lw.accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
gnosisSafe = utils.getParamFromTxEvent(
Expand Down
2 changes: 0 additions & 2 deletions test/dailyLimitModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ contract('DailyLimitModule', function(accounts) {
let proxyFactory = await ProxyFactory.new()
let createAndAddModules = await CreateAndAddModules.new()
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
// Initialize safe master copy
gnosisSafeMasterCopy.setup([accounts[0]], 1, 0, "0x", 0, 0, 0, 0)
let dailyLimitModuleMasterCopy = await DailyLimitModule.new()
// Initialize module master copy
dailyLimitModuleMasterCopy.setup([], [])
Expand Down
8 changes: 7 additions & 1 deletion test/defaultCallbackHandler.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const utils = require('./utils/general')

const ProxyFactory = artifacts.require("./ProxyFactory.sol");
const GnosisSafe = artifacts.require("./GnosisSafe.sol")
const DefaultCallbackHandler = artifacts.require("./handler/DefaultCallbackHandler.sol")
const MockToken = artifacts.require('./mocks/ERC1155Token.sol');
Expand All @@ -17,7 +18,12 @@ contract('DefaultCallbackHandler', function(accounts) {
beforeEach(async function () {
// Create Gnosis Safe and MultiSend library
lw = await utils.createLightwallet()
gnosisSafe = await utils.deployContract("deploying Gnosis Safe", GnosisSafe)
let proxyFactory = await ProxyFactory.new()
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe", GnosisSafe)
gnosisSafe = utils.getParamFromTxEvent(
await proxyFactory.createProxy(gnosisSafeMasterCopy.address, ""),
'ProxyCreation', 'proxy', proxyFactory.address, GnosisSafe, 'create Gnosis Safe and Daily Limit Module',
)
handler = await DefaultCallbackHandler.new()
})

Expand Down
1 change: 0 additions & 1 deletion test/gnosisSafe0xExploit.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ contract('GnosisSafe 0x EIP-1271 exploit', function(accounts) {
// Create Master Copies
let proxyFactory = await ProxyFactory.new()
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
gnosisSafeMasterCopy.setup([accounts[0], accounts[1], accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
// Create Gnosis Safe
let ownerSafeData = await gnosisSafeMasterCopy.contract.setup.getData([lw.accounts[0], lw.accounts[1]], 2, 0, "0x", 0, 0, 0, 0)
ownerSafe = utils.getParamFromTxEvent(
Expand Down
1 change: 0 additions & 1 deletion test/gnosisSafeDeploymentViaCreate2.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ contract('GnosisSafe deployment via create2', function(accounts) {
// Create lightwallet
lw = await utils.createLightwallet()
gnosisSafeMasterCopy = await GnosisSafe.new()
gnosisSafeMasterCopy.setup([accounts[0]], 1, 0, "0x", 0, 0, 0, 0)
})

it('should create safe from random account and pay in ETH', async () => {
Expand Down
1 change: 0 additions & 1 deletion test/gnosisSafeDeploymentViaTx.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ contract('GnosisSafe trustless deployment', function(accounts) {
// Create lightwallet
lw = await utils.createLightwallet()
gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
gnosisSafeMasterCopy.setup([accounts[0]], 1, 0, "0x", 0, 0, 0, 0)
})

it('should create safe from random account and pay in ETH', async () => {
Expand Down
1 change: 0 additions & 1 deletion test/gnosisSafeEthSign.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ contract('GnosisSafe using eth_sign', function(accounts) {
// Create Master Copies
let proxyFactory = await ProxyFactory.new()
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
gnosisSafeMasterCopy.setup([accounts[0], accounts[1], accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
// Create Gnosis Safe
let gnosisSafeData = await gnosisSafeMasterCopy.contract.setup.getData([accounts[0], accounts[1], accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
gnosisSafe = utils.getParamFromTxEvent(
Expand Down
1 change: 0 additions & 1 deletion test/gnosisSafeEthSignTypeData.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ contract('GnosisSafe using eth_signTypedData', function(accounts) {
// Create Master Copies
let proxyFactory = await ProxyFactory.new()
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
gnosisSafeMasterCopy.setup([accounts[0], accounts[1], accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
// Create Gnosis Safe
let gnosisSafeData = await gnosisSafeMasterCopy.contract.setup.getData([accounts[0], accounts[1], accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
gnosisSafe = utils.getParamFromTxEvent(
Expand Down
10 changes: 8 additions & 2 deletions test/gnosisSafeExecuteFromModule.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const utils = require('./utils/general')
const safeUtils = require('./utils/execution')
const ProxyFactory = artifacts.require("./ProxyFactory.sol");
const GnosisSafe = artifacts.require("./GnosisSafe.sol")

contract('GnosisSafe', function(accounts) {
Expand All @@ -14,8 +15,13 @@ contract('GnosisSafe', function(accounts) {
// Create lightwallet
lw = await utils.createLightwallet()
// Create Master Copies
gnosisSafe = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
gnosisSafe.setup([lw.accounts[0], lw.accounts[1], lw.accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
let proxyFactory = await ProxyFactory.new()
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
let gnosisSafeData = await gnosisSafeMasterCopy.contract.setup.getData([lw.accounts[0], lw.accounts[1], lw.accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
gnosisSafe = utils.getParamFromTxEvent(
await proxyFactory.createProxy(gnosisSafeMasterCopy.address, gnosisSafeData),
'ProxyCreation', 'proxy', proxyFactory.address, GnosisSafe, 'create Gnosis Safe',
)
})

it('Check that correct data is returned', async () => {
Expand Down
10 changes: 7 additions & 3 deletions test/gnosisSafeForceSafeSetup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const utils = require('./utils/general')

const ProxyFactory = artifacts.require("./ProxyFactory.sol");
const GnosisSafe = artifacts.require("./GnosisSafe.sol")

contract('GnosisSafe setup', function(accounts) {
Expand All @@ -10,9 +11,12 @@ contract('GnosisSafe setup', function(accounts) {
const CALL = 0

it('should not be able to call execTransaction before setup', async () => {

// Create lightwallet
gnosisSafe = await utils.deployContract("deploying Gnosis Safe", GnosisSafe)
let proxyFactory = await ProxyFactory.new()
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe", GnosisSafe)
gnosisSafe = utils.getParamFromTxEvent(
await proxyFactory.createProxy(gnosisSafeMasterCopy.address, "0x"),
'ProxyCreation', 'proxy', proxyFactory.address, GnosisSafe, 'create Gnosis Safe',
)

// Fund Safe
await web3.eth.sendTransaction({from: accounts[0], to: gnosisSafe.address, value: web3.toWei(1, 'ether')})
Expand Down
1 change: 0 additions & 1 deletion test/gnosisSafeIncomingSend.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ contract('GnosisSafe allow incoming funds via send/transfer', function(accounts)
// Create Master Copies
let proxyFactory = await ProxyFactory.new()
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
gnosisSafeMasterCopy.setup([accounts[0], accounts[1], accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
// Create Gnosis Safe
let gnosisSafeData = await gnosisSafeMasterCopy.contract.setup.getData([lw.accounts[0], lw.accounts[1]], 2, 0, "0x", 0, 0, 0, 0)
gnosisSafe = utils.getParamFromTxEvent(
Expand Down
1 change: 0 additions & 1 deletion test/gnosisSafeManagement.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ contract('GnosisSafe owner and module management', function(accounts) {
// Create Master Copies
let proxyFactory = await ProxyFactory.new()
gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
gnosisSafeMasterCopy.setup([lw.accounts[0], lw.accounts[1], lw.accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
// Create Gnosis Safe
let gnosisSafeData = await gnosisSafeMasterCopy.contract.setup.getData([lw.accounts[0], lw.accounts[1], lw.accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
gnosisSafe = utils.getParamFromTxEvent(
Expand Down
21 changes: 21 additions & 0 deletions test/gnosisSafeMasterCopyDeployment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const utils = require('./utils/general')
const safeUtils = require('./utils/execution')
const abi = require('ethereumjs-abi')


const GnosisSafe = artifacts.require("./GnosisSafe.sol")
const ProxyFactory = artifacts.require("./ProxyFactory.sol")

contract('GnosisSafe master copy deployment', function(accounts) {

it('should not allow to call setup on mastercopy', async () => {
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
assert.equal(1, await gnosisSafeMasterCopy.getThreshold())
assert.deepEqual([], await gnosisSafeMasterCopy.getOwners())
assert.deepEqual([], await gnosisSafeMasterCopy.getModules())
await utils.assertRejects(
gnosisSafeMasterCopy.setup([accounts[0], accounts[1], accounts[2]], 2, 0, "0x", 0, 0, 0, 0),
"Should not allow to call setup on mastercopy"
)
})
})
1 change: 0 additions & 1 deletion test/gnosisSafeNestedSafes.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ contract('GnosisSafe using nested safes', function(accounts) {
// Create Master Copies
let proxyFactory = await ProxyFactory.new()
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
gnosisSafeMasterCopy.setup([accounts[0], accounts[1], accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
// Create Gnosis Safe
let owner1SafeData = await gnosisSafeMasterCopy.contract.setup.getData([lw.accounts[0], lw.accounts[1]], 2, 0, "0x", 0, 0, 0, 0)
owner1Safe = utils.getParamFromTxEvent(
Expand Down
1 change: 0 additions & 1 deletion test/gnosisSafeSignatureTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ contract('GnosisSafe without refund', function(accounts) {
// Create Master Copies
let proxyFactory = await ProxyFactory.new()
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
gnosisSafeMasterCopy.setup([accounts[0]], 1, 0, "0x", 0, 0, 0, 0)
// Create Gnosis Safe
let gnosisSafeData = await gnosisSafeMasterCopy.contract.setup.getData([accounts[0], accounts[1], accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
gnosisSafe = utils.getParamFromTxEvent(
Expand Down
1 change: 0 additions & 1 deletion test/gnosisSafeSignatureValidatorErrors.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ contract('GnosisSafe using contract signatures', function(accounts) {
// Create Master Copies
let proxyFactory = await ProxyFactory.new()
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
gnosisSafeMasterCopy.setup([accounts[0], accounts[1], accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
// Create Mock Owners
owner = await MockContract.new()
// Create Gnosis Safe
Expand Down
1 change: 0 additions & 1 deletion test/gnosisSafeTransactionExecution.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ contract('GnosisSafe with refunds', function(accounts) {
// Create Master Copies
let proxyFactory = await ProxyFactory.new()
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
gnosisSafeMasterCopy.setup([lw.accounts[0], lw.accounts[1], lw.accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
// Create Gnosis Safe
let gnosisSafeData = await gnosisSafeMasterCopy.contract.setup.getData([lw.accounts[0], lw.accounts[1], lw.accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
gnosisSafe = utils.getParamFromTxEvent(
Expand Down
14 changes: 10 additions & 4 deletions test/multiSend.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const StateChannelModule = artifacts.require("./modules/StateChannelModule.sol")
contract('MultiSend', function(accounts) {

let gnosisSafe
let gnosisSafeMasterCopy
let multiSend
let createAndAddModules
let proxyFactory
Expand All @@ -28,12 +29,17 @@ contract('MultiSend', function(accounts) {
beforeEach(async function () {
// Create Gnosis Safe and MultiSend library
lw = await utils.createLightwallet()
gnosisSafe = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
await gnosisSafe.setup([lw.accounts[0], lw.accounts[1]], 1, 0, 0, 0, 0, 0, 0)
proxyFactory = await ProxyFactory.new()
gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
// Create Gnosis Safe
let gnosisSafeData = await gnosisSafeMasterCopy.contract.setup.getData([lw.accounts[0], lw.accounts[1]], 1, 0, 0, 0, 0, 0, 0)
gnosisSafe = utils.getParamFromTxEvent(
await proxyFactory.createProxy(gnosisSafeMasterCopy.address, gnosisSafeData),
'ProxyCreation', 'proxy', proxyFactory.address, GnosisSafe, 'create Gnosis Safe Proxy',
)
multiSend = await MultiSend.new()
createAndAddModules = await CreateAndAddModules.new()

proxyFactory = await ProxyFactory.new()
stateChannelModuleMasterCopy = await StateChannelModule.new()
})

Expand Down Expand Up @@ -107,7 +113,7 @@ contract('MultiSend', function(accounts) {
// Create Gnosis Safe
let gnosisSafeData = await gnosisSafe.contract.setup.getData([lw.accounts[0], lw.accounts[1]], 1, multiSend.address, multiSendData, 0, 0, 0, 0)
let newSafe = utils.getParamFromTxEvent(
await proxyFactory.createProxy(gnosisSafe.address, gnosisSafeData),
await proxyFactory.createProxy(gnosisSafeMasterCopy.address, gnosisSafeData),
'ProxyCreation', 'proxy', proxyFactory.address, GnosisSafe, 'create Gnosis Safe Proxy',
)

Expand Down
2 changes: 0 additions & 2 deletions test/socialRecoveryModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ contract('SocialRecoveryModule', function(accounts) {
let proxyFactory = await ProxyFactory.new()
let createAndAddModules = await CreateAndAddModules.new()
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
// Initialize safe master copy
gnosisSafeMasterCopy.setup([accounts[0], accounts[1]], 2, 0, "0x", 0, 0, 0, 0)
let socialRecoveryModuleMasterCopy = await SocialRecoveryModule.new()
// Initialize module master copy
socialRecoveryModuleMasterCopy.setup([accounts[0], accounts[1]], 2)
Expand Down
1 change: 0 additions & 1 deletion test/stateChannelModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ contract('StateChannelModule', function(accounts) {
// Create Master Copies
let proxyFactory = await ProxyFactory.new()
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
gnosisSafeMasterCopy.setup([lw.accounts[0], lw.accounts[1], lw.accounts[2]], 2, 0, "0x", 0, 0, 0, 0)
let stateChannelModuleMasterCopy = await StateChannelModule.new()

// State channel module setup
Expand Down
2 changes: 0 additions & 2 deletions test/whitelistModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ contract('WhitelistModule', function(accounts) {
let proxyFactory = await ProxyFactory.new()
let createAndAddModules = await CreateAndAddModules.new()
let gnosisSafeMasterCopy = await utils.deployContract("deploying Gnosis Safe Mastercopy", GnosisSafe)
// Initialize safe master copy
gnosisSafeMasterCopy.setup([accounts[0], accounts[1]], 2, 0, "0x", 0, 0, 0, 0)
let whitelistModuleMasterCopy = await WhitelistModule.new([])
// Create Gnosis Safe and Whitelist Module in one transactions
let moduleData = await whitelistModuleMasterCopy.contract.setup.getData([accounts[3]])
Expand Down