Merge pull request #46 from gnosis/development

WA-234 & WA-438 Removing owners & Daily Limit updates
This commit is contained in:
Adolfo Panizo 2018-06-26 13:02:56 +02:00 committed by GitHub
commit 9898a1bd77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
118 changed files with 24123 additions and 44541 deletions

View File

@ -8,7 +8,7 @@
"forceAllTransforms": true
}
],
"@babel/stage-0"
["@babel/preset-stage-0", { "decoratorsLegacy": true }]
],
"plugins": [
"@babel/plugin-syntax-dynamic-import",

View File

@ -17,4 +17,4 @@ after_success:
- yarn build
- cd build_webpack/ && cp index.html 200.html && cd ..
- chmod ugo+x ./config/deploy/deploy.sh
- ./config/deploy/deploy.sh
- ./config/deploy/deploy.sh

View File

@ -1,2 +1,2 @@
// @flow
jest.setTimeout(45000)
jest.setTimeout(60000)

View File

@ -192,7 +192,7 @@ module.exports = {
new webpack.DefinePlugin(env),
// Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
new ExtractTextPlugin({
filename: 'static/css/[name].[contenthash:8].css',
filename: 'static/css/[name].[hash:8].css',
allChunks: true
}),
// Generate a manifest file which contains a mapping of all asset filenames

24016
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "run-with-testrpc -l 40000000 'node scripts/test.js --env=jsdom'",
"test": "run-with-testrpc -l 40000000 --noVMErrorsOnRPCResponse true 'node scripts/test.js --env=jsdom'",
"test-local": "NODE_ENV=test && node scripts/test.js --env=jsdom",
"precommit": "./precommit.sh",
"flow": "flow",
@ -62,6 +62,7 @@
"eslint-plugin-jest": "^21.13.0",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.7.0",
"ethereumjs-abi": "^0.6.5",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"file-loader": "^1.1.11",
"flow-bin": "^0.66.0",
@ -75,9 +76,9 @@
"postcss-mixins": "^6.2.0",
"postcss-simple-vars": "^4.1.0",
"pre-commit": "^1.2.2",
"react": "^16.2.0",
"react-dev-utils": "^5.0.0",
"react-dom": "^16.2.0",
"react": "^16.4.0",
"react-dev-utils": "^5.0.1",
"react-dom": "^16.4.0",
"react-redux": "^5.0.7",
"react-router-redux": "^5.0.0-alpha.9",
"redux": "^3.7.2",
@ -88,7 +89,7 @@
"storybook-host": "^4.1.5",
"storybook-router": "^0.3.3",
"style-loader": "^0.20.2",
"truffle": "git://github.com/trufflesuite/truffle.git#develop",
"truffle": "^4.1.11",
"truffle-contract": "^1.1.8",
"truffle-solidity-loader": "0.0.8",
"uglifyjs-webpack-plugin": "^1.2.2",
@ -100,14 +101,14 @@
"webpack-manifest-plugin": "^2.0.0-rc.2"
},
"dependencies": {
"@material-ui/core": "^1.2.1",
"@material-ui/icons": "^1.1.0",
"final-form": "^4.2.1",
"history": "^4.7.2",
"material-ui": "^1.0.0-beta.35",
"material-ui-icons": "^1.0.0-beta.35",
"react-final-form": "^3.1.2",
"react-loadable": "^5.3.1",
"react-router-dom": "^4.2.2",
"recompose": "^0.27.0"
"recompose": "^0.27.1"
},
"jest": {
"verbose": true,
@ -126,7 +127,7 @@
"<rootDir>/src/**/?(*.)(spec|test).js?(x)"
],
"testEnvironment": "node",
"testURL": "http://localhost",
"testURL": "https://safe-react",
"transform": {
"^.+\\.(js|jsx)$": "<rootDir>/node_modules/babel-jest",
"^.+\\.(css|scss)$": "<rootDir>/config/jest/cssTransform.js",

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -82,7 +82,7 @@
"id": 2,
"nodeType": "ImportDirective",
"scope": 24,
"sourceUnit": 1603,
"sourceUnit": 1612,
"src": "24:21:0",
"symbolAliases": [],
"unitAlias": ""
@ -96,10 +96,10 @@
"id": 3,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1602,
"referencedDeclaration": 1611,
"src": "392:5:0",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
},
@ -109,7 +109,7 @@
}
],
"contractDependencies": [
1602
1611
],
"contractKind": "contract",
"documentation": "@title Delegate Constructor Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract. It is possible to send along initialization data with the constructor.\n @author Stefan George - <stefan@gnosis.pm>\n @author Richard Meissner - <richard@gnosis.pm>",
@ -117,7 +117,7 @@
"id": 23,
"linearizedBaseContracts": [
23,
1602
1611
],
"name": "DelegateConstructorProxy",
"nodeType": "ContractDefinition",
@ -264,10 +264,10 @@
"name": "Proxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1602,
"referencedDeclaration": 1611,
"src": "662:5:0",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_contract$_Proxy_$1602_$",
"typeIdentifier": "t_type$_t_contract$_Proxy_$1611_$",
"typeString": "type(contract Proxy)"
}
},
@ -382,7 +382,7 @@
"id": 2,
"nodeType": "ImportDirective",
"scope": 24,
"sourceUnit": 1603,
"sourceUnit": 1612,
"src": "24:21:0",
"symbolAliases": [],
"unitAlias": ""
@ -396,10 +396,10 @@
"id": 3,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1602,
"referencedDeclaration": 1611,
"src": "392:5:0",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
},
@ -409,7 +409,7 @@
}
],
"contractDependencies": [
1602
1611
],
"contractKind": "contract",
"documentation": "@title Delegate Constructor Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract. It is possible to send along initialization data with the constructor.\n @author Stefan George - <stefan@gnosis.pm>\n @author Richard Meissner - <richard@gnosis.pm>",
@ -417,7 +417,7 @@
"id": 23,
"linearizedBaseContracts": [
23,
1602
1611
],
"name": "DelegateConstructorProxy",
"nodeType": "ContractDefinition",
@ -564,10 +564,10 @@
"name": "Proxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1602,
"referencedDeclaration": 1611,
"src": "662:5:0",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_contract$_Proxy_$1602_$",
"typeIdentifier": "t_type$_t_contract$_Proxy_$1611_$",
"typeString": "type(contract Proxy)"
}
},
@ -662,5 +662,5 @@
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-05-28T05:59:52.697Z"
"updatedAt": "2018-06-18T14:44:09.445Z"
}

File diff suppressed because it is too large Load Diff

View File

