Merge pull request #25 from gnosis/feature/WA-238-withdrawn-form-component

WA-238 Daily limit UI changes (React components and tests)
This commit is contained in:
Adolfo Panizo 2018-05-16 09:26:13 +02:00 committed by GitHub
commit 8542a25941
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
79 changed files with 94970 additions and 25962 deletions

View File

@ -0,0 +1,2 @@
// @flow
jest.setTimeout(30000)

View File

@ -87,7 +87,7 @@
"storybook-host": "^4.1.5",
"storybook-router": "^0.3.3",
"style-loader": "^0.20.2",
"truffle": "4.1.5",
"truffle": "4.1.8",
"truffle-contract": "^1.1.8",
"truffle-solidity-loader": "0.0.8",
"uglifyjs-webpack-plugin": "^1.2.2",
@ -113,6 +113,7 @@
"collectCoverageFrom": [
"src/**/*.{js,jsx}"
],
"setupTestFrameworkScriptFile": "<rootDir>/config/jest/jest.setup.js",
"setupFiles": [
"<rootDir>/config/webpack.config.test.js",
"<rootDir>/config/polyfills.js",

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

View File

@ -0,0 +1,666 @@
{
"contractName": "DelegateConstructorProxy",
"abi": [
{
"constant": true,
"inputs": [],
"name": "proxyType",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "implementation",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"name": "_masterCopy",
"type": "address"
},
{
"name": "initializer",
"type": "bytes"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"payable": true,
"stateMutability": "payable",
"type": "fallback"
}
],
"bytecode": "0x608060405234801561001057600080fd5b5060405161026d38038061026d83398101806040528101908080519060200190929190805182019291905050508160008173ffffffffffffffffffffffffffffffffffffffff161415151561006457600080fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506000815111156100f15773ffffffffffffffffffffffffffffffffffffffff60005416600080835160208501846127105a03f46040513d6000823e60008214156100ed573d81fd5b5050505b505061016b806101026000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634555d5c91461008b5780635c60da1b146100b6575b73ffffffffffffffffffffffffffffffffffffffff600054163660008037600080366000845af43d6000803e6000811415610086573d6000fd5b3d6000f35b34801561009757600080fd5b506100a061010d565b6040518082815260200191505060405180910390f35b3480156100c257600080fd5b506100cb610116565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60006002905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050905600a165627a7a72305820caf2b106039b60d7c8f99a3087b6cbf6014cdee3748f0823ccd8cbf983ee4a720029",
"deployedBytecode": "0x60806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634555d5c91461008b5780635c60da1b146100b6575b73ffffffffffffffffffffffffffffffffffffffff600054163660008037600080366000845af43d6000803e6000811415610086573d6000fd5b3d6000f35b34801561009757600080fd5b506100a061010d565b6040518082815260200191505060405180910390f35b3480156100c257600080fd5b506100cb610116565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60006002905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050905600a165627a7a72305820caf2b106039b60d7c8f99a3087b6cbf6014cdee3748f0823ccd8cbf983ee4a720029",
"sourceMap": "355:882:0:-;;;610:625;8:9:-1;5:2;;;30:1;27;20:12;5:2;610:625:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;668:11;593:1:12;578:11;:16;;;;570:25;;;;;;;;618:11;605:10;;:24;;;;;;;;;;;;;;;;;;508:128;735:1:0;714:11;:18;:22;710:519;;;879:42;875:1;869:8;865:57;1043:1;1040;1026:11;1020:18;1013:4;1000:11;996:22;984:10;976:5;971:3;967:15;954:91;1079:4;1073:11;1124:14;1121:1;1116:3;1101:38;1171:1;1162:7;1159:14;1156:2;;;1188:14;1183:3;1176:27;1156:2;829:390;;;;610:625;;355:882;;;;;;",
"deployedSourceMap": "355:882:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;915:42:12;911:1;905:8;901:57;990:14;987:1;984;971:34;1085:1;1082;1066:14;1063:1;1051:10;1046:3;1033:54;1121:16;1118:1;1115;1100:38;1166:1;1157:7;1154:14;1151:2;;;1181:16;1178:1;1171:27;1151:2;1223:16;1220:1;1213:27;1386:104;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1386:104:12;;;;;;;;;;;;;;;;;;;;;;;1262:118;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1262:118:12;;;;;;;;;;;;;;;;;;;;;;;;;;;1386:104;1452:7;1482:1;1475:8;;1386:104;:::o;1262:118::-;1333:7;1363:10;;;;;;;;;;;1356:17;;1262:118;:::o",
"source": "pragma solidity 0.4.23;\nimport \"./Proxy.sol\";\n\n\n/// @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>\ncontract DelegateConstructorProxy is Proxy {\n\n /// @dev Constructor function sets address of master copy contract.\n /// @param _masterCopy Master copy address.\n /// @param initializer Data used for a delegate call to initialize the contract.\n constructor(address _masterCopy, bytes initializer) Proxy(_masterCopy)\n public\n {\n if (initializer.length > 0) {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n let success := delegatecall(sub(gas, 10000), masterCopy, add(initializer, 0x20), mload(initializer), 0, 0)\n let ptr := mload(0x40)\n returndatacopy(ptr, 0, returndatasize)\n if eq(success, 0) { revert(ptr, returndatasize) }\n }\n }\n }\n}\n",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/DelegateConstructorProxy.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/DelegateConstructorProxy.sol",
"exportedSymbols": {
"DelegateConstructorProxy": [
23
]
},
"id": 24,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1,
"literals": [
"solidity",
"0.4",
".23"
],
"nodeType": "PragmaDirective",
"src": "0:23:0"
},
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Proxy.sol",
"file": "./Proxy.sol",
"id": 2,
"nodeType": "ImportDirective",
"scope": 24,
"sourceUnit": 1509,
"src": "24:21:0",
"symbolAliases": [],
"unitAlias": ""
},
{
"baseContracts": [
{
"arguments": null,
"baseName": {
"contractScope": null,
"id": 3,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1508,
"src": "392:5:0",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1508",
"typeString": "contract Proxy"
}
},
"id": 4,
"nodeType": "InheritanceSpecifier",
"src": "392:5:0"
}
],
"contractDependencies": [
1508
],
"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>",
"fullyImplemented": true,
"id": 23,
"linearizedBaseContracts": [
23,
1508
],
"name": "DelegateConstructorProxy",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 21,
"nodeType": "Block",
"src": "700:535:0",
"statements": [
{
"condition": {
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 17,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 14,
"name": "initializer",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 8,
"src": "714:11:0",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes memory"
}
},
"id": 15,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "length",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "714:18:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "BinaryOperation",
"operator": ">",
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 16,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "735:1:0",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_0_by_1",
"typeString": "int_const 0"
},
"value": "0"
},
"src": "714:22:0",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
"falseBody": null,
"id": 20,
"nodeType": "IfStatement",
"src": "710:519:0",
"trueBody": {
"id": 19,
"nodeType": "Block",
"src": "738:491:0",
"statements": [
{
"externalReferences": [
{
"initializer": {
"declaration": 8,
"isOffset": false,
"isSlot": false,
"src": "1000:11:0",
"valueSize": 1
}
},
{
"initializer": {
"declaration": 8,
"isOffset": false,
"isSlot": false,
"src": "1026:11:0",
"valueSize": 1
}
}
],
"id": 18,
"nodeType": "InlineAssembly",
"operations": "{\n let masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n let success := delegatecall(sub(gas(), 10000), masterCopy, add(initializer, 0x20), mload(initializer), 0, 0)\n let ptr := mload(0x40)\n returndatacopy(ptr, 0, returndatasize())\n if eq(success, 0)\n {\n revert(ptr, returndatasize())\n }\n}",
"src": "820:409:0"
}
]
}
}
]
},
"documentation": "@dev Constructor function sets address of master copy contract.\n @param _masterCopy Master copy address.\n @param initializer Data used for a delegate call to initialize the contract.",
"id": 22,
"implemented": true,
"isConstructor": true,
"isDeclaredConst": false,
"modifiers": [
{
"arguments": [
{
"argumentTypes": null,
"id": 11,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 6,
"src": "668:11:0",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
}
],
"id": 12,
"modifierName": {
"argumentTypes": null,
"id": 10,
"name": "Proxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1508,
"src": "662:5:0",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_contract$_Proxy_$1508_$",
"typeString": "type(contract Proxy)"
}
},
"nodeType": "ModifierInvocation",
"src": "662:18:0"
}
],
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 9,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 6,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 22,
"src": "622:19:0",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 5,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "622:7:0",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 8,
"name": "initializer",
"nodeType": "VariableDeclaration",
"scope": 22,
"src": "643:17:0",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes"
},
"typeName": {
"id": 7,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "643:5:0",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "621:40:0"
},
"payable": false,
"returnParameters": {
"id": 13,
"nodeType": "ParameterList",
"parameters": [],
"src": "700:0:0"
},
"scope": 23,
"src": "610:625:0",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 24,
"src": "355:882:0"
}
],
"src": "0:1238:0"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/DelegateConstructorProxy.sol",
"exportedSymbols": {
"DelegateConstructorProxy": [
23
]
},
"id": 24,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1,
"literals": [
"solidity",
"0.4",
".23"
],
"nodeType": "PragmaDirective",
"src": "0:23:0"
},
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Proxy.sol",
"file": "./Proxy.sol",
"id": 2,
"nodeType": "ImportDirective",
"scope": 24,
"sourceUnit": 1509,
"src": "24:21:0",
"symbolAliases": [],
"unitAlias": ""
},
{
"baseContracts": [
{
"arguments": null,
"baseName": {
"contractScope": null,
"id": 3,
"name": "Proxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1508,
"src": "392:5:0",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxy_$1508",
"typeString": "contract Proxy"
}
},
"id": 4,
"nodeType": "InheritanceSpecifier",
"src": "392:5:0"
}
],
"contractDependencies": [
1508
],
"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>",
"fullyImplemented": true,
"id": 23,
"linearizedBaseContracts": [
23,
1508
],
"name": "DelegateConstructorProxy",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 21,
"nodeType": "Block",
"src": "700:535:0",
"statements": [
{
"condition": {
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 17,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 14,
"name": "initializer",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 8,
"src": "714:11:0",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes memory"
}
},
"id": 15,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "length",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "714:18:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "BinaryOperation",
"operator": ">",
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 16,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "735:1:0",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_0_by_1",
"typeString": "int_const 0"
},
"value": "0"
},
"src": "714:22:0",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
"falseBody": null,
"id": 20,
"nodeType": "IfStatement",
"src": "710:519:0",
"trueBody": {
"id": 19,
"nodeType": "Block",
"src": "738:491:0",
"statements": [
{
"externalReferences": [
{
"initializer": {
"declaration": 8,
"isOffset": false,
"isSlot": false,
"src": "1000:11:0",
"valueSize": 1
}
},
{
"initializer": {
"declaration": 8,
"isOffset": false,
"isSlot": false,
"src": "1026:11:0",
"valueSize": 1
}
}
],
"id": 18,
"nodeType": "InlineAssembly",
"operations": "{\n let masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n let success := delegatecall(sub(gas(), 10000), masterCopy, add(initializer, 0x20), mload(initializer), 0, 0)\n let ptr := mload(0x40)\n returndatacopy(ptr, 0, returndatasize())\n if eq(success, 0)\n {\n revert(ptr, returndatasize())\n }\n}",
"src": "820:409:0"
}
]
}
}
]
},
"documentation": "@dev Constructor function sets address of master copy contract.\n @param _masterCopy Master copy address.\n @param initializer Data used for a delegate call to initialize the contract.",
"id": 22,
"implemented": true,
"isConstructor": true,
"isDeclaredConst": false,
"modifiers": [
{
"arguments": [
{
"argumentTypes": null,
"id": 11,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 6,
"src": "668:11:0",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
}
],
"id": 12,
"modifierName": {
"argumentTypes": null,
"id": 10,
"name": "Proxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1508,
"src": "662:5:0",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_contract$_Proxy_$1508_$",
"typeString": "type(contract Proxy)"
}
},
"nodeType": "ModifierInvocation",
"src": "662:18:0"
}
],
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 9,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 6,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 22,
"src": "622:19:0",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 5,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "622:7:0",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 8,
"name": "initializer",
"nodeType": "VariableDeclaration",
"scope": 22,
"src": "643:17:0",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes"
},
"typeName": {
"id": 7,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "643:5:0",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "621:40:0"
},
"payable": false,
"returnParameters": {
"id": 13,
"nodeType": "ParameterList",
"parameters": [],
"src": "700:0:0"
},
"scope": 23,
"src": "610:625:0",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 24,
"src": "355:882:0"
}
],
"src": "0:1238:0"
},
"compiler": {
"name": "solc",
"version": "0.4.23+commit.124ca40d.Emscripten.clang"
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-05-10T10:43:07.891Z"
}

View File