@ -3,29 +3,29 @@
"abi": [],
"bytecode": "0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a72305820641ab8b295edfaa2b1c8a8e0ae7d17ea2f4c8b95ea27e45d8947ed9a4799ca1f0029",
"deployedBytecode": "0x6080604052600080fd00a165627a7a72305820641ab8b295edfaa2b1c8a8e0ae7d17ea2f4c8b95ea27e45d8947ed9a4799ca1f0029",
"sourceMap": "115:95:1:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;115:95:1;;;;;;;",
"deployedSourceMap": "115:95:1:-;;;;;",
"sourceMap": "115:95:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;115:95:0;;;;;;;",
"deployedSourceMap": "115:95:0:-;;;;;",
"source": "pragma solidity 0.4.24;\n\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract Enum {\n enum Operation {\n Call,\n DelegateCall,\n Create\n }\n}\n",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Enum.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Enum.sol",
"exportedSymbols": {
"Enum": [
30
6
]
},
"id": 31,
"id": 7,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 25,
"id": 1,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:1"
"src": "0:23:0"
},
{
"baseContracts": [],
@ -33,66 +33,66 @@
"contractKind": "contract",
"documentation": "@title Enum - Collection of enums\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 30,
"id": 6,
"linearizedBaseContracts": [
30
6
],
"name": "Enum",
"nodeType": "ContractDefinition",
"nodes": [
{
"canonicalName": "Enum.Operation",
"id": 29,
"id": 5,
"members": [
{
"id": 26,
"id": 2,
"name": "Call",
"nodeType": "EnumValue",
"src": "160:4:1"
"src": "160:4:0"
},
{
"id": 27,
"id": 3,
"name": "DelegateCall",
"nodeType": "EnumValue",
"src": "174:12:1"
"src": "174:12:0"
},
{
"id": 28,
"id": 4,
"name": "Create",
"nodeType": "EnumValue",
"src": "196:6:1"
"src": "196:6:0"
}
],
"name": "Operation",
"nodeType": "EnumDefinition",
"src": "135:73:1"
"src": "135:73:0"
}
],
"scope": 31,
"src": "115:95:1"
"scope": 7,
"src": "115:95:0"
}
],
"src": "0:211:1"
"src": "0:211:0"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Enum.sol",
"exportedSymbols": {
"Enum": [
30
6
]
},
"id": 31,
"id": 7,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 25,
"id": 1,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:1"
"src": "0:23:0"
},
{
"baseContracts": [],
@ -100,46 +100,46 @@
"contractKind": "contract",
"documentation": "@title Enum - Collection of enums\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 30,
"id": 6,
"linearizedBaseContracts": [
30
6
],
"name": "Enum",
"nodeType": "ContractDefinition",
"nodes": [
{
"canonicalName": "Enum.Operation",
"id": 29,
"id": 5,
"members": [
{
"id": 26,
"id": 2,
"name": "Call",
"nodeType": "EnumValue",
"src": "160:4:1"
"src": "160:4:0"
},
{
"id": 27,
"id": 3,
"name": "DelegateCall",
"nodeType": "EnumValue",
"src": "174:12:1"
"src": "174:12:0"
},
{
"id": 28,
"id": 4,
"name": "Create",
"nodeType": "EnumValue",
"src": "196:6:1"
"src": "196:6:0"
}
],
"name": "Operation",
"nodeType": "EnumDefinition",
"src": "135:73:1"
"src": "135:73:0"
}
],
"scope": 31,
"src": "115:95:1"
"scope": 7,
"src": "115:95:0"
}
],
"src": "0:211:1"
"src": "0:211:0"
},
"compiler": {
"name": "solc",
@ -147,5 +147,5 @@
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-05-28T05:59:52.697Z"
"updatedAt": "2018-06-20T07:57:26.985Z"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -18,38 +18,38 @@
],
"bytecode": "0x608060405234801561001057600080fd5b50610276806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637de7edef14610046575b600080fd5b34801561005257600080fd5b50610087600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610089565b005b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff1614151515610207576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a72305820243ca7a44eb0464a47c14309cc3a29e407df6e966674981a787df22c0d9280220029",
"deployedBytecode": "0x608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637de7edef14610046575b600080fd5b34801561005257600080fd5b50610087600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610089565b005b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff1614151515610207576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a72305820243ca7a44eb0464a47c14309cc3a29e407df6e966674981a787df22c0d9280220029",
"sourceMap": "203:673:5:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;203:673:5;;;;;;;",
"deployedSourceMap": "203:673:5:-;;;;;;;;;;;;;;;;;;;;;;;;626:248;;8:9:-1;5:2;;;30:1;27;20:12;5:2;626:248:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;244:4:13;222:27;;:10;:27;;;214:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;791:1:5;776:11;:16;;;;768:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;856:11;843:10;;:24;;;;;;;;;;;;;;;;;;626:248;:::o",
"sourceMap": "203:673:4:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;203:673:4;;;;;;;",
"deployedSourceMap": "203:673:4:-;;;;;;;;;;;;;;;;;;;;;;;;626:248;;8:9:-1;5:2;;;30:1;27;20:12;5:2;626:248:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;244:4:8;222:27;;:10;:27;;;214:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;791:1:4;776:11;:16;;;;768:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;856:11;843:10;;:24;;;;;;;;;;;;;;;;;;626:248;:::o",
"source": "pragma solidity 0.4.24;\nimport \"./SelfAuthorized.sol\";\n\n\n/// @title MasterCopy - Base for master copy contracts (should always be first super contract)\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract MasterCopy is SelfAuthorized {\n // masterCopy always needs to be first declared variable, to ensure that it is at the same location as in the Proxy contract.\n // It should also always be ensured that the address is stored alone (uses a full word)\n address masterCopy;\n\n /// @dev Allows to upgrade the contract. This can only be done via a Safe transaction.\n /// @param _masterCopy New contract address.\n function changeMasterCopy(address _masterCopy)\n public\n authorized\n {\n // Master copy address cannot be null.\n require(_masterCopy != 0, \"Invalid master copy address provided\");\n masterCopy = _masterCopy;\n }\n}\n",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/MasterCopy.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/MasterCopy.sol",
"exportedSymbols": {
"MasterCopy": [
662
608
]
},
"id": 663,
"id": 609,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 637,
"id": 583,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:5"
"src": "0:23:4"
},
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
"file": "./SelfAuthorized.sol",
"id": 638,
"id": 584,
"nodeType": "ImportDirective",
"scope": 663,
"sourceUnit": 1655,
"src": "24:30:5",
"scope": 609,
"sourceUnit": 1450,
"src": "24:30:4",
"symbolAliases": [],
"unitAlias": ""
},
@ -59,42 +59,42 @@
"arguments": null,
"baseName": {
"contractScope": null,
"id": 639,
"id": 585,
"name": "SelfAuthorized",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1654,
"src": "226:14:5",
"referencedDeclaration": 1449,
"src": "226:14:4",
"typeDescriptions": {
"typeIdentifier": "t_contract$_SelfAuthorized_$1654",
"typeIdentifier": "t_contract$_SelfAuthorized_$1449",
"typeString": "contract SelfAuthorized"
}
},
"id": 640,
"id": 586,
"nodeType": "InheritanceSpecifier",
"src": "226:14:5"
"src": "226:14:4"
}
],
"contractDependencies": [
1654
1449
],
"contractKind": "contract",
"documentation": "@title MasterCopy - Base for master copy contracts (should always be first super contract)\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 662,
"id": 608,
"linearizedBaseContracts": [
662,
1654
608,
1449
],
"name": "MasterCopy",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 642,
"id": 588,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 662,
"src": "465:18:5",
"scope": 608,
"src": "465:18:4",
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
@ -102,10 +102,10 @@
"typeString": "address"
},
"typeName": {
"id": 641,
"id": 587,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "465:7:5",
"src": "465:7:4",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -116,9 +116,9 @@
},
{
"body": {
"id": 660,
"id": 606,
"nodeType": "Block",
"src": "711:163:5",
"src": "711:163:4",
"statements": [
{
"expression": {
@ -130,19 +130,19 @@
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 652,
"id": 598,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 650,
"id": 596,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 644,
"src": "776:11:5",
"referencedDeclaration": 590,
"src": "776:11:4",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -153,14 +153,14 @@
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 651,
"id": 597,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "791:1:5",
"src": "791:1:4",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_0_by_1",
@ -168,7 +168,7 @@
},
"value": "0"
},
"src": "776:16:5",
"src": "776:16:4",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
@ -177,14 +177,14 @@
{
"argumentTypes": null,
"hexValue": "496e76616c6964206d617374657220636f707920616464726573732070726f7669646564",
"id": 653,
"id": 599,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "794:38:5",
"src": "794:38:4",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_108d84599042957b954e89d43b52f80be89321dfc114a37800028eba58dafc87",
@ -204,21 +204,21 @@
"typeString": "literal_string \"Invalid master copy address provided\""
}
],
"id": 649,
"id": 595,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
2657,
2658
1776,
1777
],
"referencedDeclaration": 2658,
"src": "768:7:5",
"referencedDeclaration": 1777,
"src": "768:7:4",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 654,
"id": 600,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -226,32 +226,32 @@
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "768:65:5",
"src": "768:65:4",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 655,
"id": 601,
"nodeType": "ExpressionStatement",
"src": "768:65:5"
"src": "768:65:4"
},
{
"expression": {
"argumentTypes": null,
"id": 658,
"id": 604,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 656,
"id": 602,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 642,
"src": "843:10:5",
"referencedDeclaration": 588,
"src": "843:10:4",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -261,68 +261,68 @@
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 657,
"id": 603,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 644,
"src": "856:11:5",
"referencedDeclaration": 590,
"src": "856:11:4",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "843:24:5",
"src": "843:24:4",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"id": 659,
"id": 605,
"nodeType": "ExpressionStatement",
"src": "843:24:5"
"src": "843:24:4"
}
]
},
"documentation": "@dev Allows to upgrade the contract. This can only be done via a Safe transaction.\n @param _masterCopy New contract address.",
"id": 661,
"id": 607,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [
{
"arguments": null,
"id": 647,
"id": 593,
"modifierName": {
"argumentTypes": null,
"id": 646,
"id": 592,
"name": "authorized",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1653,
"src": "696:10:5",
"referencedDeclaration": 1448,
"src": "696:10:4",
"typeDescriptions": {
"typeIdentifier": "t_modifier$__$",
"typeString": "modifier ()"
}
},
"nodeType": "ModifierInvocation",
"src": "696:10:5"
"src": "696:10:4"
}
],
"name": "changeMasterCopy",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 645,
"id": 591,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 644,
"id": 590,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 661,
"src": "652:19:5",
"scope": 607,
"src": "652:19:4",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
@ -330,10 +330,10 @@
"typeString": "address"
},
"typeName": {
"id": 643,
"id": 589,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "652:7:5",
"src": "652:7:4",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -343,56 +343,56 @@
"visibility": "internal"
}
],
"src": "651:21:5"
"src": "651:21:4"
},
"payable": false,
"returnParameters": {
"id": 648,
"id": 594,
"nodeType": "ParameterList",
"parameters": [],
"src": "711:0:5"
"src": "711:0:4"
},
"scope": 662,
"src": "626:248:5",
"scope": 608,
"src": "626:248:4",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 663,
"src": "203:673:5"
"scope": 609,
"src": "203:673:4"
}
],
"src": "0:877:5"
"src": "0:877:4"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/MasterCopy.sol",
"exportedSymbols": {
"MasterCopy": [
662
608
]
},
"id": 663,
"id": 609,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 637,
"id": 583,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:5"
"src": "0:23:4"
},
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
"file": "./SelfAuthorized.sol",
"id": 638,
"id": 584,
"nodeType": "ImportDirective",
"scope": 663,
"sourceUnit": 1655,
"src": "24:30:5",
"scope": 609,
"sourceUnit": 1450,
"src": "24:30:4",
"symbolAliases": [],
"unitAlias": ""
},
@ -402,42 +402,42 @@
"arguments": null,
"baseName": {
"contractScope": null,
"id": 639,
"id": 585,
"name": "SelfAuthorized",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1654,
"src": "226:14:5",
"referencedDeclaration": 1449,
"src": "226:14:4",
"typeDescriptions": {
"typeIdentifier": "t_contract$_SelfAuthorized_$1654",
"typeIdentifier": "t_contract$_SelfAuthorized_$1449",
"typeString": "contract SelfAuthorized"
}
},
"id": 640,
"id": 586,
"nodeType": "InheritanceSpecifier",
"src": "226:14:5"
"src": "226:14:4"
}
],
"contractDependencies": [
1654
1449
],
"contractKind": "contract",
"documentation": "@title MasterCopy - Base for master copy contracts (should always be first super contract)\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 662,
"id": 608,
"linearizedBaseContracts": [
662,
1654
608,
1449
],
"name": "MasterCopy",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 642,
"id": 588,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 662,
"src": "465:18:5",
"scope": 608,
"src": "465:18:4",
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
@ -445,10 +445,10 @@
"typeString": "address"
},
"typeName": {
"id": 641,
"id": 587,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "465:7:5",
"src": "465:7:4",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -459,9 +459,9 @@
},
{
"body": {
"id": 660,
"id": 606,
"nodeType": "Block",
"src": "711:163:5",
"src": "711:163:4",
"statements": [
{
"expression": {
@ -473,19 +473,19 @@
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 652,
"id": 598,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 650,
"id": 596,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 644,
"src": "776:11:5",
"referencedDeclaration": 590,
"src": "776:11:4",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -496,14 +496,14 @@
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 651,
"id": 597,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "791:1:5",
"src": "791:1:4",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_0_by_1",
@ -511,7 +511,7 @@
},
"value": "0"
},
"src": "776:16:5",
"src": "776:16:4",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
@ -520,14 +520,14 @@
{
"argumentTypes": null,
"hexValue": "496e76616c6964206d617374657220636f707920616464726573732070726f7669646564",
"id": 653,
"id": 599,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "794:38:5",
"src": "794:38:4",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_108d84599042957b954e89d43b52f80be89321dfc114a37800028eba58dafc87",
@ -547,21 +547,21 @@
"typeString": "literal_string \"Invalid master copy address provided\""
}
],
"id": 649,
"id": 595,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
2657,
2658
1776,
1777
],
"referencedDeclaration": 2658,
"src": "768:7:5",
"referencedDeclaration": 1777,
"src": "768:7:4",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 654,
"id": 600,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -569,32 +569,32 @@
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "768:65:5",
"src": "768:65:4",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 655,
"id": 601,
"nodeType": "ExpressionStatement",
"src": "768:65:5"
"src": "768:65:4"
},
{
"expression": {
"argumentTypes": null,
"id": 658,
"id": 604,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 656,
"id": 602,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 642,
"src": "843:10:5",
"referencedDeclaration": 588,
"src": "843:10:4",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -604,68 +604,68 @@
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 657,
"id": 603,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 644,
"src": "856:11:5",
"referencedDeclaration": 590,
"src": "856:11:4",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "843:24:5",
"src": "843:24:4",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"id": 659,
"id": 605,
"nodeType": "ExpressionStatement",
"src": "843:24:5"
"src": "843:24:4"
}
]
},
"documentation": "@dev Allows to upgrade the contract. This can only be done via a Safe transaction.\n @param _masterCopy New contract address.",
"id": 661,
"id": 607,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [
{
"arguments": null,
"id": 647,
"id": 593,
"modifierName": {
"argumentTypes": null,
"id": 646,
"id": 592,
"name": "authorized",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1653,
"src": "696:10:5",
"referencedDeclaration": 1448,
"src": "696:10:4",
"typeDescriptions": {
"typeIdentifier": "t_modifier$__$",
"typeString": "modifier ()"
}
},
"nodeType": "ModifierInvocation",
"src": "696:10:5"
"src": "696:10:4"
}
],
"name": "changeMasterCopy",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 645,
"id": 591,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 644,
"id": 590,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 661,
"src": "652:19:5",
"scope": 607,
"src": "652:19:4",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
@ -673,10 +673,10 @@
"typeString": "address"
},
"typeName": {
"id": 643,
"id": 589,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "652:7:5",
"src": "652:7:4",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -686,27 +686,27 @@
"visibility": "internal"
}
],
"src": "651:21:5"
"src": "651:21:4"
},
"payable": false,
"returnParameters": {
"id": 648,
"id": 594,
"nodeType": "ParameterList",
"parameters": [],
"src": "711:0:5"
"src": "711:0:4"
},
"scope": 662,
"src": "626:248:5",
"scope": 608,
"src": "626:248:4",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 663,
"src": "203:673:5"
"scope": 609,
"src": "203:673:4"
}
],
"src": "0:877:5"
"src": "0:877:4"
},
"compiler": {
"name": "solc",
@ -714,5 +714,5 @@
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-05-28T05:59:52.701Z"
"updatedAt": "2018-06-20T07:57:27.004Z"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -16,31 +16,31 @@
"type": "function"
}
],
"bytecode": "0x608060405234801561001057600080fd5b5061013a806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638d80ff0a14610046575b600080fd5b34801561005257600080fd5b506100ad600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506100af565b005b805160205b8181101561010957808301516020820184015160608301850151608084018601600080838386885af1600081146100ea576100ef565b600080fd5b50602080601f8401040260800185019450505050506100b4565b5050505600a165627a7a72305820d762b9a26edc788e8139b309555c37a91970e3acfe5f209dff1eaf14345bdbe60029",
"deployedBytecode": "0x608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638d80ff0a14610046575b600080fd5b34801561005257600080fd5b506100ad600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506100af565b005b805160205b8181101561010957808301516020820184015160608301850151608084018601600080838386885af1600081146100ea576100ef565b600080fd5b50602080601f8401040260800185019450505050506100b4565b5050505600a165627a7a72305820d762b9a26edc788e8139b309555c37a91970e3acfe5f209dff1eaf14345bdbe60029",
"sourceMap": "253:1073:16:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;253:1073:16;;;;;;;",
"deployedSourceMap": "253:1073:16:-;;;;;;;;;;;;;;;;;;;;;;;;593:731;;8:9:-1;5:2;;;30:1;27;20:12;5:2;593:731:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;768:12;762:19;803:4;820:488;834:6;831:1;828:13;820:488;;;898:1;884:12;880:20;874:27;962:4;959:1;955:12;941;937:31;931:38;1035:4;1032:1;1028:12;1014;1010:31;1004:38;1096:4;1093:1;1089:12;1075;1071:31;1168:1;1165;1153:10;1147:4;1140:5;1136:2;1131:3;1126:44;1192:1;1187:23;;;;1119:91;;1187:23;1206:1;1203;1196:12;1119:91;;1287:4;1280;1273;1261:10;1257:21;1253:32;1249:43;1243:4;1239:54;1236:1;1232:62;1227:67;;846:462;;;;820:488;;;734:584;;;:::o",
"source": "pragma solidity 0.4.24;\n\n\n/// @title Multi Send - Allows to batch multiple transactions into one.\n/// @author Nick Dodson - <nick.dodson@consensys.net>\n/// @author Gonçalo Sá - <goncalo.sa@consensys.net>\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract MultiSend {\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as\n /// a tuple(address,uint256,bytes). The bytes of all\n /// encoded transactions are concatenated to form the input.\n function multiSend(bytes transactions)\n public\n {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n for { } lt(i, length) { } {\n let to := mload(add(transactions, i))\n let value := mload(add(transactions, add(i, 0x20)))\n let dataLength := mload(add(transactions, add(i, 0x60)))\n let data := add(transactions, add(i, 0x80))\n switch call(gas, to, value, data, dataLength, 0, 0)\n case 0 { revert(0, 0) }\n i := add(i, add(0x80, mul(div(add(dataLength, 0x1f), 0x20), 0x20)))\n }\n }\n }\n}\n",
"bytecode": "0x608060405234801561001057600080fd5b50610169806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638d80ff0a14610046575b600080fd5b34801561005257600080fd5b506100ad600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506100af565b005b805160205b81811015610138578083015160208201840151604083018501516080840186015160a085018701600085600081146100f357600181146101035761010e565b6000808585888a5af1915061010e565b6000808585895af491505b50600081141561011d57600080fd5b602080601f8501040260a001870196505050505050506100b4565b5050505600a165627a7a72305820c1abf4988401674d6d6a5ceca56de123817c61305360ceffe26ebab59a828b7d0029",
"deployedBytecode": "0x608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638d80ff0a14610046575b600080fd5b34801561005257600080fd5b506100ad600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506100af565b005b805160205b81811015610138578083015160208201840151604083018501516080840186015160a085018701600085600081146100f357600181146101035761010e565b6000808585888a5af1915061010e565b6000808585895af491505b50600081141561011d57600080fd5b602080601f8501040260a001870196505050505050506100b4565b5050505600a165627a7a72305820c1abf4988401674d6d6a5ceca56de123817c61305360ceffe26ebab59a828b7d0029",
"sourceMap": "253:1424:17:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;253:1424:17;;;;;;;",
"deployedSourceMap": "253:1424:17:-;;;;;;;;;;;;;;;;;;;;;;;;695:980;;8:9:-1;5:2;;;30:1;27;20:12;5:2;695:980:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;870:12;864:19;905:4;922:737;936:6;933:1;930:13;922:737;;;1007:1;993:12;989:20;983:27;1068:4;1065:1;1061:12;1047;1043:31;1037:38;1136:4;1133:1;1129:12;1115;1111:31;1105:38;1209:4;1206:1;1202:12;1188;1184:31;1178:38;1270:4;1267:1;1263:12;1249;1245:31;1308:1;1333:9;1365:1;1360:66;;;;1448:1;1443:67;;;;1326:184;;1360:66;1422:1;1419;1407:10;1401:4;1394:5;1390:2;1385:3;1380:44;1369:55;;1360:66;;1443:67;1506:1;1503;1491:10;1485:4;1481:2;1476:3;1463:45;1452:56;;1326:184;;1542:1;1533:7;1530:14;1527:2;;;1557:1;1554;1547:12;1527:2;1638:4;1631;1624;1612:10;1608:21;1604:32;1600:43;1594:4;1590:54;1587:1;1583:62;1578:67;;948:711;;;;;;922:737;;;836:833;;;:::o",
"source": "pragma solidity 0.4.24;\n\n\n/// @title Multi Send - Allows to batch multiple transactions into one.\n/// @author Nick Dodson - <nick.dodson@consensys.net>\n/// @author Gonçalo Sá - <goncalo.sa@consensys.net>\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract MultiSend {\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a \n /// tuple(operation,address,uint256,bytes), where operation \n /// can be 0 for a call or 1 for a delegatecall. The bytes \n /// of all encoded transactions are concatenated to form the input.\n function multiSend(bytes transactions)\n public\n {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n for { } lt(i, length) { } {\n let operation := mload(add(transactions, i))\n let to := mload(add(transactions, add(i, 0x20)))\n let value := mload(add(transactions, add(i, 0x40)))\n let dataLength := mload(add(transactions, add(i, 0x80)))\n let data := add(transactions, add(i, 0xa0))\n let success := 0\n switch operation \n case 0 { success := call(gas, to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas, to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n i := add(i, add(0xa0, mul(div(add(dataLength, 0x1f), 0x20), 0x20)))\n }\n }\n }\n}\n",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/libraries/MultiSend.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/libraries/MultiSend.sol",
"exportedSymbols": {
"MultiSend": [
1775
1840
]
},
"id": 1776,
"id": 1841,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1767,
"id": 1832,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:16"
"src": "0:23:17"
},
{
"baseContracts": [],
@ -48,76 +48,85 @@
"contractKind": "contract",
"documentation": "@title Multi Send - Allows to batch multiple transactions into one.\n @author Nick Dodson - <nick.dodson@consensys.net>\n @author Gonçalo Sá - <goncalo.sa@consensys.net>\n @author Stefan George - <stefan@gnosis.pm>",
"fullyImplemented": true,
"id": 1775,
"id": 1840,
"linearizedBaseContracts": [
1775
1840
],
"name": "MultiSend",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1773,
"id": 1838,
"nodeType": "Block",
"src": "651:673:16",
"src": "753:922:17",
"statements": [
{
"externalReferences": [
{
"transactions": {
"declaration": 1769,
"declaration": 1834,
"isOffset": false,
"isSlot": false,
"src": "768:12:16",
"src": "870:12:17",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1769,
"declaration": 1834,
"isOffset": false,
"isSlot": false,
"src": "884:12:16",
"src": "993:12:17",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1769,
"declaration": 1834,
"isOffset": false,
"isSlot": false,
"src": "941:12:16",
"src": "1047:12:17",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1769,
"declaration": 1834,
"isOffset": false,
"isSlot": false,
"src": "1014:12:16",
"src": "1188:12:17",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1769,
"declaration": 1834,
"isOffset": false,
"isSlot": false,
"src": "1075:12:16",
"src": "1115:12:17",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1834,
"isOffset": false,
"isSlot": false,
"src": "1249:12:17",
"valueSize": 1
}
}
],
"id": 1772,
"id": 1837,
"nodeType": "InlineAssembly",
"operations": "{\n let length := mload(transactions)\n let i := 0x20\n for {\n }\n lt(i, length)\n {\n }\n {\n let to := mload(add(transactions, i))\n let value := mload(add(transactions, add(i, 0x20)))\n let dataLength := mload(add(transactions, add(i, 0x60)))\n let data := add(transactions, add(i, 0x80))\n switch call(gas(), to, value, data, dataLength, 0, 0)\n case 0 {\n revert(0, 0)\n }\n i := add(i, add(0x80, mul(div(add(dataLength, 0x1f), 0x20), 0x20)))\n }\n}",
"src": "725:599:16"
"operations": "{\n let length := mload(transactions)\n let i := 0x20\n for {\n }\n lt(i, length)\n {\n }\n {\n let operation := mload(add(transactions, i))\n let to := mload(add(transactions, add(i, 0x20)))\n let value := mload(add(transactions, add(i, 0x40)))\n let dataLength := mload(add(transactions, add(i, 0x80)))\n let data := add(transactions, add(i, 0xa0))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n case 1 {\n success := delegatecall(gas(), to, data, dataLength, 0, 0)\n }\n if eq(success, 0)\n {\n revert(0, 0)\n }\n i := add(i, add(0xa0, mul(div(add(dataLength, 0x1f), 0x20), 0x20)))\n }\n}",
"src": "827:848:17"
}
]
},
"documentation": "@dev Sends multiple transactions and reverts all if one fails.\n @param transactions Encoded transactions. Each transaction is encoded as\n a tuple(address,uint256,bytes). The bytes of all\n encoded transactions are concatenated to form the input.",
"id": 1774,
"documentation": "@dev Sends multiple transactions and reverts all if one fails.\n @param transactions Encoded transactions. Each transaction is encoded as a \n tuple(operation,address,uint256,bytes), where operation \n can be 0 for a call or 1 for a delegatecall. The bytes \n of all encoded transactions are concatenated to form the input.",
"id": 1839,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
@ -125,16 +134,16 @@
"name": "multiSend",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1770,
"id": 1835,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1769,
"id": 1834,
"name": "transactions",
"nodeType": "VariableDeclaration",
"scope": 1774,
"src": "612:18:16",
"scope": 1839,
"src": "714:18:17",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
@ -142,10 +151,10 @@
"typeString": "bytes"
},
"typeName": {
"id": 1768,
"id": 1833,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "612:5:16",
"src": "714:5:17",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes"
@ -155,47 +164,47 @@
"visibility": "internal"
}
],
"src": "611:20:16"
"src": "713:20:17"
},
"payable": false,
"returnParameters": {
"id": 1771,
"id": 1836,
"nodeType": "ParameterList",
"parameters": [],
"src": "651:0:16"
"src": "753:0:17"
},
"scope": 1775,
"src": "593:731:16",
"scope": 1840,
"src": "695:980:17",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 1776,
"src": "253:1073:16"
"scope": 1841,
"src": "253:1424:17"
}
],
"src": "0:1327:16"
"src": "0:1678:17"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/libraries/MultiSend.sol",
"exportedSymbols": {
"MultiSend": [
1775
1840
]
},
"id": 1776,
"id": 1841,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1767,
"id": 1832,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:16"
"src": "0:23:17"
},
{
"baseContracts": [],
@ -203,76 +212,85 @@
"contractKind": "contract",
"documentation": "@title Multi Send - Allows to batch multiple transactions into one.\n @author Nick Dodson - <nick.dodson@consensys.net>\n @author Gonçalo Sá - <goncalo.sa@consensys.net>\n @author Stefan George - <stefan@gnosis.pm>",
"fullyImplemented": true,
"id": 1775,
"id": 1840,
"linearizedBaseContracts": [
1775
1840
],
"name": "MultiSend",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1773,
"id": 1838,
"nodeType": "Block",
"src": "651:673:16",
"src": "753:922:17",
"statements": [
{
"externalReferences": [
{
"transactions": {
"declaration": 1769,
"declaration": 1834,
"isOffset": false,
"isSlot": false,
"src": "768:12:16",
"src": "870:12:17",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1769,
"declaration": 1834,
"isOffset": false,
"isSlot": false,
"src": "884:12:16",
"src": "993:12:17",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1769,
"declaration": 1834,
"isOffset": false,
"isSlot": false,
"src": "941:12:16",
"src": "1047:12:17",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1769,
"declaration": 1834,
"isOffset": false,
"isSlot": false,
"src": "1014:12:16",
"src": "1188:12:17",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1769,
"declaration": 1834,
"isOffset": false,
"isSlot": false,
"src": "1075:12:16",
"src": "1115:12:17",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 1834,
"isOffset": false,
"isSlot": false,
"src": "1249:12:17",
"valueSize": 1
}
}
],
"id": 1772,
"id": 1837,
"nodeType": "InlineAssembly",
"operations": "{\n let length := mload(transactions)\n let i := 0x20\n for {\n }\n lt(i, length)\n {\n }\n {\n let to := mload(add(transactions, i))\n let value := mload(add(transactions, add(i, 0x20)))\n let dataLength := mload(add(transactions, add(i, 0x60)))\n let data := add(transactions, add(i, 0x80))\n switch call(gas(), to, value, data, dataLength, 0, 0)\n case 0 {\n revert(0, 0)\n }\n i := add(i, add(0x80, mul(div(add(dataLength, 0x1f), 0x20), 0x20)))\n }\n}",
"src": "725:599:16"
"operations": "{\n let length := mload(transactions)\n let i := 0x20\n for {\n }\n lt(i, length)\n {\n }\n {\n let operation := mload(add(transactions, i))\n let to := mload(add(transactions, add(i, 0x20)))\n let value := mload(add(transactions, add(i, 0x40)))\n let dataLength := mload(add(transactions, add(i, 0x80)))\n let data := add(transactions, add(i, 0xa0))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n case 1 {\n success := delegatecall(gas(), to, data, dataLength, 0, 0)\n }\n if eq(success, 0)\n {\n revert(0, 0)\n }\n i := add(i, add(0xa0, mul(div(add(dataLength, 0x1f), 0x20), 0x20)))\n }\n}",
"src": "827:848:17"
}
]
},
"documentation": "@dev Sends multiple transactions and reverts all if one fails.\n @param transactions Encoded transactions. Each transaction is encoded as\n a tuple(address,uint256,bytes). The bytes of all\n encoded transactions are concatenated to form the input.",
"id": 1774,
"documentation": "@dev Sends multiple transactions and reverts all if one fails.\n @param transactions Encoded transactions. Each transaction is encoded as a \n tuple(operation,address,uint256,bytes), where operation \n can be 0 for a call or 1 for a delegatecall. The bytes \n of all encoded transactions are concatenated to form the input.",
"id": 1839,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
@ -280,16 +298,16 @@
"name": "multiSend",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1770,
"id": 1835,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1769,
"id": 1834,
"name": "transactions",
"nodeType": "VariableDeclaration",
"scope": 1774,
"src": "612:18:16",
"scope": 1839,
"src": "714:18:17",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
@ -297,10 +315,10 @@
"typeString": "bytes"
},
"typeName": {
"id": 1768,
"id": 1833,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "612:5:16",
"src": "714:5:17",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes"
@ -310,27 +328,27 @@
"visibility": "internal"
}
],
"src": "611:20:16"
"src": "713:20:17"
},
"payable": false,
"returnParameters": {
"id": 1771,
"id": 1836,
"nodeType": "ParameterList",
"parameters": [],
"src": "651:0:16"
"src": "753:0:17"
},
"scope": 1775,
"src": "593:731:16",
"scope": 1840,
"src": "695:980:17",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 1776,
"src": "253:1073:16"
"scope": 1841,
"src": "253:1424:17"
}
],
"src": "0:1327:16"
"src": "0:1678:17"
},
"compiler": {
"name": "solc",
@ -340,34 +358,28 @@
"4": {
"events": {},
"links": {},
"address": "0xa95bcb648df34c679b070cd7f5992ec4aa4e5275",
"transactionHash": "0x7260ac1ca4cdf29c28bc941de22f64e7dd24bc928841bebee1f2b4d5d84037c8"
"address": "0xe94c33a523bf201e412f601eff906eec0b1d21f5",
"transactionHash": "0x1f04811d6fb97329f6e96a579587fe5a3abe9fe2f202d4b2e27adb78d3de1c48"
},
"1527420696956": {
"1529327661534": {
"events": {},
"links": {},
"address": "0x8e9d29708810d650d0b43058b41687ea02c0baee",
"transactionHash": "0xd044f1662e339061a8cabf2b06ac94a9f86fcccf3f5d80ebd1bea2a7542d4021"
"address": "0xa2a1eb294e1191c1e374f9015a37db35c49e9f26",
"transactionHash": "0x5cd2551fce05a8b864a085616ee54449fdddd56dcdebf1019bebd0839c69ef5f"
},
"1527678155804": {
"1529333415702": {
"events": {},
"links": {},
"address": "0x6655c7792ebda0b1dbea3607591995ea391c8a9e",
"transactionHash": "0x70aa0d9af1bc4978d61d3f0c67523717246c4a588a4c1808d45609e0adb04a05"
"address": "0xaba1a0da223a2a5e04158bd80b2af7671e27e2c6",
"transactionHash": "0x6e7c0c3947a3a851738677ae63915781ce79fdfb0453030fc63bbcd346f2cf89"
},
"1528109761438": {
"1529652204341": {
"events": {},
"links": {},
"address": "0x3946fcaaa0ba21aaffc5e06a3cc45debc9e07f7f",
"transactionHash": "0xd044f1662e339061a8cabf2b06ac94a9f86fcccf3f5d80ebd1bea2a7542d4021"
},
"1528296677763": {
"events": {},
"links": {},
"address": "0xef9e7829f057e4d640bf66e17e06b3ab5cae508d",
"transactionHash": "0xd044f1662e339061a8cabf2b06ac94a9f86fcccf3f5d80ebd1bea2a7542d4021"
"address": "0x2013688de17569d52fc4cd4fe5f18821d8b32b2a",
"transactionHash": "0x2d7f72a94ced345c372040faa1f51a51f3e8da27a02dd04b9eefef487de3ba05"
}
},
"schemaVersion": "2.0.0",
"updatedAt": "2018-06-06T14:51:43.696Z"
"updatedAt": "2018-06-22T07:24:16.274Z"
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -56,14 +56,14 @@
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Proxy.sol",
"exportedSymbols": {
"Proxy": [
1602
1611
]
},
"id": 1603,
"id": 1612,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1561,
"id": 1570,
"literals": [
"solidity",
"0.4",
@ -78,19 +78,19 @@
"contractKind": "contract",
"documentation": "@title Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.\n @author Stefan George - <stefan@gnosis.pm>",
"fullyImplemented": true,
"id": 1602,
"id": 1611,
"linearizedBaseContracts": [
1602
1611
],
"name": "Proxy",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 1563,
"id": 1572,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1602,
"scope": 1611,
"src": "363:18:11",
"stateVariable": true,
"storageLocation": "default",
@ -99,7 +99,7 @@
"typeString": "address"
},
"typeName": {
"id": 1562,
"id": 1571,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "363:7:11",
@ -113,7 +113,7 @@
},
{
"body": {
"id": 1579,
"id": 1588,
"nodeType": "Block",
"src": "560:116:11",
"statements": [
@ -127,18 +127,18 @@
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 1571,
"id": 1580,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 1569,
"id": 1578,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1565,
"referencedDeclaration": 1574,
"src": "578:11:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -150,7 +150,7 @@
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 1570,
"id": 1579,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -174,7 +174,7 @@
{
"argumentTypes": null,
"hexValue": "496e76616c6964206d617374657220636f707920616464726573732070726f7669646564",
"id": 1572,
"id": 1581,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -201,21 +201,21 @@
"typeString": "literal_string \"Invalid master copy address provided\""
}
],
"id": 1568,
"id": 1577,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
2657,
2658
2703,
2704
],
"referencedDeclaration": 2658,
"referencedDeclaration": 2704,
"src": "570:7:11",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 1573,
"id": 1582,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -229,25 +229,25 @@
"typeString": "tuple()"
}
},
"id": 1574,
"id": 1583,
"nodeType": "ExpressionStatement",
"src": "570:65:11"
},
{
"expression": {
"argumentTypes": null,
"id": 1577,
"id": 1586,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 1575,
"id": 1584,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1563,
"referencedDeclaration": 1572,
"src": "645:10:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -258,11 +258,11 @@
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 1576,
"id": 1585,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1565,
"referencedDeclaration": 1574,
"src": "658:11:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -275,14 +275,14 @@
"typeString": "address"
}
},
"id": 1578,
"id": 1587,
"nodeType": "ExpressionStatement",
"src": "645:24:11"
}
]
},
"documentation": "@dev Constructor function sets address of master copy contract.\n @param _masterCopy Master copy address.",
"id": 1580,
"id": 1589,
"implemented": true,
"isConstructor": true,
"isDeclaredConst": false,
@ -290,15 +290,15 @@
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1566,
"id": 1575,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1565,
"id": 1574,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1580,
"scope": 1589,
"src": "520:19:11",
"stateVariable": false,
"storageLocation": "default",
@ -307,7 +307,7 @@
"typeString": "address"
},
"typeName": {
"id": 1564,
"id": 1573,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "520:7:11",
@ -324,12 +324,12 @@
},
"payable": false,
"returnParameters": {
"id": 1567,
"id": 1576,
"nodeType": "ParameterList",
"parameters": [],
"src": "560:0:11"
},
"scope": 1602,
"scope": 1611,
"src": "508:168:11",
"stateMutability": "nonpayable",
"superFunction": null,
@ -337,13 +337,13 @@
},
{
"body": {
"id": 1584,
"id": 1593,
"nodeType": "Block",
"src": "826:470:11",
"statements": [
{
"externalReferences": [],
"id": 1583,
"id": 1592,
"nodeType": "InlineAssembly",
"operations": "{\n let masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n calldatacopy(0, 0, calldatasize())\n let success := delegatecall(gas(), masterCopy, 0, calldatasize(), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if eq(success, 0)\n {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n}",
"src": "900:396:11"
@ -351,7 +351,7 @@
]
},
"documentation": "@dev Fallback function forwards all transactions and returns all received return data.",
"id": 1585,
"id": 1594,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
@ -359,19 +359,19 @@
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1581,
"id": 1590,
"nodeType": "ParameterList",
"parameters": [],
"src": "786:2:11"
},
"payable": true,
"returnParameters": {
"id": 1582,
"id": 1591,
"nodeType": "ParameterList",
"parameters": [],
"src": "826:0:11"
},
"scope": 1602,
"scope": 1611,
"src": "777:519:11",
"stateMutability": "payable",
"superFunction": null,
@ -379,33 +379,33 @@
},
{
"body": {
"id": 1592,
"id": 1601,
"nodeType": "Block",
"src": "1386:34:11",
"statements": [
{
"expression": {
"argumentTypes": null,
"id": 1590,
"id": 1599,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1563,
"referencedDeclaration": 1572,
"src": "1403:10:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"functionReturnParameters": 1589,
"id": 1591,
"functionReturnParameters": 1598,
"id": 1600,
"nodeType": "Return",
"src": "1396:17:11"
}
]
},
"documentation": null,
"id": 1593,
"id": 1602,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": true,
@ -413,22 +413,22 @@
"name": "implementation",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1586,
"id": 1595,
"nodeType": "ParameterList",
"parameters": [],
"src": "1325:2:11"
},
"payable": false,
"returnParameters": {
"id": 1589,
"id": 1598,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1588,
"id": 1597,
"name": "",
"nodeType": "VariableDeclaration",
"scope": 1593,
"scope": 1602,
"src": "1373:7:11",
"stateVariable": false,
"storageLocation": "default",
@ -437,7 +437,7 @@
"typeString": "address"
},
"typeName": {
"id": 1587,
"id": 1596,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "1373:7:11",
@ -452,7 +452,7 @@
],
"src": "1372:9:11"
},
"scope": 1602,
"scope": 1611,
"src": "1302:118:11",
"stateMutability": "view",
"superFunction": null,
@ -460,7 +460,7 @@
},
{
"body": {
"id": 1600,
"id": 1609,
"nodeType": "Block",
"src": "1505:25:11",
"statements": [
@ -468,7 +468,7 @@
"expression": {
"argumentTypes": null,
"hexValue": "32",
"id": 1598,
"id": 1607,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -483,15 +483,15 @@
},
"value": "2"
},
"functionReturnParameters": 1597,
"id": 1599,
"functionReturnParameters": 1606,
"id": 1608,
"nodeType": "Return",
"src": "1515:8:11"
}
]
},
"documentation": null,
"id": 1601,
"id": 1610,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": true,
@ -499,22 +499,22 @@
"name": "proxyType",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1594,
"id": 1603,
"nodeType": "ParameterList",
"parameters": [],
"src": "1444:2:11"
},
"payable": false,
"returnParameters": {
"id": 1597,
"id": 1606,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1596,
"id": 1605,
"name": "",
"nodeType": "VariableDeclaration",
"scope": 1601,
"scope": 1610,
"src": "1492:7:11",
"stateVariable": false,
"storageLocation": "default",
@ -523,7 +523,7 @@
"typeString": "uint256"
},
"typeName": {
"id": 1595,
"id": 1604,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "1492:7:11",
@ -538,14 +538,14 @@
],
"src": "1491:9:11"
},
"scope": 1602,
"scope": 1611,
"src": "1426:104:11",
"stateMutability": "pure",
"superFunction": null,
"visibility": "public"
}
],
"scope": 1603,
"scope": 1612,
"src": "190:1342:11"
}
],
@ -555,14 +555,14 @@
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Proxy.sol",
"exportedSymbols": {
"Proxy": [
1602
1611
]
},
"id": 1603,
"id": 1612,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1561,
"id": 1570,
"literals": [
"solidity",
"0.4",
@ -577,19 +577,19 @@
"contractKind": "contract",
"documentation": "@title Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.\n @author Stefan George - <stefan@gnosis.pm>",
"fullyImplemented": true,
"id": 1602,
"id": 1611,
"linearizedBaseContracts": [
1602
1611
],
"name": "Proxy",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 1563,
"id": 1572,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1602,
"scope": 1611,
"src": "363:18:11",
"stateVariable": true,
"storageLocation": "default",
@ -598,7 +598,7 @@
"typeString": "address"
},
"typeName": {
"id": 1562,
"id": 1571,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "363:7:11",
@ -612,7 +612,7 @@
},
{
"body": {
"id": 1579,
"id": 1588,
"nodeType": "Block",
"src": "560:116:11",
"statements": [
@ -626,18 +626,18 @@
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 1571,
"id": 1580,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 1569,
"id": 1578,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1565,
"referencedDeclaration": 1574,
"src": "578:11:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -649,7 +649,7 @@
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 1570,
"id": 1579,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -673,7 +673,7 @@
{
"argumentTypes": null,
"hexValue": "496e76616c6964206d617374657220636f707920616464726573732070726f7669646564",
"id": 1572,
"id": 1581,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -700,21 +700,21 @@
"typeString": "literal_string \"Invalid master copy address provided\""
}
],
"id": 1568,
"id": 1577,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
2657,
2658
2703,
2704
],
"referencedDeclaration": 2658,
"referencedDeclaration": 2704,
"src": "570:7:11",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 1573,
"id": 1582,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -728,25 +728,25 @@
"typeString": "tuple()"
}
},
"id": 1574,
"id": 1583,
"nodeType": "ExpressionStatement",
"src": "570:65:11"
},
{
"expression": {
"argumentTypes": null,
"id": 1577,
"id": 1586,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 1575,
"id": 1584,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1563,
"referencedDeclaration": 1572,
"src": "645:10:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -757,11 +757,11 @@
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 1576,
"id": 1585,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1565,
"referencedDeclaration": 1574,
"src": "658:11:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -774,14 +774,14 @@
"typeString": "address"
}
},
"id": 1578,
"id": 1587,
"nodeType": "ExpressionStatement",
"src": "645:24:11"
}
]
},
"documentation": "@dev Constructor function sets address of master copy contract.\n @param _masterCopy Master copy address.",
"id": 1580,
"id": 1589,
"implemented": true,
"isConstructor": true,
"isDeclaredConst": false,
@ -789,15 +789,15 @@
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1566,
"id": 1575,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1565,
"id": 1574,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1580,
"scope": 1589,
"src": "520:19:11",
"stateVariable": false,
"storageLocation": "default",
@ -806,7 +806,7 @@
"typeString": "address"
},
"typeName": {
"id": 1564,
"id": 1573,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "520:7:11",
@ -823,12 +823,12 @@
},
"payable": false,
"returnParameters": {
"id": 1567,
"id": 1576,
"nodeType": "ParameterList",
"parameters": [],
"src": "560:0:11"
},
"scope": 1602,
"scope": 1611,
"src": "508:168:11",
"stateMutability": "nonpayable",
"superFunction": null,
@ -836,13 +836,13 @@
},
{
"body": {
"id": 1584,
"id": 1593,
"nodeType": "Block",
"src": "826:470:11",
"statements": [
{
"externalReferences": [],
"id": 1583,
"id": 1592,
"nodeType": "InlineAssembly",
"operations": "{\n let masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n calldatacopy(0, 0, calldatasize())\n let success := delegatecall(gas(), masterCopy, 0, calldatasize(), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if eq(success, 0)\n {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n}",
"src": "900:396:11"
@ -850,7 +850,7 @@
]
},
"documentation": "@dev Fallback function forwards all transactions and returns all received return data.",
"id": 1585,
"id": 1594,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
@ -858,19 +858,19 @@
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1581,
"id": 1590,
"nodeType": "ParameterList",
"parameters": [],
"src": "786:2:11"
},
"payable": true,
"returnParameters": {
"id": 1582,
"id": 1591,
"nodeType": "ParameterList",
"parameters": [],
"src": "826:0:11"
},
"scope": 1602,
"scope": 1611,
"src": "777:519:11",
"stateMutability": "payable",
"superFunction": null,
@ -878,33 +878,33 @@
},
{
"body": {
"id": 1592,
"id": 1601,
"nodeType": "Block",
"src": "1386:34:11",
"statements": [
{
"expression": {
"argumentTypes": null,
"id": 1590,
"id": 1599,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1563,
"referencedDeclaration": 1572,
"src": "1403:10:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"functionReturnParameters": 1589,
"id": 1591,
"functionReturnParameters": 1598,
"id": 1600,
"nodeType": "Return",
"src": "1396:17:11"
}
]
},
"documentation": null,
"id": 1593,
"id": 1602,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": true,
@ -912,22 +912,22 @@
"name": "implementation",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1586,
"id": 1595,
"nodeType": "ParameterList",
"parameters": [],
"src": "1325:2:11"
},
"payable": false,
"returnParameters": {
"id": 1589,
"id": 1598,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1588,
"id": 1597,
"name": "",
"nodeType": "VariableDeclaration",
"scope": 1593,
"scope": 1602,
"src": "1373:7:11",
"stateVariable": false,
"storageLocation": "default",
@ -936,7 +936,7 @@
"typeString": "address"
},
"typeName": {
"id": 1587,
"id": 1596,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "1373:7:11",
@ -951,7 +951,7 @@
],
"src": "1372:9:11"
},
"scope": 1602,
"scope": 1611,
"src": "1302:118:11",
"stateMutability": "view",
"superFunction": null,
@ -959,7 +959,7 @@
},
{
"body": {
"id": 1600,
"id": 1609,
"nodeType": "Block",
"src": "1505:25:11",
"statements": [
@ -967,7 +967,7 @@
"expression": {
"argumentTypes": null,
"hexValue": "32",
"id": 1598,
"id": 1607,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -982,15 +982,15 @@
},
"value": "2"
},
"functionReturnParameters": 1597,
"id": 1599,
"functionReturnParameters": 1606,
"id": 1608,
"nodeType": "Return",
"src": "1515:8:11"
}
]
},
"documentation": null,
"id": 1601,
"id": 1610,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": true,
@ -998,22 +998,22 @@
"name": "proxyType",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1594,
"id": 1603,
"nodeType": "ParameterList",
"parameters": [],
"src": "1444:2:11"
},
"payable": false,
"returnParameters": {
"id": 1597,
"id": 1606,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1596,
"id": 1605,
"name": "",
"nodeType": "VariableDeclaration",
"scope": 1601,
"scope": 1610,
"src": "1492:7:11",
"stateVariable": false,
"storageLocation": "default",
@ -1022,7 +1022,7 @@
"typeString": "uint256"
},
"typeName": {
"id": 1595,
"id": 1604,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "1492:7:11",
@ -1037,14 +1037,14 @@
],
"src": "1491:9:11"
},
"scope": 1602,
"scope": 1611,
"src": "1426:104:11",
"stateMutability": "pure",
"superFunction": null,
"visibility": "public"
}
],
"scope": 1603,
"scope": 1612,
"src": "190:1342:11"
}
],
@ -1056,5 +1056,5 @@
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-05-28T05:59:52.706Z"
"updatedAt": "2018-06-18T14:44:09.462Z"
}