@ -0,0 +1,151 @@
{
"contractName": "Enum",
"abi": [],
"bytecode": "0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a72305820346c40fd38e691d9042d78bf7c33e05e8eafc3767b153318d8f2a9f5daf08bcf0029",
"deployedBytecode": "0x6080604052600080fd00a165627a7a72305820346c40fd38e691d9042d78bf7c33e05e8eafc3767b153318d8f2a9f5daf08bcf0029",
"sourceMap": "115:95:1:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;115:95:1;;;;;;;",
"deployedSourceMap": "115:95:1:-;;;;;",
"source": "pragma solidity 0.4.23;\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
]
},
"id": 31,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 25,
"literals": [
"solidity",
"0.4",
".23"
],
"nodeType": "PragmaDirective",
"src": "0:23:1"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title Enum - Collection of enums\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 30,
"linearizedBaseContracts": [
30
],
"name": "Enum",
"nodeType": "ContractDefinition",
"nodes": [
{
"canonicalName": "Enum.Operation",
"id": 29,
"members": [
{
"id": 26,
"name": "Call",
"nodeType": "EnumValue",
"src": "160:4:1"
},
{
"id": 27,
"name": "DelegateCall",
"nodeType": "EnumValue",
"src": "174:12:1"
},
{
"id": 28,
"name": "Create",
"nodeType": "EnumValue",
"src": "196:6:1"
}
],
"name": "Operation",
"nodeType": "EnumDefinition",
"src": "135:73:1"
}
],
"scope": 31,
"src": "115:95:1"
}
],
"src": "0:211:1"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Enum.sol",
"exportedSymbols": {
"Enum": [
30
]
},
"id": 31,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 25,
"literals": [
"solidity",
"0.4",
".23"
],
"nodeType": "PragmaDirective",
"src": "0:23:1"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title Enum - Collection of enums\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 30,
"linearizedBaseContracts": [
30
],
"name": "Enum",
"nodeType": "ContractDefinition",
"nodes": [
{
"canonicalName": "Enum.Operation",
"id": 29,
"members": [
{
"id": 26,
"name": "Call",
"nodeType": "EnumValue",
"src": "160:4:1"
},
{
"id": 27,
"name": "DelegateCall",
"nodeType": "EnumValue",
"src": "174:12:1"
},
{
"id": 28,
"name": "Create",
"nodeType": "EnumValue",
"src": "196:6:1"
}
],
"name": "Operation",
"nodeType": "EnumDefinition",
"src": "135:73:1"
}
],
"scope": 31,
"src": "115:95:1"
}
],
"src": "0:211:1"
},
"compiler": {
"name": "solc",
"version": "0.4.23+commit.124ca40d.Emscripten.clang"
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-05-10T10:43:07.892Z"
}

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

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,674 @@
{
"contractName": "MasterCopy",
"abi": [
{
"constant": false,
"inputs": [
{
"name": "_masterCopy",
"type": "address"
}
],
"name": "changeMasterCopy",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
],
"bytecode": "0x608060405234801561001057600080fd5b50610158806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637de7edef14610046575b600080fd5b34801561005257600080fd5b50610087600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610089565b005b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156100c357600080fd5b60008173ffffffffffffffffffffffffffffffffffffffff16141515156100e957600080fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a7230582073cd5ab8858f9d67e5e09748f71ecf939357d0d1230776e9f935b1ef5d664eb00029",
"deployedBytecode": "0x608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637de7edef14610046575b600080fd5b34801561005257600080fd5b50610087600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610089565b005b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156100c357600080fd5b60008173ffffffffffffffffffffffffffffffffffffffff16141515156100e957600080fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a7230582073cd5ab8858f9d67e5e09748f71ecf939357d0d1230776e9f935b1ef5d664eb00029",
"sourceMap": "203:633:6:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;203:633:6;;;;;;;",
"deployedSourceMap": "203:633:6:-;;;;;;;;;;;;;;;;;;;;;;;;626:208;;8:9:-1;5:2;;;30:1;27;20:12;5:2;626:208:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;244:4:14;222:27;;:10;:27;;;214:36;;;;;;;;791:1:6;776:11;:16;;;;768:25;;;;;;;;816:11;803:10;;:24;;;;;;;;;;;;;;;;;;626:208;:::o",
"source": "pragma solidity 0.4.23;\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);\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": [
779
]
},
"id": 780,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 755,
"literals": [
"solidity",
"0.4",
".23"
],
"nodeType": "PragmaDirective",
"src": "0:23:6"
},
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
"file": "./SelfAuthorized.sol",
"id": 756,
"nodeType": "ImportDirective",
"scope": 780,
"sourceUnit": 1560,
"src": "24:30:6",
"symbolAliases": [],
"unitAlias": ""
},
{
"baseContracts": [
{
"arguments": null,
"baseName": {
"contractScope": null,
"id": 757,
"name": "SelfAuthorized",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1559,
"src": "226:14:6",
"typeDescriptions": {
"typeIdentifier": "t_contract$_SelfAuthorized_$1559",
"typeString": "contract SelfAuthorized"
}
},
"id": 758,
"nodeType": "InheritanceSpecifier",
"src": "226:14:6"
}
],
"contractDependencies": [
1559
],
"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": 779,
"linearizedBaseContracts": [
779,
1559
],
"name": "MasterCopy",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 760,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 779,
"src": "465:18:6",
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 759,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "465:7:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"body": {
"id": 777,
"nodeType": "Block",
"src": "711:123:6",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 770,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 768,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 762,
"src": "776:11:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "BinaryOperation",
"operator": "!=",
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 769,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "791:1:6",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_0_by_1",
"typeString": "int_const 0"
},
"value": "0"
},
"src": "776:16:6",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_bool",
"typeString": "bool"
}
],
"id": 767,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
2468,
2469
],
"referencedDeclaration": 2468,
"src": "768:7:6",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$",
"typeString": "function (bool) pure"
}
},
"id": 771,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "768:25:6",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 772,
"nodeType": "ExpressionStatement",
"src": "768:25:6"
},
{
"expression": {
"argumentTypes": null,
"id": 775,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 773,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 760,
"src": "803:10:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 774,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 762,
"src": "816:11:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "803:24:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"id": 776,
"nodeType": "ExpressionStatement",
"src": "803:24:6"
}
]
},
"documentation": "@dev Allows to upgrade the contract. This can only be done via a Safe transaction.\n @param _masterCopy New contract address.",
"id": 778,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [
{
"arguments": null,
"id": 765,
"modifierName": {
"argumentTypes": null,
"id": 764,
"name": "authorized",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1558,
"src": "696:10:6",
"typeDescriptions": {
"typeIdentifier": "t_modifier$__$",
"typeString": "modifier ()"
}
},
"nodeType": "ModifierInvocation",
"src": "696:10:6"
}
],
"name": "changeMasterCopy",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 763,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 762,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 778,
"src": "652:19:6",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 761,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "652:7:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "651:21:6"
},
"payable": false,
"returnParameters": {
"id": 766,
"nodeType": "ParameterList",
"parameters": [],
"src": "711:0:6"
},
"scope": 779,
"src": "626:208:6",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 780,
"src": "203:633:6"
}
],
"src": "0:837:6"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/MasterCopy.sol",
"exportedSymbols": {
"MasterCopy": [
779
]
},
"id": 780,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 755,
"literals": [
"solidity",
"0.4",
".23"
],
"nodeType": "PragmaDirective",
"src": "0:23:6"
},
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
"file": "./SelfAuthorized.sol",
"id": 756,
"nodeType": "ImportDirective",
"scope": 780,
"sourceUnit": 1560,
"src": "24:30:6",
"symbolAliases": [],
"unitAlias": ""
},
{
"baseContracts": [
{
"arguments": null,
"baseName": {
"contractScope": null,
"id": 757,
"name": "SelfAuthorized",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1559,
"src": "226:14:6",
"typeDescriptions": {
"typeIdentifier": "t_contract$_SelfAuthorized_$1559",
"typeString": "contract SelfAuthorized"
}
},
"id": 758,
"nodeType": "InheritanceSpecifier",
"src": "226:14:6"
}
],
"contractDependencies": [
1559
],
"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": 779,
"linearizedBaseContracts": [
779,
1559
],
"name": "MasterCopy",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 760,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 779,
"src": "465:18:6",
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 759,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "465:7:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"body": {
"id": 777,
"nodeType": "Block",
"src": "711:123:6",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 770,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 768,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 762,
"src": "776:11:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "BinaryOperation",
"operator": "!=",
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 769,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "791:1:6",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_0_by_1",
"typeString": "int_const 0"
},
"value": "0"
},
"src": "776:16:6",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_bool",
"typeString": "bool"
}
],
"id": 767,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
2468,
2469
],
"referencedDeclaration": 2468,
"src": "768:7:6",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$",
"typeString": "function (bool) pure"
}
},
"id": 771,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "768:25:6",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 772,
"nodeType": "ExpressionStatement",
"src": "768:25:6"
},
{
"expression": {
"argumentTypes": null,
"id": 775,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 773,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 760,
"src": "803:10:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 774,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 762,
"src": "816:11:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "803:24:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"id": 776,
"nodeType": "ExpressionStatement",
"src": "803:24:6"
}
]
},
"documentation": "@dev Allows to upgrade the contract. This can only be done via a Safe transaction.\n @param _masterCopy New contract address.",
"id": 778,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [
{
"arguments": null,
"id": 765,
"modifierName": {
"argumentTypes": null,
"id": 764,
"name": "authorized",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1558,
"src": "696:10:6",
"typeDescriptions": {
"typeIdentifier": "t_modifier$__$",
"typeString": "modifier ()"
}
},
"nodeType": "ModifierInvocation",
"src": "696:10:6"
}
],
"name": "changeMasterCopy",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 763,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 762,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 778,
"src": "652:19:6",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 761,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "652:7:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "651:21:6"
},
"payable": false,
"returnParameters": {
"id": 766,
"nodeType": "ParameterList",
"parameters": [],
"src": "711:0:6"
},
"scope": 779,
"src": "626:208:6",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 780,
"src": "203:633:6"
}
],
"src": "0:837:6"
},
"compiler": {
"name": "solc",
"version": "0.4.23+commit.124ca40d.Emscripten.clang"
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-05-10T10:43:07.897Z"
}

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": "0x6060604052341561000f57600080fd5b6101278061001e6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638d80ff0a146044575b600080fd5b3415604e57600080fd5b609c600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050609e565b005b805160205b8181101560f65780830151602082018401516060830185015160808401860160008083838688600019f16000811460d85760dd565b600080fd5b50602080602084010402608001850194505050505060a3565b5050505600a165627a7a723058207fe7130b5215c2b7fb5987a9e0c21a2085684d930840ac75e4e7c62730c93cfc0029",
"deployedBytecode": "0x606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638d80ff0a146044575b600080fd5b3415604e57600080fd5b609c600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050609e565b005b805160205b8181101560f65780830151602082018401516060830185015160808401860160008083838688600019f16000811460d85760dd565b600080fd5b50602080602084010402608001850194505050505060a3565b5050505600a165627a7a723058207fe7130b5215c2b7fb5987a9e0c21a2085684d930840ac75e4e7c62730c93cfc0029",
"sourceMap": "253:1012:9:-;;;;;;;;;;;;;;;;;",
"deployedSourceMap": "253:1012:9:-;;;;;;;;;;;;;;;;;;;;;;;;593:670;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;704:12;698:5;739:4;756:491;770:6;767:1;764:2;756:491;;;834:1;820:12;816:3;810:5;898:4;895:1;891:3;877:12;873:3;867:5;971:4;968:1;964:3;950:12;946:3;940:5;1032:4;1029:1;1025:3;1011:12;1007:3;1107:1;1104;1092:10;1086:4;1079:5;1075:2;1071:1;1067:3;1062:4;1131:1;1126:23;;;;1055:94;;1126:23;1145:1;1142;1135:6;1055:94;;1226:4;1219;1212;1200:10;1196:3;1192;1188;1182:4;1178:3;1175:1;1171:3;1166:67;;782:465;;;;756:491;;;670:587;;;:::o",
"source": "pragma solidity 0.4.19;\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 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(not(0), to, value, data, dataLength, 0, 0)\n case 0 { revert(0, 0) }\n i := add(i, add(0x80, mul(div(add(dataLength, 0x20), 0x20), 0x20)))\n }\n }\n }\n}\n",
"bytecode": "0x608060405234801561001057600080fd5b5061013a806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638d80ff0a14610046575b600080fd5b34801561005257600080fd5b506100ad600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506100af565b005b805160205b8181101561010957808301516020820184015160608301850151608084018601600080838386885af1600081146100ea576100ef565b600080fd5b5060208060208401040260800185019450505050506100b4565b5050505600a165627a7a7230582085c54bc0284c5004bee6b973aad924e63fe6628856cdf34c1eedabe70b1787fb0029",
"deployedBytecode": "0x608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638d80ff0a14610046575b600080fd5b34801561005257600080fd5b506100ad600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506100af565b005b805160205b8181101561010957808301516020820184015160608301850151608084018601600080838386885af1600081146100ea576100ef565b600080fd5b5060208060208401040260800185019450505050506100b4565b5050505600a165627a7a7230582085c54bc0284c5004bee6b973aad924e63fe6628856cdf34c1eedabe70b1787fb0029",
"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.23;\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, 0x20), 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": [
2016
1614
]
},
"id": 2017,
"id": 1615,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 2008,
"id": 1606,
"literals": [
"solidity",
"0.4",
".19"
".23"
],
"nodeType": "PragmaDirective",
"src": "0:23:9"
"src": "0:23:16"
},
{
"baseContracts": [],
@ -48,75 +48,76 @@
"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": 2016,
"id": 1614,
"linearizedBaseContracts": [
2016
1614
],
"name": "MultiSend",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 2014,
"id": 1612,
"nodeType": "Block",
"src": "651:612:9",
"src": "651:673:16",
"statements": [
{
"externalReferences": [
{
"transactions": {
"declaration": 2010,
"declaration": 1608,
"isOffset": false,
"isSlot": false,
"src": "704:12:9",
"src": "768:12:16",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 2010,
"declaration": 1608,
"isOffset": false,
"isSlot": false,
"src": "820:12:9",
"src": "884:12:16",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 2010,
"declaration": 1608,
"isOffset": false,
"isSlot": false,
"src": "877:12:9",
"src": "941:12:16",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 2010,
"declaration": 1608,
"isOffset": false,
"isSlot": false,
"src": "950:12:9",
"src": "1014:12:16",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 2010,
"declaration": 1608,
"isOffset": false,
"isSlot": false,
"src": "1011:12:9",
"src": "1075:12:16",
"valueSize": 1
}
}
],
"id": 2013,
"id": 1611,
"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(not(0), to, value, data, dataLength, 0, 0)\n case 0 {\n revert(0, 0)\n }\n i := add(i, add(0x80, mul(div(add(dataLength, 0x20), 0x20), 0x20)))\n }\n}",
"src": "661:602:9"
"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, 0x20), 0x20), 0x20)))\n }\n}",
"src": "725:599:16"
}
]
},
"id": 2015,
"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": 1613,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
@ -124,77 +125,77 @@
"name": "multiSend",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 2011,
"id": 1609,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 2010,
"id": 1608,
"name": "transactions",
"nodeType": "VariableDeclaration",
"scope": 2015,
"src": "612:18:9",
"scope": 1613,
"src": "612:18:16",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes memory"
"typeString": "bytes"
},
"typeName": {
"id": 2009,
"id": 1607,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "612:5:9",
"src": "612:5:16",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes storage pointer"
"typeString": "bytes"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "611:20:9"
"src": "611:20:16"
},
"payable": false,
"returnParameters": {
"id": 2012,
"id": 1610,
"nodeType": "ParameterList",
"parameters": [],
"src": "651:0:9"
"src": "651:0:16"
},
"scope": 2016,
"src": "593:670:9",
"scope": 1614,
"src": "593:731:16",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 2017,
"src": "253:1012:9"
"scope": 1615,
"src": "253:1073:16"
}
],
"src": "0:1266:9"
"src": "0:1327:16"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/libraries/MultiSend.sol",
"exportedSymbols": {
"MultiSend": [
2016
1614
]
},
"id": 2017,
"id": 1615,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 2008,
"id": 1606,
"literals": [
"solidity",
"0.4",
".19"
".23"
],
"nodeType": "PragmaDirective",
"src": "0:23:9"
"src": "0:23:16"
},
{
"baseContracts": [],
@ -202,75 +203,76 @@
"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": 2016,
"id": 1614,
"linearizedBaseContracts": [
2016
1614
],
"name": "MultiSend",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 2014,
"id": 1612,
"nodeType": "Block",
"src": "651:612:9",
"src": "651:673:16",
"statements": [
{
"externalReferences": [
{
"transactions": {
"declaration": 2010,
"declaration": 1608,
"isOffset": false,
"isSlot": false,
"src": "704:12:9",
"src": "768:12:16",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 2010,
"declaration": 1608,
"isOffset": false,
"isSlot": false,
"src": "820:12:9",
"src": "884:12:16",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 2010,
"declaration": 1608,
"isOffset": false,
"isSlot": false,
"src": "877:12:9",
"src": "941:12:16",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 2010,
"declaration": 1608,
"isOffset": false,
"isSlot": false,
"src": "950:12:9",
"src": "1014:12:16",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 2010,
"declaration": 1608,
"isOffset": false,
"isSlot": false,
"src": "1011:12:9",
"src": "1075:12:16",
"valueSize": 1
}
}
],
"id": 2013,
"id": 1611,
"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(not(0), to, value, data, dataLength, 0, 0)\n case 0 {\n revert(0, 0)\n }\n i := add(i, add(0x80, mul(div(add(dataLength, 0x20), 0x20), 0x20)))\n }\n}",
"src": "661:602:9"
"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, 0x20), 0x20), 0x20)))\n }\n}",
"src": "725:599:16"
}
]
},
"id": 2015,
"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": 1613,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
@ -278,82 +280,82 @@
"name": "multiSend",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 2011,
"id": 1609,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 2010,
"id": 1608,
"name": "transactions",
"nodeType": "VariableDeclaration",
"scope": 2015,
"src": "612:18:9",
"scope": 1613,
"src": "612:18:16",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes memory"
"typeString": "bytes"
},
"typeName": {
"id": 2009,
"id": 1607,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "612:5:9",
"src": "612:5:16",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes storage pointer"
"typeString": "bytes"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "611:20:9"
"src": "611:20:16"
},
"payable": false,
"returnParameters": {
"id": 2012,
"id": 1610,
"nodeType": "ParameterList",
"parameters": [],
"src": "651:0:9"
"src": "651:0:16"
},
"scope": 2016,
"src": "593:670:9",
"scope": 1614,
"src": "593:731:16",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 2017,
"src": "253:1012:9"
"scope": 1615,
"src": "253:1073:16"
}
],
"src": "0:1266:9"
"src": "0:1327:16"
},
"compiler": {
"name": "solc",
"version": "0.4.19+commit.c4cbbb05.Emscripten.clang"
"version": "0.4.23+commit.124ca40d.Emscripten.clang"
},
"networks": {
"4": {
"events": {},
"links": {},
"address": "0xb42ea77ed35188c3d9f478ede1883c7fc3889bf4",
"transactionHash": "0x49884b2c77b96bd8fab92acb25cb6c1d31322f8d8a5285168b629d02ff0942df"
"address": "0x0bcf053aec288e75a338486b27d1340b11a5a818",
"transactionHash": "0x670d0ace2ffca0389ecff0dd2fb54fee15d237e652e7e67a06586187d00e3f2a"
},
"42": {
"1525950336085": {
"events": {},
"links": {},
"address": "0xa64866921fa040d96080a66327b57d3659aa3cb2",
"transactionHash": "0x0976055636f5f47833e456b68bbd3bd73497c17c1b51072795ee7ca472c7a1ee"
"address": "0xa4604b882b2c10ce381c4e61ad9ac72ab32f350f",
"transactionHash": "0xf4586ae05ae02801de1759128e43658bb0439e622a5ba84ad6bb4b652d641f4f"
},
"1525342778744": {
"1526283540628": {
"events": {},
"links": {},
"address": "0x1751f194e16ab8cc857b37bbbca9b796b182691b",
"transactionHash": "0xf406441274f4472d909145b4145733064edd26a8ef0c5cd1b00d19a481cec4fd"
"address": "0xf5cfa4069271285402ba2585c521c6c627810963",
"transactionHash": "0xf4586ae05ae02801de1759128e43658bb0439e622a5ba84ad6bb4b652d641f4f"
}
},
"schemaVersion": "2.0.0",
"updatedAt": "2018-05-04T13:47:03.969Z"
"updatedAt": "2018-05-14T07:39:37.970Z"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,738 @@
{
"contractName": "PayingProxy",
"abi": [
{
"constant": true,
"inputs": [],
"name": "proxyType",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "implementation",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"name": "_masterCopy",
"type": "address"
},
{
"name": "initializer",
"type": "bytes"
},
{
"name": "funder",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"payable": true,
"stateMutability": "payable",
"type": "fallback"
}
],
"bytecode": "0x608060405234801561001057600080fd5b506040516102d13803806102d18339810180604052810190808051906020019092919080518201929190602001805190602001909291908051906020019092919050505083838160008173ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505060008151111561010a5773ffffffffffffffffffffffffffffffffffffffff60005416600080835160208501846127105a03f46040513d6000823e6000821415610106573d81fd5b5050505b50508173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610152573d6000803e3d6000fd5b505050505061016b806101666000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634555d5c91461008b5780635c60da1b146100b6575b73ffffffffffffffffffffffffffffffffffffffff600054163660008037600080366000845af43d6000803e6000811415610086573d6000fd5b3d6000f35b34801561009757600080fd5b506100a061010d565b6040518082815260200191505060405180910390f35b3480156100c257600080fd5b506100cb610116565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60006002905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050905600a165627a7a723058204a5e06b82db5d9aabe30490b09e6366d2451ec220560baef426b0510057dd99b0029",
"deployedBytecode": "0x60806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634555d5c91461008b5780635c60da1b146100b6575b73ffffffffffffffffffffffffffffffffffffffff600054163660008037600080366000845af43d6000803e6000811415610086573d6000fd5b3d6000f35b34801561009757600080fd5b506100a061010d565b6040518082815260200191505060405180910390f35b3480156100c257600080fd5b506100cb610116565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60006002905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050905600a165627a7a723058204a5e06b82db5d9aabe30490b09e6366d2451ec220560baef426b0510057dd99b0029",
"sourceMap": "414:457:11:-;;;675:194;8:9:-1;5:2;;;30:1;27;20:12;5:2;675:194:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;784:11;797;668::0;593:1:12;578:11;:16;;;;570:25;;;;;;;;618:11;605:10;;:24;;;;;;;;;;;;;;;;;;508:128;735:1:0;714:11;:18;:22;710:519;;;879:42;875:1;869:8;865:57;1043:1;1040;1026:11;1020:18;1013:4;1000:11;996:22;984:10;976:5;971:3;967:15;954:91;1079:4;1073:11;1124:14;1121:1;1116:3;1101:38;1171:1;1162:7;1159:14;1156:2;;;1188:14;1183:3;1176:27;1156:2;829:390;;;;610:625;;839:6:11;:15;;:23;855:6;839:23;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;839:23:11;675:194;;;;414:457;;;;;;",
"deployedSourceMap": "414:457:11:-;;;;;;;;;;;;;;;;;;;;;;;;;;915:42:12;911:1;905:8;901:57;990:14;987:1;984;971:34;1085:1;1082;1066:14;1063:1;1051:10;1046:3;1033:54;1121:16;1118:1;1115;1100:38;1166:1;1157:7;1154:14;1151:2;;;1181:16;1178:1;1171:27;1151:2;1223:16;1220:1;1213:27;1386:104;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1386:104:12;;;;;;;;;;;;;;;;;;;;;;;1262:118;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1262:118:12;;;;;;;;;;;;;;;;;;;;;;;;;;;1386:104;1452:7;1482:1;1475:8;;1386:104;:::o;1262:118::-;1333:7;1363:10;;;;;;;;;;;1356:17;;1262:118;:::o",
"source": "pragma solidity 0.4.23;\nimport \"./DelegateConstructorProxy.sol\";\n\n/// @title Paying 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. And sends funds after creation to a specified account.\n/// @author Stefan George - <stefan@gnosis.pm>\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract PayingProxy is DelegateConstructorProxy {\n\n /// @dev Constructor function sets address of master copy contract.\n /// @param _masterCopy Master copy address.\n /// @param initializer Data used for a delegate call to initialize the contract.\n constructor(address _masterCopy, bytes initializer, address funder, uint256 amount) DelegateConstructorProxy(_masterCopy, initializer)\n public\n {\n funder.transfer(amount);\n }\n}\n",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/PayingProxy.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/PayingProxy.sol",
"exportedSymbols": {
"PayingProxy": [
1466
]
},
"id": 1467,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1440,
"literals": [
"solidity",
"0.4",
".23"
],
"nodeType": "PragmaDirective",
"src": "0:23:11"
},
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/DelegateConstructorProxy.sol",
"file": "./DelegateConstructorProxy.sol",
"id": 1441,
"nodeType": "ImportDirective",
"scope": 1467,
"sourceUnit": 24,
"src": "24:40:11",
"symbolAliases": [],
"unitAlias": ""
},
{
"baseContracts": [
{
"arguments": null,
"baseName": {
"contractScope": null,
"id": 1442,
"name": "DelegateConstructorProxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 23,
"src": "438:24:11",
"typeDescriptions": {
"typeIdentifier": "t_contract$_DelegateConstructorProxy_$23",
"typeString": "contract DelegateConstructorProxy"
}
},
"id": 1443,
"nodeType": "InheritanceSpecifier",
"src": "438:24:11"
}
],
"contractDependencies": [
23,
1508
],
"contractKind": "contract",
"documentation": "@title Paying 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. And sends funds after creation to a specified account.\n @author Stefan George - <stefan@gnosis.pm>\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 1466,
"linearizedBaseContracts": [
1466,
23,
1508
],
"name": "PayingProxy",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1464,
"nodeType": "Block",
"src": "829:40:11",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"id": 1461,
"name": "amount",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1451,
"src": "855:6:11",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
],
"expression": {
"argumentTypes": null,
"id": 1458,
"name": "funder",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1449,
"src": "839:6:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"id": 1460,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "transfer",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "839:15:11",
"typeDescriptions": {
"typeIdentifier": "t_function_transfer_nonpayable$_t_uint256_$returns$__$",
"typeString": "function (uint256)"
}
},
"id": 1462,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "839:23:11",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 1463,
"nodeType": "ExpressionStatement",
"src": "839:23:11"
}
]
},
"documentation": "@dev Constructor function sets address of master copy contract.\n @param _masterCopy Master copy address.\n @param initializer Data used for a delegate call to initialize the contract.",
"id": 1465,
"implemented": true,
"isConstructor": true,
"isDeclaredConst": false,
"modifiers": [
{
"arguments": [
{
"argumentTypes": null,
"id": 1454,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1445,
"src": "784:11:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
{
"argumentTypes": null,
"id": 1455,
"name": "initializer",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1447,
"src": "797:11:11",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes memory"
}
}
],
"id": 1456,
"modifierName": {
"argumentTypes": null,
"id": 1453,
"name": "DelegateConstructorProxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 23,
"src": "759:24:11",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_contract$_DelegateConstructorProxy_$23_$",
"typeString": "type(contract DelegateConstructorProxy)"
}
},
"nodeType": "ModifierInvocation",
"src": "759:50:11"
}
],
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1452,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1445,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1465,
"src": "687:19:11",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1444,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "687:7:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 1447,
"name": "initializer",
"nodeType": "VariableDeclaration",
"scope": 1465,
"src": "708:17:11",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes"
},
"typeName": {
"id": 1446,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "708:5:11",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 1449,
"name": "funder",
"nodeType": "VariableDeclaration",
"scope": 1465,
"src": "727:14:11",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1448,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "727:7:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 1451,
"name": "amount",
"nodeType": "VariableDeclaration",
"scope": 1465,
"src": "743:14:11",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 1450,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "743:7:11",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "686:72:11"
},
"payable": false,
"returnParameters": {
"id": 1457,
"nodeType": "ParameterList",
"parameters": [],
"src": "829:0:11"
},
"scope": 1466,
"src": "675:194:11",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 1467,
"src": "414:457:11"
}
],
"src": "0:872:11"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/PayingProxy.sol",
"exportedSymbols": {
"PayingProxy": [
1466
]
},
"id": 1467,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1440,
"literals": [
"solidity",
"0.4",
".23"
],
"nodeType": "PragmaDirective",
"src": "0:23:11"
},
{
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/DelegateConstructorProxy.sol",
"file": "./DelegateConstructorProxy.sol",
"id": 1441,
"nodeType": "ImportDirective",
"scope": 1467,
"sourceUnit": 24,
"src": "24:40:11",
"symbolAliases": [],
"unitAlias": ""
},
{
"baseContracts": [
{
"arguments": null,
"baseName": {
"contractScope": null,
"id": 1442,
"name": "DelegateConstructorProxy",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 23,
"src": "438:24:11",
"typeDescriptions": {
"typeIdentifier": "t_contract$_DelegateConstructorProxy_$23",
"typeString": "contract DelegateConstructorProxy"
}
},
"id": 1443,
"nodeType": "InheritanceSpecifier",
"src": "438:24:11"
}
],
"contractDependencies": [
23,
1508
],
"contractKind": "contract",
"documentation": "@title Paying 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. And sends funds after creation to a specified account.\n @author Stefan George - <stefan@gnosis.pm>\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 1466,
"linearizedBaseContracts": [
1466,
23,
1508
],
"name": "PayingProxy",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1464,
"nodeType": "Block",
"src": "829:40:11",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"id": 1461,
"name": "amount",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1451,
"src": "855:6:11",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
],
"expression": {
"argumentTypes": null,
"id": 1458,
"name": "funder",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1449,
"src": "839:6:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"id": 1460,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "transfer",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "839:15:11",
"typeDescriptions": {
"typeIdentifier": "t_function_transfer_nonpayable$_t_uint256_$returns$__$",
"typeString": "function (uint256)"
}
},
"id": 1462,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "839:23:11",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 1463,
"nodeType": "ExpressionStatement",
"src": "839:23:11"
}
]
},
"documentation": "@dev Constructor function sets address of master copy contract.\n @param _masterCopy Master copy address.\n @param initializer Data used for a delegate call to initialize the contract.",
"id": 1465,
"implemented": true,
"isConstructor": true,
"isDeclaredConst": false,
"modifiers": [
{
"arguments": [
{
"argumentTypes": null,
"id": 1454,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1445,
"src": "784:11:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
{
"argumentTypes": null,
"id": 1455,
"name": "initializer",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1447,
"src": "797:11:11",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes memory"
}
}
],
"id": 1456,
"modifierName": {
"argumentTypes": null,
"id": 1453,
"name": "DelegateConstructorProxy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 23,
"src": "759:24:11",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_contract$_DelegateConstructorProxy_$23_$",
"typeString": "type(contract DelegateConstructorProxy)"
}
},
"nodeType": "ModifierInvocation",
"src": "759:50:11"
}
],
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1452,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1445,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1465,
"src": "687:19:11",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1444,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "687:7:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 1447,
"name": "initializer",
"nodeType": "VariableDeclaration",
"scope": 1465,
"src": "708:17:11",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes"
},
"typeName": {
"id": 1446,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "708:5:11",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 1449,
"name": "funder",
"nodeType": "VariableDeclaration",
"scope": 1465,
"src": "727:14:11",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1448,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "727:7:11",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 1451,
"name": "amount",
"nodeType": "VariableDeclaration",
"scope": 1465,
"src": "743:14:11",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 1450,
"name": "uint256",
"nodeType": "ElementaryTypeName",
"src": "743:7:11",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "686:72:11"
},
"payable": false,
"returnParameters": {
"id": 1457,
"nodeType": "ParameterList",
"parameters": [],
"src": "829:0:11"
},
"scope": 1466,
"src": "675:194:11",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 1467,
"src": "414:457:11"
}
],
"src": "0:872:11"
},
"compiler": {
"name": "solc",
"version": "0.4.23+commit.124ca40d.Emscripten.clang"
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-05-10T10:43:07.901Z"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,435 @@
{
"contractName": "SelfAuthorized",
"abi": [],
"bytecode": "0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a72305820c359a8a0df732b4d3e100e43277411dee19c572529edb454cbf1fa9ee91508150029",
"deployedBytecode": "0x6080604052600080fd00a165627a7a72305820c359a8a0df732b4d3e100e43277411dee19c572529edb454cbf1fa9ee91508150029",
"sourceMap": "152:118:14:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;152:118:14;;;;;;;",
"deployedSourceMap": "152:118:14:-;;;;;",
"source": "pragma solidity 0.4.23;\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));\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": [
1559
]
},
"id": 1560,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1545,
"literals": [
"solidity",
"0.4",
".23"
],
"nodeType": "PragmaDirective",
"src": "0:23:14"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title SelfAuthorized - authorizes current contract to perform actions\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 1559,
"linearizedBaseContracts": [
1559
],
"name": "SelfAuthorized",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1557,
"nodeType": "Block",
"src": "204:64:14",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 1553,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 1548,
"name": "msg",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2465,
"src": "222:3:14",
"typeDescriptions": {
"typeIdentifier": "t_magic_message",
"typeString": "msg"
}
},
"id": 1549,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "sender",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "222:10:14",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "BinaryOperation",
"operator": "==",
"rightExpression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"id": 1551,
"name": "this",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2484,
"src": "244:4:14",
"typeDescriptions": {
"typeIdentifier": "t_contract$_SelfAuthorized_$1559",
"typeString": "contract SelfAuthorized"
}
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_contract$_SelfAuthorized_$1559",
"typeString": "contract SelfAuthorized"
}
],
"id": 1550,
"isConstant": false,
"isLValue": false,
"isPure": true,
"lValueRequested": false,
"nodeType": "ElementaryTypeNameExpression",
"src": "236:7:14",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_address_$",
"typeString": "type(address)"
},
"typeName": "address"
},
"id": 1552,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "typeConversion",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "236:13:14",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "222:27:14",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_bool",
"typeString": "bool"
}
],
"id": 1547,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
2468,
2469
],
"referencedDeclaration": 2468,
"src": "214:7:14",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$",
"typeString": "function (bool) pure"
}
},
"id": 1554,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "214:36:14",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 1555,
"nodeType": "ExpressionStatement",
"src": "214:36:14"
},
{
"id": 1556,
"nodeType": "PlaceholderStatement",
"src": "260:1:14"
}
]
},
"documentation": null,
"id": 1558,
"name": "authorized",
"nodeType": "ModifierDefinition",
"parameters": {
"id": 1546,
"nodeType": "ParameterList",
"parameters": [],
"src": "201:2:14"
},
"src": "182:86:14",
"visibility": "internal"
}
],
"scope": 1560,
"src": "152:118:14"
}
],
"src": "0:271:14"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
"exportedSymbols": {
"SelfAuthorized": [
1559
]
},
"id": 1560,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1545,
"literals": [
"solidity",
"0.4",
".23"
],
"nodeType": "PragmaDirective",
"src": "0:23:14"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title SelfAuthorized - authorizes current contract to perform actions\n @author Richard Meissner - <richard@gnosis.pm>",
"fullyImplemented": true,
"id": 1559,
"linearizedBaseContracts": [
1559
],
"name": "SelfAuthorized",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1557,
"nodeType": "Block",
"src": "204:64:14",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 1553,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"expression": {
"argumentTypes": null,
"id": 1548,
"name": "msg",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2465,
"src": "222:3:14",
"typeDescriptions": {
"typeIdentifier": "t_magic_message",
"typeString": "msg"
}
},
"id": 1549,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "sender",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "222:10:14",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "BinaryOperation",
"operator": "==",
"rightExpression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"id": 1551,
"name": "this",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2484,
"src": "244:4:14",
"typeDescriptions": {
"typeIdentifier": "t_contract$_SelfAuthorized_$1559",
"typeString": "contract SelfAuthorized"
}
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_contract$_SelfAuthorized_$1559",
"typeString": "contract SelfAuthorized"
}
],
"id": 1550,
"isConstant": false,
"isLValue": false,
"isPure": true,
"lValueRequested": false,
"nodeType": "ElementaryTypeNameExpression",
"src": "236:7:14",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_address_$",
"typeString": "type(address)"
},
"typeName": "address"
},
"id": 1552,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "typeConversion",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "236:13:14",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "222:27:14",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_bool",
"typeString": "bool"
}
],
"id": 1547,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
2468,
2469
],
"referencedDeclaration": 2468,
"src": "214:7:14",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$",
"typeString": "function (bool) pure"
}
},
"id": 1554,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "214:36:14",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 1555,
"nodeType": "ExpressionStatement",
"src": "214:36:14"
},
{
"id": 1556,
"nodeType": "PlaceholderStatement",
"src": "260:1:14"
}
]
},
"documentation": null,
"id": 1558,
"name": "authorized",
"nodeType": "ModifierDefinition",
"parameters": {
"id": 1546,
"nodeType": "ParameterList",
"parameters": [],
"src": "201:2:14"
},
"src": "182:86:14",
"visibility": "internal"
}
],
"scope": 1560,
"src": "152:118:14"
}
],
"src": "0:271:14"
},
"compiler": {
"name": "solc",
"version": "0.4.23+commit.124ca40d.Emscripten.clang"
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-05-10T10:43:07.901Z"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1202,8 +1202,14 @@
"links": {},
"address": "0x69c1cca644134e10f5f82fc28b3d45e136786dfc",
"transactionHash": "0x2af139a9359ac4b51195eab08a5958d134195ea3793c8851e63b2657d6b1a1be"
},
"1525789101965": {
"events": {},
"links": {},
"address": "0xa8fd8a2a990b5a5b300a6dc712d1b85b5574ffd9",
"transactionHash": "0x9477126b8b58fd22addc14218038766bb1723de3027fa4db33decd381eeb1b2d"
}
},
"schemaVersion": "2.0.0",
"updatedAt": "2018-05-04T13:47:03.968Z"
"updatedAt": "2018-05-08T14:18:44.024Z"
}