View File

@ -47,14 +47,14 @@
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/ProxyFactory.sol",
"exportedSymbols": {
"ProxyFactory": [
1637
1646
]
},
"id": 1638,
"id": 1647,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1604,
"id": 1613,
"literals": [
"solidity",
"0.4",
@ -66,10 +66,10 @@
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Proxy.sol",
"file": "./Proxy.sol",
"id": 1605,
"id": 1614,
"nodeType": "ImportDirective",
"scope": 1638,
"sourceUnit": 1603,
"scope": 1647,
"sourceUnit": 1612,
"src": "24:21:12",
"symbolAliases": [],
"unitAlias": ""
@ -77,14 +77,14 @@
{
"baseContracts": [],
"contractDependencies": [
1602
1611
],
"contractKind": "contract",
"documentation": "@title Proxy Factory - Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n @author Stefan George - <stefan@gnosis.pm>",
"fullyImplemented": true,
"id": 1637,
"id": 1646,
"linearizedBaseContracts": [
1637
1646
],
"name": "ProxyFactory",
"nodeType": "ContractDefinition",
@ -92,36 +92,36 @@
{
"anonymous": false,
"documentation": null,
"id": 1609,
"id": 1618,
"name": "ProxyCreation",
"nodeType": "EventDefinition",
"parameters": {
"id": 1608,
"id": 1617,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1607,
"id": 1616,
"indexed": false,
"name": "proxy",
"nodeType": "VariableDeclaration",
"scope": 1609,
"scope": 1618,
"src": "274:11:12",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
},
"typeName": {
"contractScope": null,
"id": 1606,
"id": 1615,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1602,
"referencedDeclaration": 1611,
"src": "274:5:12",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
},
@ -135,28 +135,28 @@
},
{
"body": {
"id": 1635,
"id": 1644,
"nodeType": "Block",
"src": "634:314:12",
"statements": [
{
"expression": {
"argumentTypes": null,
"id": 1623,
"id": 1632,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 1618,
"id": 1627,
"name": "proxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1616,
"referencedDeclaration": 1625,
"src": "644:5:12",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
},
@ -167,11 +167,11 @@
"arguments": [
{
"argumentTypes": null,
"id": 1621,
"id": 1630,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1611,
"referencedDeclaration": 1620,
"src": "662:10:12",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -186,7 +186,7 @@
"typeString": "address"
}
],
"id": 1620,
"id": 1629,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -194,23 +194,23 @@
"nodeType": "NewExpression",
"src": "652:9:12",
"typeDescriptions": {
"typeIdentifier": "t_function_creation_nonpayable$_t_address_$returns$_t_contract$_Proxy_$1602_$",
"typeIdentifier": "t_function_creation_nonpayable$_t_address_$returns$_t_contract$_Proxy_$1611_$",
"typeString": "function (address) returns (contract Proxy)"
},
"typeName": {
"contractScope": null,
"id": 1619,
"id": 1628,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1602,
"referencedDeclaration": 1611,
"src": "656:5:12",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
}
},
"id": 1622,
"id": 1631,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -220,17 +220,17 @@
"nodeType": "FunctionCall",
"src": "652:21:12",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
},
"src": "644:29:12",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
},
"id": 1624,
"id": 1633,
"nodeType": "ExpressionStatement",
"src": "644:29:12"
},
@ -241,7 +241,7 @@
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 1628,
"id": 1637,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -250,18 +250,18 @@
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 1625,
"id": 1634,
"name": "data",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1613,
"referencedDeclaration": 1622,
"src": "687:4:12",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes memory"
}
},
"id": 1626,
"id": 1635,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -280,7 +280,7 @@
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 1627,
"id": 1636,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -302,14 +302,14 @@
}
},
"falseBody": null,
"id": 1630,
"id": 1639,
"nodeType": "IfStatement",
"src": "683:237:12",
"trueBody": {
"externalReferences": [
{
"data": {
"declaration": 1613,
"declaration": 1622,
"isOffset": false,
"isSlot": false,
"src": "860:4:12",
@ -318,7 +318,7 @@
},
{
"proxy": {
"declaration": 1616,
"declaration": 1625,
"isOffset": false,
"isSlot": false,
"src": "827:5:12",
@ -327,7 +327,7 @@
},
{
"data": {
"declaration": 1613,
"declaration": 1622,
"isOffset": false,
"isSlot": false,
"src": "841:4:12",
@ -335,7 +335,7 @@
}
}
],
"id": 1629,
"id": 1638,
"nodeType": "InlineAssembly",
"operations": "{\n if eq(call(gas(), proxy, 0, add(data, 0x20), mload(data), 0, 0), 0)\n {\n revert(0, 0)\n }\n}",
"src": "784:136:12"
@ -347,14 +347,14 @@
"arguments": [
{
"argumentTypes": null,
"id": 1632,
"id": 1641,
"name": "proxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1616,
"referencedDeclaration": 1625,
"src": "935:5:12",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
}
@ -362,22 +362,22 @@
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
],
"id": 1631,
"id": 1640,
"name": "ProxyCreation",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1609,
"referencedDeclaration": 1618,
"src": "921:13:12",
"typeDescriptions": {
"typeIdentifier": "t_function_event_nonpayable$_t_contract$_Proxy_$1602_$returns$__$",
"typeIdentifier": "t_function_event_nonpayable$_t_contract$_Proxy_$1611_$returns$__$",
"typeString": "function (contract Proxy)"
}
},
"id": 1633,
"id": 1642,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -391,14 +391,14 @@
"typeString": "tuple()"
}
},
"id": 1634,
"id": 1643,
"nodeType": "EmitStatement",
"src": "916:25:12"
}
]
},
"documentation": "@dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n @param masterCopy Address of master copy.\n @param data Payload for message call sent to new proxy contract.",
"id": 1636,
"id": 1645,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
@ -406,15 +406,15 @@
"name": "createProxy",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1614,
"id": 1623,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1611,
"id": 1620,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1636,
"scope": 1645,
"src": "553:18:12",
"stateVariable": false,
"storageLocation": "default",
@ -423,7 +423,7 @@
"typeString": "address"
},
"typeName": {
"id": 1610,
"id": 1619,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "553:7:12",
@ -437,10 +437,10 @@
},
{
"constant": false,
"id": 1613,
"id": 1622,
"name": "data",
"nodeType": "VariableDeclaration",
"scope": 1636,
"scope": 1645,
"src": "573:10:12",
"stateVariable": false,
"storageLocation": "default",
@ -449,7 +449,7 @@
"typeString": "bytes"
},
"typeName": {
"id": 1612,
"id": 1621,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "573:5:12",
@ -466,31 +466,31 @@
},
"payable": false,
"returnParameters": {
"id": 1617,
"id": 1626,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1616,
"id": 1625,
"name": "proxy",
"nodeType": "VariableDeclaration",
"scope": 1636,
"scope": 1645,
"src": "617:11:12",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
},
"typeName": {
"contractScope": null,
"id": 1615,
"id": 1624,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1602,
"referencedDeclaration": 1611,
"src": "617:5:12",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
},
@ -500,14 +500,14 @@
],
"src": "616:13:12"
},
"scope": 1637,
"scope": 1646,
"src": "532:416:12",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 1638,
"scope": 1647,
"src": "225:725:12"
}
],
@ -517,14 +517,14 @@
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/ProxyFactory.sol",
"exportedSymbols": {
"ProxyFactory": [
1637
1646
]
},
"id": 1638,
"id": 1647,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1604,
"id": 1613,
"literals": [
"solidity",
"0.4",
@ -536,10 +536,10 @@
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Proxy.sol",
"file": "./Proxy.sol",
"id": 1605,
"id": 1614,
"nodeType": "ImportDirective",
"scope": 1638,
"sourceUnit": 1603,
"scope": 1647,
"sourceUnit": 1612,
"src": "24:21:12",
"symbolAliases": [],
"unitAlias": ""
@ -547,14 +547,14 @@
{
"baseContracts": [],
"contractDependencies": [
1602
1611
],
"contractKind": "contract",
"documentation": "@title Proxy Factory - Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n @author Stefan George - <stefan@gnosis.pm>",
"fullyImplemented": true,
"id": 1637,
"id": 1646,
"linearizedBaseContracts": [
1637
1646
],
"name": "ProxyFactory",
"nodeType": "ContractDefinition",
@ -562,36 +562,36 @@
{
"anonymous": false,
"documentation": null,
"id": 1609,
"id": 1618,
"name": "ProxyCreation",
"nodeType": "EventDefinition",
"parameters": {
"id": 1608,
"id": 1617,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1607,
"id": 1616,
"indexed": false,
"name": "proxy",
"nodeType": "VariableDeclaration",
"scope": 1609,
"scope": 1618,
"src": "274:11:12",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
},
"typeName": {
"contractScope": null,
"id": 1606,
"id": 1615,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1602,
"referencedDeclaration": 1611,
"src": "274:5:12",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
},
@ -605,28 +605,28 @@
},
{
"body": {
"id": 1635,
"id": 1644,
"nodeType": "Block",
"src": "634:314:12",
"statements": [
{
"expression": {
"argumentTypes": null,
"id": 1623,
"id": 1632,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 1618,
"id": 1627,
"name": "proxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1616,
"referencedDeclaration": 1625,
"src": "644:5:12",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
},
@ -637,11 +637,11 @@
"arguments": [
{
"argumentTypes": null,
"id": 1621,
"id": 1630,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1611,
"referencedDeclaration": 1620,
"src": "662:10:12",
"typeDescriptions": {
"typeIdentifier": "t_address",
@ -656,7 +656,7 @@
"typeString": "address"
}
],
"id": 1620,
"id": 1629,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -664,23 +664,23 @@
"nodeType": "NewExpression",
"src": "652:9:12",
"typeDescriptions": {
"typeIdentifier": "t_function_creation_nonpayable$_t_address_$returns$_t_contract$_Proxy_$1602_$",
"typeIdentifier": "t_function_creation_nonpayable$_t_address_$returns$_t_contract$_Proxy_$1611_$",
"typeString": "function (address) returns (contract Proxy)"
},
"typeName": {
"contractScope": null,
"id": 1619,
"id": 1628,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1602,
"referencedDeclaration": 1611,
"src": "656:5:12",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
}
},
"id": 1622,
"id": 1631,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -690,17 +690,17 @@
"nodeType": "FunctionCall",
"src": "652:21:12",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
},
"src": "644:29:12",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
},
"id": 1624,
"id": 1633,
"nodeType": "ExpressionStatement",
"src": "644:29:12"
},
@ -711,7 +711,7 @@
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 1628,
"id": 1637,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -720,18 +720,18 @@
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 1625,
"id": 1634,
"name": "data",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1613,
"referencedDeclaration": 1622,
"src": "687:4:12",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes memory"
}
},
"id": 1626,
"id": 1635,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -750,7 +750,7 @@
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 1627,
"id": 1636,
"isConstant": false,
"isLValue": false,
"isPure": true,
@ -772,14 +772,14 @@
}
},
"falseBody": null,
"id": 1630,
"id": 1639,
"nodeType": "IfStatement",
"src": "683:237:12",
"trueBody": {
"externalReferences": [
{
"data": {
"declaration": 1613,
"declaration": 1622,
"isOffset": false,
"isSlot": false,
"src": "860:4:12",
@ -788,7 +788,7 @@
},
{
"proxy": {
"declaration": 1616,
"declaration": 1625,
"isOffset": false,
"isSlot": false,
"src": "827:5:12",
@ -797,7 +797,7 @@
},
{
"data": {
"declaration": 1613,
"declaration": 1622,
"isOffset": false,
"isSlot": false,
"src": "841:4:12",
@ -805,7 +805,7 @@
}
}
],
"id": 1629,
"id": 1638,
"nodeType": "InlineAssembly",
"operations": "{\n if eq(call(gas(), proxy, 0, add(data, 0x20), mload(data), 0, 0), 0)\n {\n revert(0, 0)\n }\n}",
"src": "784:136:12"
@ -817,14 +817,14 @@
"arguments": [
{
"argumentTypes": null,
"id": 1632,
"id": 1641,
"name": "proxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1616,
"referencedDeclaration": 1625,
"src": "935:5:12",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
}
@ -832,22 +832,22 @@
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
],
"id": 1631,
"id": 1640,
"name": "ProxyCreation",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1609,
"referencedDeclaration": 1618,
"src": "921:13:12",
"typeDescriptions": {
"typeIdentifier": "t_function_event_nonpayable$_t_contract$_Proxy_$1602_$returns$__$",
"typeIdentifier": "t_function_event_nonpayable$_t_contract$_Proxy_$1611_$returns$__$",
"typeString": "function (contract Proxy)"
}
},
"id": 1633,
"id": 1642,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -861,14 +861,14 @@
"typeString": "tuple()"
}
},
"id": 1634,
"id": 1643,
"nodeType": "EmitStatement",
"src": "916:25:12"
}
]
},
"documentation": "@dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n @param masterCopy Address of master copy.\n @param data Payload for message call sent to new proxy contract.",
"id": 1636,
"id": 1645,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
@ -876,15 +876,15 @@
"name": "createProxy",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1614,
"id": 1623,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1611,
"id": 1620,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1636,
"scope": 1645,
"src": "553:18:12",
"stateVariable": false,
"storageLocation": "default",
@ -893,7 +893,7 @@
"typeString": "address"
},
"typeName": {
"id": 1610,
"id": 1619,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "553:7:12",
@ -907,10 +907,10 @@
},
{
"constant": false,
"id": 1613,
"id": 1622,
"name": "data",
"nodeType": "VariableDeclaration",
"scope": 1636,
"scope": 1645,
"src": "573:10:12",
"stateVariable": false,
"storageLocation": "default",
@ -919,7 +919,7 @@
"typeString": "bytes"
},
"typeName": {
"id": 1612,
"id": 1621,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "573:5:12",
@ -936,31 +936,31 @@
},
"payable": false,
"returnParameters": {
"id": 1617,
"id": 1626,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1616,
"id": 1625,
"name": "proxy",
"nodeType": "VariableDeclaration",
"scope": 1636,
"scope": 1645,
"src": "617:11:12",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
},
"typeName": {
"contractScope": null,
"id": 1615,
"id": 1624,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1602,
"referencedDeclaration": 1611,
"src": "617:5:12",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1602",
"typeIdentifier": "t_contract$_Proxy_$1611",
"typeString": "contract Proxy"
}
},
@ -970,14 +970,14 @@
],
"src": "616:13:12"
},
"scope": 1637,
"scope": 1646,
"src": "532:416:12",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 1638,
"scope": 1647,
"src": "225:725:12"
}
],
@ -991,34 +991,28 @@
"4": {
"events": {},
"links": {},
"address": "0x5fae0ba38b6e532e97f064a5a28276071ba5841c",
"transactionHash": "0x336dee0e43b6d4defa98ac04db8294591e55361e725d3c1e2e85037e3671ed97"
"address": "0xe799418aadc40eb8f2081424bd518cdb442d50f4",
"transactionHash": "0x83f7e65d10e5b2ae69f461d86bba33a67a845d65a591749327bd73ce6e28d50b"
},
"1527420696956": {
"1529327661534": {
"events": {},
"links": {},
"address": "0xa16e2ea106b09506111fcd01eb82c9864afa4315",
"transactionHash": "0x75ad1066b44cd801ac66a316dbe4c09e72636d72b70fd62eb647295a0fc5e285"
"address": "0xa0e45d0af3d5daeb68a725e7f2dd544bcce9dd29",
"transactionHash": "0x5db6814a3b712012c000eb4d202e8d481abd2fcd127b1f746e2ab1d88ee523c9"
},
"1527678155804": {
"1529333415702": {
"events": {},
"links": {},
"address": "0xf2bf237dc75c3a466b457a5eff498061dac4c341",
"transactionHash": "0x0a1bf7e8030e9d4d24dd7002f35ece3848830cd266ab089664fd1d44ea95d506"
"address": "0xce824fab495ef56405218cce3512b7a73df9e2ca",
"transactionHash": "0x10a89cb87c96bb1becc3a78f1bfdd54f98cdc1cb7e5164e26b1cbbd09d69be8c"
},
"1528109761438": {
"1529652204341": {
"events": {},
"links": {},
"address": "0xbefd9f4a40b1bec8ec730969a3508d1739fb2742",
"transactionHash": "0x75ad1066b44cd801ac66a316dbe4c09e72636d72b70fd62eb647295a0fc5e285"
},
"1528296677763": {
"events": {},
"links": {},
"address": "0xaa973df8ec251cf67ec387d5627d42dbb738605f",
"address": "0xffacf76025eda5f84659135a9d5c2d815dbe1caa",
"transactionHash": "0x75ad1066b44cd801ac66a316dbe4c09e72636d72b70fd62eb647295a0fc5e285"
}
},
"schemaVersion": "2.0.0",
"updatedAt": "2018-06-06T14:51:43.668Z"
"updatedAt": "2018-06-22T07:24:16.243Z"
}

View File

@ -3,29 +3,29 @@
"abi": [],
"bytecode": "0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a72305820ec80f1b4520aa5197e4181778f1e2e4fc460002d4a40e2e8e6709c8986067c220029",
"deployedBytecode": "0x6080604052600080fd00a165627a7a72305820ec80f1b4520aa5197e4181778f1e2e4fc460002d4a40e2e8e6709c8986067c220029",
"sourceMap": "152:166:13:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;152:166:13;;;;;;;",
"deployedSourceMap": "152:166:13:-;;;;;",
"sourceMap": "152:166:8:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;152:166:8;;;;;;;",
"deployedSourceMap": "152:166:8:-;;;;;",
"source": "pragma solidity 0.4.24;\n\n\n/// @title SelfAuthorized - authorizes current contract to perform actions\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract SelfAuthorized {\n modifier authorized() {\n require(msg.sender == address(this), \"Method can only be called from this contract\");\n _;\n }\n}\n",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
"exportedSymbols": {
"SelfAuthorized": [
1654
1449
]
},
"id": 1655,
"id": 1450,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1639,
"id": 1434,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:13"
"src": "0:23:8"
},
{
"baseContracts": [],
@ -33,18 +33,18 @@
"contractKind": "contract",
"documentation": "@title SelfAuthorized - authorizes current contract to perform actions\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 1654,
"id": 1449,
"linearizedBaseContracts": [
1654
1449
],
"name": "SelfAuthorized",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1652,
"id": 1447,
"nodeType": "Block",
"src": "204:112:13",
"src": "204:112:8",
"statements": [
{
"expression": {
@ -56,7 +56,7 @@
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 1647,
"id": 1442,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -65,18 +65,18 @@
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 1642,
"id": 1437,
"name": "msg",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2654,
"src": "222:3:13",
"referencedDeclaration": 1773,
"src": "222:3:8",
"typeDescriptions": {
"typeIdentifier": "t_magic_message",
"typeString": "msg"
}
},
"id": 1643,
"id": 1438,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -84,7 +84,7 @@
"memberName": "sender",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "222:10:13",
"src": "222:10:8",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -97,14 +97,14 @@
"arguments": [
{
"argumentTypes": null,
"id": 1645,
"id": 1440,
"name": "this",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2673,
"src": "244:4:13",
"referencedDeclaration": 1788,
"src": "244:4:8",
"typeDescriptions": {
"typeIdentifier": "t_contract$_SelfAuthorized_$1654",
"typeIdentifier": "t_contract$_SelfAuthorized_$1449",
"typeString": "contract SelfAuthorized"
}
}
@ -112,24 +112,24 @@
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_contract$_SelfAuthorized_$1654",
"typeIdentifier": "t_contract$_SelfAuthorized_$1449",
"typeString": "contract SelfAuthorized"
}
],
"id": 1644,
"id": 1439,
"isConstant": false,
"isLValue": false,
"isPure": true,
"lValueRequested": false,
"nodeType": "ElementaryTypeNameExpression",
"src": "236:7:13",
"src": "236:7:8",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_address_$",
"typeString": "type(address)"
},
"typeName": "address"
},
"id": 1646,
"id": 1441,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -137,13 +137,13 @@
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "236:13:13",
"src": "236:13:8",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "222:27:13",
"src": "222:27:8",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
@ -152,14 +152,14 @@
{
"argumentTypes": null,
"hexValue": "4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207468697320636f6e7472616374",
"id": 1648,
"id": 1443,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "251:46:13",
"src": "251:46:8",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_c4780ef0a1d41d59bac8c510cf9ada421bccf2b90f75a8e4ba2e8c09e8d72733",
@ -179,21 +179,21 @@
"typeString": "literal_string \"Method can only be called from this contract\""
}
],
"id": 1641,
"id": 1436,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
2657,
2658
1776,
1777
],
"referencedDeclaration": 2658,
"src": "214:7:13",
"referencedDeclaration": 1777,
"src": "214:7:8",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 1649,
"id": 1444,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -201,62 +201,62 @@
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "214:84:13",
"src": "214:84:8",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 1650,
"id": 1445,
"nodeType": "ExpressionStatement",
"src": "214:84:13"
"src": "214:84:8"
},
{
"id": 1651,
"id": 1446,
"nodeType": "PlaceholderStatement",
"src": "308:1:13"
"src": "308:1:8"
}
]
},
"documentation": null,
"id": 1653,
"id": 1448,
"name": "authorized",
"nodeType": "ModifierDefinition",
"parameters": {
"id": 1640,
"id": 1435,
"nodeType": "ParameterList",
"parameters": [],
"src": "201:2:13"
"src": "201:2:8"
},
"src": "182:134:13",
"src": "182:134:8",
"visibility": "internal"
}
],
"scope": 1655,
"src": "152:166:13"
"scope": 1450,
"src": "152:166:8"
}
],
"src": "0:319:13"
"src": "0:319:8"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
"exportedSymbols": {
"SelfAuthorized": [
1654
1449
]
},
"id": 1655,
"id": 1450,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1639,
"id": 1434,
"literals": [
"solidity",
"0.4",
".24"
],
"nodeType": "PragmaDirective",
"src": "0:23:13"
"src": "0:23:8"
},
{
"baseContracts": [],
@ -264,18 +264,18 @@
"contractKind": "contract",
"documentation": "@title SelfAuthorized - authorizes current contract to perform actions\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 1654,
"id": 1449,
"linearizedBaseContracts": [
1654
1449
],
"name": "SelfAuthorized",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1652,
"id": 1447,
"nodeType": "Block",
"src": "204:112:13",
"src": "204:112:8",
"statements": [
{
"expression": {
@ -287,7 +287,7 @@
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 1647,
"id": 1442,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -296,18 +296,18 @@
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 1642,
"id": 1437,
"name": "msg",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2654,
"src": "222:3:13",
"referencedDeclaration": 1773,
"src": "222:3:8",
"typeDescriptions": {
"typeIdentifier": "t_magic_message",
"typeString": "msg"
}
},
"id": 1643,
"id": 1438,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -315,7 +315,7 @@
"memberName": "sender",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "222:10:13",
"src": "222:10:8",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
@ -328,14 +328,14 @@
"arguments": [
{
"argumentTypes": null,
"id": 1645,
"id": 1440,
"name": "this",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2673,
"src": "244:4:13",
"referencedDeclaration": 1788,
"src": "244:4:8",
"typeDescriptions": {
"typeIdentifier": "t_contract$_SelfAuthorized_$1654",
"typeIdentifier": "t_contract$_SelfAuthorized_$1449",
"typeString": "contract SelfAuthorized"
}
}
@ -343,24 +343,24 @@
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_contract$_SelfAuthorized_$1654",
"typeIdentifier": "t_contract$_SelfAuthorized_$1449",
"typeString": "contract SelfAuthorized"
}
],
"id": 1644,
"id": 1439,
"isConstant": false,
"isLValue": false,
"isPure": true,
"lValueRequested": false,
"nodeType": "ElementaryTypeNameExpression",
"src": "236:7:13",
"src": "236:7:8",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_address_$",
"typeString": "type(address)"
},
"typeName": "address"
},
"id": 1646,
"id": 1441,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -368,13 +368,13 @@
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "236:13:13",
"src": "236:13:8",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "222:27:13",
"src": "222:27:8",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
@ -383,14 +383,14 @@
{
"argumentTypes": null,
"hexValue": "4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207468697320636f6e7472616374",
"id": 1648,
"id": 1443,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "251:46:13",
"src": "251:46:8",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_c4780ef0a1d41d59bac8c510cf9ada421bccf2b90f75a8e4ba2e8c09e8d72733",
@ -410,21 +410,21 @@
"typeString": "literal_string \"Method can only be called from this contract\""
}
],
"id": 1641,
"id": 1436,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
2657,
2658
1776,
1777
],
"referencedDeclaration": 2658,
"src": "214:7:13",
"referencedDeclaration": 1777,
"src": "214:7:8",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 1649,
"id": 1444,
"isConstant": false,
"isLValue": false,
"isPure": false,
@ -432,42 +432,42 @@
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "214:84:13",
"src": "214:84:8",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 1650,
"id": 1445,
"nodeType": "ExpressionStatement",
"src": "214:84:13"
"src": "214:84:8"
},
{
"id": 1651,
"id": 1446,
"nodeType": "PlaceholderStatement",
"src": "308:1:13"
"src": "308:1:8"
}
]
},
"documentation": null,
"id": 1653,
"id": 1448,
"name": "authorized",
"nodeType": "ModifierDefinition",
"parameters": {
"id": 1640,
"id": 1435,
"nodeType": "ParameterList",
"parameters": [],
"src": "201:2:13"
"src": "201:2:8"
},
"src": "182:134:13",
"src": "182:134:8",
"visibility": "internal"
}
],
"scope": 1655,
"src": "152:166:13"
"scope": 1450,
"src": "152:166:8"
}
],
"src": "0:319:13"
"src": "0:319:8"
},
"compiler": {
"name": "solc",
@ -475,5 +475,5 @@
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-05-28T05:59:52.707Z"
"updatedAt": "2018-06-20T07:57:27.027Z"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
// @flow
import * as React from 'react'
import { ListItemText } from 'material-ui/List'
import { withStyles } from 'material-ui/styles'
import MuiListItemText from '@material-ui/core/ListItemText'
import { withStyles } from '@material-ui/core/styles'
import { type WithStyles } from '~/theme/mui'
type Props = WithStyles & {
@ -18,21 +18,26 @@ const styles = {
},
}
const GnoListItemText = ({
primary, secondary, classes, cut = false,
}: Props) => {
const cutStyle = cut ? {
secondary: classes.itemTextSecondary,
} : undefined
class ListItemText extends React.PureComponent<Props> {
render() {
const {
primary, secondary, classes, cut = false,
} = this.props
return (
<ListItemText
classes={cutStyle}
inset
primary={primary}
secondary={secondary}
/>
)
const cutStyle = cut ? {
secondary: classes.itemTextSecondary,
} : undefined
return (
<MuiListItemText
classes={cutStyle}
inset
primary={primary}
secondary={secondary}
/>
)
}
}
export default withStyles(styles)(GnoListItemText)
export default withStyles(styles)(ListItemText)

View File

@ -1,7 +1,7 @@
// @flow
import * as React from 'react'
import Page from '~/components/layout/Page'
import { CircularProgress } from 'material-ui/Progress'
import CircularProgress from '@material-ui/core/CircularProgress'
const centerStyle = {
margin: 'auto 0',

View File

@ -1,7 +1,7 @@
// @flow
import * as React from 'react'
import { CircularProgress } from 'material-ui/Progress'
import RefreshIcon from 'material-ui-icons/Refresh'
import CircularProgress from '@material-ui/core/CircularProgress'
import RefreshIcon from '@material-ui/icons/Refresh'
import { sm, secondary } from '~/theme/variables'
type Props = {

View File

@ -0,0 +1,103 @@
// @flow
import SnackbarContent from '@material-ui/core/SnackbarContent'
import classNames from 'classnames/bind'
import * as React from 'react'
import green from '@material-ui/core/colors/green'
import amber from '@material-ui/core/colors/amber'
import CloseIcon from '@material-ui/icons/Close'
import CheckCircleIcon from '@material-ui/icons/CheckCircle'
import ErrorIcon from '@material-ui/icons/Error'
import InfoIcon from '@material-ui/icons/Info'
import IconButton from '@material-ui/core/IconButton'
import { withStyles } from '@material-ui/core/styles'
import WarningIcon from '@material-ui/icons/Warning'
import { type WithStyles } from '~/theme/mui'
type Variant = 'success' | 'error' | 'warning' | 'info'
type MessageProps = WithStyles & {
variant: Variant,
message: string,
}
type Props = MessageProps & {
onClose?: () => void,
}
type CloseProps = WithStyles & {
onClose: () => void,
}
const variantIcon = {
success: CheckCircleIcon,
warning: WarningIcon,
error: ErrorIcon,
info: InfoIcon,
}
const styles = theme => ({
success: {
backgroundColor: green[600],
},
error: {
backgroundColor: theme.palette.error.dark,
},
info: {
backgroundColor: theme.palette.primary.dark,
},
warning: {
backgroundColor: amber[700],
},
icon: {
fontSize: 20,
},
iconVariant: {
opacity: 0.9,
marginRight: theme.spacing.unit,
},
message: {
display: 'flex',
alignItems: 'center',
},
})
const Close = ({ classes, onClose }: CloseProps) => (
<IconButton
key="close"
aria-label="Close"
color="inherit"
className={classes.close}
onClick={onClose}
>
<CloseIcon className={classes.icon} />
</IconButton>
)
const Message = ({ classes, message, variant }: MessageProps) => {
const Icon = variantIcon[variant]
return (
<span id="client-snackbar" className={classes.message}>
<Icon className={classNames(classes.icon, classes.iconVariant)} />
{message}
</span>
)
}
const GnoSnackbarContent = ({
variant, classes, message, onClose,
}: Props) => {
const action = onClose ? [<Close onClose={onClose} classes={classes} />] : undefined
const messageComponent = <Message classes={classes} message={message} variant={variant} />
return (
<SnackbarContent
className={classNames(classes[variant])}
aria-describedby="client-snackbar"
message={messageComponent}
action={action}
/>
)
}
export default withStyles(styles)(GnoSnackbarContent)

View File

@ -1,6 +1,8 @@
// @flow
import Stepper, { Step as FormStep, StepLabel } from 'material-ui/Stepper'
import { withStyles } from 'material-ui/styles'
import Stepper from '@material-ui/core/Stepper'
import FormStep from '@material-ui/core/Step'
import StepLabel from '@material-ui/core/StepLabel'
import { withStyles } from '@material-ui/core/styles'
import * as React from 'react'
import type { FormApi } from 'react-final-form'
import GnoForm from '~/components/forms/GnoForm'

View File

@ -1,6 +1,6 @@
// @flow
import React from 'react'
import Checkbox, { type CheckoxProps } from 'material-ui/Checkbox'
import Checkbox, { type CheckoxProps } from '@material-ui/core/Checkbox'
class GnoCheckbox extends React.PureComponent<CheckoxProps> {
render() {

View File

@ -1,6 +1,6 @@
// @flow
import React from 'react'
import MuiTextField, { TextFieldProps } from 'material-ui/TextField'
import MuiTextField, { TextFieldProps } from '@material-ui/core/TextField'
// Neded for solving a fix in Windows browsers
const overflowStyle = {

View File

@ -1,4 +1,4 @@
// @flow
import Button from 'material-ui/Button'
import Button from '@material-ui/core/Button'
export default Button

View File

@ -1,6 +1,10 @@
// @flow
import * as React from 'react'
import Table, { TableBody, TableCell, TableHead, TableRow } from 'material-ui/Table'
import Table from '@material-ui/core/Table'
import TableBody from '@material-ui/core/TableBody'
import TableCell from '@material-ui/core/TableCell'
import TableHead from '@material-ui/core/TableHead'
import TableRow from '@material-ui/core/TableRow'
export { TableBody, TableCell, TableHead, TableRow }

View File

@ -1,7 +1,7 @@
// @flow
import 'babel-polyfill'
import { MuiThemeProvider } from 'material-ui/styles'
import { MuiThemeProvider } from '@material-ui/core/styles'
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'

View File

@ -1,6 +1,6 @@
// @flow
import * as React from 'react'
import { CircularProgress } from 'material-ui/Progress'
import CircularProgress from '@material-ui/core/CircularProgress'
import Block from '~/components/layout/Block'
import Bold from '~/components/layout/Bold'
import Col from '~/components/layout/Col'

View File

@ -5,7 +5,7 @@ import * as TestUtils from 'react-dom/test-utils'
import Layout from '~/routes/open/components/Layout'
import { FIELD_CONFIRMATIONS, FIELD_OWNERS } from '~/routes/open/components/fields'
import { getProviderInfo } from '~/wallets/getWeb3'
import Wrapper from '~/test/Wrapper'
import Wrapper from '~/test/utils/Wrapper'
import { CONFIRMATIONS_ERROR } from '~/routes/open/components/SafeForm'
const obSubmitMock = () => {}

View File

@ -6,7 +6,7 @@ import GnoForm from '~/components/forms/GnoForm'
import { FIELD_OWNERS } from '~/routes/open/components/fields'
import { getAccountsFrom } from '~/routes/open/utils/safeDataExtractor'
import { getProviderInfo } from '~/wallets/getWeb3'
import Wrapper from '~/test/Wrapper'
import Wrapper from '~/test/utils/Wrapper'
import { ADDRESS_REPEATED_ERROR } from '~/components/forms/validator'
import Owners from './index'

View File

@ -63,7 +63,7 @@ const AddOwnerForm = ({ addresses, numOwners, threshold }: Props) => () => (
component={Checkbox}
type="checkbox"
/>
<Block>Increase owner?</Block>
<Block>Increase threshold?</Block>
</Block>
</Block>
)

View File

@ -1,6 +1,6 @@
// @flow
import * as React from 'react'
import { CircularProgress } from 'material-ui/Progress'
import CircularProgress from '@material-ui/core/CircularProgress'
import Block from '~/components/layout/Block'
import Bold from '~/components/layout/Bold'
import Heading from '~/components/layout/Heading'

View File

@ -23,7 +23,7 @@ type Props = {
balance: number,
}
const WithdrawnForm = ({ balance }: Props) => () => (
const WithdrawForm = ({ balance }: Props) => () => (
<Block margin="md">
<Heading tag="h2" margin="lg">
Multisig Transaction
@ -64,4 +64,4 @@ const WithdrawnForm = ({ balance }: Props) => () => (
</Block>
)
export default WithdrawnForm
export default WithdrawForm

View File

@ -1,6 +1,6 @@
// @flow
import * as React from 'react'
import { CircularProgress } from 'material-ui/Progress'
import CircularProgress from '@material-ui/core/CircularProgress'
import Block from '~/components/layout/Block'
import Bold from '~/components/layout/Bold'
import Heading from '~/components/layout/Heading'

View File

@ -8,7 +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, { checkReceiptStatus } from '~/wallets/ethTransactions'
import { checkReceiptStatus, calculateGasOf, calculateGasPrice } from '~/wallets/ethTransactions'
export const TX_NAME_PARAM = 'txName'
export const TX_DESTINATION_PARAM = 'txDestination'
@ -100,24 +100,27 @@ export const createTransaction = async (
const gnosisSafe = await getSafeEthereumInstance(safeAddress)
const valueInWei = web3.toWei(txValue, 'ether')
const CALL = 0
const gasPrice = await calculateGasPrice()
const thresholdIsOne = safe.get('threshold') === 1
if (hasOneOwner(safe) || thresholdIsOne) {
const txConfirmationData =
gnosisSafe.contract.execTransactionIfApproved.getData(txDest, valueInWei, data, CALL, nonce)
const txHash = await executeTransaction(txConfirmationData, user, safeAddress)
checkReceiptStatus(txHash)
const gas = await calculateGasOf(txConfirmationData, user, safeAddress)
const txHash =
await gnosisSafe.execTransactionIfApproved(txDest, valueInWei, data, CALL, nonce, { from: user, gas, gasPrice })
await checkReceiptStatus(txHash.tx)
const executedConfirmations: List<Confirmation> = buildExecutedConfirmationFrom(safe.get('owners'), user)
return storeTransaction(txName, nonce, txDest, txValue, user, executedConfirmations, txHash, safeAddress, safe.get('threshold'), data)
return storeTransaction(txName, nonce, txDest, txValue, user, executedConfirmations, txHash.tx, safeAddress, safe.get('threshold'), data)
}
const txConfirmationData =
gnosisSafe.contract.approveTransactionWithParameters.getData(txDest, valueInWei, data, CALL, nonce)
const txConfirmationHash = await executeTransaction(txConfirmationData, user, safeAddress)
checkReceiptStatus(txConfirmationHash)
const txData = gnosisSafe.contract.approveTransactionWithParameters.getData(txDest, valueInWei, data, CALL, nonce)
const gas = await calculateGasOf(txData, user, safeAddress)
const txConfirmationHash = await gnosisSafe
.approveTransactionWithParameters(txDest, valueInWei, data, CALL, nonce, { from: user, gas, gasPrice })
await checkReceiptStatus(txConfirmationHash.tx)
const confirmations: List<Confirmation> = buildConfirmationsFrom(safe.get('owners'), user, txConfirmationHash)
const confirmations: List<Confirmation> = buildConfirmationsFrom(safe.get('owners'), user, txConfirmationHash.tx)
return storeTransaction(txName, nonce, txDest, txValue, user, confirmations, '', safeAddress, safe.get('threshold'), data)
}

View File

@ -0,0 +1,36 @@
// @flow
import * as React from 'react'
import Block from '~/components/layout/Block'
import Heading from '~/components/layout/Heading'
import Field from '~/components/forms/Field'
import TextField from '~/components/forms/TextField'
import { composeValidators, minValue, mustBeFloat, required } from '~/components/forms/validator'
export const EDIT_DAILY_LIMIT_PARAM = 'daily'
type EditDailyLimitProps = {
dailyLimit: string,
}
const EditDailyLimitForm = ({ dailyLimit }: EditDailyLimitProps) => () => (
<Block margin="md">
<Heading tag="h2" margin="lg">
{'Change safe\'s daily limit'}
</Heading>
<Heading tag="h4" margin="lg">
{`Actual daily limit: ${dailyLimit}`}
</Heading>
<Block margin="md">
<Field
name={EDIT_DAILY_LIMIT_PARAM}
component={TextField}
type="text"
validate={composeValidators(required, mustBeFloat, minValue(0))}
placeholder="New daily limit"
text="Safe's daily limit"
/>
</Block>
</Block>
)
export default EditDailyLimitForm

View File

@ -0,0 +1,31 @@
// @flow
import * as React from 'react'
import CircularProgress from '@material-ui/core/CircularProgress'
import Block from '~/components/layout/Block'
import Bold from '~/components/layout/Bold'
import Heading from '~/components/layout/Heading'
import Paragraph from '~/components/layout/Paragraph'
import { EDIT_DAILY_LIMIT_PARAM } from '~/routes/safe/component/EditDailyLimit/EditDailyLimitForm'
type FormProps = {
values: Object,
submitting: boolean,
}
const spinnerStyle = {
minHeight: '50px',
}
const Review = () => ({ values, submitting }: FormProps) => (
<Block>
<Heading tag="h2">Review the DailyLimit operation</Heading>
<Paragraph align="left">
<Bold>The new daily limit will be: </Bold> {values[EDIT_DAILY_LIMIT_PARAM]}
</Paragraph>
<Block style={spinnerStyle}>
{ submitting && <CircularProgress size={50} /> }
</Block>
</Block>
)
export default Review

View File

@ -0,0 +1,12 @@
// @flow
import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions'
type FetchTransactions = typeof fetchTransactions
export type Actions = {
fetchTransactions: FetchTransactions,
}
export default {
fetchTransactions,
}

View File

@ -0,0 +1,84 @@
// @flow
import * as React from 'react'
import Stepper from '~/components/Stepper'
import { connect } from 'react-redux'
import { createTransaction } from '~/routes/safe/component/AddTransaction/createTransactions'
import { getEditDailyLimitData, getDailyLimitAddress } from '~/routes/safe/component/Withdraw/withdraw'
import { type Safe } from '~/routes/safe/store/model/safe'
import EditDailyLimitForm, { EDIT_DAILY_LIMIT_PARAM } from './EditDailyLimitForm'
import selector, { type SelectorProps } from './selector'
import actions, { type Actions } from './actions'
import Review from './Review'
type Props = SelectorProps & Actions & {
dailyLimit: number,
onReset: () => void,
safe: Safe,
}
const getSteps = () => [
'Fill Edit Daily Limit Form', 'Review Edit Daily Limit operation',
]
type State = {
done: boolean,
}
export const CHANGE_THRESHOLD_RESET_BUTTON_TEXT = 'SEE TXs'
class EditDailyLimit extends React.PureComponent<Props, State> {
state = {
done: false,
}
onEditDailyLimit = async (values: Object) => {
try {
const { safe, userAddress } = this.props
const newDailyLimit = values[EDIT_DAILY_LIMIT_PARAM]
const safeAddress = safe.get('address')
const data = await getEditDailyLimitData(safeAddress, 0, Number(newDailyLimit))
const to = await getDailyLimitAddress(safeAddress)
const nonce = Date.now()
await createTransaction(safe, `Change Safe's daily limit to ${newDailyLimit} [${nonce}]`, to, 0, nonce, userAddress, data)
await this.props.fetchTransactions()
this.setState({ done: true })
} catch (error) {
this.setState({ done: false })
// eslint-disable-next-line
console.log('Error while editing the daily limit ' + error)
}
}
onReset = () => {
this.setState({ done: false })
this.props.onReset()
}
render() {
const { dailyLimit } = this.props
const { done } = this.state
const steps = getSteps()
const finishedButton = <Stepper.FinishButton title={CHANGE_THRESHOLD_RESET_BUTTON_TEXT} />
return (
<React.Fragment>
<Stepper
finishedTransaction={done}
finishedButton={finishedButton}
onSubmit={this.onEditDailyLimit}
steps={steps}
onReset={this.onReset}
>
<Stepper.Page dailyLimit={dailyLimit} >
{ EditDailyLimitForm }
</Stepper.Page>
<Stepper.Page>
{ Review }
</Stepper.Page>
</Stepper>
</React.Fragment>
)
}
}
export default connect(selector, actions)(EditDailyLimit)

View File

@ -6,10 +6,12 @@ import GnoSafe from './Safe'
type Props = SelectorProps
const Layout = ({ safe, balance, provider }: Props) => (
const Layout = ({
safe, balance, provider, userAddress,
}: Props) => (
<React.Fragment>
{ safe
? <GnoSafe safe={safe} balance={balance} />
? <GnoSafe safe={safe} balance={balance} userAddress={userAddress} />
: <NoSafe provider={provider} text="Not found safe" />
}
</React.Fragment>

View File

@ -16,6 +16,7 @@ storiesOf('Routes /safe:address', module)
.addDecorator(FrameDecorator)
.add('Safe undefined being connected', () => (
<Component
userAddress="foo"
safe={undefined}
provider="METAMASK"
balance="0"
@ -24,6 +25,7 @@ storiesOf('Routes /safe:address', module)
))
.add('Safe undefined NOT connected', () => (
<Component
userAddress="foo"
safe={undefined}
provider=""
balance="0"
@ -35,6 +37,7 @@ storiesOf('Routes /safe:address', module)
return (
<Component
userAddress="foo"
safe={safe}
provider="METAMASK"
balance="2"
@ -47,6 +50,7 @@ storiesOf('Routes /safe:address', module)
return (
<Component
userAddress="foo"
safe={safe}
provider="METAMASK"
balance="2"

View File

@ -0,0 +1,47 @@
// @flow
import * as React from 'react'
import Field from '~/components/forms/Field'
import SnackbarContent from '~/components/SnackbarContent'
import Checkbox from '~/components/forms/Checkbox'
import Block from '~/components/layout/Block'
import Heading from '~/components/layout/Heading'
export const DECREASE_PARAM = 'decrease'
type Props = {
numOwners: number,
threshold: number,
name: string,
disabled: boolean,
pendingTransactions: boolean,
}
const RemoveOwnerForm = ({
numOwners, threshold, name, disabled, pendingTransactions,
}: Props) => () => (
<Block margin="md">
<Heading tag="h2" margin="lg">
Remove Owner { !!name && name }
</Heading>
<Heading tag="h4" margin="lg">
{`Actual number of owners: ${numOwners}, threhsold of safe: ${threshold}`}
</Heading>
{ pendingTransactions &&
<SnackbarContent
variant="warning"
message="Be careful removing an owner might incur in some of the pending transactions could never be executed"
/>
}
<Block margin="md">
<Field
name={DECREASE_PARAM}
component={Checkbox}
type="checkbox"
disabled={disabled}
/>
<Block>{disabled && '(disabled) '}Decrease threshold?</Block>
</Block>
</Block>
)
export default RemoveOwnerForm

View File

@ -0,0 +1,44 @@
// @flow
import * as React from 'react'
import CircularProgress from '@material-ui/core/CircularProgress'
import Block from '~/components/layout/Block'
import Bold from '~/components/layout/Bold'
import Heading from '~/components/layout/Heading'
import Paragraph from '~/components/layout/Paragraph'
import { DECREASE_PARAM } from '~/routes/safe/component/RemoveOwner/RemoveOwnerForm'
type Props = {
name: string,
}
type FormProps = {
values: Object,
submitting: boolean,
}
const spinnerStyle = {
minHeight: '50px',
}
const Review = ({ name }: Props) => ({ values, submitting }: FormProps) => {
const text = values[DECREASE_PARAM]
? 'This operation will decrease the threshold of the safe'
: 'This operation will not modify the threshold of the safe'
return (
<Block>
<Heading tag="h2">Review the Remove Owner operation</Heading>
<Paragraph align="left">
<Bold>Owner Name: </Bold> {name}
</Paragraph>
<Paragraph align="left">
<Bold>{text}</Bold>
</Paragraph>
<Block style={spinnerStyle}>
{ submitting && <CircularProgress size={50} /> }
</Block>
</Block>
)
}
export default Review

View File

@ -0,0 +1,12 @@
// @flow
import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions'
type FetchTransactions = typeof fetchTransactions
export type Actions = {
fetchTransactions: FetchTransactions,
}
export default {
fetchTransactions,
}

View File

@ -0,0 +1,111 @@
// @flow
import * as React from 'react'
import Stepper from '~/components/Stepper'
import { connect } from 'react-redux'
import { type Safe } from '~/routes/safe/store/model/safe'
import { getSafeEthereumInstance, createTransaction } from '~/routes/safe/component/AddTransaction/createTransactions'
import RemoveOwnerForm, { DECREASE_PARAM } from './RemoveOwnerForm'
import Review from './Review'
import selector, { type SelectorProps } from './selector'
import actions, { type Actions } from './actions'
const getSteps = () => [
'Fill Owner Form', 'Review Remove order operation',
]
type Props = SelectorProps & Actions & {
safe: Safe,
threshold: number,
name: string,
userToRemove: string,
}
type State = {
done: boolean,
}
const SENTINEL_ADDRESS = '0x0000000000000000000000000000000000000001'
export const REMOVE_OWNER_RESET_BUTTON_TEXT = 'RESET'
const initialValuesFrom = (decreaseMandatory: boolean = false) => ({
[DECREASE_PARAM]: decreaseMandatory,
})
const shouldDecrease = (numOwners: number, threshold: number) => threshold === numOwners
class RemoveOwner extends React.Component<Props, State> {
state = {
done: false,
}
onRemoveOwner = async (values: Object) => {
try {
const {
safe, threshold, executor, fetchTransactions, userToRemove, name,
} = this.props
const nonce = Date.now()
const newThreshold = values[DECREASE_PARAM] ? threshold - 1 : threshold
const safeAddress = safe.get('address')
const gnosisSafe = await getSafeEthereumInstance(safeAddress)
const storedOwners = await gnosisSafe.getOwners()
const index = storedOwners.findIndex(ownerAddress => ownerAddress === userToRemove)
const prevAddress = index === 0 ? SENTINEL_ADDRESS : storedOwners[index - 1]
const data = gnosisSafe.contract.removeOwner.getData(prevAddress, userToRemove, newThreshold)
const text = name || userToRemove
await createTransaction(safe, `Remove Owner ${text}`, safeAddress, 0, nonce, executor, data)
fetchTransactions()
this.setState({ done: true })
} catch (error) {
this.setState({ done: false })
// eslint-disable-next-line
console.log('Error while adding owner ' + error)
}
}
onReset = () => {
this.setState({ done: false })
}
render() {
const { safe, name, pendingTransactions } = this.props
const { done } = this.state
const steps = getSteps()
const numOwners = safe.get('owners').count()
const threshold = safe.get('threshold')
const finishedButton = <Stepper.FinishButton title={REMOVE_OWNER_RESET_BUTTON_TEXT} />
const decrease = shouldDecrease(numOwners, threshold)
const initialValues = initialValuesFrom(decrease)
const disabled = decrease || threshold === 1
return (
<React.Fragment>
<Stepper
finishedTransaction={done}
finishedButton={finishedButton}
onSubmit={this.onRemoveOwner}
steps={steps}
onReset={this.onReset}
initialValues={initialValues}
>
<Stepper.Page
numOwners={numOwners}
threshold={threshold}
name={name}
disabled={disabled}
pendingTransactions={pendingTransactions}
>
{ RemoveOwnerForm }
</Stepper.Page>
<Stepper.Page name={name}>
{ Review }
</Stepper.Page>
</Stepper>
</React.Fragment>
)
}
}
export default connect(selector, actions)(RemoveOwner)

View File

@ -0,0 +1,26 @@
// @flow
import { List } from 'immutable'
import { createStructuredSelector, createSelector } from 'reselect'
import { userAccountSelector } from '~/wallets/store/selectors/index'
import { type Transaction } from '~/routes/safe/store/model/transaction'
import { safeTransactionsSelector } from '~/routes/safe/store/selectors/index'
const pendingTransactionsSelector = createSelector(
safeTransactionsSelector,
(transactions: List<Transaction>) =>
transactions.findEntry((transaction: Transaction) => {
const txHash = transaction.get('tx')
return txHash === '' || txHash === undefined
}) !== undefined,
)
export type SelectorProps = {
executor: userAccountSelector,
pendingTransactions: pendingTransactionsSelector,
}
export default createStructuredSelector({
executor: userAccountSelector,
pendingTransactions: pendingTransactionsSelector,
})

View File

@ -1,8 +1,8 @@
// @flow
import * as React from 'react'
import { ListItem } from 'material-ui/List'
import Avatar from 'material-ui/Avatar'
import Mail from 'material-ui-icons/Mail'
import ListItem from '@material-ui/core/ListItem'
import Avatar from '@material-ui/core/Avatar'
import Mail from '@material-ui/icons/Mail'
import ListItemText from '~/components/List/ListItemText'
type Props = {

View File

@ -1,8 +1,9 @@
// @flow
import * as React from 'react'
import { ListItem, ListItemText } from 'material-ui/List'
import Avatar from 'material-ui/Avatar'
import AccountBalance from 'material-ui-icons/AccountBalance'
import ListItem from '@material-ui/core/ListItem'
import ListItemText from '@material-ui/core/ListItemText'
import Avatar from '@material-ui/core/Avatar'
import AccountBalance from '@material-ui/icons/AccountBalance'
type Props = {
balance: string,

View File

@ -1,8 +1,8 @@
// @flow
import * as React from 'react'
import { ListItem } from 'material-ui/List'
import Avatar from 'material-ui/Avatar'
import DoneAll from 'material-ui-icons/DoneAll'
import ListItem from '@material-ui/core/ListItem'
import Avatar from '@material-ui/core/Avatar'
import DoneAll from '@material-ui/icons/DoneAll'
import ListItemText from '~/components/List/ListItemText'
import Button from '~/components/layout/Button'

View File

@ -1,21 +1,28 @@
// @flow
import * as React from 'react'
import { ListItem } from 'material-ui/List'
import Avatar from 'material-ui/Avatar'
import NotificationsPaused from 'material-ui-icons/NotificationsPaused'
import ListItem from '@material-ui/core/ListItem'
import Avatar from '@material-ui/core/Avatar'
import NotificationsPaused from '@material-ui/icons/NotificationsPaused'
import Button from '~/components/layout/Button'
import ListItemText from '~/components/List/ListItemText'
import { type DailyLimit } from '~/routes/safe/store/model/dailyLimit'
type Props = {
dailyLimit: DailyLimit,
onWithdrawn: () => void,
onWithdraw: () => void,
onEditDailyLimit: () => void,
balance: string,
}
export const EDIT_WITHDRAW = 'Edit'
export const WITHDRAW_BUTTON_TEXT = 'Withdraw'
export const WITHDRAWN_BUTTON_TEXT = 'Withdrawn'
const editStyle = {
marginRight: '10px',
}
const DailyLimitComponent = ({ dailyLimit, balance, onWithdrawn }: Props) => {
const DailyLimitComponent = ({
dailyLimit, balance, onWithdraw, onEditDailyLimit,
}: Props) => {
const limit = dailyLimit.get('value')
const spentToday = dailyLimit.get('spentToday')
@ -29,12 +36,20 @@ const DailyLimitComponent = ({ dailyLimit, balance, onWithdrawn }: Props) => {
</Avatar>
<ListItemText primary="Daily Limit" secondary={text} />
<Button
style={editStyle}
variant="raised"
color="primary"
onClick={onWithdrawn}
onClick={onEditDailyLimit}
>
{EDIT_WITHDRAW}
</Button>
<Button
variant="raised"
color="primary"
onClick={onWithdraw}
disabled={disabled}
>
{WITHDRAWN_BUTTON_TEXT}
{WITHDRAW_BUTTON_TEXT}
</Button>
</ListItem>
)

View File

@ -1,8 +1,8 @@
// @flow
import * as React from 'react'
import { ListItem } from 'material-ui/List'
import Avatar from 'material-ui/Avatar'
import AcoountBalanceWallet from 'material-ui-icons/AccountBalanceWallet'
import ListItem from '@material-ui/core/ListItem'
import Avatar from '@material-ui/core/Avatar'
import AcoountBalanceWallet from '@material-ui/icons/AccountBalanceWallet'
import Button from '~/components/layout/Button'
import ListItemText from '~/components/List/ListItemText'

View File

@ -1,18 +1,23 @@
// @flow
import * as React from 'react'
import openHoc, { type Open } from '~/components/hoc/OpenHoc'
import { withStyles } from 'material-ui/styles'
import Collapse from 'material-ui/transitions/Collapse'
import { withStyles } from '@material-ui/core/styles'
import Collapse from '@material-ui/core/Collapse'
import ListItemText from '~/components/List/ListItemText'
import List, { ListItem, ListItemIcon } from 'material-ui/List'
import Avatar from 'material-ui/Avatar'
import List from '@material-ui/core/List'
import ListItem from '@material-ui/core/ListItem'
import ListItemIcon from '@material-ui/core/ListItemIcon'
import Avatar from '@material-ui/core/Avatar'
import IconButton from '@material-ui/core/IconButton'
import Button from '~/components/layout/Button'
import Group from 'material-ui-icons/Group'
import Person from 'material-ui-icons/Person'
import ExpandLess from 'material-ui-icons/ExpandLess'
import ExpandMore from 'material-ui-icons/ExpandMore'
import Group from '@material-ui/icons/Group'
import Delete from '@material-ui/icons/Delete'
import Person from '@material-ui/icons/Person'
import ExpandLess from '@material-ui/icons/ExpandLess'
import ExpandMore from '@material-ui/icons/ExpandMore'
import { type OwnerProps } from '~/routes/safe/store/model/owner'
import { type WithStyles } from '~/theme/mui'
import { sameAddress } from '~/wallets/ethAddresses'
const styles = {
nested: {
@ -22,13 +27,16 @@ const styles = {
type Props = Open & WithStyles & {
owners: List<OwnerProps>,
userAddress: string,
onAddOwner: () => void,
onRemoveOwner: (name: string, addres: string) => void,
}
export const ADD_OWNER_BUTTON_TEXT = 'Add'
export const REMOVE_OWNER_BUTTON_TEXT = 'Delete'
const Owners = openHoc(({
open, toggle, owners, classes, onAddOwner,
open, toggle, owners, classes, onAddOwner, userAddress, onRemoveOwner,
}: Props) => (
<React.Fragment>
<ListItem onClick={toggle}>
@ -37,7 +45,10 @@ const Owners = openHoc(({
</Avatar>
<ListItemText primary="Owners" secondary={`${owners.size} owners`} />
<ListItemIcon>
{open ? <ExpandLess /> : <ExpandMore />}
{open
? <IconButton disableRipple><ExpandLess /></IconButton>
: <IconButton disableRipple><ExpandMore /></IconButton>
}
</ListItemIcon>
<Button
variant="raised"
@ -49,18 +60,27 @@ const Owners = openHoc(({
</ListItem>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
{owners.map(owner => (
<ListItem key={owner.address} className={classes.nested}>
<ListItemIcon>
<Person />
</ListItemIcon>
<ListItemText
cut
primary={owner.name}
secondary={owner.address}
/>
</ListItem>
))}
{owners.map((owner) => {
const onRemoveIconClick = () => onRemoveOwner(owner.name, owner.address)
return (
<ListItem key={owner.address} className={classes.nested}>
<ListItemIcon>
<Person />
</ListItemIcon>
<ListItemText
cut
primary={owner.name}
secondary={owner.address}
/>
{ !sameAddress(userAddress, owner.address) &&
<IconButton aria-label="Delete" onClick={onRemoveIconClick}>
<Delete />
</IconButton>
}
</ListItem>
)
})}
</List>
</Collapse>
</React.Fragment>

View File

@ -7,13 +7,15 @@ import Img from '~/components/layout/Img'
import Paragraph from '~/components/layout/Paragraph'
import Row from '~/components/layout/Row'
import { type Safe } from '~/routes/safe/store/model/safe'
import List from 'material-ui/List'
import List from '@material-ui/core/List'
import Withdrawn from '~/routes/safe/component/Withdrawn'
import Withdraw from '~/routes/safe/component/Withdraw'
import Transactions from '~/routes/safe/component/Transactions'
import AddTransaction from '~/routes/safe/component/AddTransaction'
import Threshold from '~/routes/safe/component/Threshold'
import AddOwner from '~/routes/safe/component/AddOwner'
import RemoveOwner from '~/routes/safe/component/RemoveOwner'
import EditDailyLimit from '~/routes/safe/component/EditDailyLimit'
import Address from './Address'
import Balance from './Balance'
@ -27,6 +29,7 @@ const safeIcon = require('./assets/gnosis_safe.svg')
type SafeProps = {
safe: Safe,
balance: string,
userAddress: string,
}
type State = {
@ -42,10 +45,17 @@ class GnoSafe extends React.PureComponent<SafeProps, State> {
component: undefined,
}
onWithdrawn = () => {
onEditDailyLimit = () => {
const { safe } = this.props
this.setState({ component: <Withdrawn safeAddress={safe.get('address')} dailyLimit={safe.get('dailyLimit')} /> })
const value = safe.get('dailyLimit').get('value')
this.setState({ component: <EditDailyLimit safe={safe} dailyLimit={value} onReset={this.onListTransactions} /> })
}
onWithdraw = () => {
const { safe } = this.props
this.setState({ component: <Withdraw safe={safe} dailyLimit={safe.get('dailyLimit')} /> })
}
onAddTx = () => {
@ -64,7 +74,7 @@ class GnoSafe extends React.PureComponent<SafeProps, State> {
onEditThreshold = () => {
const { safe } = this.props
this.setState({ component: <Threshold numOwners={safe.get('owners').count()} safe={safe} /> })
this.setState({ component: <Threshold numOwners={safe.get('owners').count()} safe={safe} onReset={this.onListTransactions} /> })
}
onAddOwner = (e: SyntheticEvent<HTMLButtonElement>) => {
@ -73,8 +83,14 @@ class GnoSafe extends React.PureComponent<SafeProps, State> {
this.setState({ component: <AddOwner threshold={safe.get('threshold')} safe={safe} /> })
}
onRemoveOwner = (name: string, address: string) => {
const { safe } = this.props
this.setState({ component: <RemoveOwner safeAddress={safe.get('address')} threshold={safe.get('threshold')} safe={safe} name={name} userToRemove={address} /> })
}
render() {
const { safe, balance } = this.props
const { safe, balance, userAddress } = this.props
const { component } = this.state
return (
@ -82,10 +98,15 @@ class GnoSafe extends React.PureComponent<SafeProps, State> {
<Col sm={12} top="xs" md={5} margin="xl" overflow>
<List style={listStyle}>
<Balance balance={balance} />
<Owners owners={safe.owners} onAddOwner={this.onAddOwner} />
<Owners
owners={safe.owners}
onAddOwner={this.onAddOwner}
userAddress={userAddress}
onRemoveOwner={this.onRemoveOwner}
/>
<Confirmations confirmations={safe.get('threshold')} onEditThreshold={this.onEditThreshold} />
<Address address={safe.get('address')} />
<DailyLimit balance={balance} dailyLimit={safe.get('dailyLimit')} onWithdrawn={this.onWithdrawn} />
<DailyLimit balance={balance} dailyLimit={safe.get('dailyLimit')} onWithdraw={this.onWithdraw} onEditDailyLimit={this.onEditDailyLimit} />
<MultisigTx balance={balance} onAddTx={this.onAddTx} onSeeTxs={this.onListTransactions} />
</List>
</Col>

View File

@ -1,6 +1,6 @@
// @flow
import * as React from 'react'
import { CircularProgress } from 'material-ui/Progress'
import CircularProgress from '@material-ui/core/CircularProgress'
import Block from '~/components/layout/Block'
import Bold from '~/components/layout/Bold'
import Heading from '~/components/layout/Heading'

View File

@ -23,7 +23,7 @@ type State = {
done: boolean,
}
export const CHANGE_THRESHOLD_RESET_BUTTON_TEXT = 'RESET'
export const CHANGE_THRESHOLD_RESET_BUTTON_TEXT = 'SEE TXs'
class Threshold extends React.PureComponent<Props, State> {
state = {
@ -49,6 +49,7 @@ class Threshold extends React.PureComponent<Props, State> {
onReset = () => {
this.setState({ done: false })
this.props.onReset()
}
render() {

View File

@ -1,15 +1,18 @@
// @flow
import * as React from 'react'
import openHoc, { type Open } from '~/components/hoc/OpenHoc'
import { withStyles } from 'material-ui/styles'
import Collapse from 'material-ui/transitions/Collapse'
import { withStyles } from '@material-ui/core/styles'
import Collapse from '@material-ui/core/Collapse'
import IconButton from '@material-ui/core/IconButton'
import ListItemText from '~/components/List/ListItemText'
import List, { ListItem, ListItemIcon } from 'material-ui/List'
import Avatar from 'material-ui/Avatar'
import Group from 'material-ui-icons/Group'
import Person from 'material-ui-icons/Person'
import ExpandLess from 'material-ui-icons/ExpandLess'
import ExpandMore from 'material-ui-icons/ExpandMore'
import List from '@material-ui/core/List'
import ListItem from '@material-ui/core/ListItem'
import ListItemIcon from '@material-ui/core/ListItemIcon'
import Avatar from '@material-ui/core/Avatar'
import Group from '@material-ui/icons/Group'
import Person from '@material-ui/icons/Person'
import ExpandLess from '@material-ui/icons/ExpandLess'
import ExpandMore from '@material-ui/icons/ExpandMore'
import { type WithStyles } from '~/theme/mui'
import { type Confirmation, type ConfirmationProps } from '~/routes/safe/store/model/confirmation'
@ -55,7 +58,10 @@ const Confirmaitons = openHoc(({
</Avatar>
<ListItemText primary="Threshold" secondary={`${threshold} confirmation${threshold === 1 ? '' : 's'} needed`} />
<ListItemIcon>
{open ? <ExpandLess /> : <ExpandMore />}
{open
? <IconButton disableRipple><ExpandLess /></IconButton>
: <IconButton disableRipple><ExpandMore /></IconButton>
}
</ListItemIcon>
</ListItem>
<Collapse in={open} timeout="auto" unmountOnExit>

View File

@ -3,11 +3,12 @@ import * as React from 'react'
import { List as ImmutableList } from 'immutable'
import Row from '~/components/layout/Row'
import Col from '~/components/layout/Col'
import List, { ListItem } from 'material-ui/List'
import List from '@material-ui/core/List'
import ListItem from '@material-ui/core/ListItem'
import ListItemText from '~/components/List/ListItemText'
import Avatar from 'material-ui/Avatar'
import Group from 'material-ui-icons/Group'
import MailOutline from 'material-ui-icons/MailOutline'
import Avatar from '@material-ui/core/Avatar'
import Group from '@material-ui/icons/Group'
import MailOutline from '@material-ui/icons/MailOutline'
import { type Confirmation } from '~/routes/safe/store/model/confirmation'
import Confirmations from './Confirmations'

View File

@ -3,16 +3,18 @@ import * as React from 'react'
import { List } from 'immutable'
import { connect } from 'react-redux'
import openHoc, { type Open } from '~/components/hoc/OpenHoc'
import ExpandLess from 'material-ui-icons/ExpandLess'
import ExpandMore from 'material-ui-icons/ExpandMore'
import ExpandLess from '@material-ui/icons/ExpandLess'
import ExpandMore from '@material-ui/icons/ExpandMore'
import IconButton from '@material-ui/core/IconButton'
import ListItemText from '~/components/List/ListItemText'
import Row from '~/components/layout/Row'
import { ListItem, ListItemIcon } from 'material-ui/List'
import Avatar from 'material-ui/Avatar'
import AttachMoney from 'material-ui-icons/AttachMoney'
import Atm from 'material-ui-icons/LocalAtm'
import DoneAll from 'material-ui-icons/DoneAll'
import CompareArrows from 'material-ui-icons/CompareArrows'
import ListItem from '@material-ui/core/ListItem'
import ListItemIcon from '@material-ui/core/ListItemIcon'
import Avatar from '@material-ui/core/Avatar'
import AttachMoney from '@material-ui/icons/AttachMoney'
import Atm from '@material-ui/icons/LocalAtm'
import DoneAll from '@material-ui/icons/DoneAll'
import CompareArrows from '@material-ui/icons/CompareArrows'
import Collapsed from '~/routes/safe/component/Transactions/Collapsed'
import { type Transaction } from '~/routes/safe/store/model/transaction'
import Hairline from '~/components/layout/Hairline/index'
@ -61,7 +63,10 @@ class GnoTransaction extends React.PureComponent<Props, {}> {
</Avatar>
<ListItemText primary="Status" secondary={confirmationText} />
<ListItemIcon>
{open ? <ExpandLess /> : <ExpandMore />}
{open
? <IconButton disableRipple><ExpandLess /></IconButton>
: <IconButton disableRipple><ExpandMore /></IconButton>
}
</ListItemIcon>
</ListItem>
</Row>

View File

@ -8,7 +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, { checkReceiptStatus } from '~/wallets/ethTransactions'
import { checkReceiptStatus, calculateGasOf, calculateGasPrice } from '~/wallets/ethTransactions'
export const updateTransaction = (
name: string,
@ -50,9 +50,14 @@ const execTransaction = async (
const CALL = getOperation()
const web3 = getWeb3()
const valueInWei = web3.toWei(txValue, 'ether')
const txData = await gnosisSafe.contract.execTransactionIfApproved.getData(destination, valueInWei, data, CALL, nonce)
return executeTransaction(txData, executor, gnosisSafe.address)
const txData = await gnosisSafe.contract.execTransactionIfApproved.getData(destination, valueInWei, data, CALL, nonce)
const owners = await gnosisSafe.getOwners()
const gas = await calculateGasOf(txData, executor, gnosisSafe.address) + (17000 * owners.length)
const gasPrice = await calculateGasPrice()
return gnosisSafe
.execTransactionIfApproved(destination, valueInWei, data, CALL, nonce, { from: executor, gas, gasPrice })
}
const execConfirmation = async (
@ -66,10 +71,13 @@ const execConfirmation = async (
const CALL = getOperation()
const web3 = getWeb3()
const valueInWei = web3.toWei(txValue, 'ether')
const txConfirmationData =
await gnosisSafe.contract.approveTransactionWithParameters.getData(txDestination, valueInWei, data, CALL, nonce)
const txData = await gnosisSafe.contract
.approveTransactionWithParameters.getData(txDestination, valueInWei, data, CALL, nonce)
const gas = await calculateGasOf(txData, executor, gnosisSafe.address)
const gasPrice = await calculateGasPrice()
return executeTransaction(txConfirmationData, executor, gnosisSafe.address)
return gnosisSafe
.approveTransactionWithParameters(txDestination, valueInWei, data, CALL, nonce, { from: executor, gas, gasPrice })
}
const updateConfirmations = (confirmations: List<Confirmation>, userAddress: string, txHash: string) =>
@ -116,10 +124,12 @@ export const processTransaction = async (
? await execTransaction(gnosisSafe, txDestination, txValue, nonce, userAddress, data)
: await execConfirmation(gnosisSafe, txDestination, txValue, nonce, userAddress, data)
checkReceiptStatus(txHash)
checkReceiptStatus(txHash.tx)
const confirmationHash = thresholdReached ? EXECUTED_CONFIRMATION_HASH : txHash
const executedConfirmations: List<Confirmation> = updateConfirmations(tx.get('confirmations'), userAddress, confirmationHash)
const confirmationHash =
thresholdReached ? EXECUTED_CONFIRMATION_HASH : txHash.tx
const executedConfirmations: List<Confirmation> =
updateConfirmations(tx.get('confirmations'), userAddress, confirmationHash)
return updateTransaction(
txName,
@ -128,7 +138,7 @@ export const processTransaction = async (
txValue,
userAddress,
executedConfirmations,
thresholdReached ? txHash : '',
thresholdReached ? txHash.tx : '',
safeAddress,
threshold,
data,

View File

@ -1,11 +1,11 @@
// @flow
import * as React from 'react'
import { CircularProgress } from 'material-ui/Progress'
import CircularProgress from '@material-ui/core/CircularProgress'
import Block from '~/components/layout/Block'
import Bold from '~/components/layout/Bold'
import Heading from '~/components/layout/Heading'
import Paragraph from '~/components/layout/Paragraph'
import { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdrawn/withdrawn'
import { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/withdraw'
type FormProps = {
values: Object,
@ -18,7 +18,7 @@ const spinnerStyle = {
const Review = () => ({ values, submitting }: FormProps) => (
<Block>
<Heading tag="h2">Review the Withdrawn Operation</Heading>
<Heading tag="h2">Review the Withdraw Operation</Heading>
<Paragraph align="left">
<Bold>Destination: </Bold> {values[DESTINATION_PARAM]}
</Paragraph>

View File

@ -3,7 +3,7 @@ import { storiesOf } from '@storybook/react'
import * as React from 'react'
import Stepper from '~/components/Stepper'
import styles from '~/components/layout/PageFrame/index.scss'
import WithdrawnForm from './index'
import WithdrawForm from './index'
const FrameDecorator = story => (
@ -14,16 +14,16 @@ const FrameDecorator = story => (
storiesOf('Components', module)
.addDecorator(FrameDecorator)
.add('WithdrawnForm', () => (
.add('WithdrawForm', () => (
<Stepper
finishedTransaction={false}
finishedButton={<Stepper.FinishButton title="RESET" />}
onSubmit={() => {}}
steps={['Fill Withdrawn Form', 'Review Withdrawn']}
steps={['Fill Withdraw Form', 'Review Withdraw']}
onReset={() => {}}
>
<Stepper.Page dailyLimit={10} spentToday={7}>
{ WithdrawnForm }
{ WithdrawForm }
</Stepper.Page>
</Stepper>
))

View File

@ -5,7 +5,7 @@ import TextField from '~/components/forms/TextField'
import { composeValidators, inLimit, mustBeFloat, required, greaterThan, mustBeEthereumAddress } from '~/components/forms/validator'
import Block from '~/components/layout/Block'
import Heading from '~/components/layout/Heading'
import { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdrawn/withdrawn'
import { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/withdraw'
export const CONFIRMATIONS_ERROR = 'Number of confirmations can not be higher than the number of owners'
@ -24,10 +24,10 @@ type Props = {
spentToday: number,
}
const WithdrawnForm = ({ limit, spentToday }: Props) => () => (
const WithdrawForm = ({ limit, spentToday }: Props) => () => (
<Block margin="md">
<Heading tag="h2" margin="lg">
Withdrawn Funds
Withdraw Funds
</Heading>
<Heading tag="h4" margin="lg">
{`Daily limit ${limit} ETH (spent today: ${spentToday} ETH)`}
@ -55,4 +55,4 @@ const WithdrawnForm = ({ limit, spentToday }: Props) => () => (
</Block>
)
export default WithdrawnForm
export default WithdrawForm

View File

@ -0,0 +1,12 @@
// @flow
import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions'
type FetchTransactions = typeof fetchTransactions
export type Actions = {
fetchTransactions: FetchTransactions,
}
export default {
fetchTransactions,
}

View File

@ -3,17 +3,19 @@ import * as React from 'react'
import { connect } from 'react-redux'
import Stepper from '~/components/Stepper'
import { type DailyLimit } from '~/routes/safe/store/model/dailyLimit'
import { type Safe } from '~/routes/safe/store/model/safe'
import selector, { type SelectorProps } from './selector'
import withdrawn from './withdrawn'
import WithdrawnForm from './WithdrawnForm'
import withdraw from './withdraw'
import WithdrawForm from './WithdrawForm'
import Review from './Review'
import actions, { type Actions } from './actions'
const getSteps = () => [
'Fill Withdrawn Form', 'Review Withdrawn',
'Fill Withdraw Form', 'Review Withdraw',
]
type Props = SelectorProps & {
safeAddress: string,
type Props = SelectorProps & Actions & {
safe: Safe,
dailyLimit: DailyLimit,
}
@ -23,15 +25,17 @@ type State = {
export const SEE_TXS_BUTTON_TEXT = 'RESET'
class Withdrawn extends React.Component<Props, State> {
class Withdraw extends React.Component<Props, State> {
state = {
done: false,
}
onWithdrawn = async (values: Object) => {
onWithdraw = async (values: Object) => {
try {
const { safeAddress, userAddress } = this.props
await withdrawn(values, safeAddress, userAddress)
const { safe, userAddress, fetchTransactions } = this.props
await withdraw(values, safe, userAddress)
fetchTransactions()
this.setState({ done: true })
} catch (error) {
this.setState({ done: false })
@ -55,12 +59,12 @@ class Withdrawn extends React.Component<Props, State> {
<Stepper
finishedTransaction={done}
finishedButton={finishedButton}
onSubmit={this.onWithdrawn}
onSubmit={this.onWithdraw}
steps={steps}
onReset={this.onReset}
>
<Stepper.Page limit={dailyLimit.get('value')} spentToday={dailyLimit.get('spentToday')}>
{ WithdrawnForm }
{ WithdrawForm }
</Stepper.Page>
<Stepper.Page>
{ Review }
@ -71,5 +75,5 @@ class Withdrawn extends React.Component<Props, State> {
}
}
export default connect(selector)(Withdrawn)
export default connect(selector, actions)(Withdraw)

View File

@ -0,0 +1,11 @@
// @flow
import { createStructuredSelector } from 'reselect'
import { userAccountSelector } from '~/wallets/store/selectors/index'
export type SelectorProps = {
userAddress: userAccountSelector,
}
export default createStructuredSelector({
userAddress: userAccountSelector,
})

View File

@ -0,0 +1,76 @@
// @flow
import { getWeb3 } from '~/wallets/getWeb3'
import { getGnosisSafeContract, getCreateDailyLimitExtensionContract } from '~/wallets/safeContracts'
import { type DailyLimitProps } from '~/routes/safe/store/model/dailyLimit'
import { checkReceiptStatus, calculateGasOf, calculateGasPrice } from '~/wallets/ethTransactions'
import { type Safe } from '~/routes/safe/store/model/safe'
import { buildExecutedConfirmationFrom, storeTransaction } from '~/routes/safe/component/AddTransaction/createTransactions'
export const LIMIT_POSITION = 0
export const SPENT_TODAY_POS = 1
export const DESTINATION_PARAM = 'destination'
export const VALUE_PARAM = 'ether'
const getDailyLimitModuleFrom = async (safeAddress) => {
const web3 = getWeb3()
const gnosisSafe = getGnosisSafeContract(web3).at(safeAddress)
const modules = await gnosisSafe.getModules()
const dailyAddress = modules[0]
const dailyLimitModule = getCreateDailyLimitExtensionContract(web3).at(dailyAddress)
if (await dailyLimitModule.manager.call() !== gnosisSafe.address) {
throw new Error('Using an extension of different safe')
}
return dailyLimitModule
}
export const getDailyLimitFrom = async (safeAddress: string, tokenAddress: number): Promise<DailyLimitProps> => {
const web3 = getWeb3()
const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress)
const dailyLimitEth = await dailyLimitModule.dailyLimits(tokenAddress)
const limit = web3.fromWei(dailyLimitEth[LIMIT_POSITION].valueOf(), 'ether').toString()
const spentToday = web3.fromWei(dailyLimitEth[SPENT_TODAY_POS].valueOf(), 'ether').toString()
return { value: Number(limit), spentToday: Number(spentToday) }
}
export const getDailyLimitAddress = async (safeAddress: string) => {
const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress)
return dailyLimitModule.address
}
export const getEditDailyLimitData = async (safeAddress: string, token: string, dailyLimit: string) => {
const web3 = getWeb3()
const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress)
const dailyLimitInWei = web3.toWei(dailyLimit, 'ether')
return dailyLimitModule.contract.changeDailyLimit.getData(token, dailyLimitInWei)
}
const withdraw = async (values: Object, safe: Safe, userAccount: string): Promise<void> => {
const web3 = getWeb3()
const safeAddress = safe.get('address')
const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress)
const destination = values[DESTINATION_PARAM]
const valueInEth = values[VALUE_PARAM]
const value = web3.toWei(valueInEth, 'ether')
const dailyLimitData = dailyLimitModule.contract.executeDailyLimit.getData(0, destination, value)
const gas = await calculateGasOf(dailyLimitData, userAccount, dailyLimitModule.address)
const gasPrice = await calculateGasPrice()
const txHash = await dailyLimitModule.executeDailyLimit(0, destination, value, { from: userAccount, gas, gasPrice })
checkReceiptStatus(txHash.tx)
const nonce = Date.now()
const executedConfirmations: List<Confirmation> = buildExecutedConfirmationFrom(safe.get('owners'), userAccount)
return storeTransaction(`Withdraw movement of ${valueInEth}`, nonce, destination, valueInEth, userAccount, executedConfirmations, txHash.tx, safeAddress, safe.get('threshold'), '0x')
}
export default withdraw

View File

@ -0,0 +1,30 @@
// @flow
import { aNewStore } from '~/store'
import { addEtherTo } from '~/test/utils/etherMovements'
import { aDeployedSafe, executeWithdrawOn } from '~/routes/safe/store/test/builder/deployedSafe.builder'
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
import { safeSelector } from '~/routes/safe/store/selectors/index'
describe('Safe Blockchain Test', () => {
let store
beforeEach(async () => {
store = aNewStore()
})
it('wihdrawn should return revert error if exceeded dailyLimit', async () => {
// GIVEN
const dailyLimitValue = 0.30
const safeAddress = await aDeployedSafe(store, dailyLimitValue)
await addEtherTo(safeAddress, '0.7')
const value = 0.15
// WHEN
const match: Match = buildMathPropsFrom(safeAddress)
const safe = safeSelector(store.getState(), { match })
await executeWithdrawOn(safe, value)
await executeWithdrawOn(safe, value)
// THEN
expect(executeWithdrawOn(safeAddress, value)).rejects.toThrow('VM Exception while processing transaction: revert')
})
})

View File

@ -1,52 +0,0 @@
// @flow
import { getWeb3 } from '~/wallets/getWeb3'
import { getGnosisSafeContract, getCreateDailyLimitExtensionContract } from '~/wallets/safeContracts'
import { type DailyLimitProps } from '~/routes/safe/store/model/dailyLimit'
import executeTransaction, { checkReceiptStatus } from '~/wallets/ethTransactions'
export const LIMIT_POSITION = 0
export const SPENT_TODAY_POS = 1
export const DESTINATION_PARAM = 'destination'
export const VALUE_PARAM = 'ether'
const getDailyLimitModuleFrom = async (safeAddress) => {
const web3 = getWeb3()
const gnosisSafe = getGnosisSafeContract(web3).at(safeAddress)
const modules = await gnosisSafe.getModules()
const dailyAddress = modules[0]
const dailyLimitModule = getCreateDailyLimitExtensionContract(web3).at(dailyAddress)
if (await dailyLimitModule.manager.call() !== gnosisSafe.address) {
throw new Error('Using an extension of different safe')
}
return dailyLimitModule
}
export const getDailyLimitFrom = async (safeAddress: string, tokenAddress: number): Promise<DailyLimitProps> => {
const web3 = getWeb3()
const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress)
const dailyLimitEth = await dailyLimitModule.dailyLimits(tokenAddress)
const limit = web3.fromWei(dailyLimitEth[LIMIT_POSITION].valueOf(), 'ether').toString()
const spentToday = web3.fromWei(dailyLimitEth[SPENT_TODAY_POS].valueOf(), 'ether').toString()
return { value: Number(limit), spentToday: Number(spentToday) }
}
const withdrawn = async (values: Object, safeAddress: string, userAccount: string): Promise<void> => {
const web3 = getWeb3()
const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress)
const destination = values[DESTINATION_PARAM]
const value = web3.toWei(values[VALUE_PARAM], 'ether')
const dailyLimitData = dailyLimitModule.contract.executeDailyLimit.getData(0, destination, value)
const txHash = await executeTransaction(dailyLimitData, userAccount, dailyLimitModule.address)
checkReceiptStatus(txHash)
}
export default withdrawn

View File

@ -1,26 +0,0 @@
// @flow
import { aNewStore } from '~/store'
import { addEtherTo } from '~/test/addEtherTo'
import { aDeployedSafe, executeWithdrawnOn } from '~/routes/safe/store/test/builder/deployedSafe.builder'
describe('Safe Blockchain Test', () => {
let store
beforeEach(async () => {
store = aNewStore()
})
it('wihdrawn should return revert error if exceeded dailyLimit', async () => {
// GIVEN
const dailyLimitValue = 0.30
const safeAddress = await aDeployedSafe(store, dailyLimitValue)
await addEtherTo(safeAddress, '0.7')
const value = 0.15
// WHEN
await executeWithdrawnOn(safeAddress, value)
await executeWithdrawnOn(safeAddress, value)
// THEN
expect(executeWithdrawnOn(safeAddress, value)).rejects.toThrow('VM Exception while processing transaction: revert')
})
})

View File

@ -18,7 +18,9 @@ class SafeView extends React.PureComponent<Props> {
if (!safe) { return }
const safeAddress: string = safe.get('address')
fetchBalance(safeAddress)
fetchSafe(safe)
if (safe) {
fetchSafe(safe)
}
}, 1500)
}
@ -30,13 +32,13 @@ class SafeView extends React.PureComponent<Props> {
render() {
const {
safe, provider, balance, granted,
safe, provider, balance, granted, userAddress,
} = this.props
return (
<Page>
{ granted
? <Layout balance={balance} provider={provider} safe={safe} />
? <Layout balance={balance} provider={provider} safe={safe} userAddress={userAddress} />
: <NoRights />
}
</Page>

View File

@ -12,6 +12,7 @@ export type SelectorProps = {
safe: SafeSelectorProps,
provider: string,
balance: string,
userAddress: string,
}
export const grantedSelector: Selector<GlobalState, RouterProps, boolean> = createSelector(
@ -40,4 +41,5 @@ export default createStructuredSelector({
provider: providerNameSelector,
balance: balanceSelector,
granted: grantedSelector,
userAddress: userAccountSelector,
})

View File

@ -5,7 +5,7 @@ import { type GlobalState } from '~/store/index'
import { makeOwner } from '~/routes/safe/store/model/owner'
import { type SafeProps, type Safe, makeSafe } from '~/routes/safe/store/model/safe'
import { makeDailyLimit } from '~/routes/safe/store/model/dailyLimit'
import { getDailyLimitFrom } from '~/routes/safe/component/Withdrawn/withdrawn'
import { getDailyLimitFrom } from '~/routes/safe/component/Withdraw/withdraw'
import { getGnosisSafeInstanceAt } from '~/wallets/safeContracts'
import updateSafe from '~/routes/safe/store/actions/updateSafe'
import { getOwners } from '~/utils/localStorage'

View File

@ -24,7 +24,8 @@ action: AddSafeType
export default handleActions({
[UPDATE_SAFE]: (state: State, action: ActionType<typeof updateSafe>): State =>
state.set(action.payload.get('address'), action.payload),
state.update(action.payload.get('address'), prevSafe =>
(prevSafe.equals(action.payload) ? prevSafe : action.payload)),
[UPDATE_SAFES]: (state: State, action: ActionType<typeof updateSafes>): State =>
action.payload,
[ADD_SAFE]: (state: State, action: ActionType<typeof addSafe>): State => {

View File

@ -75,7 +75,9 @@ export const safeSelector: Selector<GlobalState, RouterProps, SafeSelectorProps>
return undefined
}
return safes.get(address)
const safe = safes.get(address)
return safe
},
)

View File

@ -2,7 +2,7 @@
import { BALANCE_REDUCER_ID } from '~/routes/safe/store/reducer/balances'
import fetchBalance from '~/routes/safe/store/actions/fetchBalance'
import { aNewStore } from '~/store'
import { addEtherTo } from '~/test/addEtherTo'
import { addEtherTo } from '~/test/utils/etherMovements'
import { aDeployedSafe } from './builder/deployedSafe.builder'
const balanceReducerTests = () => {

View File

@ -1,7 +1,7 @@
// @flow
import addBalance from '~/routes/safe/store/actions/addBalance'
import { aNewStore } from '~/store'
import { buildMathPropsFrom } from '~/test/buildReactRouterProps'
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
import { balanceSelector } from '../selectors'
const balanceSelectorTests = () => {

View File

@ -11,8 +11,9 @@ import { sleep } from '~/utils/timer'
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 withdraw, { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/withdraw'
import { promisify } from '~/utils/promisify'
import { type Safe } from '~/routes/safe/store/model/safe'
export const renderSafe = async (localStore: Store<GlobalState>) => {
const provider = await getProviderInfo()
@ -68,7 +69,7 @@ const deploySafe = async (safe: React$Component<{}>, dailyLimit: string, thresho
// giving some time to the component for updating its state with safe
// before destroying its context
await sleep(9000)
await sleep(12000)
// THEN
const deployed = TestUtils.findRenderedDOMComponentWithClass(safe, DEPLOYED_COMPONENT_ID)
@ -94,7 +95,7 @@ export const aDeployedSafe = async (
return deployedSafe.logs[1].args.proxy
}
export const executeWithdrawnOn = async (safeAddress: string, value: number) => {
export const executeWithdrawOn = async (safe: Safe, value: number) => {
const providerInfo = await getProviderInfo()
const userAddress = providerInfo.account
@ -103,5 +104,5 @@ export const executeWithdrawnOn = async (safeAddress: string, value: number) =>
[VALUE_PARAM]: `${value}`,
}
return withdrawn(values, safeAddress, userAddress)
return withdraw(values, safe, userAddress)
}

View File

@ -4,7 +4,7 @@ import { type Match } from 'react-router-dom'
import { SAFE_REDUCER_ID } from '~/routes/safe/store/reducer/safe'
import { type Safe } from '~/routes/safe/store/model/safe'
import { SafeFactory } from '~/routes/safe/store/test/builder/safe.builder'
import { buildMathPropsFrom } from '~/test/buildReactRouterProps'
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
import { getProviderInfo } from '~/wallets/getWeb3'
import { grantedSelector } from '~/routes/safe/container/selector'
import { makeProvider } from '~/wallets/store/model/provider'

View File

@ -4,7 +4,7 @@ import { type Match } from 'react-router-dom'
import { SAFE_REDUCER_ID } from '~/routes/safe/store/reducer/safe'
import { type Safe } from '~/routes/safe/store/model/safe'
import { SafeFactory } from '~/routes/safe/store/test/builder/safe.builder'
import { buildMathPropsFrom } from '~/test/buildReactRouterProps'
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
import { safeSelector } from '../selectors'
const safeSelectorTests = () => {

View File

@ -5,7 +5,7 @@ import { Provider } from 'react-redux'
import { ConnectedRouter } from 'react-router-redux'
import Button from '~/components/layout/Button'
import { aNewStore, history } from '~/store'
import { addEtherTo } from '~/test/addEtherTo'
import { addEtherTo } from '~/test/utils/etherMovements'
import { aDeployedSafe } from '~/routes/safe/store/test/builder/deployedSafe.builder'
import { SAFELIST_ADDRESS } from '~/routes/routes'
import SafeView from '~/routes/safe/component/Safe'
@ -17,8 +17,9 @@ import { getBalanceInEtherOf } from '~/wallets/getWeb3'
import { sleep } from '~/utils/timer'
import { ADD_MULTISIG_BUTTON_TEXT } from '~/routes/safe/component/Safe/MultisigTx'
import { safeTransactionsSelector } from '~/routes/safe/store/selectors/index'
import { MOVE_FUNDS_INDEX } from '~/test/builder/safe.dom.utils'
describe('React DOM TESTS > Withdrawn funds from safe', () => {
describe('React DOM TESTS > Withdraw funds from safe', () => {
let SafeDom
let store
let address
@ -44,12 +45,13 @@ describe('React DOM TESTS > Withdrawn funds from safe', () => {
const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView)
// $FlowFixMe
const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button)
const addTxButton = buttons[3]
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])
const buttons = TestUtils.scryRenderedDOMComponentsWithTag(Safe, 'button')
const addTxButton = buttons[MOVE_FUNDS_INDEX]
expect(addTxButton.getElementsByTagName('span')[0].innerHTML).toEqual(ADD_MULTISIG_BUTTON_TEXT)
await sleep(1800) // Give time to enable Add button
TestUtils.Simulate.click(addTxButton)
await sleep(1800) // Give time to render the form
const AddTransaction = TestUtils.findRenderedComponentWithType(SafeDom, AddTransactionComponent)
// $FlowFixMe
@ -75,6 +77,7 @@ describe('React DOM TESTS > Withdrawn funds from safe', () => {
const addTransactionButtons = TestUtils.scryRenderedComponentsWithType(AddTransaction, Button)
expect(addTransactionButtons.length).toBe(1)
const visitTxsButton = addTransactionButtons[0]
expect(visitTxsButton.props.children).toEqual(SEE_TXS_BUTTON_TEXT)
// NOW it is time to check the just executed transaction

View File

@ -8,7 +8,7 @@ import { aDeployedSafe } from '~/routes/safe/store/test/builder/deployedSafe.bui
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'
import { createMultisigTxFilling, addFundsTo, checkBalanceOf, listTxsOf, getListItemsFrom, expandTransactionOf, getTransactionFromReduxStore, confirmOwners } from '~/routes/safe/test/testMultisig'
import { sleep } from '~/utils/timer'
const renderSafe = localStore => (
@ -46,17 +46,17 @@ describe('React DOM TESTS > Multisig transactions from safe [3 owners & 1 thresh
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 listItems = getListItemsFrom(SafeDom)
const status = paragraphs[2].innerHTML
const status = listItems[2].props.secondary
expect(status).toBe('Already executed')
const confirmed = paragraphs[3].innerHTML
const confirmed = listItems[3].props.secondary
const tx = getTransactionFromReduxStore(store, address)
if (!tx) throw new Error()
expect(confirmed).toBe(tx.get('tx'))
const ownerTx = paragraphs[6].innerHTML
const ownerTx = listItems[6].props.secondary
expect(ownerTx).toBe('Confirmation hash: EXECUTED')
})
})

View File

@ -14,7 +14,7 @@ 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'
import { createMultisigTxFilling, addFundsTo, checkBalanceOf, listTxsOf, getListItemsFrom, expandTransactionOf, getTransactionFromReduxStore, confirmOwners } from '~/routes/safe/test/testMultisig'
const renderSafe = localStore => (
TestUtils.renderIntoDocument((
@ -74,12 +74,12 @@ describe('React DOM TESTS > Multisig transactions from safe [3 owners & 3 thresh
await checkBalanceOf(address, '0.1')
await listTxsOf(SafeDom)
sleep(1400)
const paragraphs = getTagFromTransaction(SafeDom, 'p')
const listItems = getListItemsFrom(SafeDom)
const status = paragraphs[2].innerHTML
const status = listItems[2].props.secondary
expect(status).toBe('1 of the 3 confirmations needed')
const confirmed = paragraphs[3].innerHTML
const confirmed = listItems[3].props.secondary
expect(confirmed).toBe('Waiting for the rest of confirmations')
await expandTransactionOf(SafeDom, 3, 3)
@ -91,12 +91,12 @@ describe('React DOM TESTS > Multisig transactions from safe [3 owners & 3 thresh
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 listItemsExecuted = getListItemsFrom(SafeDom)
const statusExecuted = paragraphsExecuted[2].innerHTML
const statusExecuted = listItemsExecuted[2].props.secondary
expect(statusExecuted).toBe('Already executed')
const confirmedExecuted = paragraphsExecuted[3].innerHTML
const confirmedExecuted = listItemsExecuted[3].props.secondary
const tx = getTransactionFromReduxStore(store, address)
if (!tx) throw new Error()
expect(confirmedExecuted).toBe(tx.get('tx'))

View File

@ -8,7 +8,7 @@ import { promisify } from '~/utils/promisify'
import { processTransaction } from '~/routes/safe/component/Transactions/processTransactions'
import { confirmationsTransactionSelector, safeSelector, safeTransactionsSelector } from '~/routes/safe/store/selectors/index'
import { getTransactionFromReduxStore } from '~/routes/safe/test/testMultisig'
import { buildMathPropsFrom } from '~/test/buildReactRouterProps'
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
import { createTransaction } from '~/routes/safe/component/AddTransaction/createTransactions'
import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions'
import { type GlobalState } from '~/store/index'

View File

@ -8,7 +8,7 @@ import { promisify } from '~/utils/promisify'
import { processTransaction } from '~/routes/safe/component/Transactions/processTransactions'
import { confirmationsTransactionSelector, safeSelector, safeTransactionsSelector } from '~/routes/safe/store/selectors/index'
import { getTransactionFromReduxStore } from '~/routes/safe/test/testMultisig'
import { buildMathPropsFrom } from '~/test/buildReactRouterProps'
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
import { createTransaction } from '~/routes/safe/component/AddTransaction/createTransactions'
import { getGnosisSafeContract } from '~/wallets/safeContracts'
import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions'

View File

@ -5,20 +5,23 @@ import { Provider } from 'react-redux'
import { ConnectedRouter } from 'react-router-redux'
import Button from '~/components/layout/Button'
import { aNewStore, history } from '~/store'
import { addEtherTo } from '~/test/addEtherTo'
import { aDeployedSafe, executeWithdrawnOn } from '~/routes/safe/store/test/builder/deployedSafe.builder'
import { addEtherTo } from '~/test/utils/etherMovements'
import { aDeployedSafe, executeWithdrawOn } from '~/routes/safe/store/test/builder/deployedSafe.builder'
import { SAFELIST_ADDRESS } from '~/routes/routes'
import SafeView from '~/routes/safe/component/Safe'
import AppRoutes from '~/routes'
import { WITHDRAWN_BUTTON_TEXT } from '~/routes/safe/component/Safe/DailyLimit'
import WithdrawnComponent, { SEE_TXS_BUTTON_TEXT } from '~/routes/safe/component/Withdrawn'
import { WITHDRAW_BUTTON_TEXT } from '~/routes/safe/component/Safe/DailyLimit'
import WithdrawComponent, { SEE_TXS_BUTTON_TEXT } from '~/routes/safe/component/Withdraw'
import { getBalanceInEtherOf } from '~/wallets/getWeb3'
import { sleep } from '~/utils/timer'
import { getDailyLimitFrom } from '~/routes/safe/component/Withdrawn/withdrawn'
import { getDailyLimitFrom } from '~/routes/safe/component/Withdraw/withdraw'
import { type DailyLimitProps } from '~/routes/safe/store/model/dailyLimit'
import { ADD_MULTISIG_BUTTON_TEXT } from '~/routes/safe/component/Safe/MultisigTx'
import { WITHDRAW_INDEX, MOVE_FUNDS_INDEX } from '~/test/builder/safe.dom.utils'
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
import { safeSelector } from '~/routes/safe/store/selectors/index'
describe('React DOM TESTS > Withdrawn funds from safe', () => {
describe('React DOM TESTS > Withdraw funds from safe', () => {
let SafeDom
let store
let address
@ -38,29 +41,29 @@ describe('React DOM TESTS > Withdrawn funds from safe', () => {
))
})
it('should withdrawn funds under dailyLimit without needing confirmations', async () => {
it('should withdraw 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
const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button)
const withdrawnButton = buttons[2]
expect(withdrawnButton.props.children).toEqual(WITHDRAWN_BUTTON_TEXT)
TestUtils.Simulate.click(TestUtils.scryRenderedDOMComponentsWithTag(withdrawnButton, 'button')[0])
const buttons = TestUtils.scryRenderedDOMComponentsWithTag(Safe, 'button')
const addWithdrawButton = buttons[WITHDRAW_INDEX]
expect(addWithdrawButton.getElementsByTagName('span')[0].innerHTML).toEqual(WITHDRAW_BUTTON_TEXT)
TestUtils.Simulate.click(addWithdrawButton)
await sleep(4000)
const Withdrawn = TestUtils.findRenderedComponentWithType(SafeDom, WithdrawnComponent)
const Withdraw = TestUtils.findRenderedComponentWithType(SafeDom, WithdrawComponent)
// $FlowFixMe
const inputs = TestUtils.scryRenderedDOMComponentsWithTag(Withdrawn, 'input')
const inputs = TestUtils.scryRenderedDOMComponentsWithTag(Withdraw, 'input')
const amountInEth = inputs[0]
const toAddress = inputs[1]
TestUtils.Simulate.change(amountInEth, { target: { value: '0.01' } })
TestUtils.Simulate.change(toAddress, { target: { value: store.getState().providers.account } })
// $FlowFixMe
const form = TestUtils.findRenderedDOMComponentWithTag(Withdrawn, 'form')
const form = TestUtils.findRenderedDOMComponentWithTag(Withdraw, 'form')
TestUtils.Simulate.submit(form) // fill the form
TestUtils.Simulate.submit(form) // confirming data
@ -70,8 +73,8 @@ describe('React DOM TESTS > Withdrawn funds from safe', () => {
expect(safeBalance).toBe('0.09')
// $FlowFixMe
const withdrawnButtons = TestUtils.scryRenderedComponentsWithType(Withdrawn, Button)
const visitTxsButton = withdrawnButtons[0]
const withdrawButtons = TestUtils.scryRenderedComponentsWithType(Withdraw, Button)
const visitTxsButton = withdrawButtons[0]
expect(visitTxsButton.props.children).toEqual(SEE_TXS_BUTTON_TEXT)
})
@ -79,10 +82,10 @@ describe('React DOM TESTS > Withdrawn funds from safe', () => {
// add funds to safe
await addEtherTo(address, '0.1')
// GIVEN in beforeEach
// WHEN
await executeWithdrawnOn(address, 0.01)
await executeWithdrawnOn(address, 0.01)
const match: Match = buildMathPropsFrom(address)
const safe = safeSelector(store.getState(), { match })
await executeWithdrawOn(safe, 0.01)
await executeWithdrawOn(safe, 0.01)
const ethAddress = 0
const dailyLimit: DailyLimitProps = await getDailyLimitFrom(address, ethAddress)
@ -95,28 +98,28 @@ describe('React DOM TESTS > Withdrawn funds from safe', () => {
it('add multisig txs button disabled when balance is 0', async () => {
const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView)
// $FlowFixMe
const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button)
const addTxButton = buttons[3]
expect(addTxButton.props.children).toEqual(ADD_MULTISIG_BUTTON_TEXT)
expect(addTxButton.props.disabled).toBe(true)
const buttons = TestUtils.scryRenderedDOMComponentsWithTag(Safe, 'button')
const addTxButton = buttons[MOVE_FUNDS_INDEX]
expect(addTxButton.getElementsByTagName('span')[0].innerHTML).toEqual(ADD_MULTISIG_BUTTON_TEXT)
expect(addTxButton.hasAttribute('disabled')).toBe(true)
await addEtherTo(address, '0.1')
await sleep(1800)
expect(addTxButton.props.disabled).toBe(false)
expect(addTxButton.hasAttribute('disabled')).toBe(false)
})
it('Withdrawn button disabled when balance is 0', async () => {
it('Withdraw button disabled when balance is 0', async () => {
const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView)
// $FlowFixMe
const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button)
const addTxButton = buttons[2]
expect(addTxButton.props.children).toEqual(WITHDRAWN_BUTTON_TEXT)
expect(addTxButton.props.disabled).toBe(true)
const buttons = TestUtils.scryRenderedDOMComponentsWithTag(Safe, 'button')
const addWithdrawButton = buttons[WITHDRAW_INDEX]
expect(addWithdrawButton.getElementsByTagName('span')[0].innerHTML).toEqual(WITHDRAW_BUTTON_TEXT)
expect(addWithdrawButton.hasAttribute('disabled')).toBe(true)
await addEtherTo(address, '0.1')
await sleep(1800)
expect(addTxButton.props.disabled).toBe(false)
expect(addWithdrawButton.hasAttribute('disabled')).toBe(false)
})
})

View File

@ -2,14 +2,15 @@
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 { addEtherTo } from '~/test/utils/etherMovements'
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'
import { type GlobalState } from '~/store/index'
import ListItemText from '~/components/List/ListItemText'
import { MOVE_FUNDS_INDEX, LIST_TXS_INDEX } from '~/test/builder/safe.dom.utils'
export const createMultisigTxFilling = async (
SafeDom: React$Component<any, any>,
@ -47,30 +48,31 @@ export const addFundsTo = async (SafeDom: React$Component<any, any>, destination
const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView)
// $FlowFixMe
const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button)
const addTxButton = buttons[3]
expect(addTxButton.props.children).toEqual(ADD_MULTISIG_BUTTON_TEXT)
const buttons = TestUtils.scryRenderedDOMComponentsWithTag(Safe, 'button')
const addTxButton = buttons[MOVE_FUNDS_INDEX]
expect(addTxButton.getElementsByTagName('span')[0].innerHTML).toEqual(ADD_MULTISIG_BUTTON_TEXT)
await sleep(1800) // Give time to enable Add button
TestUtils.Simulate.click(TestUtils.scryRenderedDOMComponentsWithTag(addTxButton, 'button')[0])
TestUtils.Simulate.click(addTxButton)
}
export const listTxsOf = (SafeDom: React$Component<any, any>) => {
const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView)
// $FlowFixMe
const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button)
const seeTx = buttons[4]
expect(seeTx.props.children).toEqual(SEE_MULTISIG_BUTTON_TEXT)
TestUtils.Simulate.click(TestUtils.scryRenderedDOMComponentsWithTag(seeTx, 'button')[0])
const buttons = TestUtils.scryRenderedDOMComponentsWithTag(Safe, 'button')
const seeTx = buttons[LIST_TXS_INDEX]
expect(seeTx.getElementsByTagName('span')[0].innerHTML).toEqual(SEE_MULTISIG_BUTTON_TEXT)
TestUtils.Simulate.click(seeTx)
}
export const getTagFromTransaction = (SafeDom: React$Component<any, any>, tag: string) => {
export const getListItemsFrom = (SafeDom: React$Component<any, any>) => {
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)
return TestUtils.scryRenderedComponentsWithType(Transaction, ListItemText)
}
export const expandTransactionOf = async (
@ -78,15 +80,15 @@ export const expandTransactionOf = async (
numOwners: number,
safeThreshold: number,
) => {
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)
const listItems = getListItemsFrom(SafeDom)
TestUtils.Simulate.click(TestUtils.scryRenderedDOMComponentsWithTag(listItems[2], 'p')[0]) // expanded
await sleep(2500) // Time to expand
const listItemsExpanded = getListItemsFrom(SafeDom)
const threshold = listItemsExpanded[5]
expect(threshold.props.secondary).toContain(`confirmation${safeThreshold === 1 ? '' : 's'} needed`)
TestUtils.Simulate.click(TestUtils.scryRenderedDOMComponentsWithTag(threshold, 'p')[0]) // expanded
await sleep(2500) // Time to expand
expect(listItemsExpanded.length).toBe(listItems.length + numOwners)
}
export const getTransactionFromReduxStore = (store: Store<GlobalState>, address: string, index: number = 0) => {
@ -96,10 +98,17 @@ export const getTransactionFromReduxStore = (store: Store<GlobalState>, address:
}
export const confirmOwners = async (SafeDom: React$Component<any, any>, ...statusses: string[]) => {
const paragraphsWithOwners = getTagFromTransaction(SafeDom, 'h3')
const Transactions = TestUtils.findRenderedComponentWithType(SafeDom, TransactionsComponent)
if (!Transactions) throw new Error()
const Transaction = TestUtils.findRenderedComponentWithType(Transactions, TransactionComponent)
if (!Transaction) throw new Error()
const listItems = TestUtils.scryRenderedComponentsWithType(Transaction, ListItemText)
for (let i = 0; i < statusses.length; i += 1) {
const ownerIndex = i + 6
const ownerParagraph = paragraphsWithOwners[ownerIndex].innerHTML
const ownerParagraph = listItems[ownerIndex].props.primary
expect(statusses[i]).toEqual(ownerParagraph)
}
}

View File

@ -59,7 +59,7 @@ describe('React DOM TESTS > Create Safe form', () => {
// giving some time to the component for updating its state with safe
// before destroying its context
await sleep(6000)
await sleep(9000)
// THEN
const deployed = TestUtils.findRenderedDOMComponentWithClass(open, DEPLOYED_COMPONENT_ID)

View File

@ -1,10 +0,0 @@
// @flow
import { getWeb3 } from '~/wallets/getWeb3'
import { promisify } from '~/utils/promisify'
export const addEtherTo = async (address: string, eth: string) => {
const web3 = getWeb3()
const accounts = await promisify(cb => web3.eth.getAccounts(cb))
const txData = { from: accounts[0], to: address, value: web3.toWei(eth, 'ether') }
return promisify(cb => web3.eth.sendTransaction(txData, cb))
}

Some files were not shown because too many files have changed in this diff Show More