View File

@ -9121,8 +9121,14 @@
"links": {},
"address": "0x1b701c69619a38a7b779bef1f8a72dec2b9f402f",
"transactionHash": "0xe329bfbfb0449b969df0e144a935e7f94e58f4e7188f6c6626faf1d7ee7ded84"
},
"1525789101965": {
"events": {},
"links": {},
"address": "0xee471df0173d120eface5e5cf69a05cc4d1ce78a",
"transactionHash": "0xfd1473bdb9d32d9cef56f6fc22af6034ebd9f2aeb8d55ce0985f29b4086514a2"
}
},
"schemaVersion": "2.0.0",
"updatedAt": "2018-05-04T13:47:03.962Z"
"updatedAt": "2018-05-08T14:18:44.022Z"
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,365 @@
{
"contractName": "MultiSend",
"abi": [
{
"constant": false,
"inputs": [
{
"name": "transactions",
"type": "bytes"
}
],
"name": "multiSend",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
],
"bytecode": "0x6060604052341561000f57600080fd5b6101278061001e6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638d80ff0a146044575b600080fd5b3415604e57600080fd5b609c600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050609e565b005b805160205b8181101560f65780830151602082018401516060830185015160808401860160008083838688600019f16000811460d85760dd565b600080fd5b50602080602084010402608001850194505050505060a3565b5050505600a165627a7a723058207fe7130b5215c2b7fb5987a9e0c21a2085684d930840ac75e4e7c62730c93cfc0029",
"deployedBytecode": "0x606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638d80ff0a146044575b600080fd5b3415604e57600080fd5b609c600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050609e565b005b805160205b8181101560f65780830151602082018401516060830185015160808401860160008083838688600019f16000811460d85760dd565b600080fd5b50602080602084010402608001850194505050505060a3565b5050505600a165627a7a723058207fe7130b5215c2b7fb5987a9e0c21a2085684d930840ac75e4e7c62730c93cfc0029",
"sourceMap": "253:1012:9:-;;;;;;;;;;;;;;;;;",
"deployedSourceMap": "253:1012:9:-;;;;;;;;;;;;;;;;;;;;;;;;593:670;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;704:12;698:5;739:4;756:491;770:6;767:1;764:2;756:491;;;834:1;820:12;816:3;810:5;898:4;895:1;891:3;877:12;873:3;867:5;971:4;968:1;964:3;950:12;946:3;940:5;1032:4;1029:1;1025:3;1011:12;1007:3;1107:1;1104;1092:10;1086:4;1079:5;1075:2;1071:1;1067:3;1062:4;1131:1;1126:23;;;;1055:94;;1126:23;1145:1;1142;1135:6;1055:94;;1226:4;1219;1212;1200:10;1196:3;1192;1188;1182:4;1178:3;1175:1;1171:3;1166:67;;782:465;;;;756:491;;;670:587;;;:::o",
"source": "pragma solidity 0.4.19;\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 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(not(0), to, value, data, dataLength, 0, 0)\n case 0 { revert(0, 0) }\n i := add(i, add(0x80, mul(div(add(dataLength, 0x20), 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": [
2016
]
},
"id": 2017,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 2008,
"literals": [
"solidity",
"0.4",
".19"
],
"nodeType": "PragmaDirective",
"src": "0:23:9"
},
{
"baseContracts": [],
"contractDependencies": [],
"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": 2016,
"linearizedBaseContracts": [
2016
],
"name": "MultiSend",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 2014,
"nodeType": "Block",
"src": "651:612:9",
"statements": [
{
"externalReferences": [
{
"transactions": {
"declaration": 2010,
"isOffset": false,
"isSlot": false,
"src": "704:12:9",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 2010,
"isOffset": false,
"isSlot": false,
"src": "820:12:9",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 2010,
"isOffset": false,
"isSlot": false,
"src": "877:12:9",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 2010,
"isOffset": false,
"isSlot": false,
"src": "950:12:9",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 2010,
"isOffset": false,
"isSlot": false,
"src": "1011:12:9",
"valueSize": 1
}
}
],
"id": 2013,
"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(not(0), to, value, data, dataLength, 0, 0)\n case 0 {\n revert(0, 0)\n }\n i := add(i, add(0x80, mul(div(add(dataLength, 0x20), 0x20), 0x20)))\n }\n}",
"src": "661:602:9"
}
]
},
"id": 2015,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "multiSend",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 2011,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 2010,
"name": "transactions",
"nodeType": "VariableDeclaration",
"scope": 2015,
"src": "612:18:9",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes memory"
},
"typeName": {
"id": 2009,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "612:5:9",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes storage pointer"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "611:20:9"
},
"payable": false,
"returnParameters": {
"id": 2012,
"nodeType": "ParameterList",
"parameters": [],
"src": "651:0:9"
},
"scope": 2016,
"src": "593:670:9",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 2017,
"src": "253:1012:9"
}
],
"src": "0:1266:9"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/libraries/MultiSend.sol",
"exportedSymbols": {
"MultiSend": [
2016
]
},
"id": 2017,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 2008,
"literals": [
"solidity",
"0.4",
".19"
],
"nodeType": "PragmaDirective",
"src": "0:23:9"
},
{
"baseContracts": [],
"contractDependencies": [],
"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": 2016,
"linearizedBaseContracts": [
2016
],
"name": "MultiSend",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 2014,
"nodeType": "Block",
"src": "651:612:9",
"statements": [
{
"externalReferences": [
{
"transactions": {
"declaration": 2010,
"isOffset": false,
"isSlot": false,
"src": "704:12:9",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 2010,
"isOffset": false,
"isSlot": false,
"src": "820:12:9",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 2010,
"isOffset": false,
"isSlot": false,
"src": "877:12:9",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 2010,
"isOffset": false,
"isSlot": false,
"src": "950:12:9",
"valueSize": 1
}
},
{
"transactions": {
"declaration": 2010,
"isOffset": false,
"isSlot": false,
"src": "1011:12:9",
"valueSize": 1
}
}
],
"id": 2013,
"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(not(0), to, value, data, dataLength, 0, 0)\n case 0 {\n revert(0, 0)\n }\n i := add(i, add(0x80, mul(div(add(dataLength, 0x20), 0x20), 0x20)))\n }\n}",
"src": "661:602:9"
}
]
},
"id": 2015,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "multiSend",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 2011,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 2010,
"name": "transactions",
"nodeType": "VariableDeclaration",
"scope": 2015,
"src": "612:18:9",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_bytes_memory_ptr",
"typeString": "bytes memory"
},
"typeName": {
"id": 2009,
"name": "bytes",
"nodeType": "ElementaryTypeName",
"src": "612:5:9",
"typeDescriptions": {
"typeIdentifier": "t_bytes_storage_ptr",
"typeString": "bytes storage pointer"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "611:20:9"
},
"payable": false,
"returnParameters": {
"id": 2012,
"nodeType": "ParameterList",
"parameters": [],
"src": "651:0:9"
},
"scope": 2016,
"src": "593:670:9",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 2017,
"src": "253:1012:9"
}
],
"src": "0:1266:9"
},
"compiler": {
"name": "solc",
"version": "0.4.19+commit.c4cbbb05.Emscripten.clang"
},
"networks": {
"4": {
"events": {},
"links": {},
"address": "0xb42ea77ed35188c3d9f478ede1883c7fc3889bf4",
"transactionHash": "0x49884b2c77b96bd8fab92acb25cb6c1d31322f8d8a5285168b629d02ff0942df"
},
"42": {
"events": {},
"links": {},
"address": "0xa64866921fa040d96080a66327b57d3659aa3cb2",
"transactionHash": "0x0976055636f5f47833e456b68bbd3bd73497c17c1b51072795ee7ca472c7a1ee"
},
"1525342778744": {
"events": {},
"links": {},
"address": "0x1751f194e16ab8cc857b37bbbca9b796b182691b",
"transactionHash": "0xf406441274f4472d909145b4145733064edd26a8ef0c5cd1b00d19a481cec4fd"
},
"1525789101965": {
"events": {},
"links": {},
"address": "0x1e2dee6ce961ee356fd4382bf3e34e9b7f3876ce",
"transactionHash": "0x03595ae31f80fbcd00b5c0e5c51593841fe78041c8750420decf364f0f3d724c"
}
},
"schemaVersion": "2.0.0",
"updatedAt": "2018-05-08T14:18:44.025Z"
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,644 @@
{
"contractName": "Proxy",
"abi": [
{
"inputs": [
{
"name": "_masterCopy",
"type": "address"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"payable": true,
"stateMutability": "payable",
"type": "fallback"
}
],
"bytecode": "0x6060604052341561000f57600080fd5b6040516020806101108339810160405280805190602001909190505060008173ffffffffffffffffffffffffffffffffffffffff161415151561005157600080fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506070806100a06000396000f300606060405273ffffffffffffffffffffffffffffffffffffffff60005416366000803760008036600084600019f43d6000803e8060008114603f573d6000f35b3d6000fd00a165627a7a72305820daad8330a1c74b6650ef400638bc3fcb59dcd0b0341bff33bbe640bd2ffdaff60029",
"deployedBytecode": "0x606060405273ffffffffffffffffffffffffffffffffffffffff60005416366000803760008036600084600019f43d6000803e8060008114603f573d6000f35b3d6000fd00a165627a7a72305820daad8330a1c74b6650ef400638bc3fcb59dcd0b0341bff33bbe640bd2ffdaff60029",
"sourceMap": "190:887:3:-;;;357:131;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;445:1;430:11;:16;;;;422:25;;;;;;;;470:11;457:10;;:24;;;;;;;;;;;;;;;;;;357:131;190:887;;;;;;",
"deployedSourceMap": "190:887:3:-;;;703:42;699:1;693:5;689:3;778:12;775:1;772;759:12;876:1;873;857:12;854:1;842:10;838:1;834:3;821:12;912:14;909:1;906;891:14;949:7;974:1;969:38;;;;1040:14;1037:1;1030:6;969:38;988:14;985:1;978:6",
"source": "pragma solidity 0.4.19;\n\n\n/// @title Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract Proxy {\n\n address masterCopy;\n\n /// @dev Constructor function sets address of master copy contract.\n /// @param _masterCopy Master copy address.\n function Proxy(address _masterCopy)\n public\n {\n require(_masterCopy != 0);\n masterCopy = _masterCopy;\n }\n\n /// @dev Fallback function forwards all transactions and returns all received return data.\n function ()\n external\n payable\n {\n assembly {\n let masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n calldatacopy(0, 0, calldatasize())\n let success := delegatecall(not(0), masterCopy, 0, calldatasize(), 0, 0)\n returndatacopy(0, 0, returndatasize())\n switch success\n case 0 { revert(0, returndatasize()) }\n default { return(0, returndatasize()) }\n }\n }\n}\n",
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Proxy.sol",
"ast": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Proxy.sol",
"exportedSymbols": {
"Proxy": [
1046
]
},
"id": 1047,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1022,
"literals": [
"solidity",
"0.4",
".19"
],
"nodeType": "PragmaDirective",
"src": "0:23:3"
},
{
"baseContracts": [],
"contractDependencies": [],
"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": 1046,
"linearizedBaseContracts": [
1046
],
"name": "Proxy",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 1024,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1046,
"src": "212:18:3",
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1023,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "212:7:3",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"body": {
"id": 1039,
"nodeType": "Block",
"src": "412:76:3",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 1032,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 1030,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1026,
"src": "430:11:3",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "BinaryOperation",
"operator": "!=",
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 1031,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "445:1:3",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_0_by_1",
"typeString": "int_const 0"
},
"value": "0"
},
"src": "430:16:3",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_bool",
"typeString": "bool"
}
],
"id": 1029,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2092,
"src": "422:7:3",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$",
"typeString": "function (bool) pure"
}
},
"id": 1033,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "422:25:3",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 1034,
"nodeType": "ExpressionStatement",
"src": "422:25:3"
},
{
"expression": {
"argumentTypes": null,
"id": 1037,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 1035,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1024,
"src": "457:10:3",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 1036,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1026,
"src": "470:11:3",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "457:24:3",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"id": 1038,
"nodeType": "ExpressionStatement",
"src": "457:24:3"
}
]
},
"id": 1040,
"implemented": true,
"isConstructor": true,
"isDeclaredConst": false,
"modifiers": [],
"name": "Proxy",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1027,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1026,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1040,
"src": "372:19:3",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1025,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "372:7:3",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "371:21:3"
},
"payable": false,
"returnParameters": {
"id": 1028,
"nodeType": "ParameterList",
"parameters": [],
"src": "412:0:3"
},
"scope": 1046,
"src": "357:131:3",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
},
{
"body": {
"id": 1044,
"nodeType": "Block",
"src": "638:437:3",
"statements": [
{
"externalReferences": [],
"id": 1043,
"nodeType": "InlineAssembly",
"operations": "{\n let masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n calldatacopy(0, 0, calldatasize())\n let success := delegatecall(not(0), masterCopy, 0, calldatasize(), 0, 0)\n returndatacopy(0, 0, returndatasize())\n switch success\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n}",
"src": "648:427:3"
}
]
},
"id": 1045,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1041,
"nodeType": "ParameterList",
"parameters": [],
"src": "598:2:3"
},
"payable": true,
"returnParameters": {
"id": 1042,
"nodeType": "ParameterList",
"parameters": [],
"src": "638:0:3"
},
"scope": 1046,
"src": "589:486:3",
"stateMutability": "payable",
"superFunction": null,
"visibility": "external"
}
],
"scope": 1047,
"src": "190:887:3"
}
],
"src": "0:1078:3"
},
"legacyAST": {
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Proxy.sol",
"exportedSymbols": {
"Proxy": [
1046
]
},
"id": 1047,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1022,
"literals": [
"solidity",
"0.4",
".19"
],
"nodeType": "PragmaDirective",
"src": "0:23:3"
},
{
"baseContracts": [],
"contractDependencies": [],
"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": 1046,
"linearizedBaseContracts": [
1046
],
"name": "Proxy",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 1024,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1046,
"src": "212:18:3",
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1023,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "212:7:3",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
},
{
"body": {
"id": 1039,
"nodeType": "Block",
"src": "412:76:3",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 1032,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 1030,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1026,
"src": "430:11:3",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "BinaryOperation",
"operator": "!=",
"rightExpression": {
"argumentTypes": null,
"hexValue": "30",
"id": 1031,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "445:1:3",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_0_by_1",
"typeString": "int_const 0"
},
"value": "0"
},
"src": "430:16:3",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_bool",
"typeString": "bool"
}
],
"id": 1029,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 2092,
"src": "422:7:3",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$returns$__$",
"typeString": "function (bool) pure"
}
},
"id": 1033,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "422:25:3",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 1034,
"nodeType": "ExpressionStatement",
"src": "422:25:3"
},
{
"expression": {
"argumentTypes": null,
"id": 1037,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 1035,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1024,
"src": "457:10:3",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 1036,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1026,
"src": "470:11:3",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "457:24:3",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"id": 1038,
"nodeType": "ExpressionStatement",
"src": "457:24:3"
}
]
},
"id": 1040,
"implemented": true,
"isConstructor": true,
"isDeclaredConst": false,
"modifiers": [],
"name": "Proxy",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1027,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1026,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1040,
"src": "372:19:3",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1025,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "372:7:3",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "371:21:3"
},
"payable": false,
"returnParameters": {
"id": 1028,
"nodeType": "ParameterList",
"parameters": [],
"src": "412:0:3"
},
"scope": 1046,
"src": "357:131:3",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
},
{
"body": {
"id": 1044,
"nodeType": "Block",
"src": "638:437:3",
"statements": [
{
"externalReferences": [],
"id": 1043,
"nodeType": "InlineAssembly",
"operations": "{\n let masterCopy := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n calldatacopy(0, 0, calldatasize())\n let success := delegatecall(not(0), masterCopy, 0, calldatasize(), 0, 0)\n returndatacopy(0, 0, returndatasize())\n switch success\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n}",
"src": "648:427:3"
}
]
},
"id": 1045,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1041,
"nodeType": "ParameterList",
"parameters": [],
"src": "598:2:3"
},
"payable": true,
"returnParameters": {
"id": 1042,
"nodeType": "ParameterList",
"parameters": [],
"src": "638:0:3"
},
"scope": 1046,
"src": "589:486:3",
"stateMutability": "payable",
"superFunction": null,
"visibility": "external"
}
],
"scope": 1047,
"src": "190:887:3"
}
],
"src": "0:1078:3"
},
"compiler": {
"name": "solc",
"version": "0.4.19+commit.c4cbbb05.Emscripten.clang"
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-05-04T10:42:18.368Z"
}

File diff suppressed because it is too large Load Diff

View File

@ -9108,8 +9108,14 @@
"links": {},
"address": "0x38ba6d49ff8d62e729429947e2381f8e1b01933b",
"transactionHash": "0x6ade3e6ed704785b52fedb81d093263eeaccdcb3dd3883a7c040679c6c8096fc"
},
"1525789101965": {
"events": {},
"links": {},
"address": "0xf24ba0f83a48b995c7cac0d028e7db00bad3e42c",
"transactionHash": "0xeae217ba71df737e9f757f2a8918a4fe5f0e1c862ebe2a74f655e8f7ae25be15"
}
},
"schemaVersion": "2.0.0",
"updatedAt": "2018-05-04T13:47:03.966Z"
"updatedAt": "2018-05-08T14:18:44.029Z"
}

View File

@ -5393,8 +5393,14 @@
"links": {},
"address": "0xb5d9423b5e38ccdc3d578f1f0347e7fba3641474",
"transactionHash": "0x66e2aea779f2c020e2c01741d018f5d7ea897659a32f2c7eb58add9b29ca981b"
},
"1525789101965": {
"events": {},
"links": {},
"address": "0x1e23400dccfd4764b3ae1c5b8cd91a4450c4a3a9",
"transactionHash": "0x367fe2685adc2fffdbdeaa57294f376e0249544c3169f1d80387d9cadcf81a97"
}
},
"schemaVersion": "2.0.0",
"updatedAt": "2018-05-04T13:47:03.971Z"
"updatedAt": "2018-05-08T14:18:44.036Z"
}

View File

@ -20,7 +20,7 @@ const Header = ({ provider, reloadWallet }: Props) => (
<Col xs={12} center="xs" sm={6} start="sm" margin="lg">
<Img src={logo} height={40} alt="Gnosis Safe" />
</Col>
<Col xs={12} center="xs" sm={6} end="sm" margin="lg">
<Col xs={12} center="xs" sm={6} end="sm" middle="xs" margin="lg">
{ provider ? <Connected provider={provider} /> : <NotConnected /> }
<Refresh callback={reloadWallet} />
</Col>

View File

@ -2,7 +2,6 @@
import * as React from 'react'
import Button from '~/components/layout/Button'
import Link from '~/components/layout/Link'
import { SAFELIST_ADDRESS } from '~/routes/routes'
type NextButtonProps = {
text: string,
@ -20,9 +19,14 @@ const NextButton = ({ text, disabled }: NextButtonProps) => (
</Button>
)
const GoButton = () => (
<Link to={SAFELIST_ADDRESS}>
<NextButton text="VISIT SAFES" disabled={false} />
type GoProps = {
title: string,
to: string,
}
const GoButton = ({ title, to }: GoProps) => (
<Link to={to}>
<NextButton text={title} disabled={false} />
</Link>
)
@ -54,14 +58,16 @@ type Props = {
firstPage: boolean,
lastPage: boolean,
submitting: boolean,
goTitle: string,
goPath: string,
}
const Controls = ({
finishedTx, onPrevious, firstPage, lastPage, submitting,
finishedTx, onPrevious, firstPage, lastPage, submitting, goTitle, goPath,
}: Props) => (
<React.Fragment>
{ finishedTx
? <GoButton />
? <GoButton title={goTitle} to={goPath} />
: <ControlButtons
submitting={submitting}
next={lastPage ? 'Finish' : 'Next'}

View File

@ -1,5 +1,6 @@
// @flow
import Stepper, { Step as FormStep, StepLabel } from 'material-ui/Stepper'
import { withStyles } from 'material-ui/styles'
import * as React from 'react'
import type { FormApi } from 'react-final-form'
import GnoForm from '~/components/forms/GnoForm'
@ -10,6 +11,9 @@ import Controls from './Controls'
export { default as Step } from './Step'
type Props = {
classes: Object,
goTitle: string,
goPath: string,
steps: string[],
finishedTransaction: boolean,
initialValues?: Object,
@ -75,14 +79,16 @@ class GnoStepper extends React.PureComponent<Props, State> {
}
render() {
const { steps, children, finishedTransaction } = this.props
const {
steps, children, finishedTransaction, goTitle, goPath, classes,
} = this.props
const { page, values } = this.state
const activePage = this.getActivePageFrom(children)
const isLastPage = page === steps.length - 1
return (
<React.Fragment>
<Stepper activeStep={page} alternativeLabel>
<Stepper classes={{ root: classes.root }} activeStep={page} alternativeLabel>
{steps.map(label => (
<FormStep key={label}>
<StepLabel>{label}</StepLabel>
@ -105,6 +111,8 @@ class GnoStepper extends React.PureComponent<Props, State> {
onPrevious={this.previous}
firstPage={page === 0}
lastPage={isLastPage}
goTitle={goTitle}
goPath={goPath}
/>
</Col>
</Row>
@ -115,4 +123,10 @@ class GnoStepper extends React.PureComponent<Props, State> {
}
}
export default GnoStepper
const styles = {
root: {
flex: '1 1 auto',
},
}
export default withStyles(styles)(GnoStepper)

View File

@ -16,7 +16,8 @@ type Props = {
around?: 'xs' | 'sm' | 'md' | 'lg',
between?: 'xs' | 'sm' | 'md' | 'lg',
margin?: 'sm' | 'md' | 'lg' | 'xl',
layout?: 'inherit' | 'block',
layout?: 'inherit' | 'block' | 'column',
overflow?: boolean,
xs?: number | boolean,
sm?: number | boolean,
md?: number | boolean,
@ -30,7 +31,7 @@ type Props = {
}
const Col = ({
children, margin, layout = 'inherit',
children, margin, layout = 'inherit', overflow,
xs, sm, md, lg,
start, center, end, top, middle, bottom, around, between,
xsOffset, smOffset, mdOffset, lgOffset,
@ -55,6 +56,7 @@ const Col = ({
smOffset ? capitalize(smOffset, 'smOffset') : undefined,
mdOffset ? capitalize(mdOffset, 'mdOffset') : undefined,
lgOffset ? capitalize(lgOffset, 'lgOffset') : undefined,
{ overflow },
layout,
props.className,
)

View File

@ -1,6 +1,5 @@
.col {
flex: 1 1 auto;
align-items: center;
display: inherit;
}
@ -12,6 +11,15 @@
display: block;
}
.column {
display: flex;
flex-direction: column;
}
.overflow {
overflow: hidden;
}
.marginSm {
margin-bottom: $sm;
}
@ -30,107 +38,107 @@
@define-mixin col $size {
.$(size)1 {
flex-basis: 8.333%;
max-width: 8.333%;
flex-basis: 8.333%;
max-width: 8.333%;
}
.$(size)2 {
flex-basis: 16.667%;
max-width: 16.667%;
flex-basis: 16.667%;
max-width: 16.667%;
}
.$(size)3 {
flex-basis: 25%;
max-width: 25%;
flex-basis: 25%;
max-width: 25%;
}
.$(size)4 {
flex-basis: 33.333%;
max-width: 33.333%;
flex-basis: 33.333%;
max-width: 33.333%;
}
.$(size)5 {
flex-basis: 41.667%;
max-width: 41.667%;
flex-basis: 41.667%;
max-width: 41.667%;
}
.$(size)6 {
flex-basis: 50%;
max-width: 50%;
flex-basis: 50%;
max-width: 50%;
}
.$(size)7 {
flex-basis: 58.333%;
max-width: 58.333%;
flex-basis: 58.333%;
max-width: 58.333%;
}
.$(size)8 {
flex-basis: 66.667%;
max-width: 66.667%;
flex-basis: 66.667%;
max-width: 66.667%;
}
.$(size)9 {
flex-basis: 75%;
max-width: 75%;
flex-basis: 75%;
max-width: 75%;
}
.$(size)10 {
flex-basis: 83.333%;
max-width: 83.333%;
flex-basis: 83.333%;
max-width: 83.333%;
}
.$(size)11 {
flex-basis: 91.667%;
max-width: 91.667%;
flex-basis: 91.667%;
max-width: 91.667%;
}
.$(size)12 {
flex-basis: 100%;
max-width: 100%;
flex-basis: 100%;
max-width: 100%;
}
.$(size)Offset1 {
margin-left: 8.333%;
margin-left: 8.333%;
}
.$(size)Offset2 {
margin-left: 16.667%;
margin-left: 16.667%;
}
.$(size)Offset3 {
margin-left: 25%;
margin-left: 25%;
}
.$(size)Offset4 {
margin-left: 33.333%;
margin-left: 33.333%;
}
.$(size)Offset5 {
margin-left: 41.667%;
margin-left: 41.667%;
}
.$(size)Offset6 {
margin-left: 50%;
margin-left: 50%;
}
.$(size)Offset7 {
margin-left: 58.333%;
margin-left: 58.333%;
}
.$(size)Offset8 {
margin-left: 66.667%;
margin-left: 66.667%;
}
.$(size)Offset9 {
margin-left: 75%;
margin-left: 75%;
}
.$(size)Offset10 {
margin-left: 83.333%;
margin-left: 83.333%;
}
.$(size)Offset11 {
margin-left: 91.667%;
margin-left: 91.667%;
}
}
@ -164,16 +172,16 @@
@define-mixin row $size {
.start$(size) {
justify-content: flex-start;
text-align: start;
justify-content: flex-start;
text-align: start;
}
.center$(size) {
justify-content: center;
text-align: center;
justify-content: center;
text-align: center;
}
.end$(size) {
justify-content: flex-end;
text-align: end;
justify-content: flex-end;
text-align: end;
}
.top$(size) {
align-items: flex-start;

View File

@ -6,7 +6,7 @@ import styles from './index.scss'
const cx = classNames.bind(styles)
type Props = {
center?: boolean,
align?: 'right' | 'center' | 'left',
noMargin?: boolean,
bold?: boolean,
size?: 'sm' | 'md' | 'lg' | 'xl',
@ -17,11 +17,11 @@ type Props = {
class Paragraph extends React.PureComponent<Props> {
render() {
const {
bold, children, color, center, size, noMargin, ...props
bold, children, color, align, size, noMargin, ...props
} = this.props
return (
<p className={cx(styles.paragraph, { bold }, { noMargin }, size, { center })} {...props}>
<p className={cx(styles.paragraph, { bold }, { noMargin }, size, align)} {...props}>
{ children }
</p>
)

View File

@ -24,7 +24,15 @@
}
.center {
text-align: center;
text-align: center;
}
.left {
text-align: left;
}
.right {
text-align: right;
}
.sm {

View File

@ -35,10 +35,10 @@ export default ({ address, tx }: Props) => ({ submitting }: FormProps) => {
<Block>
{ !txFinished &&
<React.Fragment>
<Paragraph center size="lg">
<Paragraph align="center" size="lg">
You are about to create a Safe for keeping your funds more secure.
</Paragraph>
<Paragraph center size="lg">
<Paragraph align="center" size="lg">
Remember to check you have enough funds in your wallet.
</Paragraph>
</React.Fragment>

View File

@ -5,6 +5,7 @@ import Stepper from '~/components/Stepper'
import Confirmation from '~/routes/open/components/FormConfirmation'
import Review from '~/routes/open/components/ReviewInformation'
import SafeFields, { safeFieldsValidation } from '~/routes/open/components/SafeForm'
import { SAFELIST_ADDRESS } from '~/routes/routes'
const getSteps = () => [
'Fill Safe Form', 'Review Information', 'Deploy it',
@ -34,6 +35,8 @@ const Layout = ({
{ provider
? (
<Stepper
goPath={SAFELIST_ADDRESS}
goTitle="VISIT SAFES"
onSubmit={onCallSafeContractSubmit}
finishedTransaction={!!safeAddress}
steps={steps}

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(1500)
await sleep(6000)
// THEN
const deployed = TestUtils.findRenderedDOMComponentWithClass(open, DEPLOYED_COMPONENT_ID)

View File

@ -31,7 +31,7 @@ const createSafe = async (values: Object, userAccount: string, addSafe: AddSafe)
const GnosisSafe = getGnosisSafeContract(web3)
await initContracts()
const safe = await deploySafeContract(accounts, numConfirmations, userAccount)
const safe = await deploySafeContract(accounts, numConfirmations, dailyLimit, userAccount)
const param = safe.logs[1].args.proxy
const safeContract = GnosisSafe.at(param)

View File

@ -30,8 +30,20 @@ storiesOf('Routes /safe:address', module)
fetchBalance={() => {}}
/>
))
.add('Safe with 2 owners', () => {
const safe = SafeFactory.twoOwnersSafe
.add('Safe with 2 owners and 10ETH as dailyLimit', () => {
const safe = SafeFactory.dailyLimitSafe(10, 1.345)
return (
<Component
safe={safe}
provider="METAMASK"
balance="2"
fetchBalance={() => {}}
/>
)
})
.add('Safe with dailyLimit reached', () => {
const safe = SafeFactory.dailyLimitSafe(10, 10)
return (
<Component

View File

@ -0,0 +1,88 @@
// @flow
import * as React from 'react'
import TestUtils from 'react-dom/test-utils'
import { Provider } from 'react-redux'
import { ConnectedRouter } from 'react-router-redux'
import 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 { 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 { getBalanceInEtherOf } from '~/wallets/getWeb3'
import { sleep } from '~/utils/timer'
import { getDailyLimitFrom } from '~/routes/safe/component/Withdrawn/withdrawn'
describe('React DOM TESTS > Withdrawn funds from safe', () => {
let SafeDom
let store
let address
beforeEach(async () => {
// create store
store = aNewStore()
// deploy safe updating store
address = await aDeployedSafe(store)
// add funds to safe
await addEtherTo(address, '0.1')
// navigate to SAFE route
history.push(`${SAFELIST_ADDRESS}/${address}`)
SafeDom = TestUtils.renderIntoDocument((
<Provider store={store}>
<ConnectedRouter history={history}>
<AppRoutes />
</ConnectedRouter>
</Provider>
))
})
it('should withdrawn funds under dailyLimit without needing confirmations', async () => {
const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView)
// $FlowFixMe
const buttons = TestUtils.scryRenderedComponentsWithType(Safe, Button)
const withdrawnButton = buttons[0]
expect(withdrawnButton.props.children).toEqual(WITHDRAWN_BUTTON_TEXT)
TestUtils.Simulate.click(TestUtils.scryRenderedDOMComponentsWithTag(withdrawnButton, 'button')[0])
const Withdrawn = TestUtils.findRenderedComponentWithType(SafeDom, WithdrawnComponent)
// $FlowFixMe
const inputs = TestUtils.scryRenderedDOMComponentsWithTag(Withdrawn, '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')
TestUtils.Simulate.submit(form) // fill the form
TestUtils.Simulate.submit(form) // confirming data
await sleep(4000)
const safeBalance = await getBalanceInEtherOf(address)
expect(safeBalance).toBe('0.09')
// $FlowFixMe
const withdrawnButtons = TestUtils.scryRenderedComponentsWithType(Withdrawn, Button)
const visitTxsButton = withdrawnButtons[0]
expect(visitTxsButton.props.children).toEqual(SEE_TXS_BUTTON_TEXT)
})
it('spentToday dailyLimitModule property is updated correctly', async () => {
// GIVEN in beforeEach
// WHEN
await executeWithdrawnOn(address, 0.01)
await executeWithdrawnOn(address, 0.01)
const ethAddress = 0
const dailyLimit: DailyLimitProps = await getDailyLimitFrom(address, ethAddress)
// THEN
expect(dailyLimit.value).toBe(0.5)
expect(dailyLimit.spentToday).toBe(0.02)
})
})

View File

@ -3,19 +3,38 @@ 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 Button from '~/components/layout/Button'
import ListItemText from '~/components/List/ListItemText'
type Props = {
limit: number,
dailyLimit: DailyLimit,
onWithdrawn: () => void,
}
const DailyLimit = ({ limit }: Props) => (
<ListItem>
<Avatar>
<NotificationsPaused />
</Avatar>
<ListItemText primary="Daily Limit" secondary={`${limit} ETH`} />
</ListItem>
)
export const WITHDRAWN_BUTTON_TEXT = 'Withdrawn'
export default DailyLimit
const DailyLimitComponent = ({ dailyLimit, onWithdrawn }: Props) => {
const limit = dailyLimit.get('value')
const spentToday = dailyLimit.get('spentToday')
const disabled = spentToday >= limit
const text = `${limit} ETH (spent today: ${spentToday} ETH)`
return (
<ListItem>
<Avatar>
<NotificationsPaused />
</Avatar>
<ListItemText primary="Daily Limit" secondary={text} />
<Button
variant="raised"
color="primary"
onClick={onWithdrawn}
disabled={disabled}
>
{WITHDRAWN_BUTTON_TEXT}
</Button>
</ListItem>
)
}
export default DailyLimitComponent

View File

@ -0,0 +1,17 @@
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
<defs>
<linearGradient id="a" x1="0%" y1="50.001%" y2="50.001%">
<stop offset="0%" stop-color="#00B3CE"/>
<stop offset="100%" stop-color="#00C8DD"/>
</linearGradient>
</defs>
<g fill="none" fill-rule="nonzero">
<circle cx="250" cy="250" r="250" fill="url(#a)"/>
<g fill="#FFF">
<path d="M189.93 245.903l-49.95-49.674c-4.508 6.049-7.237 13.563-7.237 21.674 0 19.583 15.972 35.52 35.528 35.52 8.118 0 15.66-2.715 21.66-7.52z"/>
<path d="M248.639 71.028c-52.077 0-100.542 21.097-136.063 58.694l-5.708 6.042 143.84 144.48v25.923l-.555.562-37.007-37.326c-17.18 11.423-39.153 14.757-59.903 7.528-34.924-12.653-53-50.882-40.361-85.5 1.826-5.41 4.52-10.23 7.52-14.743l-15.937-15.959-3.014 5.118c-16.555 27.104-25.597 58.403-25.597 90.59-.285 96.042 77.965 174.577 173.965 174.577h29.396V71.056l-30.576-.028zm-118.292 64.729c31.945-31.02 73.743-47.854 118.611-47.854h.285c.5 0 .993 0 1.465.02v168.5l-120.36-120.666z"/>
<path d="M248.639 71.028c-52.077 0-100.542 21.097-136.063 58.694l-5.708 6.042 143.84 144.48v25.923l-.555.562-37.007-37.326c-17.18 11.423-39.153 14.757-59.903 7.528-34.924-12.653-53-50.882-40.361-85.5 1.826-5.41 4.52-10.23 7.52-14.743l-15.937-15.959-3.014 5.118c-16.555 27.104-25.597 58.403-25.597 90.59-.285 96.042 77.965 174.577 173.965 174.577h29.396V71.056l-30.576-.028zm-118.292 64.729c31.945-31.02 73.743-47.854 118.611-47.854h.285c.5 0 .993 0 1.465.02v168.5l-120.36-120.666zM423.611 250.41c0-79.618-64.764-144.417-144.389-144.473v17.3c70.104.027 127.125 57.069 127.125 127.166 0 70.11-57.02 127.166-127.125 127.194v17.278c79.625-.035 144.39-64.813 144.39-144.465z"/>
<path d="M314.549 250.486l-6.855 42.98h33.577l-6.854-42.98c7.646-3.743 12.944-11.59 12.944-20.708 0-12.702-10.236-23-22.868-23-12.632 0-22.875 10.298-22.875 23-.014 9.132 5.285 16.965 12.93 20.708zM303.25 152.986c9.028 2.333 12.507-11.201 3.48-13.528-9.015-2.312-12.508 11.223-3.48 13.528M342.868 173.549c7.139 5.972 16.111-4.73 8.972-10.702-7.11-6-16.104 4.715-8.972 10.702M368.333 206.944c4.105 8.362 16.646 2.223 12.549-6.138-4.09-8.369-16.646-2.209-12.549 6.138M303.25 347.618c9.028-2.326 12.507 11.23 3.48 13.549-9.015 2.305-12.508-11.23-3.48-13.549M342.868 327.07c7.139-5.98 16.111 4.729 8.972 10.687-7.11 6.014-16.104-4.701-8.972-10.688M368.333 293.66c4.105-8.361 16.646-2.202 12.549 6.166-4.09 8.34-16.646 2.202-12.549-6.166M378.424 250.826c0 9.334 13.958 9.334 13.958 0 0-9.312-13.958-9.312-13.958 0"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -3,59 +3,76 @@ import * as React from 'react'
import Block from '~/components/layout/Block'
import Col from '~/components/layout/Col'
import Bold from '~/components/layout/Bold'
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 Withdrawn from '~/routes/safe/component/Withdrawn'
import Address from './Address'
import Balance from './Balance'
import Owners from './Owners'
import Confirmations from './Confirmations'
import DailyLimit from './DailyLimit'
const safeIcon = require('./assets/gnosis_safe.svg')
type SafeProps = {
safe: Safe,
balance: string,
}
const listStyle = {
width: '100%',
minWidth: '485px',
type State = {
component: React$Node,
}
class GnoSafe extends React.PureComponent<SafeProps> {
const listStyle = {
width: '100%',
}
class GnoSafe extends React.PureComponent<SafeProps, State> {
state = {
component: undefined,
}
onWithdrawn = () => {
const { safe } = this.props
this.setState({ component: <Withdrawn safeAddress={safe.get('address')} dailyLimit={safe.get('dailyLimit')} /> })
}
render() {
const { safe, balance } = this.props
const { component } = this.state
return (
<Row>
<Col xs={12} top="xs" sm={4} margin="xl">
<Row grow>
<Col sm={12} top="xs" md={5} margin="xl" overflow>
<List style={listStyle}>
<Balance balance={balance} />
<Owners owners={safe.owners} />
<Confirmations confirmations={safe.get('confirmations')} />
<Address address={safe.get('address')} />
<DailyLimit limit={safe.get('dailyLimit')} />
<DailyLimit dailyLimit={safe.get('dailyLimit')} onWithdrawn={this.onWithdrawn} />
</List>
</Col>
<Col xs={12} center="xs" sm={8} margin="xl" layout="block">
<Col sm={12} center="xs" md={7} margin="xl" layout="column">
<Block margin="xl">
<Paragraph size="lg" noMargin align="right">
<Bold>{safe.name.toUpperCase()}</Bold>
</Paragraph>
</Block>
<Block>
Extra info will be placed here
</Block>
<Row grow>
<Col sm={12} center="sm" middle={component ? undefined : 'sm'} layout="column">
{ component || <Img alt="Safe Icon" src={safeIcon} height={330} /> }
</Col>
</Row>
</Col>
</Row>
)
}
}
/*
<Paragraph size="lg">
<Bold>{safe.name.toUpperCase()}</Bold>
*/
export default GnoSafe

View File

@ -0,0 +1,34 @@
// @flow
import * as React from 'react'
import { CircularProgress } from 'material-ui/Progress'
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'
type FormProps = {
values: Object,
submitting: boolean,
}
const spinnerStyle = {
minHeight: '50px',
}
const Review = () => ({ values, submitting }: FormProps) => (
<Block>
<Heading tag="h2">Review the Withdrawn Operation</Heading>
<Paragraph align="left">
<Bold>Destination: </Bold> {values[DESTINATION_PARAM]}
</Paragraph>
<Paragraph align="left">
<Bold>Value in ETH: </Bold> {values[VALUE_PARAM]}
</Paragraph>
<Block style={spinnerStyle}>
{ submitting && <CircularProgress size={50} /> }
</Block>
</Block>
)
export default Review

View File

@ -0,0 +1,23 @@
// @flow
import { storiesOf } from '@storybook/react'
import * as React from 'react'
import styles from '~/components/layout/PageFrame/index.scss'
import { makeDailyLimit, type DailyLimit } from '~/routes/safe/store/model/dailyLimit'
import Component from './index'
const FrameDecorator = story => (
<div className={styles.frame}>
{ story() }
</div>
)
storiesOf('Components', module)
.addDecorator(FrameDecorator)
.add('WitdrawnForm', () => {
const dailyLimit: DailyLimit = makeDailyLimit({ value: 10, spentToday: 6 })
return (
<Component dailyLimit={dailyLimit} safeAddress="" />
)
})

View File

@ -0,0 +1,67 @@
// @flow
import * as React from 'react'
import Field from '~/components/forms/Field'
import TextField from '~/components/forms/TextField'
import { composeValidators, mustBeNumber, 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'
export const CONFIRMATIONS_ERROR = 'Number of confirmations can not be higher than the number of owners'
export const safeFieldsValidation = (values: Object) => {
const errors = {}
if (Number.parseInt(values.owners, 10) < Number.parseInt(values.confirmations, 10)) {
errors.confirmations = CONFIRMATIONS_ERROR
}
return errors
}
type Props = {
limit: number,
spentToday: number,
}
export const inLimit = (limit: number, spentToday: number) => (value: string) => {
const amount = Number(value)
const max = limit - spentToday
if (amount <= max) {
return undefined
}
return `Should not exceed ${max} ETH (amount to reach daily limit)`
}
export default ({ limit, spentToday }: Props) => () => (
<Block margin="md">
<Heading tag="h2" margin="lg">
Withdrawn Funds
</Heading>
<Heading tag="h4" margin="lg">
{`Daily limit ${limit} ETH (spent today: ${spentToday} ETH)`}
</Heading>
<Block margin="md">
<Field
name={VALUE_PARAM}
component={TextField}
type="text"
validate={composeValidators(required, mustBeNumber, greaterThan(0), inLimit(limit, spentToday))}
placeholder="Amount in ETH*"
text="Amount in ETH"
/>
</Block>
<Block margin="md">
<Field
name={DESTINATION_PARAM}
component={TextField}
type="text"
validate={composeValidators(required, mustBeEthereumAddress)}
placeholder="Destination*"
text="Destination"
/>
</Block>
</Block>
)

View File

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

View File

@ -0,0 +1,74 @@
// @flow
import * as React from 'react'
import { connect } from 'react-redux'
import Stepper from '~/components/Stepper'
import { SAFELIST_ADDRESS } from '~/routes/routes'
import { sleep } from '~/utils/timer'
import actions, { type Actions } from './actions'
import selector, { type SelectorProps } from './selector'
import withdrawn from './withdrawn'
import WithdrawnForm from './WithdrawnForm'
import Review from './Review'
const getSteps = () => [
'Fill Withdrawn Form', 'Review Withdrawn',
]
type Props = SelectorProps & Actions & {
safeAddress: string,
dailyLimit: DailyLimit,
}
type State = {
done: boolean,
}
export const SEE_TXS_BUTTON_TEXT = 'DONE'
class Withdrawn extends React.Component<Props, State> {
state = {
done: false,
}
onWithdrawn = async (values: Object) => {
try {
const { safeAddress, userAddress } = this.props
await withdrawn(values, safeAddress, userAddress)
await sleep(3500)
this.props.fetchDailyLimit(safeAddress)
this.setState({ done: true })
} catch (error) {
this.setState({ done: false })
// eslint-disable-next-line
console.log('Error while withdrawing funds ' + error)
}
}
render() {
const { dailyLimit, safeAddress } = this.props
const { done } = this.state
const steps = getSteps()
return (
<React.Fragment>
<Stepper
goPath={`${SAFELIST_ADDRESS}/${safeAddress}`}
goTitle={SEE_TXS_BUTTON_TEXT}
onSubmit={this.onWithdrawn}
finishedTransaction={done}
steps={steps}
>
<Stepper.Page limit={dailyLimit.get('value')} spentToday={dailyLimit.get('spentToday')}>
{ WithdrawnForm }
</Stepper.Page>
<Stepper.Page>
{ Review }
</Stepper.Page>
</Stepper>
</React.Fragment>
)
}
}
export default connect(selector, actions)(Withdrawn)

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,53 @@
// @flow
import { getWeb3 } from '~/wallets/getWeb3'
import { getGnosisSafeContract, getCreateDailyLimitExtensionContract } from '~/wallets/safeContracts'
import { type DailyLimitProps } from '~/routes/safe/store/model/safe'
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, tokenAddress): 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')
return dailyLimitModule.executeDailyLimit(
destination,
value,
0,
{ from: userAccount, gas: '5000000' },
)
}
export default withdrawn

View File

@ -0,0 +1,26 @@
// @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

@ -1,10 +1,13 @@
// @flow
import fetchBalance from '~/routes/safe/store/actions/fetchBalance'
import fetchDailyLimit from '~/routes/safe/store/actions/fetchDailyLimit'
export type Actions = {
fetchBalance: typeof fetchBalance,
fetchDailyLimit: typeof fetchDailyLimit,
}
export default {
fetchBalance,
fetchDailyLimit,
}

View File

@ -17,6 +17,8 @@ class SafeView extends React.PureComponent<Props> {
const safeAddress: string = safe.get('address')
fetchBalance(safeAddress)
}, 1500)
this.props.fetchDailyLimit(this.props.safe.get('address'))
}
componentWillUnmount() {

View File

@ -1,6 +1,7 @@
// @flow
import { List } from 'immutable'
import { createAction } from 'redux-actions'
import { makeDailyLimit, type DailyLimit } from '~/routes/safe/store/model/dailyLimit'
import { type SafeProps } from '~/routes/safe/store/model/safe'
import { makeOwner, type Owner } from '~/routes/safe/store/model/owner'
@ -12,14 +13,18 @@ export const buildOwnersFrom = (names: string[], addresses: string[]) => {
return List(owners)
}
export const buildDailyLimitFrom = (dailyLimit: number, spentToday: number = 0): DailyLimit =>
makeDailyLimit({ value: dailyLimit, spentToday })
const addSafe = createAction(
ADD_SAFE,
(
name: string, address: string,
confirmations: number, dailyLimit: number,
confirmations: number, limit: number,
ownersName: string[], ownersAddress: string[],
): SafeProps => {
const owners: List<Owner> = buildOwnersFrom(ownersName, ownersAddress)
const dailyLimit: DailyLimit = buildDailyLimitFrom(limit)
return ({
address, name, confirmations, owners, dailyLimit,

View File

@ -0,0 +1,12 @@
// @flow
import type { Dispatch as ReduxDispatch } from 'redux'
import { type GlobalState } from '~/store/index'
import { getDailyLimitFrom } from '~/routes/safe/component/Withdrawn/withdrawn'
import updateDailyLimit from './updateDailyLimit'
export default (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalState>) => {
const ethAddress = 0
const dailyLimit: DailyLimitProps = await getDailyLimitFrom(safeAddress, ethAddress)
return dispatch(updateDailyLimit(safeAddress, dailyLimit))
}

View File

@ -0,0 +1,19 @@
// @flow
import { createAction } from 'redux-actions'
export const UPDATE_DAILY_LIMIT = 'UPDATE_DAILY_LIMIT'
type SpentTodayProps = {
safeAddress: string,
dailyLimit: DailyLimitProps,
}
const updateDailyLimit = createAction(
UPDATE_DAILY_LIMIT,
(safeAddress: string, dailyLimit: DailyLimitProps): SpentTodayProps => ({
safeAddress,
dailyLimit,
}),
)
export default updateDailyLimit

View File

@ -0,0 +1,15 @@
// @flow
import { Record } from 'immutable'
import type { RecordFactory, RecordOf } from 'immutable'
export type DailyLimitProps = {
value: number,
spentToday: number,
}
export const makeDailyLimit: RecordFactory<DailyLimitProps> = Record({
value: 0,
spentToday: 0,
})
export type DailyLimit = RecordOf<DailyLimitProps>

View File

@ -1,6 +1,7 @@
// @flow
import { List, Record } from 'immutable'
import type { RecordFactory, RecordOf } from 'immutable'
import { type DailyLimit, makeDailyLimit } from '~/routes/safe/store/model/dailyLimit'
import type { Owner } from '~/routes/safe/store/model/owner'
export type SafeProps = {
@ -8,7 +9,7 @@ export type SafeProps = {
address: string,
confirmations: number,
owners: List<Owner>,
dailyLimit: number,
dailyLimit: DailyLimit,
}
export const makeSafe: RecordFactory<SafeProps> = Record({
@ -16,7 +17,7 @@ export const makeSafe: RecordFactory<SafeProps> = Record({
address: '',
confirmations: 0,
owners: List([]),
dailyLimit: 0,
dailyLimit: makeDailyLimit(),
})
export type Safe = RecordOf<SafeProps>

View File

@ -2,9 +2,11 @@
import { Map, List } from 'immutable'
import { handleActions, type ActionType } from 'redux-actions'
import addSafe, { ADD_SAFE } from '~/routes/safe/store/actions/addSafe'
import updateDailyLimit, { UPDATE_DAILY_LIMIT } from '~/routes/safe/store/actions/updateDailyLimit'
import { makeOwner } from '~/routes/safe/store/model/owner'
import { type Safe, makeSafe } from '~/routes/safe/store/model/safe'
import { loadSafes, saveSafes } from '~/utils/localStorage'
import { makeDailyLimit } from '~/routes/safe/store/model/dailyLimit'
export const SAFE_REDUCER_ID = 'safes'
@ -17,6 +19,7 @@ const buildSafesFrom = (loadedSafes: Object): State => {
Object.keys(loadedSafes).forEach((address) => {
const safe = loadedSafes[address]
safe.owners = List(safe.owners.map((owner => makeOwner(owner))))
safe.dailyLimit = makeDailyLimit({ value: safe.dailyLimit.value, spentToday: safe.dailyLimit.spentToday })
return map.set(address, makeSafe(safe))
})
})
@ -45,4 +48,6 @@ export default handleActions({
saveSafes(safes.toJSON())
return safes
},
[UPDATE_DAILY_LIMIT]: (state: State, action: ActionType<typeof updateDailyLimit>): State =>
state.updateIn([action.payload.safeAddress, 'dailyLimit'], () => makeDailyLimit(action.payload.dailyLimit)),
}, Map())

View File

@ -2,17 +2,9 @@
import { BALANCE_REDUCER_ID } from '~/routes/safe/store/reducer/balances'
import fetchBalance from '~/routes/safe/store/actions/fetchBalance'
import { aNewStore } from '~/store'
import { getWeb3 } from '~/wallets/getWeb3'
import { promisify } from '~/utils/promisify'
import { addEtherTo } from '~/test/addEtherTo'
import { aDeployedSafe } from './builder/deployedSafe.builder'
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))
}
const balanceReducerTests = () => {
describe('Safe Actions[fetchBalance]', () => {
let store
@ -22,8 +14,7 @@ const balanceReducerTests = () => {
it('reducer should return 0 to just deployed safe', async () => {
// GIVEN
const safeTx = await aDeployedSafe(store)
const address = safeTx.logs[1].args.proxy
const address = await aDeployedSafe(store)
// WHEN
await store.dispatch(fetchBalance(address))
@ -36,8 +27,7 @@ const balanceReducerTests = () => {
it('reducer should return 1.3456 ETH as funds to safe with 1 ETH', async () => {
// GIVEN
const safeTx = await aDeployedSafe(store)
const address = safeTx.logs[1].args.proxy
const address = await aDeployedSafe(store)
// WHEN
await addEtherTo(address, '1.3456')

View File

@ -1,18 +1,9 @@
// @flow
import { type Match } from 'react-router-dom'
import addBalance from '~/routes/safe/store/actions/addBalance'
import { aNewStore } from '~/store'
import { buildMathPropsFrom } from '~/test/buildReactRouterProps'
import { balanceSelector } from '../selectors'
const buildMathPropsFrom = (address): Match => ({
params: {
address,
},
isExact: true,
path: '',
url: '',
})
const balanceSelectorTests = () => {
describe('Safe Selector[balanceSelector]', () => {
it('should return 0 when safe address is not found', () => {

View File

@ -11,6 +11,7 @@ import { sleep } from '~/utils/timer'
import { getProviderInfo } 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'
export const renderSafe = async (localStore: Store<GlobalState>) => {
const provider = await getProviderInfo()
@ -28,7 +29,7 @@ export const renderSafe = async (localStore: Store<GlobalState>) => {
)
}
const deploySafe = async (safe: React$Component<{}>) => {
const deploySafe = async (safe: React$Component<{}>, dailyLimit: string) => {
const inputs = TestUtils.scryRenderedDOMComponentsWithTag(safe, 'input')
const fieldName = inputs[0]
const fieldOwners = inputs[1]
@ -42,7 +43,7 @@ const deploySafe = async (safe: React$Component<{}>) => {
TestUtils.Simulate.change(fieldName, { target: { value: 'Adolfo Safe' } })
TestUtils.Simulate.change(fieldConfirmations, { target: { value: '1' } })
TestUtils.Simulate.change(ownerName, { target: { value: 'Adolfo Eth Account' } })
TestUtils.Simulate.change(fieldDailyLimit, { target: { value: '10' } })
TestUtils.Simulate.change(fieldDailyLimit, { target: { value: dailyLimit } })
const form = TestUtils.findRenderedDOMComponentWithTag(safe, 'form')
@ -52,7 +53,7 @@ const deploySafe = async (safe: React$Component<{}>) => {
// giving some time to the component for updating its state with safe
// before destroying its context
await sleep(1500)
await sleep(3500)
// THEN
const deployed = TestUtils.findRenderedDOMComponentWithClass(safe, DEPLOYED_COMPONENT_ID)
@ -66,9 +67,21 @@ const deploySafe = async (safe: React$Component<{}>) => {
return transactionHash
}
export const aDeployedSafe = async (specificStore: Store<GlobalState>) => {
export const aDeployedSafe = async (specificStore: Store<GlobalState>, dailyLimit?: number = 0.5) => {
const safe: React$Component<{}> = await renderSafe(specificStore)
const deployedSafe = deploySafe(safe)
const deployedSafe = await deploySafe(safe, `${dailyLimit}`)
return deployedSafe
return deployedSafe.logs[1].args.proxy
}
export const executeWithdrawnOn = async (safeAddress: string, value: number) => {
const providerInfo = await getProviderInfo()
const userAddress = providerInfo.account
const values = {
[DESTINATION_PARAM]: userAddress,
[VALUE_PARAM]: `${value}`,
}
return withdrawn(values, safeAddress, userAddress)
}

View File

@ -1,6 +1,6 @@
// @flow
import { makeSafe, type Safe } from '~/routes/safe/store/model/safe'
import { buildOwnersFrom } from '~/routes/safe/store/actions'
import { buildOwnersFrom, buildDailyLimitFrom } from '~/routes/safe/store/actions'
class SafeBuilder {
safe: Safe
@ -24,8 +24,9 @@ class SafeBuilder {
return this
}
withDailyLimit(limit: number) {
this.safe = this.safe.set('dailyLimit', limit)
withDailyLimit(limit: number, spentToday: number = 0) {
const dailyLimit = buildDailyLimitFrom(limit, spentToday)
this.safe = this.safe.set('dailyLimit', dailyLimit)
return this
}
@ -59,7 +60,19 @@ export class SafeFactory {
['Adol Metamask', 'Tobias Metamask'],
['0x03db1a8b26d08df23337e9276a36b474510f0023', '0x03db1a8b26d08df23337e9276a36b474510f0024'],
)
.withDailyLimit(10, 1.34)
.get()
static dailyLimitSafe = (dailyLimit: number, spentToday: number) => aSafe()
.withAddress('0x03db1a8b26d08df23337e9276a36b474510f0026')
.withName('Adol & Tobias Safe')
.withConfirmations(2)
.withOwner(
['Adol Metamask', 'Tobias Metamask'],
['0x03db1a8b26d08df23337e9276a36b474510f0023', '0x03db1a8b26d08df23337e9276a36b474510f0024'],
)
.withDailyLimit(dailyLimit, spentToday)
.get()
}
export default aSafe

View File

@ -0,0 +1,51 @@
// @flow
import { SAFE_REDUCER_ID } from '~/routes/safe/store/reducer/safe'
import fetchDailyLimit from '~/routes/safe/store/actions/fetchDailyLimit'
import { aNewStore } from '~/store'
import { addEtherTo } from '~/test/addEtherTo'
import { aDeployedSafe, executeWithdrawnOn } from './builder/deployedSafe.builder'
const updateDailyLimitReducerTests = () => {
describe('Safe Actions[updateDailyLimit]', () => {
let store
beforeEach(async () => {
store = aNewStore()
})
it('reducer should return 0 as spentToday value from just deployed safe', async () => {
// GIVEN
const dailyLimitValue = 0.5
const safeAddress = await aDeployedSafe(store, 0.5)
// WHEN
await store.dispatch(fetchDailyLimit(safeAddress))
// THEN
const safes = store.getState()[SAFE_REDUCER_ID]
const dailyLimit = safes.get(safeAddress).get('dailyLimit')
expect(dailyLimit).not.toBe(undefined)
expect(dailyLimit.value).toBe(dailyLimitValue)
expect(dailyLimit.spentToday).toBe(0)
})
it('reducer should return 0.1456 ETH as spentToday if the user has withdrawn 0.1456 from MAX of 0.3 ETH', async () => {
// GIVEN
const dailyLimitValue = 0.3
const safeAddress = await aDeployedSafe(store, dailyLimitValue)
await addEtherTo(safeAddress, '0.5')
const value = 0.1456
// WHEN
await executeWithdrawnOn(safeAddress, value)
await store.dispatch(fetchDailyLimit(safeAddress))
// THEN
const safes = store.getState()[SAFE_REDUCER_ID]
const dailyLimit = safes.get(safeAddress).get('dailyLimit')
expect(dailyLimit).not.toBe(undefined)
expect(dailyLimit.value).toBe(dailyLimitValue)
expect(dailyLimit.spentToday).toBe(value)
})
})
}
export default updateDailyLimitReducerTests

View File

@ -4,17 +4,9 @@ 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 { safeSelector } from '../selectors'
const buildMathPropsFrom = (address): Match => ({
params: {
address,
},
isExact: true,
path: '',
url: '',
})
const safeSelectorTests = () => {
describe('Safe Selector[safeSelector]', () => {
it('should return empty list when no safes', () => {

View File

@ -1,6 +1,7 @@
// @flow
import balanceReducerTests from './balance.reducer'
import safeReducerTests from './safe.reducer'
import dailyLimitReducerTests from './dailyLimit.reducer'
import balanceSelectorTests from './balance.selector'
import safeSelectorTests from './safe.selector'
@ -8,6 +9,7 @@ describe('Safe Test suite', () => {
// ACTIONS AND REDUCERS
safeReducerTests()
balanceReducerTests()
dailyLimitReducerTests()
// SAFE SELECTOR
safeSelectorTests()

View File

@ -34,7 +34,7 @@ const SafeTable = ({ safes }: Props) => (
<TableCell padding="none">{safe.get('address')}</TableCell>
<TableCell padding="none" numeric>{safe.get('confirmations')}</TableCell>
<TableCell padding="none" numeric>{safe.get('owners').count()}</TableCell>
<TableCell padding="none" numeric>{`${safe.get('dailyLimit')} ETH`}</TableCell>
<TableCell padding="none" numeric>{`${safe.get('dailyLimit').get('value')} ETH`}</TableCell>
</TableRow>
))}
</TableBody>

10
src/test/addEtherTo.js Normal file
View File

@ -0,0 +1,10 @@
// @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))
}

View File

@ -0,0 +1,11 @@
// @flow
import { type Match } from 'react-router-dom'
export const buildMathPropsFrom = (address: string): Match => ({
params: {
address,
},
isExact: true,
path: '',
url: '',
})

View File

@ -3,10 +3,10 @@ import contract from 'truffle-contract'
import { promisify } from '~/utils/promisify'
import { ensureOnce } from '~/utils/singleton'
import { getWeb3 } from '~/wallets/getWeb3'
import GnosisSafeSol from '#/GnosisSafe.json'
import GnosisSafeSol from '#/GnosisSafeTeamEdition.json'
import ProxyFactorySol from '#/ProxyFactory.json'
import CreateAndAddExtensionSol from '#/CreateAndAddExtension.json'
import DailyLimitExtensionSol from '#/DailyLimitExtension.json'
import CreateAndAddModule from '#/CreateAndAddModule.json'
import DailyLimitModule from '#/DailyLimitModule.json'
let proxyFactoryMaster
let createAndAddExtensionMaster
@ -28,23 +28,23 @@ const createProxyFactoryContract = (web3: any) => {
}
const createAddExtensionContract = (web3: any) => {
const createAndAddExtension = contract(CreateAndAddExtensionSol)
createAndAddExtension.setProvider(web3.currentProvider)
const createAndAddModule = contract(CreateAndAddModule)
createAndAddModule.setProvider(web3.currentProvider)
return createAndAddExtension
return createAndAddModule
}
const createDailyLimitExtensionContract = (web3: any) => {
const dailyLimitExtension = contract(DailyLimitExtensionSol)
dailyLimitExtension.setProvider(web3.currentProvider)
const dailyLimitModule = contract(DailyLimitModule)
dailyLimitModule.setProvider(web3.currentProvider)
return dailyLimitExtension
return dailyLimitModule
}
export const getGnosisSafeContract = ensureOnce(createGnosisSafeContract)
const getCreateProxyFactoryContract = ensureOnce(createProxyFactoryContract)
const getCreateAddExtensionContract = ensureOnce(createAddExtensionContract)
const getCreateDailyLimitExtensionContract = ensureOnce(createDailyLimitExtensionContract)
export const getCreateDailyLimitExtensionContract = ensureOnce(createDailyLimitExtensionContract)
const createMasterCopies = async () => {
const web3 = getWeb3()
@ -86,19 +86,28 @@ const createMasterCopies = async () => {
export const initContracts = ensureOnce(createMasterCopies)
const getSafeDataBasedOn = async (accounts, numConfirmations) => {
const extensionData = await dailyLimitMaster.contract.setup
.getData([0], [100])
const getSafeDataBasedOn = async (accounts, numConfirmations, dailyLimitInEth) => {
const web3 = getWeb3()
const moduleData = await dailyLimitMaster.contract.setup
.getData([0], [web3.toWei(dailyLimitInEth, 'ether')])
const proxyFactoryData = await proxyFactoryMaster.contract.createProxy
.getData(dailyLimitMaster.address, extensionData)
const createAndAddExtensionData = createAndAddExtensionMaster.contract.createAndAddExtension
.getData(dailyLimitMaster.address, moduleData)
const createAndAddExtensionData = createAndAddExtensionMaster.contract.createAndAddModule
.getData(proxyFactoryMaster.address, proxyFactoryData)
return safeMaster.contract.setup
.getData(accounts, numConfirmations, createAndAddExtensionMaster.address, createAndAddExtensionData)
}
export const deploySafeContract = async (safeAccounts: string[], numConfirmations: number, userAccount: string) => {
const gnosisSafeData = await getSafeDataBasedOn(safeAccounts, numConfirmations)
export const deploySafeContract = async (
safeAccounts: string[],
numConfirmations: number,
dailyLimit: number,
userAccount: string,
) => {
const gnosisSafeData = await getSafeDataBasedOn(safeAccounts, numConfirmations, dailyLimit)
return proxyFactoryMaster.createProxy(safeMaster.address, gnosisSafeData, { from: userAccount, gas: '5000000' })
}

View File

@ -10477,9 +10477,9 @@ sockjs@0.3.19:
faye-websocket "^0.10.0"
uuid "^3.0.1"
solc@0.4.21, solc@^0.4.2:
version "0.4.21"
resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.21.tgz#6a7ecd505bfa0fc268330d5de6b9ae65c8c68264"
solc@0.4.23:
version "0.4.23"
resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.23.tgz#54a0ff4015827b32fddb62c0a418b5247310a58e"
dependencies:
fs-extra "^0.30.0"
memorystream "^0.3.1"
@ -10505,6 +10505,16 @@ solc@^0.3.6:
require-from-string "^1.1.0"
yargs "^4.7.1"
solc@^0.4.2:
version "0.4.21"
resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.21.tgz#6a7ecd505bfa0fc268330d5de6b9ae65c8c68264"
dependencies:
fs-extra "^0.30.0"
memorystream "^0.3.1"
require-from-string "^1.1.0"
semver "^5.3.0"
yargs "^4.7.1"
solidity-parser@^0.1.0, solidity-parser@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/solidity-parser/-/solidity-parser-0.1.1.tgz#0fb3b665ed7041bef4575962ee426e7cd9d0a90a"
@ -11252,13 +11262,13 @@ truffle-solidity-loader@0.0.8:
truffle "^2.0.8"
web3 "^0.17.0-alpha"
truffle@4.1.5:
version "4.1.5"
resolved "https://registry.yarnpkg.com/truffle/-/truffle-4.1.5.tgz#763c8175fe5ea1ada92aa7a02eff84b4ab272f72"
truffle@4.1.8:
version "4.1.8"
resolved "https://registry.yarnpkg.com/truffle/-/truffle-4.1.8.tgz#b0b9175e0270145999567a3f0a2337c914a23a9c"
dependencies:
mocha "^3.4.2"
original-require "^1.0.1"
solc "0.4.21"
solc "0.4.23"
truffle@^2.0.8:
version "2.1.2"