Merge pull request #70 from gnosis/development
Feature - Safe route [updated safe-contracts and transaction-history-service]
This commit is contained in:
commit
f6f37dd1a0
|
@ -34,6 +34,8 @@ before_script:
|
|||
# Give some time to docker to enable all services
|
||||
- sleep 15
|
||||
- cd ..
|
||||
script:
|
||||
- yarn build
|
||||
after_success:
|
||||
- cd safe-transaction-history
|
||||
- docker-compose stop
|
||||
|
|
|
@ -68,7 +68,6 @@ Add additional notes about how to deploy this on a live system
|
|||
* [Material UI 1.X](https://material-ui-next.com/) - React components that implement Google's Material Design
|
||||
* [redux, immutable, reselect, final-form](https://redux.js.org/) - React ecosystem libraries
|
||||
* [Flow](https://flow.org/) - Sttic Type Checker
|
||||
* [Surge](https://surge.sh/) - Static web publishing for generating staging links on GitHub
|
||||
|
||||
## Contributing
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -50,40 +50,40 @@
|
|||
"type": "fallback"
|
||||
}
|
||||
],
|
||||
"bytecode": "0x608060405234801561001057600080fd5b506040516102fc3803806102fc83398101806040528101908080519060200190929190805182019291905050508160008173ffffffffffffffffffffffffffffffffffffffff16141515156100f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506000815111156101805773ffffffffffffffffffffffffffffffffffffffff60005416600080835160208501846127105a03f46040513d6000823e600082141561017c573d81fd5b5050505b505061016b806101916000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634555d5c91461008b5780635c60da1b146100b6575b73ffffffffffffffffffffffffffffffffffffffff600054163660008037600080366000845af43d6000803e6000811415610086573d6000fd5b3d6000f35b34801561009757600080fd5b506100a061010d565b6040518082815260200191505060405180910390f35b3480156100c257600080fd5b506100cb610116565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60006002905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050905600a165627a7a72305820bab5357556c704bffef0f96326dd27742408be175057ffd8f4f58237314cfd520029",
|
||||
"deployedBytecode": "0x60806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634555d5c91461008b5780635c60da1b146100b6575b73ffffffffffffffffffffffffffffffffffffffff600054163660008037600080366000845af43d6000803e6000811415610086573d6000fd5b3d6000f35b34801561009757600080fd5b506100a061010d565b6040518082815260200191505060405180910390f35b3480156100c257600080fd5b506100cb610116565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60006002905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050905600a165627a7a72305820bab5357556c704bffef0f96326dd27742408be175057ffd8f4f58237314cfd520029",
|
||||
"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:13;578:11;:16;;;;570:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;658:11;645:10;;:24;;;;;;;;;;;;;;;;;;508:168;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:-;;;;;;;;;;;;;;;;;;;;;;;;;;955:42:13;951:1;945:8;941:57;1030:14;1027:1;1024;1011:34;1125:1;1122;1106:14;1103:1;1091:10;1086:3;1073:54;1161:16;1158:1;1155;1140:38;1206:1;1197:7;1194:14;1191:2;;;1221:16;1218:1;1211:27;1191:2;1263:16;1260:1;1253:27;1426:104;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1426:104:13;;;;;;;;;;;;;;;;;;;;;;;1302:118;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1302:118:13;;;;;;;;;;;;;;;;;;;;;;;;;;;1426:104;1492:7;1522:1;1515:8;;1426:104;:::o;1302:118::-;1373:7;1403:10;;;;;;;;;;;1396:17;;1302:118;:::o",
|
||||
"bytecode": "0x608060405234801561001057600080fd5b506040516102fc3803806102fc83398101806040528101908080519060200190929190805182019291905050508160008173ffffffffffffffffffffffffffffffffffffffff16141515156100f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506000815111156101805773ffffffffffffffffffffffffffffffffffffffff60005416600080835160208501846127105a03f46040513d6000823e600082141561017c573d81fd5b5050505b505061016b806101916000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634555d5c91461008b5780635c60da1b146100b6575b73ffffffffffffffffffffffffffffffffffffffff600054163660008037600080366000845af43d6000803e6000811415610086573d6000fd5b3d6000f35b34801561009757600080fd5b506100a061010d565b6040518082815260200191505060405180910390f35b3480156100c257600080fd5b506100cb610116565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60006002905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050905600a165627a7a72305820b2de5726e0943c0fae0f20300b651ccee9090eab24beaf21fd7dbc55f5eef5970029",
|
||||
"deployedBytecode": "0x60806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634555d5c91461008b5780635c60da1b146100b6575b73ffffffffffffffffffffffffffffffffffffffff600054163660008037600080366000845af43d6000803e6000811415610086573d6000fd5b3d6000f35b34801561009757600080fd5b506100a061010d565b6040518082815260200191505060405180910390f35b3480156100c257600080fd5b506100cb610116565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60006002905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050905600a165627a7a72305820b2de5726e0943c0fae0f20300b651ccee9090eab24beaf21fd7dbc55f5eef5970029",
|
||||
"sourceMap": "355:882:21:-;;;610:625;8:9:-1;5:2;;;30:1;27;20:12;5:2;610:625:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;668:11;593:1:23;578:11;:16;;;;570:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;658:11;645:10;;:24;;;;;;;;;;;;;;;;;;508:168;735:1:21;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:21:-;;;;;;;;;;;;;;;;;;;;;;;;;;955:42:23;951:1;945:8;941:57;1030:14;1027:1;1024;1011:34;1125:1;1122;1106:14;1103:1;1091:10;1086:3;1073:54;1161:16;1158:1;1155;1140:38;1206:1;1197:7;1194:14;1191:2;;;1221:16;1218:1;1211:27;1191:2;1263:16;1260:1;1253:27;1426:104;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1426:104:23;;;;;;;;;;;;;;;;;;;;;;;1302:118;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1302:118:23;;;;;;;;;;;;;;;;;;;;;;;;;;;1426:104;1492:7;1522:1;1515:8;;1426:104;:::o;1302:118::-;1373:7;1403:10;;;;;;;;;;;1396:17;;1302:118;:::o",
|
||||
"source": "pragma solidity 0.4.24;\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",
|
||||
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/proxies/DelegateConstructorProxy.sol",
|
||||
"ast": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/DelegateConstructorProxy.sol",
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/proxies/DelegateConstructorProxy.sol",
|
||||
"exportedSymbols": {
|
||||
"DelegateConstructorProxy": [
|
||||
23
|
||||
2740
|
||||
]
|
||||
},
|
||||
"id": 24,
|
||||
"id": 2741,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1,
|
||||
"id": 2718,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:0"
|
||||
"src": "0:23:21"
|
||||
},
|
||||
{
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Proxy.sol",
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/proxies/Proxy.sol",
|
||||
"file": "./Proxy.sol",
|
||||
"id": 2,
|
||||
"id": 2719,
|
||||
"nodeType": "ImportDirective",
|
||||
"scope": 24,
|
||||
"sourceUnit": 1689,
|
||||
"src": "24:21:0",
|
||||
"scope": 2741,
|
||||
"sourceUnit": 2841,
|
||||
"src": "24:21:21",
|
||||
"symbolAliases": [],
|
||||
"unitAlias": ""
|
||||
},
|
||||
|
@ -93,40 +93,40 @@
|
|||
"arguments": null,
|
||||
"baseName": {
|
||||
"contractScope": null,
|
||||
"id": 3,
|
||||
"id": 2720,
|
||||
"name": "Proxy",
|
||||
"nodeType": "UserDefinedTypeName",
|
||||
"referencedDeclaration": 1688,
|
||||
"src": "392:5:0",
|
||||
"referencedDeclaration": 2840,
|
||||
"src": "392:5:21",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_contract$_Proxy_$1688",
|
||||
"typeIdentifier": "t_contract$_Proxy_$2840",
|
||||
"typeString": "contract Proxy"
|
||||
}
|
||||
},
|
||||
"id": 4,
|
||||
"id": 2721,
|
||||
"nodeType": "InheritanceSpecifier",
|
||||
"src": "392:5:0"
|
||||
"src": "392:5:21"
|
||||
}
|
||||
],
|
||||
"contractDependencies": [
|
||||
1688
|
||||
2840
|
||||
],
|
||||
"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,
|
||||
"id": 2740,
|
||||
"linearizedBaseContracts": [
|
||||
23,
|
||||
1688
|
||||
2740,
|
||||
2840
|
||||
],
|
||||
"name": "DelegateConstructorProxy",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 21,
|
||||
"id": 2738,
|
||||
"nodeType": "Block",
|
||||
"src": "700:535:0",
|
||||
"src": "700:535:21",
|
||||
"statements": [
|
||||
{
|
||||
"condition": {
|
||||
|
@ -135,7 +135,7 @@
|
|||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
},
|
||||
"id": 17,
|
||||
"id": 2734,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -144,18 +144,18 @@
|
|||
"argumentTypes": null,
|
||||
"expression": {
|
||||
"argumentTypes": null,
|
||||
"id": 14,
|
||||
"id": 2731,
|
||||
"name": "initializer",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 8,
|
||||
"src": "714:11:0",
|
||||
"referencedDeclaration": 2725,
|
||||
"src": "714:11:21",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_memory_ptr",
|
||||
"typeString": "bytes memory"
|
||||
}
|
||||
},
|
||||
"id": 15,
|
||||
"id": 2732,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -163,7 +163,7 @@
|
|||
"memberName": "length",
|
||||
"nodeType": "MemberAccess",
|
||||
"referencedDeclaration": null,
|
||||
"src": "714:18:0",
|
||||
"src": "714:18:21",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
|
@ -174,14 +174,14 @@
|
|||
"rightExpression": {
|
||||
"argumentTypes": null,
|
||||
"hexValue": "30",
|
||||
"id": 16,
|
||||
"id": 2733,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "number",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "735:1:0",
|
||||
"src": "735:1:21",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_rational_0_by_1",
|
||||
|
@ -189,46 +189,46 @@
|
|||
},
|
||||
"value": "0"
|
||||
},
|
||||
"src": "714:22:0",
|
||||
"src": "714:22:21",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
}
|
||||
},
|
||||
"falseBody": null,
|
||||
"id": 20,
|
||||
"id": 2737,
|
||||
"nodeType": "IfStatement",
|
||||
"src": "710:519:0",
|
||||
"src": "710:519:21",
|
||||
"trueBody": {
|
||||
"id": 19,
|
||||
"id": 2736,
|
||||
"nodeType": "Block",
|
||||
"src": "738:491:0",
|
||||
"src": "738:491:21",
|
||||
"statements": [
|
||||
{
|
||||
"externalReferences": [
|
||||
{
|
||||
"initializer": {
|
||||
"declaration": 8,
|
||||
"declaration": 2725,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1000:11:0",
|
||||
"src": "1026:11:21",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"initializer": {
|
||||
"declaration": 8,
|
||||
"declaration": 2725,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1026:11:0",
|
||||
"src": "1000:11:21",
|
||||
"valueSize": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": 18,
|
||||
"id": 2735,
|
||||
"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"
|
||||
"src": "820:409:21"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -236,7 +236,7 @@
|
|||
]
|
||||
},
|
||||
"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,
|
||||
"id": 2739,
|
||||
"implemented": true,
|
||||
"isConstructor": true,
|
||||
"isDeclaredConst": false,
|
||||
|
@ -245,49 +245,49 @@
|
|||
"arguments": [
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"id": 11,
|
||||
"id": 2728,
|
||||
"name": "_masterCopy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 6,
|
||||
"src": "668:11:0",
|
||||
"referencedDeclaration": 2723,
|
||||
"src": "668:11:21",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": 12,
|
||||
"id": 2729,
|
||||
"modifierName": {
|
||||
"argumentTypes": null,
|
||||
"id": 10,
|
||||
"id": 2727,
|
||||
"name": "Proxy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 1688,
|
||||
"src": "662:5:0",
|
||||
"referencedDeclaration": 2840,
|
||||
"src": "662:5:21",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_type$_t_contract$_Proxy_$1688_$",
|
||||
"typeIdentifier": "t_type$_t_contract$_Proxy_$2840_$",
|
||||
"typeString": "type(contract Proxy)"
|
||||
}
|
||||
},
|
||||
"nodeType": "ModifierInvocation",
|
||||
"src": "662:18:0"
|
||||
"src": "662:18:21"
|
||||
}
|
||||
],
|
||||
"name": "",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 9,
|
||||
"id": 2726,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 6,
|
||||
"id": 2723,
|
||||
"name": "_masterCopy",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 22,
|
||||
"src": "622:19:0",
|
||||
"scope": 2739,
|
||||
"src": "622:19:21",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -295,10 +295,10 @@
|
|||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 5,
|
||||
"id": 2722,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "622:7:0",
|
||||
"src": "622:7:21",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -309,11 +309,11 @@
|
|||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 8,
|
||||
"id": 2725,
|
||||
"name": "initializer",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 22,
|
||||
"src": "643:17:0",
|
||||
"scope": 2739,
|
||||
"src": "643:17:21",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -321,10 +321,10 @@
|
|||
"typeString": "bytes"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 7,
|
||||
"id": 2724,
|
||||
"name": "bytes",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "643:5:0",
|
||||
"src": "643:5:21",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_storage_ptr",
|
||||
"typeString": "bytes"
|
||||
|
@ -334,56 +334,56 @@
|
|||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "621:40:0"
|
||||
"src": "621:40:21"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 13,
|
||||
"id": 2730,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "700:0:0"
|
||||
"src": "700:0:21"
|
||||
},
|
||||
"scope": 23,
|
||||
"src": "610:625:0",
|
||||
"scope": 2740,
|
||||
"src": "610:625:21",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 24,
|
||||
"src": "355:882:0"
|
||||
"scope": 2741,
|
||||
"src": "355:882:21"
|
||||
}
|
||||
],
|
||||
"src": "0:1238:0"
|
||||
"src": "0:1238:21"
|
||||
},
|
||||
"legacyAST": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/DelegateConstructorProxy.sol",
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/proxies/DelegateConstructorProxy.sol",
|
||||
"exportedSymbols": {
|
||||
"DelegateConstructorProxy": [
|
||||
23
|
||||
2740
|
||||
]
|
||||
},
|
||||
"id": 24,
|
||||
"id": 2741,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1,
|
||||
"id": 2718,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:0"
|
||||
"src": "0:23:21"
|
||||
},
|
||||
{
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Proxy.sol",
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/proxies/Proxy.sol",
|
||||
"file": "./Proxy.sol",
|
||||
"id": 2,
|
||||
"id": 2719,
|
||||
"nodeType": "ImportDirective",
|
||||
"scope": 24,
|
||||
"sourceUnit": 1689,
|
||||
"src": "24:21:0",
|
||||
"scope": 2741,
|
||||
"sourceUnit": 2841,
|
||||
"src": "24:21:21",
|
||||
"symbolAliases": [],
|
||||
"unitAlias": ""
|
||||
},
|
||||
|
@ -393,40 +393,40 @@
|
|||
"arguments": null,
|
||||
"baseName": {
|
||||
"contractScope": null,
|
||||
"id": 3,
|
||||
"id": 2720,
|
||||
"name": "Proxy",
|
||||
"nodeType": "UserDefinedTypeName",
|
||||
"referencedDeclaration": 1688,
|
||||
"src": "392:5:0",
|
||||
"referencedDeclaration": 2840,
|
||||
"src": "392:5:21",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_contract$_Proxy_$1688",
|
||||
"typeIdentifier": "t_contract$_Proxy_$2840",
|
||||
"typeString": "contract Proxy"
|
||||
}
|
||||
},
|
||||
"id": 4,
|
||||
"id": 2721,
|
||||
"nodeType": "InheritanceSpecifier",
|
||||
"src": "392:5:0"
|
||||
"src": "392:5:21"
|
||||
}
|
||||
],
|
||||
"contractDependencies": [
|
||||
1688
|
||||
2840
|
||||
],
|
||||
"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,
|
||||
"id": 2740,
|
||||
"linearizedBaseContracts": [
|
||||
23,
|
||||
1688
|
||||
2740,
|
||||
2840
|
||||
],
|
||||
"name": "DelegateConstructorProxy",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 21,
|
||||
"id": 2738,
|
||||
"nodeType": "Block",
|
||||
"src": "700:535:0",
|
||||
"src": "700:535:21",
|
||||
"statements": [
|
||||
{
|
||||
"condition": {
|
||||
|
@ -435,7 +435,7 @@
|
|||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
},
|
||||
"id": 17,
|
||||
"id": 2734,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -444,18 +444,18 @@
|
|||
"argumentTypes": null,
|
||||
"expression": {
|
||||
"argumentTypes": null,
|
||||
"id": 14,
|
||||
"id": 2731,
|
||||
"name": "initializer",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 8,
|
||||
"src": "714:11:0",
|
||||
"referencedDeclaration": 2725,
|
||||
"src": "714:11:21",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_memory_ptr",
|
||||
"typeString": "bytes memory"
|
||||
}
|
||||
},
|
||||
"id": 15,
|
||||
"id": 2732,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -463,7 +463,7 @@
|
|||
"memberName": "length",
|
||||
"nodeType": "MemberAccess",
|
||||
"referencedDeclaration": null,
|
||||
"src": "714:18:0",
|
||||
"src": "714:18:21",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
|
@ -474,14 +474,14 @@
|
|||
"rightExpression": {
|
||||
"argumentTypes": null,
|
||||
"hexValue": "30",
|
||||
"id": 16,
|
||||
"id": 2733,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "number",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "735:1:0",
|
||||
"src": "735:1:21",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_rational_0_by_1",
|
||||
|
@ -489,46 +489,46 @@
|
|||
},
|
||||
"value": "0"
|
||||
},
|
||||
"src": "714:22:0",
|
||||
"src": "714:22:21",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
}
|
||||
},
|
||||
"falseBody": null,
|
||||
"id": 20,
|
||||
"id": 2737,
|
||||
"nodeType": "IfStatement",
|
||||
"src": "710:519:0",
|
||||
"src": "710:519:21",
|
||||
"trueBody": {
|
||||
"id": 19,
|
||||
"id": 2736,
|
||||
"nodeType": "Block",
|
||||
"src": "738:491:0",
|
||||
"src": "738:491:21",
|
||||
"statements": [
|
||||
{
|
||||
"externalReferences": [
|
||||
{
|
||||
"initializer": {
|
||||
"declaration": 8,
|
||||
"declaration": 2725,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1000:11:0",
|
||||
"src": "1026:11:21",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"initializer": {
|
||||
"declaration": 8,
|
||||
"declaration": 2725,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1026:11:0",
|
||||
"src": "1000:11:21",
|
||||
"valueSize": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": 18,
|
||||
"id": 2735,
|
||||
"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"
|
||||
"src": "820:409:21"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -536,7 +536,7 @@
|
|||
]
|
||||
},
|
||||
"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,
|
||||
"id": 2739,
|
||||
"implemented": true,
|
||||
"isConstructor": true,
|
||||
"isDeclaredConst": false,
|
||||
|
@ -545,49 +545,49 @@
|
|||
"arguments": [
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"id": 11,
|
||||
"id": 2728,
|
||||
"name": "_masterCopy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 6,
|
||||
"src": "668:11:0",
|
||||
"referencedDeclaration": 2723,
|
||||
"src": "668:11:21",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": 12,
|
||||
"id": 2729,
|
||||
"modifierName": {
|
||||
"argumentTypes": null,
|
||||
"id": 10,
|
||||
"id": 2727,
|
||||
"name": "Proxy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 1688,
|
||||
"src": "662:5:0",
|
||||
"referencedDeclaration": 2840,
|
||||
"src": "662:5:21",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_type$_t_contract$_Proxy_$1688_$",
|
||||
"typeIdentifier": "t_type$_t_contract$_Proxy_$2840_$",
|
||||
"typeString": "type(contract Proxy)"
|
||||
}
|
||||
},
|
||||
"nodeType": "ModifierInvocation",
|
||||
"src": "662:18:0"
|
||||
"src": "662:18:21"
|
||||
}
|
||||
],
|
||||
"name": "",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 9,
|
||||
"id": 2726,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 6,
|
||||
"id": 2723,
|
||||
"name": "_masterCopy",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 22,
|
||||
"src": "622:19:0",
|
||||
"scope": 2739,
|
||||
"src": "622:19:21",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -595,10 +595,10 @@
|
|||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 5,
|
||||
"id": 2722,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "622:7:0",
|
||||
"src": "622:7:21",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -609,11 +609,11 @@
|
|||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 8,
|
||||
"id": 2725,
|
||||
"name": "initializer",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 22,
|
||||
"src": "643:17:0",
|
||||
"scope": 2739,
|
||||
"src": "643:17:21",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -621,10 +621,10 @@
|
|||
"typeString": "bytes"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 7,
|
||||
"id": 2724,
|
||||
"name": "bytes",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "643:5:0",
|
||||
"src": "643:5:21",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_storage_ptr",
|
||||
"typeString": "bytes"
|
||||
|
@ -634,27 +634,27 @@
|
|||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "621:40:0"
|
||||
"src": "621:40:21"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 13,
|
||||
"id": 2730,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "700:0:0"
|
||||
"src": "700:0:21"
|
||||
},
|
||||
"scope": 23,
|
||||
"src": "610:625:0",
|
||||
"scope": 2740,
|
||||
"src": "610:625:21",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 24,
|
||||
"src": "355:882:0"
|
||||
"scope": 2741,
|
||||
"src": "355:882:21"
|
||||
}
|
||||
],
|
||||
"src": "0:1238:0"
|
||||
"src": "0:1238:21"
|
||||
},
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
|
@ -662,5 +662,5 @@
|
|||
},
|
||||
"networks": {},
|
||||
"schemaVersion": "2.0.0",
|
||||
"updatedAt": "2018-08-20T07:44:41.083Z"
|
||||
"updatedAt": "2018-10-05T14:25:58.944Z"
|
||||
}
|
|
@ -1,31 +1,31 @@
|
|||
{
|
||||
"contractName": "Enum",
|
||||
"abi": [],
|
||||
"bytecode": "0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a72305820641ab8b295edfaa2b1c8a8e0ae7d17ea2f4c8b95ea27e45d8947ed9a4799ca1f0029",
|
||||
"deployedBytecode": "0x6080604052600080fd00a165627a7a72305820641ab8b295edfaa2b1c8a8e0ae7d17ea2f4c8b95ea27e45d8947ed9a4799ca1f0029",
|
||||
"sourceMap": "115:95:1:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;115:95:1;;;;;;;",
|
||||
"deployedSourceMap": "115:95:1:-;;;;;",
|
||||
"bytecode": "0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a72305820e8f35ac07bd2a835eacbee7ba38b086a012b371f6bdc0da93abfb72fe3b38ec20029",
|
||||
"deployedBytecode": "0x6080604052600080fd00a165627a7a72305820e8f35ac07bd2a835eacbee7ba38b086a012b371f6bdc0da93abfb72fe3b38ec20029",
|
||||
"sourceMap": "115:95:7:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;115:95:7;;;;;;;",
|
||||
"deployedSourceMap": "115:95:7:-;;;;;",
|
||||
"source": "pragma solidity 0.4.24;\n\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract Enum {\n enum Operation {\n Call,\n DelegateCall,\n Create\n }\n}\n",
|
||||
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Enum.sol",
|
||||
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/Enum.sol",
|
||||
"ast": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Enum.sol",
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/Enum.sol",
|
||||
"exportedSymbols": {
|
||||
"Enum": [
|
||||
30
|
||||
1659
|
||||
]
|
||||
},
|
||||
"id": 31,
|
||||
"id": 1660,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 25,
|
||||
"id": 1654,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:1"
|
||||
"src": "0:23:7"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
|
@ -33,66 +33,66 @@
|
|||
"contractKind": "contract",
|
||||
"documentation": "@title Enum - Collection of enums\n @author Richard Meissner - <richard@gnosis.pm>",
|
||||
"fullyImplemented": true,
|
||||
"id": 30,
|
||||
"id": 1659,
|
||||
"linearizedBaseContracts": [
|
||||
30
|
||||
1659
|
||||
],
|
||||
"name": "Enum",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"canonicalName": "Enum.Operation",
|
||||
"id": 29,
|
||||
"id": 1658,
|
||||
"members": [
|
||||
{
|
||||
"id": 26,
|
||||
"id": 1655,
|
||||
"name": "Call",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "160:4:1"
|
||||
"src": "160:4:7"
|
||||
},
|
||||
{
|
||||
"id": 27,
|
||||
"id": 1656,
|
||||
"name": "DelegateCall",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "174:12:1"
|
||||
"src": "174:12:7"
|
||||
},
|
||||
{
|
||||
"id": 28,
|
||||
"id": 1657,
|
||||
"name": "Create",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "196:6:1"
|
||||
"src": "196:6:7"
|
||||
}
|
||||
],
|
||||
"name": "Operation",
|
||||
"nodeType": "EnumDefinition",
|
||||
"src": "135:73:1"
|
||||
"src": "135:73:7"
|
||||
}
|
||||
],
|
||||
"scope": 31,
|
||||
"src": "115:95:1"
|
||||
"scope": 1660,
|
||||
"src": "115:95:7"
|
||||
}
|
||||
],
|
||||
"src": "0:211:1"
|
||||
"src": "0:211:7"
|
||||
},
|
||||
"legacyAST": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Enum.sol",
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/Enum.sol",
|
||||
"exportedSymbols": {
|
||||
"Enum": [
|
||||
30
|
||||
1659
|
||||
]
|
||||
},
|
||||
"id": 31,
|
||||
"id": 1660,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 25,
|
||||
"id": 1654,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:1"
|
||||
"src": "0:23:7"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
|
@ -100,46 +100,46 @@
|
|||
"contractKind": "contract",
|
||||
"documentation": "@title Enum - Collection of enums\n @author Richard Meissner - <richard@gnosis.pm>",
|
||||
"fullyImplemented": true,
|
||||
"id": 30,
|
||||
"id": 1659,
|
||||
"linearizedBaseContracts": [
|
||||
30
|
||||
1659
|
||||
],
|
||||
"name": "Enum",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"canonicalName": "Enum.Operation",
|
||||
"id": 29,
|
||||
"id": 1658,
|
||||
"members": [
|
||||
{
|
||||
"id": 26,
|
||||
"id": 1655,
|
||||
"name": "Call",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "160:4:1"
|
||||
"src": "160:4:7"
|
||||
},
|
||||
{
|
||||
"id": 27,
|
||||
"id": 1656,
|
||||
"name": "DelegateCall",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "174:12:1"
|
||||
"src": "174:12:7"
|
||||
},
|
||||
{
|
||||
"id": 28,
|
||||
"id": 1657,
|
||||
"name": "Create",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "196:6:1"
|
||||
"src": "196:6:7"
|
||||
}
|
||||
],
|
||||
"name": "Operation",
|
||||
"nodeType": "EnumDefinition",
|
||||
"src": "135:73:1"
|
||||
"src": "135:73:7"
|
||||
}
|
||||
],
|
||||
"scope": 31,
|
||||
"src": "115:95:1"
|
||||
"scope": 1660,
|
||||
"src": "115:95:7"
|
||||
}
|
||||
],
|
||||
"src": "0:211:1"
|
||||
"src": "0:211:7"
|
||||
},
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
|
@ -147,5 +147,5 @@
|
|||
},
|
||||
"networks": {},
|
||||
"schemaVersion": "2.0.0",
|
||||
"updatedAt": "2018-08-20T07:44:41.083Z"
|
||||
"updatedAt": "2018-10-05T14:25:58.921Z"
|
||||
}
|
|
@ -7,31 +7,31 @@
|
|||
"type": "fallback"
|
||||
}
|
||||
],
|
||||
"bytecode": "0x6080604052348015600f57600080fd5b50603280601d6000396000f30060806040520000a165627a7a723058208226d93ca47e5b6cb455362823a9ae7ae1ffe3fb79b732dd39f124670f780a070029",
|
||||
"deployedBytecode": "0x60806040520000a165627a7a723058208226d93ca47e5b6cb455362823a9ae7ae1ffe3fb79b732dd39f124670f780a070029",
|
||||
"sourceMap": "167:155:2:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;167:155:2;;;;;;;",
|
||||
"deployedSourceMap": "167:155:2:-;;;",
|
||||
"bytecode": "0x6080604052348015600f57600080fd5b50603280601d6000396000f30060806040520000a165627a7a723058200c4d2e3a714c9a462ec30383030f16e7035d8647c8e18373ebc02f115b5a1d690029",
|
||||
"deployedBytecode": "0x60806040520000a165627a7a723058200c4d2e3a714c9a462ec30383030f16e7035d8647c8e18373ebc02f115b5a1d690029",
|
||||
"sourceMap": "167:155:8:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;167:155:8;;;;;;;",
|
||||
"deployedSourceMap": "167:155:8:-;;;",
|
||||
"source": "pragma solidity 0.4.24;\n\n\n/// @title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract EtherPaymentFallback {\n\n /// @dev Fallback function accepts Ether transactions.\n function ()\n external\n payable\n {\n\n }\n}\n",
|
||||
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/EtherPaymentFallback.sol",
|
||||
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/EtherPaymentFallback.sol",
|
||||
"ast": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/EtherPaymentFallback.sol",
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/EtherPaymentFallback.sol",
|
||||
"exportedSymbols": {
|
||||
"EtherPaymentFallback": [
|
||||
37
|
||||
1666
|
||||
]
|
||||
},
|
||||
"id": 38,
|
||||
"id": 1667,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 32,
|
||||
"id": 1661,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:2"
|
||||
"src": "0:23:8"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
|
@ -39,22 +39,22 @@
|
|||
"contractKind": "contract",
|
||||
"documentation": "@title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n @author Richard Meissner - <richard@gnosis.pm>",
|
||||
"fullyImplemented": true,
|
||||
"id": 37,
|
||||
"id": 1666,
|
||||
"linearizedBaseContracts": [
|
||||
37
|
||||
1666
|
||||
],
|
||||
"name": "EtherPaymentFallback",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 35,
|
||||
"id": 1664,
|
||||
"nodeType": "Block",
|
||||
"src": "312:8:2",
|
||||
"src": "312:8:8",
|
||||
"statements": []
|
||||
},
|
||||
"documentation": "@dev Fallback function accepts Ether transactions.",
|
||||
"id": 36,
|
||||
"id": 1665,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
|
@ -62,50 +62,50 @@
|
|||
"name": "",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 33,
|
||||
"id": 1662,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "272:2:2"
|
||||
"src": "272:2:8"
|
||||
},
|
||||
"payable": true,
|
||||
"returnParameters": {
|
||||
"id": 34,
|
||||
"id": 1663,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "312:0:2"
|
||||
"src": "312:0:8"
|
||||
},
|
||||
"scope": 37,
|
||||
"src": "263:57:2",
|
||||
"scope": 1666,
|
||||
"src": "263:57:8",
|
||||
"stateMutability": "payable",
|
||||
"superFunction": null,
|
||||
"visibility": "external"
|
||||
}
|
||||
],
|
||||
"scope": 38,
|
||||
"src": "167:155:2"
|
||||
"scope": 1667,
|
||||
"src": "167:155:8"
|
||||
}
|
||||
],
|
||||
"src": "0:323:2"
|
||||
"src": "0:323:8"
|
||||
},
|
||||
"legacyAST": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/EtherPaymentFallback.sol",
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/EtherPaymentFallback.sol",
|
||||
"exportedSymbols": {
|
||||
"EtherPaymentFallback": [
|
||||
37
|
||||
1666
|
||||
]
|
||||
},
|
||||
"id": 38,
|
||||
"id": 1667,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 32,
|
||||
"id": 1661,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:2"
|
||||
"src": "0:23:8"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
|
@ -113,22 +113,22 @@
|
|||
"contractKind": "contract",
|
||||
"documentation": "@title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n @author Richard Meissner - <richard@gnosis.pm>",
|
||||
"fullyImplemented": true,
|
||||
"id": 37,
|
||||
"id": 1666,
|
||||
"linearizedBaseContracts": [
|
||||
37
|
||||
1666
|
||||
],
|
||||
"name": "EtherPaymentFallback",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 35,
|
||||
"id": 1664,
|
||||
"nodeType": "Block",
|
||||
"src": "312:8:2",
|
||||
"src": "312:8:8",
|
||||
"statements": []
|
||||
},
|
||||
"documentation": "@dev Fallback function accepts Ether transactions.",
|
||||
"id": 36,
|
||||
"id": 1665,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
|
@ -136,30 +136,30 @@
|
|||
"name": "",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 33,
|
||||
"id": 1662,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "272:2:2"
|
||||
"src": "272:2:8"
|
||||
},
|
||||
"payable": true,
|
||||
"returnParameters": {
|
||||
"id": 34,
|
||||
"id": 1663,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "312:0:2"
|
||||
"src": "312:0:8"
|
||||
},
|
||||
"scope": 37,
|
||||
"src": "263:57:2",
|
||||
"scope": 1666,
|
||||
"src": "263:57:8",
|
||||
"stateMutability": "payable",
|
||||
"superFunction": null,
|
||||
"visibility": "external"
|
||||
}
|
||||
],
|
||||
"scope": 38,
|
||||
"src": "167:155:2"
|
||||
"scope": 1667,
|
||||
"src": "167:155:8"
|
||||
}
|
||||
],
|
||||
"src": "0:323:2"
|
||||
"src": "0:323:8"
|
||||
},
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
|
@ -167,5 +167,5 @@
|
|||
},
|
||||
"networks": {},
|
||||
"schemaVersion": "2.0.0",
|
||||
"updatedAt": "2018-08-20T07:44:41.083Z"
|
||||
"updatedAt": "2018-10-05T14:25:58.922Z"
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,339 @@
|
|||
{
|
||||
"contractName": "ISignatureValidator",
|
||||
"abi": [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_data",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"name": "_signature",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "isValidSignature",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "isValid",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
],
|
||||
"bytecode": "0x",
|
||||
"deployedBytecode": "0x",
|
||||
"sourceMap": "",
|
||||
"deployedSourceMap": "",
|
||||
"source": "pragma solidity 0.4.24;\n\ncontract ISignatureValidator {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param _data Arbitrary length data signed on the behalf of address(this)\n * @param _signature Signature byte array associated with _data\n *\n * MUST return a bool upon valid or invalid signature with corresponding _data\n * MUST take (bytes, bytes) as arguments\n */ \n function isValidSignature(\n bytes _data, \n bytes _signature)\n public\n returns (bool isValid); \n}",
|
||||
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/interfaces/ISignatureValidator.sol",
|
||||
"ast": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/interfaces/ISignatureValidator.sol",
|
||||
"exportedSymbols": {
|
||||
"ISignatureValidator": [
|
||||
1803
|
||||
]
|
||||
},
|
||||
"id": 1804,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1793,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:13"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"documentation": null,
|
||||
"fullyImplemented": false,
|
||||
"id": 1803,
|
||||
"linearizedBaseContracts": [
|
||||
1803
|
||||
],
|
||||
"name": "ISignatureValidator",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": null,
|
||||
"documentation": "@dev Should return whether the signature provided is valid for the provided data\n@param _data Arbitrary length data signed on the behalf of address(this)\n@param _signature Signature byte array associated with _data\n * MUST return a bool upon valid or invalid signature with corresponding _data\nMUST take (bytes, bytes) as arguments",
|
||||
"id": 1802,
|
||||
"implemented": false,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
"modifiers": [],
|
||||
"name": "isValidSignature",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 1798,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1795,
|
||||
"name": "_data",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1802,
|
||||
"src": "476:11:13",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_memory_ptr",
|
||||
"typeString": "bytes"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1794,
|
||||
"name": "bytes",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "476:5:13",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_storage_ptr",
|
||||
"typeString": "bytes"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1797,
|
||||
"name": "_signature",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1802,
|
||||
"src": "498:16:13",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_memory_ptr",
|
||||
"typeString": "bytes"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1796,
|
||||
"name": "bytes",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "498:5:13",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_storage_ptr",
|
||||
"typeString": "bytes"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "466:49:13"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 1801,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1800,
|
||||
"name": "isValid",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1802,
|
||||
"src": "548:12:13",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1799,
|
||||
"name": "bool",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "548:4:13",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "547:14:13"
|
||||
},
|
||||
"scope": 1803,
|
||||
"src": "441:121:13",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 1804,
|
||||
"src": "25:540:13"
|
||||
}
|
||||
],
|
||||
"src": "0:565:13"
|
||||
},
|
||||
"legacyAST": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/interfaces/ISignatureValidator.sol",
|
||||
"exportedSymbols": {
|
||||
"ISignatureValidator": [
|
||||
1803
|
||||
]
|
||||
},
|
||||
"id": 1804,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1793,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:13"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"documentation": null,
|
||||
"fullyImplemented": false,
|
||||
"id": 1803,
|
||||
"linearizedBaseContracts": [
|
||||
1803
|
||||
],
|
||||
"name": "ISignatureValidator",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": null,
|
||||
"documentation": "@dev Should return whether the signature provided is valid for the provided data\n@param _data Arbitrary length data signed on the behalf of address(this)\n@param _signature Signature byte array associated with _data\n * MUST return a bool upon valid or invalid signature with corresponding _data\nMUST take (bytes, bytes) as arguments",
|
||||
"id": 1802,
|
||||
"implemented": false,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
"modifiers": [],
|
||||
"name": "isValidSignature",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 1798,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1795,
|
||||
"name": "_data",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1802,
|
||||
"src": "476:11:13",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_memory_ptr",
|
||||
"typeString": "bytes"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1794,
|
||||
"name": "bytes",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "476:5:13",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_storage_ptr",
|
||||
"typeString": "bytes"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1797,
|
||||
"name": "_signature",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1802,
|
||||
"src": "498:16:13",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_memory_ptr",
|
||||
"typeString": "bytes"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1796,
|
||||
"name": "bytes",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "498:5:13",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_storage_ptr",
|
||||
"typeString": "bytes"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "466:49:13"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 1801,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1800,
|
||||
"name": "isValid",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1802,
|
||||
"src": "548:12:13",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1799,
|
||||
"name": "bool",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "548:4:13",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "547:14:13"
|
||||
},
|
||||
"scope": 1803,
|
||||
"src": "441:121:13",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 1804,
|
||||
"src": "25:540:13"
|
||||
}
|
||||
],
|
||||
"src": "0:565:13"
|
||||
},
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
"version": "0.4.24+commit.e67f0147.Emscripten.clang"
|
||||
},
|
||||
"networks": {},
|
||||
"schemaVersion": "2.0.0",
|
||||
"updatedAt": "2018-10-05T14:25:58.938Z"
|
||||
}
|
|
@ -16,40 +16,40 @@
|
|||
"type": "function"
|
||||
}
|
||||
],
|
||||
"bytecode": "0x608060405234801561001057600080fd5b50610276806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637de7edef14610046575b600080fd5b34801561005257600080fd5b50610087600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610089565b005b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff1614151515610207576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a72305820243ca7a44eb0464a47c14309cc3a29e407df6e966674981a787df22c0d9280220029",
|
||||
"deployedBytecode": "0x608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637de7edef14610046575b600080fd5b34801561005257600080fd5b50610087600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610089565b005b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff1614151515610207576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a72305820243ca7a44eb0464a47c14309cc3a29e407df6e966674981a787df22c0d9280220029",
|
||||
"sourceMap": "203:673:7:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;203:673:7;;;;;;;",
|
||||
"deployedSourceMap": "203:673:7:-;;;;;;;;;;;;;;;;;;;;;;;;626:248;;8:9:-1;5:2;;;30:1;27;20:12;5:2;626:248:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;244:4:16;222:27;;:10;:27;;;214:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;791:1:7;776:11;:16;;;;768:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;856:11;843:10;;:24;;;;;;;;;;;;;;;;;;626:248;:::o",
|
||||
"bytecode": "0x608060405234801561001057600080fd5b50610276806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637de7edef14610046575b600080fd5b34801561005257600080fd5b50610087600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610089565b005b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff1614151515610207576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a7230582035e9d5d611938f796affd4397aed671c5c4079783e0a67a874440cb154a411440029",
|
||||
"deployedBytecode": "0x608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637de7edef14610046575b600080fd5b34801561005257600080fd5b50610087600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610089565b005b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff1614151515610207576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a7230582035e9d5d611938f796affd4397aed671c5c4079783e0a67a874440cb154a411440029",
|
||||
"sourceMap": "203:673:9:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;203:673:9;;;;;;;",
|
||||
"deployedSourceMap": "203:673:9:-;;;;;;;;;;;;;;;;;;;;;;;;626:248;;8:9:-1;5:2;;;30:1;27;20:12;5:2;626:248:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;244:4:11;222:27;;:10;:27;;;214:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;791:1:9;776:11;:16;;;;768:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;856:11;843:10;;:24;;;;;;;;;;;;;;;;;;626:248;:::o",
|
||||
"source": "pragma solidity 0.4.24;\nimport \"./SelfAuthorized.sol\";\n\n\n/// @title MasterCopy - Base for master copy contracts (should always be first super contract)\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract MasterCopy is SelfAuthorized {\n // masterCopy always needs to be first declared variable, to ensure that it is at the same location as in the Proxy contract.\n // It should also always be ensured that the address is stored alone (uses a full word)\n address masterCopy;\n\n /// @dev Allows to upgrade the contract. This can only be done via a Safe transaction.\n /// @param _masterCopy New contract address.\n function changeMasterCopy(address _masterCopy)\n public\n authorized\n {\n // Master copy address cannot be null.\n require(_masterCopy != 0, \"Invalid master copy address provided\");\n masterCopy = _masterCopy;\n }\n}\n",
|
||||
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/MasterCopy.sol",
|
||||
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/MasterCopy.sol",
|
||||
"ast": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/MasterCopy.sol",
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/MasterCopy.sol",
|
||||
"exportedSymbols": {
|
||||
"MasterCopy": [
|
||||
813
|
||||
1693
|
||||
]
|
||||
},
|
||||
"id": 814,
|
||||
"id": 1694,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 788,
|
||||
"id": 1668,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:7"
|
||||
"src": "0:23:9"
|
||||
},
|
||||
{
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/SelfAuthorized.sol",
|
||||
"file": "./SelfAuthorized.sol",
|
||||
"id": 789,
|
||||
"id": 1669,
|
||||
"nodeType": "ImportDirective",
|
||||
"scope": 814,
|
||||
"sourceUnit": 1766,
|
||||
"src": "24:30:7",
|
||||
"scope": 1694,
|
||||
"sourceUnit": 1736,
|
||||
"src": "24:30:9",
|
||||
"symbolAliases": [],
|
||||
"unitAlias": ""
|
||||
},
|
||||
|
@ -59,42 +59,42 @@
|
|||
"arguments": null,
|
||||
"baseName": {
|
||||
"contractScope": null,
|
||||
"id": 790,
|
||||
"id": 1670,
|
||||
"name": "SelfAuthorized",
|
||||
"nodeType": "UserDefinedTypeName",
|
||||
"referencedDeclaration": 1765,
|
||||
"src": "226:14:7",
|
||||
"referencedDeclaration": 1735,
|
||||
"src": "226:14:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1765",
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1735",
|
||||
"typeString": "contract SelfAuthorized"
|
||||
}
|
||||
},
|
||||
"id": 791,
|
||||
"id": 1671,
|
||||
"nodeType": "InheritanceSpecifier",
|
||||
"src": "226:14:7"
|
||||
"src": "226:14:9"
|
||||
}
|
||||
],
|
||||
"contractDependencies": [
|
||||
1765
|
||||
1735
|
||||
],
|
||||
"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": 813,
|
||||
"id": 1693,
|
||||
"linearizedBaseContracts": [
|
||||
813,
|
||||
1765
|
||||
1693,
|
||||
1735
|
||||
],
|
||||
"name": "MasterCopy",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 793,
|
||||
"id": 1673,
|
||||
"name": "masterCopy",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 813,
|
||||
"src": "465:18:7",
|
||||
"scope": 1693,
|
||||
"src": "465:18:9",
|
||||
"stateVariable": true,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -102,10 +102,10 @@
|
|||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 792,
|
||||
"id": 1672,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "465:7:7",
|
||||
"src": "465:7:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -116,9 +116,9 @@
|
|||
},
|
||||
{
|
||||
"body": {
|
||||
"id": 811,
|
||||
"id": 1691,
|
||||
"nodeType": "Block",
|
||||
"src": "711:163:7",
|
||||
"src": "711:163:9",
|
||||
"statements": [
|
||||
{
|
||||
"expression": {
|
||||
|
@ -130,19 +130,19 @@
|
|||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
},
|
||||
"id": 803,
|
||||
"id": 1683,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
"lValueRequested": false,
|
||||
"leftExpression": {
|
||||
"argumentTypes": null,
|
||||
"id": 801,
|
||||
"id": 1681,
|
||||
"name": "_masterCopy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 795,
|
||||
"src": "776:11:7",
|
||||
"referencedDeclaration": 1675,
|
||||
"src": "776:11:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -153,14 +153,14 @@
|
|||
"rightExpression": {
|
||||
"argumentTypes": null,
|
||||
"hexValue": "30",
|
||||
"id": 802,
|
||||
"id": 1682,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "number",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "791:1:7",
|
||||
"src": "791:1:9",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_rational_0_by_1",
|
||||
|
@ -168,7 +168,7 @@
|
|||
},
|
||||
"value": "0"
|
||||
},
|
||||
"src": "776:16:7",
|
||||
"src": "776:16:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
|
@ -177,14 +177,14 @@
|
|||
{
|
||||
"argumentTypes": null,
|
||||
"hexValue": "496e76616c6964206d617374657220636f707920616464726573732070726f7669646564",
|
||||
"id": 804,
|
||||
"id": 1684,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "string",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "794:38:7",
|
||||
"src": "794:38:9",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_stringliteral_108d84599042957b954e89d43b52f80be89321dfc114a37800028eba58dafc87",
|
||||
|
@ -204,21 +204,21 @@
|
|||
"typeString": "literal_string \"Invalid master copy address provided\""
|
||||
}
|
||||
],
|
||||
"id": 800,
|
||||
"id": 1680,
|
||||
"name": "require",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [
|
||||
3831,
|
||||
3832
|
||||
4018,
|
||||
4019
|
||||
],
|
||||
"referencedDeclaration": 3832,
|
||||
"src": "768:7:7",
|
||||
"referencedDeclaration": 4019,
|
||||
"src": "768:7:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
|
||||
"typeString": "function (bool,string memory) pure"
|
||||
}
|
||||
},
|
||||
"id": 805,
|
||||
"id": 1685,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -226,32 +226,32 @@
|
|||
"lValueRequested": false,
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "768:65:7",
|
||||
"src": "768:65:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_tuple$__$",
|
||||
"typeString": "tuple()"
|
||||
}
|
||||
},
|
||||
"id": 806,
|
||||
"id": 1686,
|
||||
"nodeType": "ExpressionStatement",
|
||||
"src": "768:65:7"
|
||||
"src": "768:65:9"
|
||||
},
|
||||
{
|
||||
"expression": {
|
||||
"argumentTypes": null,
|
||||
"id": 809,
|
||||
"id": 1689,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
"lValueRequested": false,
|
||||
"leftHandSide": {
|
||||
"argumentTypes": null,
|
||||
"id": 807,
|
||||
"id": 1687,
|
||||
"name": "masterCopy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 793,
|
||||
"src": "843:10:7",
|
||||
"referencedDeclaration": 1673,
|
||||
"src": "843:10:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -261,68 +261,68 @@
|
|||
"operator": "=",
|
||||
"rightHandSide": {
|
||||
"argumentTypes": null,
|
||||
"id": 808,
|
||||
"id": 1688,
|
||||
"name": "_masterCopy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 795,
|
||||
"src": "856:11:7",
|
||||
"referencedDeclaration": 1675,
|
||||
"src": "856:11:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"src": "843:24:7",
|
||||
"src": "843:24:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"id": 810,
|
||||
"id": 1690,
|
||||
"nodeType": "ExpressionStatement",
|
||||
"src": "843:24:7"
|
||||
"src": "843:24:9"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": "@dev Allows to upgrade the contract. This can only be done via a Safe transaction.\n @param _masterCopy New contract address.",
|
||||
"id": 812,
|
||||
"id": 1692,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
"modifiers": [
|
||||
{
|
||||
"arguments": null,
|
||||
"id": 798,
|
||||
"id": 1678,
|
||||
"modifierName": {
|
||||
"argumentTypes": null,
|
||||
"id": 797,
|
||||
"id": 1677,
|
||||
"name": "authorized",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 1764,
|
||||
"src": "696:10:7",
|
||||
"referencedDeclaration": 1734,
|
||||
"src": "696:10:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_modifier$__$",
|
||||
"typeString": "modifier ()"
|
||||
}
|
||||
},
|
||||
"nodeType": "ModifierInvocation",
|
||||
"src": "696:10:7"
|
||||
"src": "696:10:9"
|
||||
}
|
||||
],
|
||||
"name": "changeMasterCopy",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 796,
|
||||
"id": 1676,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 795,
|
||||
"id": 1675,
|
||||
"name": "_masterCopy",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 812,
|
||||
"src": "652:19:7",
|
||||
"scope": 1692,
|
||||
"src": "652:19:9",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -330,10 +330,10 @@
|
|||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 794,
|
||||
"id": 1674,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "652:7:7",
|
||||
"src": "652:7:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -343,56 +343,56 @@
|
|||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "651:21:7"
|
||||
"src": "651:21:9"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 799,
|
||||
"id": 1679,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "711:0:7"
|
||||
"src": "711:0:9"
|
||||
},
|
||||
"scope": 813,
|
||||
"src": "626:248:7",
|
||||
"scope": 1693,
|
||||
"src": "626:248:9",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 814,
|
||||
"src": "203:673:7"
|
||||
"scope": 1694,
|
||||
"src": "203:673:9"
|
||||
}
|
||||
],
|
||||
"src": "0:877:7"
|
||||
"src": "0:877:9"
|
||||
},
|
||||
"legacyAST": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/MasterCopy.sol",
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/MasterCopy.sol",
|
||||
"exportedSymbols": {
|
||||
"MasterCopy": [
|
||||
813
|
||||
1693
|
||||
]
|
||||
},
|
||||
"id": 814,
|
||||
"id": 1694,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 788,
|
||||
"id": 1668,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:7"
|
||||
"src": "0:23:9"
|
||||
},
|
||||
{
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/SelfAuthorized.sol",
|
||||
"file": "./SelfAuthorized.sol",
|
||||
"id": 789,
|
||||
"id": 1669,
|
||||
"nodeType": "ImportDirective",
|
||||
"scope": 814,
|
||||
"sourceUnit": 1766,
|
||||
"src": "24:30:7",
|
||||
"scope": 1694,
|
||||
"sourceUnit": 1736,
|
||||
"src": "24:30:9",
|
||||
"symbolAliases": [],
|
||||
"unitAlias": ""
|
||||
},
|
||||
|
@ -402,42 +402,42 @@
|
|||
"arguments": null,
|
||||
"baseName": {
|
||||
"contractScope": null,
|
||||
"id": 790,
|
||||
"id": 1670,
|
||||
"name": "SelfAuthorized",
|
||||
"nodeType": "UserDefinedTypeName",
|
||||
"referencedDeclaration": 1765,
|
||||
"src": "226:14:7",
|
||||
"referencedDeclaration": 1735,
|
||||
"src": "226:14:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1765",
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1735",
|
||||
"typeString": "contract SelfAuthorized"
|
||||
}
|
||||
},
|
||||
"id": 791,
|
||||
"id": 1671,
|
||||
"nodeType": "InheritanceSpecifier",
|
||||
"src": "226:14:7"
|
||||
"src": "226:14:9"
|
||||
}
|
||||
],
|
||||
"contractDependencies": [
|
||||
1765
|
||||
1735
|
||||
],
|
||||
"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": 813,
|
||||
"id": 1693,
|
||||
"linearizedBaseContracts": [
|
||||
813,
|
||||
1765
|
||||
1693,
|
||||
1735
|
||||
],
|
||||
"name": "MasterCopy",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 793,
|
||||
"id": 1673,
|
||||
"name": "masterCopy",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 813,
|
||||
"src": "465:18:7",
|
||||
"scope": 1693,
|
||||
"src": "465:18:9",
|
||||
"stateVariable": true,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -445,10 +445,10 @@
|
|||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 792,
|
||||
"id": 1672,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "465:7:7",
|
||||
"src": "465:7:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -459,9 +459,9 @@
|
|||
},
|
||||
{
|
||||
"body": {
|
||||
"id": 811,
|
||||
"id": 1691,
|
||||
"nodeType": "Block",
|
||||
"src": "711:163:7",
|
||||
"src": "711:163:9",
|
||||
"statements": [
|
||||
{
|
||||
"expression": {
|
||||
|
@ -473,19 +473,19 @@
|
|||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
},
|
||||
"id": 803,
|
||||
"id": 1683,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
"lValueRequested": false,
|
||||
"leftExpression": {
|
||||
"argumentTypes": null,
|
||||
"id": 801,
|
||||
"id": 1681,
|
||||
"name": "_masterCopy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 795,
|
||||
"src": "776:11:7",
|
||||
"referencedDeclaration": 1675,
|
||||
"src": "776:11:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -496,14 +496,14 @@
|
|||
"rightExpression": {
|
||||
"argumentTypes": null,
|
||||
"hexValue": "30",
|
||||
"id": 802,
|
||||
"id": 1682,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "number",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "791:1:7",
|
||||
"src": "791:1:9",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_rational_0_by_1",
|
||||
|
@ -511,7 +511,7 @@
|
|||
},
|
||||
"value": "0"
|
||||
},
|
||||
"src": "776:16:7",
|
||||
"src": "776:16:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
|
@ -520,14 +520,14 @@
|
|||
{
|
||||
"argumentTypes": null,
|
||||
"hexValue": "496e76616c6964206d617374657220636f707920616464726573732070726f7669646564",
|
||||
"id": 804,
|
||||
"id": 1684,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "string",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "794:38:7",
|
||||
"src": "794:38:9",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_stringliteral_108d84599042957b954e89d43b52f80be89321dfc114a37800028eba58dafc87",
|
||||
|
@ -547,21 +547,21 @@
|
|||
"typeString": "literal_string \"Invalid master copy address provided\""
|
||||
}
|
||||
],
|
||||
"id": 800,
|
||||
"id": 1680,
|
||||
"name": "require",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [
|
||||
3831,
|
||||
3832
|
||||
4018,
|
||||
4019
|
||||
],
|
||||
"referencedDeclaration": 3832,
|
||||
"src": "768:7:7",
|
||||
"referencedDeclaration": 4019,
|
||||
"src": "768:7:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
|
||||
"typeString": "function (bool,string memory) pure"
|
||||
}
|
||||
},
|
||||
"id": 805,
|
||||
"id": 1685,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -569,32 +569,32 @@
|
|||
"lValueRequested": false,
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "768:65:7",
|
||||
"src": "768:65:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_tuple$__$",
|
||||
"typeString": "tuple()"
|
||||
}
|
||||
},
|
||||
"id": 806,
|
||||
"id": 1686,
|
||||
"nodeType": "ExpressionStatement",
|
||||
"src": "768:65:7"
|
||||
"src": "768:65:9"
|
||||
},
|
||||
{
|
||||
"expression": {
|
||||
"argumentTypes": null,
|
||||
"id": 809,
|
||||
"id": 1689,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
"lValueRequested": false,
|
||||
"leftHandSide": {
|
||||
"argumentTypes": null,
|
||||
"id": 807,
|
||||
"id": 1687,
|
||||
"name": "masterCopy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 793,
|
||||
"src": "843:10:7",
|
||||
"referencedDeclaration": 1673,
|
||||
"src": "843:10:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -604,68 +604,68 @@
|
|||
"operator": "=",
|
||||
"rightHandSide": {
|
||||
"argumentTypes": null,
|
||||
"id": 808,
|
||||
"id": 1688,
|
||||
"name": "_masterCopy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 795,
|
||||
"src": "856:11:7",
|
||||
"referencedDeclaration": 1675,
|
||||
"src": "856:11:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"src": "843:24:7",
|
||||
"src": "843:24:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"id": 810,
|
||||
"id": 1690,
|
||||
"nodeType": "ExpressionStatement",
|
||||
"src": "843:24:7"
|
||||
"src": "843:24:9"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": "@dev Allows to upgrade the contract. This can only be done via a Safe transaction.\n @param _masterCopy New contract address.",
|
||||
"id": 812,
|
||||
"id": 1692,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
"modifiers": [
|
||||
{
|
||||
"arguments": null,
|
||||
"id": 798,
|
||||
"id": 1678,
|
||||
"modifierName": {
|
||||
"argumentTypes": null,
|
||||
"id": 797,
|
||||
"id": 1677,
|
||||
"name": "authorized",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 1764,
|
||||
"src": "696:10:7",
|
||||
"referencedDeclaration": 1734,
|
||||
"src": "696:10:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_modifier$__$",
|
||||
"typeString": "modifier ()"
|
||||
}
|
||||
},
|
||||
"nodeType": "ModifierInvocation",
|
||||
"src": "696:10:7"
|
||||
"src": "696:10:9"
|
||||
}
|
||||
],
|
||||
"name": "changeMasterCopy",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 796,
|
||||
"id": 1676,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 795,
|
||||
"id": 1675,
|
||||
"name": "_masterCopy",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 812,
|
||||
"src": "652:19:7",
|
||||
"scope": 1692,
|
||||
"src": "652:19:9",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -673,10 +673,10 @@
|
|||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 794,
|
||||
"id": 1674,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "652:7:7",
|
||||
"src": "652:7:9",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -686,27 +686,27 @@
|
|||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "651:21:7"
|
||||
"src": "651:21:9"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 799,
|
||||
"id": 1679,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "711:0:7"
|
||||
"src": "711:0:9"
|
||||
},
|
||||
"scope": 813,
|
||||
"src": "626:248:7",
|
||||
"scope": 1693,
|
||||
"src": "626:248:9",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 814,
|
||||
"src": "203:673:7"
|
||||
"scope": 1694,
|
||||
"src": "203:673:9"
|
||||
}
|
||||
],
|
||||
"src": "0:877:7"
|
||||
"src": "0:877:9"
|
||||
},
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
|
@ -714,5 +714,5 @@
|
|||
},
|
||||
"networks": {},
|
||||
"schemaVersion": "2.0.0",
|
||||
"updatedAt": "2018-08-20T07:44:41.087Z"
|
||||
"updatedAt": "2018-10-05T14:25:58.937Z"
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -18,29 +18,29 @@
|
|||
],
|
||||
"bytecode": "0x608060405234801561001057600080fd5b50610169806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638d80ff0a14610046575b600080fd5b34801561005257600080fd5b506100ad600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506100af565b005b805160205b81811015610138578083015160208201840151604083018501516080840186015160a085018701600085600081146100f357600181146101035761010e565b6000808585888a5af1915061010e565b6000808585895af491505b50600081141561011d57600080fd5b602080601f8501040260a001870196505050505050506100b4565b5050505600a165627a7a72305820c1abf4988401674d6d6a5ceca56de123817c61305360ceffe26ebab59a828b7d0029",
|
||||
"deployedBytecode": "0x608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638d80ff0a14610046575b600080fd5b34801561005257600080fd5b506100ad600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506100af565b005b805160205b81811015610138578083015160208201840151604083018501516080840186015160a085018701600085600081146100f357600181146101035761010e565b6000808585888a5af1915061010e565b6000808585895af491505b50600081141561011d57600080fd5b602080601f8501040260a001870196505050505050506100b4565b5050505600a165627a7a72305820c1abf4988401674d6d6a5ceca56de123817c61305360ceffe26ebab59a828b7d0029",
|
||||
"sourceMap": "253:1424:19:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;253:1424:19;;;;;;;",
|
||||
"deployedSourceMap": "253:1424:19:-;;;;;;;;;;;;;;;;;;;;;;;;695:980;;8:9:-1;5:2;;;30:1;27;20:12;5:2;695:980:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;870:12;864:19;905:4;922:737;936:6;933:1;930:13;922:737;;;1007:1;993:12;989:20;983:27;1068:4;1065:1;1061:12;1047;1043:31;1037:38;1136:4;1133:1;1129:12;1115;1111:31;1105:38;1209:4;1206:1;1202:12;1188;1184:31;1178:38;1270:4;1267:1;1263:12;1249;1245:31;1308:1;1333:9;1365:1;1360:66;;;;1448:1;1443:67;;;;1326:184;;1360:66;1422:1;1419;1407:10;1401:4;1394:5;1390:2;1385:3;1380:44;1369:55;;1360:66;;1443:67;1506:1;1503;1491:10;1485:4;1481:2;1476:3;1463:45;1452:56;;1326:184;;1542:1;1533:7;1530:14;1527:2;;;1557:1;1554;1547:12;1527:2;1638:4;1631;1624;1612:10;1608:21;1604:32;1600:43;1594:4;1590:54;1587:1;1583:62;1578:67;;948:711;;;;;;922:737;;;836:833;;;:::o",
|
||||
"sourceMap": "253:1424:15:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;253:1424:15;;;;;;;",
|
||||
"deployedSourceMap": "253:1424:15:-;;;;;;;;;;;;;;;;;;;;;;;;695:980;;8:9:-1;5:2;;;30:1;27;20:12;5:2;695:980:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;870:12;864:19;905:4;922:737;936:6;933:1;930:13;922:737;;;1007:1;993:12;989:20;983:27;1068:4;1065:1;1061:12;1047;1043:31;1037:38;1136:4;1133:1;1129:12;1115;1111:31;1105:38;1209:4;1206:1;1202:12;1188;1184:31;1178:38;1270:4;1267:1;1263:12;1249;1245:31;1308:1;1333:9;1365:1;1360:66;;;;1448:1;1443:67;;;;1326:184;;1360:66;1422:1;1419;1407:10;1401:4;1394:5;1390:2;1385:3;1380:44;1369:55;;1360:66;;1443:67;1506:1;1503;1491:10;1485:4;1481:2;1476:3;1463:45;1452:56;;1326:184;;1542:1;1533:7;1530:14;1527:2;;;1557:1;1554;1547:12;1527:2;1638:4;1631;1624;1612:10;1608:21;1604:32;1600:43;1594:4;1590:54;1587:1;1583:62;1578:67;;948:711;;;;;;922:737;;;836:833;;;:::o",
|
||||
"source": "pragma solidity 0.4.24;\n\n\n/// @title Multi Send - Allows to batch multiple transactions into one.\n/// @author Nick Dodson - <nick.dodson@consensys.net>\n/// @author Gonçalo Sá - <goncalo.sa@consensys.net>\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract MultiSend {\n\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a \n /// tuple(operation,address,uint256,bytes), where operation \n /// can be 0 for a call or 1 for a delegatecall. The bytes \n /// of all encoded transactions are concatenated to form the input.\n function multiSend(bytes transactions)\n public\n {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n for { } lt(i, length) { } {\n let operation := mload(add(transactions, i))\n let to := mload(add(transactions, add(i, 0x20)))\n let value := mload(add(transactions, add(i, 0x40)))\n let dataLength := mload(add(transactions, add(i, 0x80)))\n let data := add(transactions, add(i, 0xa0))\n let success := 0\n switch operation \n case 0 { success := call(gas, to, value, data, dataLength, 0, 0) }\n case 1 { success := delegatecall(gas, to, data, dataLength, 0, 0) }\n if eq(success, 0) { revert(0, 0) }\n i := add(i, add(0xa0, mul(div(add(dataLength, 0x1f), 0x20), 0x20)))\n }\n }\n }\n}\n",
|
||||
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/libraries/MultiSend.sol",
|
||||
"ast": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/libraries/MultiSend.sol",
|
||||
"exportedSymbols": {
|
||||
"MultiSend": [
|
||||
1876
|
||||
1858
|
||||
]
|
||||
},
|
||||
"id": 1877,
|
||||
"id": 1859,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1868,
|
||||
"id": 1850,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:19"
|
||||
"src": "0:23:15"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
|
@ -48,85 +48,85 @@
|
|||
"contractKind": "contract",
|
||||
"documentation": "@title Multi Send - Allows to batch multiple transactions into one.\n @author Nick Dodson - <nick.dodson@consensys.net>\n @author Gonçalo Sá - <goncalo.sa@consensys.net>\n @author Stefan George - <stefan@gnosis.pm>",
|
||||
"fullyImplemented": true,
|
||||
"id": 1876,
|
||||
"id": 1858,
|
||||
"linearizedBaseContracts": [
|
||||
1876
|
||||
1858
|
||||
],
|
||||
"name": "MultiSend",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 1874,
|
||||
"id": 1856,
|
||||
"nodeType": "Block",
|
||||
"src": "753:922:19",
|
||||
"src": "753:922:15",
|
||||
"statements": [
|
||||
{
|
||||
"externalReferences": [
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1870,
|
||||
"declaration": 1852,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "870:12:19",
|
||||
"src": "870:12:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1870,
|
||||
"declaration": 1852,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "993:12:19",
|
||||
"src": "993:12:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1870,
|
||||
"declaration": 1852,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1047:12:19",
|
||||
"src": "1047:12:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1870,
|
||||
"declaration": 1852,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1188:12:19",
|
||||
"src": "1188:12:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1870,
|
||||
"declaration": 1852,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1115:12:19",
|
||||
"src": "1115:12:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1870,
|
||||
"declaration": 1852,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1249:12:19",
|
||||
"src": "1249:12:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": 1873,
|
||||
"id": 1855,
|
||||
"nodeType": "InlineAssembly",
|
||||
"operations": "{\n let length := mload(transactions)\n let i := 0x20\n for {\n }\n lt(i, length)\n {\n }\n {\n let operation := mload(add(transactions, i))\n let to := mload(add(transactions, add(i, 0x20)))\n let value := mload(add(transactions, add(i, 0x40)))\n let dataLength := mload(add(transactions, add(i, 0x80)))\n let data := add(transactions, add(i, 0xa0))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n case 1 {\n success := delegatecall(gas(), to, data, dataLength, 0, 0)\n }\n if eq(success, 0)\n {\n revert(0, 0)\n }\n i := add(i, add(0xa0, mul(div(add(dataLength, 0x1f), 0x20), 0x20)))\n }\n}",
|
||||
"src": "827:848:19"
|
||||
"src": "827:848:15"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": "@dev Sends multiple transactions and reverts all if one fails.\n @param transactions Encoded transactions. Each transaction is encoded as a \n tuple(operation,address,uint256,bytes), where operation \n can be 0 for a call or 1 for a delegatecall. The bytes \n of all encoded transactions are concatenated to form the input.",
|
||||
"id": 1875,
|
||||
"id": 1857,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
|
@ -134,16 +134,16 @@
|
|||
"name": "multiSend",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 1871,
|
||||
"id": 1853,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1870,
|
||||
"id": 1852,
|
||||
"name": "transactions",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1875,
|
||||
"src": "714:18:19",
|
||||
"scope": 1857,
|
||||
"src": "714:18:15",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -151,10 +151,10 @@
|
|||
"typeString": "bytes"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1869,
|
||||
"id": 1851,
|
||||
"name": "bytes",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "714:5:19",
|
||||
"src": "714:5:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_storage_ptr",
|
||||
"typeString": "bytes"
|
||||
|
@ -164,47 +164,47 @@
|
|||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "713:20:19"
|
||||
"src": "713:20:15"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 1872,
|
||||
"id": 1854,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "753:0:19"
|
||||
"src": "753:0:15"
|
||||
},
|
||||
"scope": 1876,
|
||||
"src": "695:980:19",
|
||||
"scope": 1858,
|
||||
"src": "695:980:15",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 1877,
|
||||
"src": "253:1424:19"
|
||||
"scope": 1859,
|
||||
"src": "253:1424:15"
|
||||
}
|
||||
],
|
||||
"src": "0:1678:19"
|
||||
"src": "0:1678:15"
|
||||
},
|
||||
"legacyAST": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/libraries/MultiSend.sol",
|
||||
"exportedSymbols": {
|
||||
"MultiSend": [
|
||||
1876
|
||||
1858
|
||||
]
|
||||
},
|
||||
"id": 1877,
|
||||
"id": 1859,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1868,
|
||||
"id": 1850,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:19"
|
||||
"src": "0:23:15"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
|
@ -212,85 +212,85 @@
|
|||
"contractKind": "contract",
|
||||
"documentation": "@title Multi Send - Allows to batch multiple transactions into one.\n @author Nick Dodson - <nick.dodson@consensys.net>\n @author Gonçalo Sá - <goncalo.sa@consensys.net>\n @author Stefan George - <stefan@gnosis.pm>",
|
||||
"fullyImplemented": true,
|
||||
"id": 1876,
|
||||
"id": 1858,
|
||||
"linearizedBaseContracts": [
|
||||
1876
|
||||
1858
|
||||
],
|
||||
"name": "MultiSend",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 1874,
|
||||
"id": 1856,
|
||||
"nodeType": "Block",
|
||||
"src": "753:922:19",
|
||||
"src": "753:922:15",
|
||||
"statements": [
|
||||
{
|
||||
"externalReferences": [
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1870,
|
||||
"declaration": 1852,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "870:12:19",
|
||||
"src": "870:12:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1870,
|
||||
"declaration": 1852,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "993:12:19",
|
||||
"src": "993:12:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1870,
|
||||
"declaration": 1852,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1047:12:19",
|
||||
"src": "1047:12:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1870,
|
||||
"declaration": 1852,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1188:12:19",
|
||||
"src": "1188:12:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1870,
|
||||
"declaration": 1852,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1115:12:19",
|
||||
"src": "1115:12:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1870,
|
||||
"declaration": 1852,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1249:12:19",
|
||||
"src": "1249:12:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": 1873,
|
||||
"id": 1855,
|
||||
"nodeType": "InlineAssembly",
|
||||
"operations": "{\n let length := mload(transactions)\n let i := 0x20\n for {\n }\n lt(i, length)\n {\n }\n {\n let operation := mload(add(transactions, i))\n let to := mload(add(transactions, add(i, 0x20)))\n let value := mload(add(transactions, add(i, 0x40)))\n let dataLength := mload(add(transactions, add(i, 0x80)))\n let data := add(transactions, add(i, 0xa0))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n case 1 {\n success := delegatecall(gas(), to, data, dataLength, 0, 0)\n }\n if eq(success, 0)\n {\n revert(0, 0)\n }\n i := add(i, add(0xa0, mul(div(add(dataLength, 0x1f), 0x20), 0x20)))\n }\n}",
|
||||
"src": "827:848:19"
|
||||
"src": "827:848:15"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": "@dev Sends multiple transactions and reverts all if one fails.\n @param transactions Encoded transactions. Each transaction is encoded as a \n tuple(operation,address,uint256,bytes), where operation \n can be 0 for a call or 1 for a delegatecall. The bytes \n of all encoded transactions are concatenated to form the input.",
|
||||
"id": 1875,
|
||||
"id": 1857,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
|
@ -298,16 +298,16 @@
|
|||
"name": "multiSend",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 1871,
|
||||
"id": 1853,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1870,
|
||||
"id": 1852,
|
||||
"name": "transactions",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1875,
|
||||
"src": "714:18:19",
|
||||
"scope": 1857,
|
||||
"src": "714:18:15",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -315,10 +315,10 @@
|
|||
"typeString": "bytes"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1869,
|
||||
"id": 1851,
|
||||
"name": "bytes",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "714:5:19",
|
||||
"src": "714:5:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_storage_ptr",
|
||||
"typeString": "bytes"
|
||||
|
@ -328,27 +328,27 @@
|
|||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "713:20:19"
|
||||
"src": "713:20:15"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 1872,
|
||||
"id": 1854,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "753:0:19"
|
||||
"src": "753:0:15"
|
||||
},
|
||||
"scope": 1876,
|
||||
"src": "695:980:19",
|
||||
"scope": 1858,
|
||||
"src": "695:980:15",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 1877,
|
||||
"src": "253:1424:19"
|
||||
"scope": 1859,
|
||||
"src": "253:1424:15"
|
||||
}
|
||||
],
|
||||
"src": "0:1678:19"
|
||||
"src": "0:1678:15"
|
||||
},
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
|
@ -358,16 +358,16 @@
|
|||
"4": {
|
||||
"events": {},
|
||||
"links": {},
|
||||
"address": "0x3a29cf32d22f38b7338874b689a88f185663a1c3",
|
||||
"transactionHash": "0x86b6895207dff0b3e19c202e140dc9cf823cbfc02672e02636af23a1b580e7e7"
|
||||
"address": "0x6f6f431429fb15bb2ca4bb55bf353c15f044df9e",
|
||||
"transactionHash": "0xeaf5db265940b81d6fe881ebf0b05aa9dde905851a966a9cda08dcabd7dc10bd"
|
||||
},
|
||||
"1534750848541": {
|
||||
"1538739975997": {
|
||||
"events": {},
|
||||
"links": {},
|
||||
"address": "0x5b9b42d6e4b2e4bf8d42eba32d46918e10899b66",
|
||||
"transactionHash": "0xaf733882096b301ccf5bf4a12ebf84616b88927c71cc656cc037fbd892a24104"
|
||||
"address": "0x26b4afb60d6c903165150c6f0aa14f8016be4aec",
|
||||
"transactionHash": "0x4a85e63a3968cc7f7aaa5303f6ed331cf782929fc758645b44145286ad4076a6"
|
||||
}
|
||||
},
|
||||
"schemaVersion": "2.0.0",
|
||||
"updatedAt": "2018-08-20T07:50:29.677Z"
|
||||
"updatedAt": "2018-10-05T14:43:41.420Z"
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,31 +1,31 @@
|
|||
{
|
||||
"contractName": "SecuredTokenTransfer",
|
||||
"abi": [],
|
||||
"bytecode": "0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a723058203704d691dd103c6cda573e69dcd48a2de4d0edf672da44096a50180687c79a770029",
|
||||
"deployedBytecode": "0x6080604052600080fd00a165627a7a723058203704d691dd103c6cda573e69dcd48a2de4d0edf672da44096a50180687c79a770029",
|
||||
"sourceMap": "133:1051:15:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;133:1051:15;;;;;;;",
|
||||
"deployedSourceMap": "133:1051:15:-;;;;;",
|
||||
"bytecode": "0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a72305820ba27992b3b19c83b563b2634ef4e6e4b21311676e3d2a13b83cfd34834dfb8510029",
|
||||
"deployedBytecode": "0x6080604052600080fd00a165627a7a72305820ba27992b3b19c83b563b2634ef4e6e4b21311676e3d2a13b83cfd34834dfb8510029",
|
||||
"sourceMap": "133:1051:10:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;133:1051:10;;;;;;;",
|
||||
"deployedSourceMap": "133:1051:10:-;;;;;",
|
||||
"source": "pragma solidity 0.4.24;\n\n\n/// @title SecuredTokenTransfer - Secure token transfer\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract SecuredTokenTransfer {\n\n /// @dev Transfers a token and returns if it was a success\n /// @param token Token that should be transferred\n /// @param receiver Receiver to whom the token should be transferred\n /// @param amount The amount of tokens that should be transferred\n function transferToken (\n address token, \n address receiver,\n uint256 amount\n )\n internal\n returns (bool transferred)\n {\n bytes memory data = abi.encodeWithSignature(\"transfer(address,uint256)\", receiver, amount);\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let success := call(sub(gas, 10000), token, 0, add(data, 0x20), mload(data), 0, 0)\n let ptr := mload(0x40)\n returndatacopy(ptr, 0, returndatasize)\n switch returndatasize \n case 0 { transferred := success }\n case 0x20 { transferred := iszero(or(iszero(success), iszero(mload(ptr)))) }\n default { transferred := 0 }\n }\n }\n}\n",
|
||||
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SecuredTokenTransfer.sol",
|
||||
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/SecuredTokenTransfer.sol",
|
||||
"ast": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SecuredTokenTransfer.sol",
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/SecuredTokenTransfer.sol",
|
||||
"exportedSymbols": {
|
||||
"SecuredTokenTransfer": [
|
||||
1748
|
||||
1718
|
||||
]
|
||||
},
|
||||
"id": 1749,
|
||||
"id": 1719,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1725,
|
||||
"id": 1695,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:15"
|
||||
"src": "0:23:10"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
|
@ -33,31 +33,31 @@
|
|||
"contractKind": "contract",
|
||||
"documentation": "@title SecuredTokenTransfer - Secure token transfer\n @author Richard Meissner - <richard@gnosis.pm>",
|
||||
"fullyImplemented": true,
|
||||
"id": 1748,
|
||||
"id": 1718,
|
||||
"linearizedBaseContracts": [
|
||||
1748
|
||||
1718
|
||||
],
|
||||
"name": "SecuredTokenTransfer",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 1746,
|
||||
"id": 1716,
|
||||
"nodeType": "Block",
|
||||
"src": "590:592:15",
|
||||
"src": "590:592:10",
|
||||
"statements": [
|
||||
{
|
||||
"assignments": [
|
||||
1737
|
||||
1707
|
||||
],
|
||||
"declarations": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1737,
|
||||
"id": 1707,
|
||||
"name": "data",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1747,
|
||||
"src": "600:17:15",
|
||||
"scope": 1717,
|
||||
"src": "600:17:10",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "memory",
|
||||
"typeDescriptions": {
|
||||
|
@ -65,10 +65,10 @@
|
|||
"typeString": "bytes"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1736,
|
||||
"id": 1706,
|
||||
"name": "bytes",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "600:5:15",
|
||||
"src": "600:5:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_storage_ptr",
|
||||
"typeString": "bytes"
|
||||
|
@ -78,21 +78,21 @@
|
|||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"id": 1744,
|
||||
"id": 1714,
|
||||
"initialValue": {
|
||||
"argumentTypes": null,
|
||||
"arguments": [
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"hexValue": "7472616e7366657228616464726573732c75696e7432353629",
|
||||
"id": 1740,
|
||||
"id": 1710,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "string",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "644:27:15",
|
||||
"src": "644:27:10",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_stringliteral_a9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b",
|
||||
|
@ -102,12 +102,12 @@
|
|||
},
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"id": 1741,
|
||||
"id": 1711,
|
||||
"name": "receiver",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 1729,
|
||||
"src": "673:8:15",
|
||||
"referencedDeclaration": 1699,
|
||||
"src": "673:8:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -115,12 +115,12 @@
|
|||
},
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"id": 1742,
|
||||
"id": 1712,
|
||||
"name": "amount",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 1731,
|
||||
"src": "683:6:15",
|
||||
"referencedDeclaration": 1701,
|
||||
"src": "683:6:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
|
@ -144,18 +144,18 @@
|
|||
],
|
||||
"expression": {
|
||||
"argumentTypes": null,
|
||||
"id": 1738,
|
||||
"id": 1708,
|
||||
"name": "abi",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 3815,
|
||||
"src": "620:3:15",
|
||||
"referencedDeclaration": 4002,
|
||||
"src": "620:3:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_magic_abi",
|
||||
"typeString": "abi"
|
||||
}
|
||||
},
|
||||
"id": 1739,
|
||||
"id": 1709,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
|
@ -163,13 +163,13 @@
|
|||
"memberName": "encodeWithSignature",
|
||||
"nodeType": "MemberAccess",
|
||||
"referencedDeclaration": null,
|
||||
"src": "620:23:15",
|
||||
"src": "620:23:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$",
|
||||
"typeString": "function (string memory) pure returns (bytes memory)"
|
||||
}
|
||||
},
|
||||
"id": 1743,
|
||||
"id": 1713,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -177,81 +177,81 @@
|
|||
"lValueRequested": false,
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "620:70:15",
|
||||
"src": "620:70:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_memory_ptr",
|
||||
"typeString": "bytes memory"
|
||||
}
|
||||
},
|
||||
"nodeType": "VariableDeclarationStatement",
|
||||
"src": "600:90:15"
|
||||
"src": "600:90:10"
|
||||
},
|
||||
{
|
||||
"externalReferences": [
|
||||
{
|
||||
"transferred": {
|
||||
"declaration": 1734,
|
||||
"declaration": 1704,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1061:11:15",
|
||||
"src": "1061:11:10",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"declaration": 1737,
|
||||
"declaration": 1707,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "857:4:15",
|
||||
"src": "857:4:10",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"token": {
|
||||
"declaration": 1727,
|
||||
"declaration": 1697,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "824:5:15",
|
||||
"src": "824:5:10",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"declaration": 1737,
|
||||
"declaration": 1707,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "838:4:15",
|
||||
"src": "838:4:10",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transferred": {
|
||||
"declaration": 1734,
|
||||
"declaration": 1704,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1012:11:15",
|
||||
"src": "1012:11:10",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transferred": {
|
||||
"declaration": 1734,
|
||||
"declaration": 1704,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1148:11:15",
|
||||
"src": "1148:11:10",
|
||||
"valueSize": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": 1745,
|
||||
"id": 1715,
|
||||
"nodeType": "InlineAssembly",
|
||||
"operations": "{\n let success := call(sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0)\n let ptr := mload(0x40)\n returndatacopy(ptr, 0, returndatasize())\n switch returndatasize()\n case 0 {\n transferred := success\n }\n case 0x20 {\n transferred := iszero(or(iszero(success), iszero(mload(ptr))))\n }\n default {\n transferred := 0\n }\n}",
|
||||
"src": "764:418:15"
|
||||
"src": "764:418:10"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": "@dev Transfers a token and returns if it was a success\n @param token Token that should be transferred\n @param receiver Receiver to whom the token should be transferred\n @param amount The amount of tokens that should be transferred",
|
||||
"id": 1747,
|
||||
"id": 1717,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
|
@ -259,16 +259,16 @@
|
|||
"name": "transferToken",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 1732,
|
||||
"id": 1702,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1727,
|
||||
"id": 1697,
|
||||
"name": "token",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1747,
|
||||
"src": "463:13:15",
|
||||
"scope": 1717,
|
||||
"src": "463:13:10",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -276,10 +276,10 @@
|
|||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1726,
|
||||
"id": 1696,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "463:7:15",
|
||||
"src": "463:7:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -290,11 +290,11 @@
|
|||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1729,
|
||||
"id": 1699,
|
||||
"name": "receiver",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1747,
|
||||
"src": "487:16:15",
|
||||
"scope": 1717,
|
||||
"src": "487:16:10",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -302,10 +302,10 @@
|
|||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1728,
|
||||
"id": 1698,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "487:7:15",
|
||||
"src": "487:7:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -316,11 +316,11 @@
|
|||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1731,
|
||||
"id": 1701,
|
||||
"name": "amount",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1747,
|
||||
"src": "513:14:15",
|
||||
"scope": 1717,
|
||||
"src": "513:14:10",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -328,10 +328,10 @@
|
|||
"typeString": "uint256"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1730,
|
||||
"id": 1700,
|
||||
"name": "uint256",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "513:7:15",
|
||||
"src": "513:7:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
|
@ -341,20 +341,20 @@
|
|||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "453:80:15"
|
||||
"src": "453:80:10"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 1735,
|
||||
"id": 1705,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1734,
|
||||
"id": 1704,
|
||||
"name": "transferred",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1747,
|
||||
"src": "568:16:15",
|
||||
"scope": 1717,
|
||||
"src": "568:16:10",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -362,10 +362,10 @@
|
|||
"typeString": "bool"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1733,
|
||||
"id": 1703,
|
||||
"name": "bool",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "568:4:15",
|
||||
"src": "568:4:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
|
@ -375,40 +375,40 @@
|
|||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "567:18:15"
|
||||
"src": "567:18:10"
|
||||
},
|
||||
"scope": 1748,
|
||||
"src": "430:752:15",
|
||||
"scope": 1718,
|
||||
"src": "430:752:10",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"scope": 1749,
|
||||
"src": "133:1051:15"
|
||||
"scope": 1719,
|
||||
"src": "133:1051:10"
|
||||
}
|
||||
],
|
||||
"src": "0:1185:15"
|
||||
"src": "0:1185:10"
|
||||
},
|
||||
"legacyAST": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SecuredTokenTransfer.sol",
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/SecuredTokenTransfer.sol",
|
||||
"exportedSymbols": {
|
||||
"SecuredTokenTransfer": [
|
||||
1748
|
||||
1718
|
||||
]
|
||||
},
|
||||
"id": 1749,
|
||||
"id": 1719,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1725,
|
||||
"id": 1695,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:15"
|
||||
"src": "0:23:10"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
|
@ -416,31 +416,31 @@
|
|||
"contractKind": "contract",
|
||||
"documentation": "@title SecuredTokenTransfer - Secure token transfer\n @author Richard Meissner - <richard@gnosis.pm>",
|
||||
"fullyImplemented": true,
|
||||
"id": 1748,
|
||||
"id": 1718,
|
||||
"linearizedBaseContracts": [
|
||||
1748
|
||||
1718
|
||||
],
|
||||
"name": "SecuredTokenTransfer",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 1746,
|
||||
"id": 1716,
|
||||
"nodeType": "Block",
|
||||
"src": "590:592:15",
|
||||
"src": "590:592:10",
|
||||
"statements": [
|
||||
{
|
||||
"assignments": [
|
||||
1737
|
||||
1707
|
||||
],
|
||||
"declarations": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1737,
|
||||
"id": 1707,
|
||||
"name": "data",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1747,
|
||||
"src": "600:17:15",
|
||||
"scope": 1717,
|
||||
"src": "600:17:10",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "memory",
|
||||
"typeDescriptions": {
|
||||
|
@ -448,10 +448,10 @@
|
|||
"typeString": "bytes"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1736,
|
||||
"id": 1706,
|
||||
"name": "bytes",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "600:5:15",
|
||||
"src": "600:5:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_storage_ptr",
|
||||
"typeString": "bytes"
|
||||
|
@ -461,21 +461,21 @@
|
|||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"id": 1744,
|
||||
"id": 1714,
|
||||
"initialValue": {
|
||||
"argumentTypes": null,
|
||||
"arguments": [
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"hexValue": "7472616e7366657228616464726573732c75696e7432353629",
|
||||
"id": 1740,
|
||||
"id": 1710,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "string",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "644:27:15",
|
||||
"src": "644:27:10",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_stringliteral_a9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b",
|
||||
|
@ -485,12 +485,12 @@
|
|||
},
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"id": 1741,
|
||||
"id": 1711,
|
||||
"name": "receiver",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 1729,
|
||||
"src": "673:8:15",
|
||||
"referencedDeclaration": 1699,
|
||||
"src": "673:8:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -498,12 +498,12 @@
|
|||
},
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"id": 1742,
|
||||
"id": 1712,
|
||||
"name": "amount",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 1731,
|
||||
"src": "683:6:15",
|
||||
"referencedDeclaration": 1701,
|
||||
"src": "683:6:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
|
@ -527,18 +527,18 @@
|
|||
],
|
||||
"expression": {
|
||||
"argumentTypes": null,
|
||||
"id": 1738,
|
||||
"id": 1708,
|
||||
"name": "abi",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 3815,
|
||||
"src": "620:3:15",
|
||||
"referencedDeclaration": 4002,
|
||||
"src": "620:3:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_magic_abi",
|
||||
"typeString": "abi"
|
||||
}
|
||||
},
|
||||
"id": 1739,
|
||||
"id": 1709,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
|
@ -546,13 +546,13 @@
|
|||
"memberName": "encodeWithSignature",
|
||||
"nodeType": "MemberAccess",
|
||||
"referencedDeclaration": null,
|
||||
"src": "620:23:15",
|
||||
"src": "620:23:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$",
|
||||
"typeString": "function (string memory) pure returns (bytes memory)"
|
||||
}
|
||||
},
|
||||
"id": 1743,
|
||||
"id": 1713,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -560,81 +560,81 @@
|
|||
"lValueRequested": false,
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "620:70:15",
|
||||
"src": "620:70:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_memory_ptr",
|
||||
"typeString": "bytes memory"
|
||||
}
|
||||
},
|
||||
"nodeType": "VariableDeclarationStatement",
|
||||
"src": "600:90:15"
|
||||
"src": "600:90:10"
|
||||
},
|
||||
{
|
||||
"externalReferences": [
|
||||
{
|
||||
"transferred": {
|
||||
"declaration": 1734,
|
||||
"declaration": 1704,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1061:11:15",
|
||||
"src": "1061:11:10",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"declaration": 1737,
|
||||
"declaration": 1707,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "857:4:15",
|
||||
"src": "857:4:10",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"token": {
|
||||
"declaration": 1727,
|
||||
"declaration": 1697,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "824:5:15",
|
||||
"src": "824:5:10",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"declaration": 1737,
|
||||
"declaration": 1707,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "838:4:15",
|
||||
"src": "838:4:10",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transferred": {
|
||||
"declaration": 1734,
|
||||
"declaration": 1704,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1012:11:15",
|
||||
"src": "1012:11:10",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transferred": {
|
||||
"declaration": 1734,
|
||||
"declaration": 1704,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1148:11:15",
|
||||
"src": "1148:11:10",
|
||||
"valueSize": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": 1745,
|
||||
"id": 1715,
|
||||
"nodeType": "InlineAssembly",
|
||||
"operations": "{\n let success := call(sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0)\n let ptr := mload(0x40)\n returndatacopy(ptr, 0, returndatasize())\n switch returndatasize()\n case 0 {\n transferred := success\n }\n case 0x20 {\n transferred := iszero(or(iszero(success), iszero(mload(ptr))))\n }\n default {\n transferred := 0\n }\n}",
|
||||
"src": "764:418:15"
|
||||
"src": "764:418:10"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": "@dev Transfers a token and returns if it was a success\n @param token Token that should be transferred\n @param receiver Receiver to whom the token should be transferred\n @param amount The amount of tokens that should be transferred",
|
||||
"id": 1747,
|
||||
"id": 1717,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
|
@ -642,16 +642,16 @@
|
|||
"name": "transferToken",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 1732,
|
||||
"id": 1702,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1727,
|
||||
"id": 1697,
|
||||
"name": "token",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1747,
|
||||
"src": "463:13:15",
|
||||
"scope": 1717,
|
||||
"src": "463:13:10",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -659,10 +659,10 @@
|
|||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1726,
|
||||
"id": 1696,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "463:7:15",
|
||||
"src": "463:7:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -673,11 +673,11 @@
|
|||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1729,
|
||||
"id": 1699,
|
||||
"name": "receiver",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1747,
|
||||
"src": "487:16:15",
|
||||
"scope": 1717,
|
||||
"src": "487:16:10",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -685,10 +685,10 @@
|
|||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1728,
|
||||
"id": 1698,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "487:7:15",
|
||||
"src": "487:7:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -699,11 +699,11 @@
|
|||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1731,
|
||||
"id": 1701,
|
||||
"name": "amount",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1747,
|
||||
"src": "513:14:15",
|
||||
"scope": 1717,
|
||||
"src": "513:14:10",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -711,10 +711,10 @@
|
|||
"typeString": "uint256"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1730,
|
||||
"id": 1700,
|
||||
"name": "uint256",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "513:7:15",
|
||||
"src": "513:7:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
|
@ -724,20 +724,20 @@
|
|||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "453:80:15"
|
||||
"src": "453:80:10"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 1735,
|
||||
"id": 1705,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1734,
|
||||
"id": 1704,
|
||||
"name": "transferred",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1747,
|
||||
"src": "568:16:15",
|
||||
"scope": 1717,
|
||||
"src": "568:16:10",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -745,10 +745,10 @@
|
|||
"typeString": "bool"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1733,
|
||||
"id": 1703,
|
||||
"name": "bool",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "568:4:15",
|
||||
"src": "568:4:10",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
|
@ -758,20 +758,20 @@
|
|||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "567:18:15"
|
||||
"src": "567:18:10"
|
||||
},
|
||||
"scope": 1748,
|
||||
"src": "430:752:15",
|
||||
"scope": 1718,
|
||||
"src": "430:752:10",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"scope": 1749,
|
||||
"src": "133:1051:15"
|
||||
"scope": 1719,
|
||||
"src": "133:1051:10"
|
||||
}
|
||||
],
|
||||
"src": "0:1185:15"
|
||||
"src": "0:1185:10"
|
||||
},
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
|
@ -779,5 +779,5 @@
|
|||
},
|
||||
"networks": {},
|
||||
"schemaVersion": "2.0.0",
|
||||
"updatedAt": "2018-08-20T07:44:41.093Z"
|
||||
"updatedAt": "2018-10-05T14:25:58.937Z"
|
||||
}
|
|
@ -1,31 +1,31 @@
|
|||
{
|
||||
"contractName": "SelfAuthorized",
|
||||
"abi": [],
|
||||
"bytecode": "0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a72305820ec80f1b4520aa5197e4181778f1e2e4fc460002d4a40e2e8e6709c8986067c220029",
|
||||
"deployedBytecode": "0x6080604052600080fd00a165627a7a72305820ec80f1b4520aa5197e4181778f1e2e4fc460002d4a40e2e8e6709c8986067c220029",
|
||||
"sourceMap": "152:166:16:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;152:166:16;;;;;;;",
|
||||
"deployedSourceMap": "152:166:16:-;;;;;",
|
||||
"bytecode": "0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a7230582089be6830aa63b2ce4480c1565e02c1d4e7d28bdf01f3f1cfbca1af4fc2fd06f50029",
|
||||
"deployedBytecode": "0x6080604052600080fd00a165627a7a7230582089be6830aa63b2ce4480c1565e02c1d4e7d28bdf01f3f1cfbca1af4fc2fd06f50029",
|
||||
"sourceMap": "152:166:11:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;152:166:11;;;;;;;",
|
||||
"deployedSourceMap": "152:166:11:-;;;;;",
|
||||
"source": "pragma solidity 0.4.24;\n\n\n/// @title SelfAuthorized - authorizes current contract to perform actions\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract SelfAuthorized {\n modifier authorized() {\n require(msg.sender == address(this), \"Method can only be called from this contract\");\n _;\n }\n}\n",
|
||||
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
|
||||
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/SelfAuthorized.sol",
|
||||
"ast": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/SelfAuthorized.sol",
|
||||
"exportedSymbols": {
|
||||
"SelfAuthorized": [
|
||||
1765
|
||||
1735
|
||||
]
|
||||
},
|
||||
"id": 1766,
|
||||
"id": 1736,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1750,
|
||||
"id": 1720,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:16"
|
||||
"src": "0:23:11"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
|
@ -33,18 +33,18 @@
|
|||
"contractKind": "contract",
|
||||
"documentation": "@title SelfAuthorized - authorizes current contract to perform actions\n @author Richard Meissner - <richard@gnosis.pm>",
|
||||
"fullyImplemented": true,
|
||||
"id": 1765,
|
||||
"id": 1735,
|
||||
"linearizedBaseContracts": [
|
||||
1765
|
||||
1735
|
||||
],
|
||||
"name": "SelfAuthorized",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 1763,
|
||||
"id": 1733,
|
||||
"nodeType": "Block",
|
||||
"src": "204:112:16",
|
||||
"src": "204:112:11",
|
||||
"statements": [
|
||||
{
|
||||
"expression": {
|
||||
|
@ -56,7 +56,7 @@
|
|||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
},
|
||||
"id": 1758,
|
||||
"id": 1728,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -65,18 +65,18 @@
|
|||
"argumentTypes": null,
|
||||
"expression": {
|
||||
"argumentTypes": null,
|
||||
"id": 1753,
|
||||
"id": 1723,
|
||||
"name": "msg",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 3828,
|
||||
"src": "222:3:16",
|
||||
"referencedDeclaration": 4015,
|
||||
"src": "222:3:11",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_magic_message",
|
||||
"typeString": "msg"
|
||||
}
|
||||
},
|
||||
"id": 1754,
|
||||
"id": 1724,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -84,7 +84,7 @@
|
|||
"memberName": "sender",
|
||||
"nodeType": "MemberAccess",
|
||||
"referencedDeclaration": null,
|
||||
"src": "222:10:16",
|
||||
"src": "222:10:11",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -97,14 +97,14 @@
|
|||
"arguments": [
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"id": 1756,
|
||||
"id": 1726,
|
||||
"name": "this",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 3851,
|
||||
"src": "244:4:16",
|
||||
"referencedDeclaration": 4028,
|
||||
"src": "244:4:11",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1765",
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1735",
|
||||
"typeString": "contract SelfAuthorized"
|
||||
}
|
||||
}
|
||||
|
@ -112,24 +112,24 @@
|
|||
"expression": {
|
||||
"argumentTypes": [
|
||||
{
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1765",
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1735",
|
||||
"typeString": "contract SelfAuthorized"
|
||||
}
|
||||
],
|
||||
"id": 1755,
|
||||
"id": 1725,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"lValueRequested": false,
|
||||
"nodeType": "ElementaryTypeNameExpression",
|
||||
"src": "236:7:16",
|
||||
"src": "236:7:11",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_type$_t_address_$",
|
||||
"typeString": "type(address)"
|
||||
},
|
||||
"typeName": "address"
|
||||
},
|
||||
"id": 1757,
|
||||
"id": 1727,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -137,13 +137,13 @@
|
|||
"lValueRequested": false,
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "236:13:16",
|
||||
"src": "236:13:11",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"src": "222:27:16",
|
||||
"src": "222:27:11",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
|
@ -152,14 +152,14 @@
|
|||
{
|
||||
"argumentTypes": null,
|
||||
"hexValue": "4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207468697320636f6e7472616374",
|
||||
"id": 1759,
|
||||
"id": 1729,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "string",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "251:46:16",
|
||||
"src": "251:46:11",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_stringliteral_c4780ef0a1d41d59bac8c510cf9ada421bccf2b90f75a8e4ba2e8c09e8d72733",
|
||||
|
@ -179,21 +179,21 @@
|
|||
"typeString": "literal_string \"Method can only be called from this contract\""
|
||||
}
|
||||
],
|
||||
"id": 1752,
|
||||
"id": 1722,
|
||||
"name": "require",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [
|
||||
3831,
|
||||
3832
|
||||
4018,
|
||||
4019
|
||||
],
|
||||
"referencedDeclaration": 3832,
|
||||
"src": "214:7:16",
|
||||
"referencedDeclaration": 4019,
|
||||
"src": "214:7:11",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
|
||||
"typeString": "function (bool,string memory) pure"
|
||||
}
|
||||
},
|
||||
"id": 1760,
|
||||
"id": 1730,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -201,62 +201,62 @@
|
|||
"lValueRequested": false,
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "214:84:16",
|
||||
"src": "214:84:11",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_tuple$__$",
|
||||
"typeString": "tuple()"
|
||||
}
|
||||
},
|
||||
"id": 1761,
|
||||
"id": 1731,
|
||||
"nodeType": "ExpressionStatement",
|
||||
"src": "214:84:16"
|
||||
"src": "214:84:11"
|
||||
},
|
||||
{
|
||||
"id": 1762,
|
||||
"id": 1732,
|
||||
"nodeType": "PlaceholderStatement",
|
||||
"src": "308:1:16"
|
||||
"src": "308:1:11"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": null,
|
||||
"id": 1764,
|
||||
"id": 1734,
|
||||
"name": "authorized",
|
||||
"nodeType": "ModifierDefinition",
|
||||
"parameters": {
|
||||
"id": 1751,
|
||||
"id": 1721,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "201:2:16"
|
||||
"src": "201:2:11"
|
||||
},
|
||||
"src": "182:134:16",
|
||||
"src": "182:134:11",
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"scope": 1766,
|
||||
"src": "152:166:16"
|
||||
"scope": 1736,
|
||||
"src": "152:166:11"
|
||||
}
|
||||
],
|
||||
"src": "0:319:16"
|
||||
"src": "0:319:11"
|
||||
},
|
||||
"legacyAST": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/common/SelfAuthorized.sol",
|
||||
"exportedSymbols": {
|
||||
"SelfAuthorized": [
|
||||
1765
|
||||
1735
|
||||
]
|
||||
},
|
||||
"id": 1766,
|
||||
"id": 1736,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1750,
|
||||
"id": 1720,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:16"
|
||||
"src": "0:23:11"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
|
@ -264,18 +264,18 @@
|
|||
"contractKind": "contract",
|
||||
"documentation": "@title SelfAuthorized - authorizes current contract to perform actions\n @author Richard Meissner - <richard@gnosis.pm>",
|
||||
"fullyImplemented": true,
|
||||
"id": 1765,
|
||||
"id": 1735,
|
||||
"linearizedBaseContracts": [
|
||||
1765
|
||||
1735
|
||||
],
|
||||
"name": "SelfAuthorized",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 1763,
|
||||
"id": 1733,
|
||||
"nodeType": "Block",
|
||||
"src": "204:112:16",
|
||||
"src": "204:112:11",
|
||||
"statements": [
|
||||
{
|
||||
"expression": {
|
||||
|
@ -287,7 +287,7 @@
|
|||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
},
|
||||
"id": 1758,
|
||||
"id": 1728,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -296,18 +296,18 @@
|
|||
"argumentTypes": null,
|
||||
"expression": {
|
||||
"argumentTypes": null,
|
||||
"id": 1753,
|
||||
"id": 1723,
|
||||
"name": "msg",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 3828,
|
||||
"src": "222:3:16",
|
||||
"referencedDeclaration": 4015,
|
||||
"src": "222:3:11",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_magic_message",
|
||||
"typeString": "msg"
|
||||
}
|
||||
},
|
||||
"id": 1754,
|
||||
"id": 1724,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -315,7 +315,7 @@
|
|||
"memberName": "sender",
|
||||
"nodeType": "MemberAccess",
|
||||
"referencedDeclaration": null,
|
||||
"src": "222:10:16",
|
||||
"src": "222:10:11",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -328,14 +328,14 @@
|
|||
"arguments": [
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"id": 1756,
|
||||
"id": 1726,
|
||||
"name": "this",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 3851,
|
||||
"src": "244:4:16",
|
||||
"referencedDeclaration": 4028,
|
||||
"src": "244:4:11",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1765",
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1735",
|
||||
"typeString": "contract SelfAuthorized"
|
||||
}
|
||||
}
|
||||
|
@ -343,24 +343,24 @@
|
|||
"expression": {
|
||||
"argumentTypes": [
|
||||
{
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1765",
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1735",
|
||||
"typeString": "contract SelfAuthorized"
|
||||
}
|
||||
],
|
||||
"id": 1755,
|
||||
"id": 1725,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"lValueRequested": false,
|
||||
"nodeType": "ElementaryTypeNameExpression",
|
||||
"src": "236:7:16",
|
||||
"src": "236:7:11",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_type$_t_address_$",
|
||||
"typeString": "type(address)"
|
||||
},
|
||||
"typeName": "address"
|
||||
},
|
||||
"id": 1757,
|
||||
"id": 1727,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -368,13 +368,13 @@
|
|||
"lValueRequested": false,
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "236:13:16",
|
||||
"src": "236:13:11",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"src": "222:27:16",
|
||||
"src": "222:27:11",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
|
@ -383,14 +383,14 @@
|
|||
{
|
||||
"argumentTypes": null,
|
||||
"hexValue": "4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207468697320636f6e7472616374",
|
||||
"id": 1759,
|
||||
"id": 1729,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "string",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "251:46:16",
|
||||
"src": "251:46:11",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_stringliteral_c4780ef0a1d41d59bac8c510cf9ada421bccf2b90f75a8e4ba2e8c09e8d72733",
|
||||
|
@ -410,21 +410,21 @@
|
|||
"typeString": "literal_string \"Method can only be called from this contract\""
|
||||
}
|
||||
],
|
||||
"id": 1752,
|
||||
"id": 1722,
|
||||
"name": "require",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [
|
||||
3831,
|
||||
3832
|
||||
4018,
|
||||
4019
|
||||
],
|
||||
"referencedDeclaration": 3832,
|
||||
"src": "214:7:16",
|
||||
"referencedDeclaration": 4019,
|
||||
"src": "214:7:11",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
|
||||
"typeString": "function (bool,string memory) pure"
|
||||
}
|
||||
},
|
||||
"id": 1760,
|
||||
"id": 1730,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -432,42 +432,42 @@
|
|||
"lValueRequested": false,
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "214:84:16",
|
||||
"src": "214:84:11",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_tuple$__$",
|
||||
"typeString": "tuple()"
|
||||
}
|
||||
},
|
||||
"id": 1761,
|
||||
"id": 1731,
|
||||
"nodeType": "ExpressionStatement",
|
||||
"src": "214:84:16"
|
||||
"src": "214:84:11"
|
||||
},
|
||||
{
|
||||
"id": 1762,
|
||||
"id": 1732,
|
||||
"nodeType": "PlaceholderStatement",
|
||||
"src": "308:1:16"
|
||||
"src": "308:1:11"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": null,
|
||||
"id": 1764,
|
||||
"id": 1734,
|
||||
"name": "authorized",
|
||||
"nodeType": "ModifierDefinition",
|
||||
"parameters": {
|
||||
"id": 1751,
|
||||
"id": 1721,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "201:2:16"
|
||||
"src": "201:2:11"
|
||||
},
|
||||
"src": "182:134:16",
|
||||
"src": "182:134:11",
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"scope": 1766,
|
||||
"src": "152:166:16"
|
||||
"scope": 1736,
|
||||
"src": "152:166:11"
|
||||
}
|
||||
],
|
||||
"src": "0:319:16"
|
||||
"src": "0:319:11"
|
||||
},
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
|
@ -475,5 +475,5 @@
|
|||
},
|
||||
"networks": {},
|
||||
"schemaVersion": "2.0.0",
|
||||
"updatedAt": "2018-08-20T07:44:41.093Z"
|
||||
"updatedAt": "2018-10-05T14:25:58.938Z"
|
||||
}
|
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
|
@ -0,0 +1,363 @@
|
|||
{
|
||||
"contractName": "Token",
|
||||
"abi": [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transfer",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
],
|
||||
"bytecode": "0x",
|
||||
"deployedBytecode": "0x",
|
||||
"sourceMap": "",
|
||||
"deployedSourceMap": "",
|
||||
"source": "pragma solidity ^0.4.23;\nimport \"@gnosis.pm/mock-contract/contracts/MockContract.sol\";\ncontract Token {\n\tfunction transfer(address _to, uint value) public returns (bool);\n}\n",
|
||||
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/mocks/Token.sol",
|
||||
"ast": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/mocks/Token.sol",
|
||||
"exportedSymbols": {
|
||||
"Token": [
|
||||
1871
|
||||
]
|
||||
},
|
||||
"id": 1872,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1860,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"^",
|
||||
"0.4",
|
||||
".23"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:24:16"
|
||||
},
|
||||
{
|
||||
"absolutePath": "@gnosis.pm/mock-contract/contracts/MockContract.sol",
|
||||
"file": "@gnosis.pm/mock-contract/contracts/MockContract.sol",
|
||||
"id": 1861,
|
||||
"nodeType": "ImportDirective",
|
||||
"scope": 1872,
|
||||
"sourceUnit": 4001,
|
||||
"src": "25:61:16",
|
||||
"symbolAliases": [],
|
||||
"unitAlias": ""
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"documentation": null,
|
||||
"fullyImplemented": false,
|
||||
"id": 1871,
|
||||
"linearizedBaseContracts": [
|
||||
1871
|
||||
],
|
||||
"name": "Token",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": null,
|
||||
"documentation": null,
|
||||
"id": 1870,
|
||||
"implemented": false,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
"modifiers": [],
|
||||
"name": "transfer",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 1866,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1863,
|
||||
"name": "_to",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1870,
|
||||
"src": "123:11:16",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1862,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "123:7:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1865,
|
||||
"name": "value",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1870,
|
||||
"src": "136:10:16",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1864,
|
||||
"name": "uint",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "136:4:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "122:25:16"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 1869,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1868,
|
||||
"name": "",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1870,
|
||||
"src": "164:4:16",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1867,
|
||||
"name": "bool",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "164:4:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "163:6:16"
|
||||
},
|
||||
"scope": 1871,
|
||||
"src": "105:65:16",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 1872,
|
||||
"src": "87:85:16"
|
||||
}
|
||||
],
|
||||
"src": "0:173:16"
|
||||
},
|
||||
"legacyAST": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/mocks/Token.sol",
|
||||
"exportedSymbols": {
|
||||
"Token": [
|
||||
1871
|
||||
]
|
||||
},
|
||||
"id": 1872,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1860,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"^",
|
||||
"0.4",
|
||||
".23"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:24:16"
|
||||
},
|
||||
{
|
||||
"absolutePath": "@gnosis.pm/mock-contract/contracts/MockContract.sol",
|
||||
"file": "@gnosis.pm/mock-contract/contracts/MockContract.sol",
|
||||
"id": 1861,
|
||||
"nodeType": "ImportDirective",
|
||||
"scope": 1872,
|
||||
"sourceUnit": 4001,
|
||||
"src": "25:61:16",
|
||||
"symbolAliases": [],
|
||||
"unitAlias": ""
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"documentation": null,
|
||||
"fullyImplemented": false,
|
||||
"id": 1871,
|
||||
"linearizedBaseContracts": [
|
||||
1871
|
||||
],
|
||||
"name": "Token",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": null,
|
||||
"documentation": null,
|
||||
"id": 1870,
|
||||
"implemented": false,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
"modifiers": [],
|
||||
"name": "transfer",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 1866,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1863,
|
||||
"name": "_to",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1870,
|
||||
"src": "123:11:16",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1862,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "123:7:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1865,
|
||||
"name": "value",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1870,
|
||||
"src": "136:10:16",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1864,
|
||||
"name": "uint",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "136:4:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "122:25:16"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 1869,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1868,
|
||||
"name": "",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1870,
|
||||
"src": "164:4:16",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1867,
|
||||
"name": "bool",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "164:4:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "163:6:16"
|
||||
},
|
||||
"scope": 1871,
|
||||
"src": "105:65:16",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 1872,
|
||||
"src": "87:85:16"
|
||||
}
|
||||
],
|
||||
"src": "0:173:16"
|
||||
},
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
"version": "0.4.24+commit.e67f0147.Emscripten.clang"
|
||||
},
|
||||
"networks": {},
|
||||
"schemaVersion": "2.0.0",
|
||||
"updatedAt": "2018-10-05T14:25:58.939Z"
|
||||
}
|
File diff suppressed because one or more lines are too long
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
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
|
@ -39,11 +39,12 @@ const styles = () => ({
|
|||
logo: {
|
||||
padding: `${sm} ${md}`,
|
||||
flexBasis: '95px',
|
||||
flexGrow: 0,
|
||||
},
|
||||
})
|
||||
|
||||
const Layout = openHoc(({
|
||||
open, toggle, classes, providerInfo, providerDetails,
|
||||
open, toggle, clickAway, classes, providerInfo, providerDetails,
|
||||
}: Props) => (
|
||||
<React.Fragment>
|
||||
<Row className={classes.summary}>
|
||||
|
@ -60,7 +61,7 @@ const Layout = openHoc(({
|
|||
<Grow
|
||||
{...TransitionProps}
|
||||
>
|
||||
<ClickAwayListener onClickAway={toggle}>
|
||||
<ClickAwayListener onClickAway={clickAway} mouseEvent="onClick" touchEvent={false}>
|
||||
<List className={classes.root} component="div">
|
||||
{providerDetails}
|
||||
</List>
|
||||
|
|
|
@ -54,10 +54,9 @@ class Provider extends React.Component<Props> {
|
|||
return (
|
||||
<React.Fragment>
|
||||
<div ref={this.myRef} className={classes.root}>
|
||||
<Col end="sm" middle="xs" className={classes.provider}>
|
||||
<Col end="sm" middle="xs" className={classes.provider} onClick={toggle}>
|
||||
{ info }
|
||||
<IconButton
|
||||
onClick={toggle}
|
||||
disableRipple
|
||||
className={classes.expand}
|
||||
>
|
||||
|
|
|
@ -11,10 +11,10 @@ import Img from '~/components/layout/Img'
|
|||
import Row from '~/components/layout/Row'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Spacer from '~/components/Spacer'
|
||||
import { xs, sm, md, lg, background } from '~/theme/variables'
|
||||
import { xs, sm, md, lg, background, secondary } from '~/theme/variables'
|
||||
import { upperFirst } from '~/utils/css'
|
||||
import { shortVersionOf } from '~/logic/wallets/ethAddresses'
|
||||
import { openInEtherScan } from '~/logic/wallets/getWeb3'
|
||||
import { openAddressInEtherScan } from '~/logic/wallets/getWeb3'
|
||||
|
||||
const metamask = require('../../assets/metamask.svg')
|
||||
const connectedLogo = require('../../assets/connected.svg')
|
||||
|
@ -32,7 +32,7 @@ type Props = {
|
|||
|
||||
const openIconStyle = {
|
||||
height: '16px',
|
||||
color: '#467ee5',
|
||||
color: secondary,
|
||||
}
|
||||
|
||||
const styles = () => ({
|
||||
|
@ -97,7 +97,11 @@ const UserDetails = ({
|
|||
<Block align="center" className={classes.user}>
|
||||
<Paragraph className={classes.address} size="sm" noMargin>{address}</Paragraph>
|
||||
{ userAddress &&
|
||||
<OpenInNew className={classes.open} style={openIconStyle} onClick={openInEtherScan(userAddress, network)} />
|
||||
<OpenInNew
|
||||
className={classes.open}
|
||||
style={openIconStyle}
|
||||
onClick={openAddressInEtherScan(userAddress, network)}
|
||||
/>
|
||||
}
|
||||
</Block>
|
||||
</Block>
|
||||
|
|
|
@ -53,7 +53,7 @@ const ProviderInfo = ({
|
|||
<React.Fragment>
|
||||
<Identicon address={identiconAddress} diameter={30} />
|
||||
<Img className={classes.logo} src={logo} height={20} alt="Connection status" />
|
||||
<Col end="sm" middle="xs" layout="column" className={classes.account}>
|
||||
<Col start="sm" layout="column" className={classes.account}>
|
||||
<Paragraph size="sm" transform="capitalize" className={classes.network} noMargin weight="bold">{providerText}</Paragraph>
|
||||
<Paragraph size="sm" className={classes.address} noMargin color={color}>{cutAddress}</Paragraph>
|
||||
</Col>
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
import * as React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import { logComponentStack, type Info } from '~/utils/logBoundaries'
|
||||
import { SharedSnackbarConsumer, type Variant } from '~/components/SharedSnackBar/Context'
|
||||
import { WALLET_ERROR_MSG } from '~/logic/wallets/store/actions'
|
||||
import ProviderInfo from './component/ProviderInfo'
|
||||
import ProviderDetails from './component/ProviderInfo/UserDetails'
|
||||
import ProviderDisconnected from './component/ProviderDisconnected'
|
||||
|
@ -10,33 +12,36 @@ import Layout from './component/Layout'
|
|||
import actions, { type Actions } from './actions'
|
||||
import selector, { type SelectorProps } from './selector'
|
||||
|
||||
type Props = Actions & SelectorProps
|
||||
type Props = Actions & SelectorProps & {
|
||||
openSnackbar: (message: string, variant: Variant) => void,
|
||||
}
|
||||
|
||||
type State = {
|
||||
hasError: boolean,
|
||||
}
|
||||
|
||||
class Header extends React.PureComponent<Props, State> {
|
||||
class HeaderComponent extends React.PureComponent<Props, State> {
|
||||
state = {
|
||||
hasError: false,
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.fetchProvider()
|
||||
this.props.fetchProvider(this.props.openSnackbar)
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, info: Info) {
|
||||
this.setState({ hasError: true })
|
||||
this.props.openSnackbar(WALLET_ERROR_MSG, 'error')
|
||||
|
||||
logComponentStack(error, info)
|
||||
}
|
||||
|
||||
onDisconnect = () => {
|
||||
this.props.removeProvider()
|
||||
this.props.removeProvider(this.props.openSnackbar)
|
||||
}
|
||||
|
||||
onConnect = () => {
|
||||
this.props.fetchProvider()
|
||||
this.props.fetchProvider(this.props.openSnackbar)
|
||||
}
|
||||
|
||||
getProviderInfoBased = () => {
|
||||
|
@ -79,4 +84,14 @@ class Header extends React.PureComponent<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
export default connect(selector, actions)(Header)
|
||||
const Header = connect(selector, actions)(HeaderComponent)
|
||||
|
||||
const HeaderSnack = () => (
|
||||
<SharedSnackbarConsumer>
|
||||
{({ openSnackbar }) => (
|
||||
<Header openSnackbar={openSnackbar} />
|
||||
)}
|
||||
</SharedSnackbarConsumer>
|
||||
)
|
||||
|
||||
export default HeaderSnack
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import SharedSnackBar from './index'
|
||||
|
||||
const SharedSnackbarContext = React.createContext({
|
||||
openSnackbar: undefined,
|
||||
closeSnackbar: undefined,
|
||||
snackbarIsOpen: false,
|
||||
message: '',
|
||||
variant: 'info',
|
||||
})
|
||||
|
||||
type Props = {
|
||||
children: React$Node,
|
||||
}
|
||||
|
||||
export type Variant = 'success' | 'error' | 'warning' | 'info'
|
||||
|
||||
type State = {
|
||||
isOpen: boolean,
|
||||
message: string,
|
||||
variant: Variant,
|
||||
}
|
||||
|
||||
export class SharedSnackbarProvider extends React.Component<Props, State> {
|
||||
state = {
|
||||
isOpen: false,
|
||||
message: '',
|
||||
variant: 'info',
|
||||
}
|
||||
|
||||
openSnackbar = (message: string, variant: Variant) => {
|
||||
this.setState({
|
||||
message,
|
||||
variant,
|
||||
isOpen: true,
|
||||
})
|
||||
}
|
||||
|
||||
closeSnackbar = () => {
|
||||
this.setState({
|
||||
message: '',
|
||||
isOpen: false,
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children } = this.props
|
||||
|
||||
return (
|
||||
<SharedSnackbarContext.Provider
|
||||
value={{
|
||||
openSnackbar: this.openSnackbar,
|
||||
closeSnackbar: this.closeSnackbar,
|
||||
snackbarIsOpen: this.state.isOpen,
|
||||
message: this.state.message,
|
||||
variant: this.state.variant,
|
||||
}}
|
||||
>
|
||||
<SharedSnackBar />
|
||||
{children}
|
||||
</SharedSnackbarContext.Provider>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export const SharedSnackbarConsumer = SharedSnackbarContext.Consumer
|
|
@ -0,0 +1,35 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { Snackbar } from '@material-ui/core'
|
||||
import SnackbarContent from '~/components/SnackbarContent'
|
||||
import { SharedSnackbarConsumer } from './Context'
|
||||
|
||||
const SharedSnackbar = () => (
|
||||
<SharedSnackbarConsumer>
|
||||
{(value) => {
|
||||
const {
|
||||
snackbarIsOpen, message, closeSnackbar, variant,
|
||||
} = value
|
||||
|
||||
return (
|
||||
<Snackbar
|
||||
anchorOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'right',
|
||||
}}
|
||||
open={snackbarIsOpen}
|
||||
autoHideDuration={4000}
|
||||
onClose={closeSnackbar}
|
||||
>
|
||||
<SnackbarContent
|
||||
onClose={closeSnackbar}
|
||||
message={message}
|
||||
variant={variant}
|
||||
/>
|
||||
</Snackbar>
|
||||
)
|
||||
}}
|
||||
</SharedSnackbarConsumer>
|
||||
)
|
||||
|
||||
export default SharedSnackbar
|
|
@ -2,8 +2,6 @@
|
|||
import SnackbarContent from '@material-ui/core/SnackbarContent'
|
||||
import classNames from 'classnames/bind'
|
||||
import * as React from 'react'
|
||||
import green from '@material-ui/core/colors/green'
|
||||
import amber from '@material-ui/core/colors/amber'
|
||||
import CloseIcon from '@material-ui/icons/Close'
|
||||
import CheckCircleIcon from '@material-ui/icons/CheckCircle'
|
||||
import ErrorIcon from '@material-ui/icons/Error'
|
||||
|
@ -12,6 +10,7 @@ import IconButton from '@material-ui/core/IconButton'
|
|||
import { withStyles } from '@material-ui/core/styles'
|
||||
import WarningIcon from '@material-ui/icons/Warning'
|
||||
import { type WithStyles } from '~/theme/mui'
|
||||
import { secondary } from '~/theme/variables'
|
||||
|
||||
type Variant = 'success' | 'error' | 'warning' | 'info'
|
||||
|
||||
|
@ -37,16 +36,28 @@ const variantIcon = {
|
|||
|
||||
const styles = theme => ({
|
||||
success: {
|
||||
backgroundColor: green[600],
|
||||
backgroundColor: '#ffffff',
|
||||
},
|
||||
error: {
|
||||
backgroundColor: theme.palette.error.dark,
|
||||
},
|
||||
info: {
|
||||
backgroundColor: theme.palette.primary.dark,
|
||||
successIcon: {
|
||||
color: '#00c4c4',
|
||||
},
|
||||
warning: {
|
||||
backgroundColor: amber[700],
|
||||
backgroundColor: '#fff3e2',
|
||||
},
|
||||
warningIcon: {
|
||||
color: '#ffc05f',
|
||||
},
|
||||
error: {
|
||||
backgroundColor: '#ffe6ea',
|
||||
},
|
||||
errorIcon: {
|
||||
color: '#fd7890',
|
||||
},
|
||||
info: {
|
||||
backgroundColor: '#ffffff',
|
||||
},
|
||||
infoIcon: {
|
||||
color: secondary,
|
||||
},
|
||||
icon: {
|
||||
fontSize: 20,
|
||||
|
@ -78,7 +89,7 @@ const Message = ({ classes, message, variant }: MessageProps) => {
|
|||
|
||||
return (
|
||||
<span id="client-snackbar" className={classes.message}>
|
||||
<Icon className={classNames(classes.icon, classes.iconVariant)} />
|
||||
<Icon className={classNames(classes.icon, classes.iconVariant, classes[`${variant}Icon`])} />
|
||||
{message}
|
||||
</span>
|
||||
)
|
||||
|
@ -87,7 +98,7 @@ const Message = ({ classes, message, variant }: MessageProps) => {
|
|||
const GnoSnackbarContent = ({
|
||||
variant, classes, message, onClose,
|
||||
}: Props) => {
|
||||
const action = onClose ? [<Close onClose={onClose} classes={classes} />] : undefined
|
||||
const action = onClose ? [<Close key="close" onClose={onClose} classes={classes} />] : undefined
|
||||
const messageComponent = <Message classes={classes} message={message} variant={variant} />
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,56 +1,57 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import Button from '~/components/layout/Button'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Row from '~/components/layout/Row'
|
||||
import { sm } from '~/theme/variables'
|
||||
|
||||
type ControlProps = {
|
||||
next: string,
|
||||
onPrevious: () => void,
|
||||
firstPage: boolean,
|
||||
disabled: boolean,
|
||||
const controlStyle = {
|
||||
backgroundColor: 'white',
|
||||
padding: sm,
|
||||
}
|
||||
|
||||
const ControlButtons = ({
|
||||
next, firstPage, onPrevious, disabled,
|
||||
}: ControlProps) => (
|
||||
<React.Fragment>
|
||||
<Button
|
||||
type="button"
|
||||
disabled={firstPage || disabled}
|
||||
onClick={onPrevious}
|
||||
>
|
||||
Back
|
||||
</Button>
|
||||
<Button
|
||||
variant="raised"
|
||||
color="primary"
|
||||
type="submit"
|
||||
disabled={disabled}
|
||||
>
|
||||
{next}
|
||||
</Button>
|
||||
</React.Fragment>
|
||||
)
|
||||
const firstButtonStyle = {
|
||||
marginRight: sm,
|
||||
}
|
||||
|
||||
type Props = {
|
||||
finishedTx: boolean,
|
||||
finishedButton: React$Node,
|
||||
onPrevious: () => void,
|
||||
firstPage: boolean,
|
||||
lastPage: boolean,
|
||||
disabled: boolean,
|
||||
penultimate: boolean,
|
||||
}
|
||||
|
||||
const Controls = ({
|
||||
finishedTx, finishedButton, onPrevious, firstPage, lastPage, disabled,
|
||||
}: Props) => (
|
||||
finishedTx
|
||||
? <React.Fragment>{finishedButton}</React.Fragment>
|
||||
: <ControlButtons
|
||||
disabled={disabled}
|
||||
next={lastPage ? 'Finish' : 'Next'}
|
||||
firstPage={firstPage}
|
||||
onPrevious={onPrevious}
|
||||
/>
|
||||
)
|
||||
onPrevious, firstPage, penultimate, lastPage, disabled,
|
||||
}: Props) => {
|
||||
// eslint-disable-next-line
|
||||
const next = firstPage ? 'Start' : penultimate ? 'Review' : lastPage ? 'Submit' : 'Next'
|
||||
const back = firstPage ? 'Cancel' : 'Back'
|
||||
|
||||
return (
|
||||
<Row style={controlStyle} align="end" grow>
|
||||
<Col xs={12} end="xs">
|
||||
<Button
|
||||
style={firstButtonStyle}
|
||||
type="button"
|
||||
onClick={onPrevious}
|
||||
size="small"
|
||||
>
|
||||
{back}
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
variant="raised"
|
||||
color="primary"
|
||||
type="submit"
|
||||
disabled={disabled}
|
||||
>
|
||||
{next}
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default Controls
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Paper from '@material-ui/core/Paper'
|
||||
import Block from '~/components/layout/Block'
|
||||
import { lg } from '~/theme/variables'
|
||||
|
||||
const styles = () => ({
|
||||
root: {
|
||||
margin: '10px',
|
||||
maxWidth: '870px',
|
||||
},
|
||||
container: {
|
||||
letterSpacing: '-0.5px',
|
||||
},
|
||||
padding: {
|
||||
padding: lg,
|
||||
},
|
||||
})
|
||||
|
||||
type Props = {
|
||||
classes: Object,
|
||||
children: React$Node,
|
||||
controls: React$Node,
|
||||
container?: number,
|
||||
padding?: boolean,
|
||||
}
|
||||
|
||||
const generateContainerStyleFrom = (container?: number) => ({
|
||||
maxWidth: container ? `${container}px` : undefined,
|
||||
})
|
||||
|
||||
const OpenPaper = ({
|
||||
classes, children, controls, container, padding = true,
|
||||
}: Props) => {
|
||||
const containerStyle = generateContainerStyleFrom(container)
|
||||
|
||||
return (
|
||||
<Paper className={classes.root} elevation={1}>
|
||||
<Block style={containerStyle} className={`${classes.container} ${padding ? classes.padding : ''}`}>
|
||||
{children}
|
||||
</Block>
|
||||
{ controls }
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
|
||||
export default withStyles(styles)(OpenPaper)
|
|
@ -2,26 +2,25 @@
|
|||
import Stepper from '@material-ui/core/Stepper'
|
||||
import FormStep from '@material-ui/core/Step'
|
||||
import StepLabel from '@material-ui/core/StepLabel'
|
||||
import StepContent from '@material-ui/core/StepContent'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import * as React from 'react'
|
||||
import GnoForm from '~/components/forms/GnoForm'
|
||||
import Hairline from '~/components/layout/Hairline'
|
||||
import Button from '~/components/layout/Button'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Row from '~/components/layout/Row'
|
||||
import { history } from '~/store'
|
||||
import Controls from './Controls'
|
||||
|
||||
export { default as Step } from './Step'
|
||||
|
||||
type Props = {
|
||||
disabledWhenValidating?: boolean,
|
||||
classes: Object,
|
||||
steps: string[],
|
||||
finishedTransaction: boolean,
|
||||
finishedButton: React$Node,
|
||||
initialValues?: Object,
|
||||
children: React$Node,
|
||||
onReset?: () => void,
|
||||
onSubmit: (values: Object) => Promise<void>,
|
||||
children: React$Node,
|
||||
classes: Object,
|
||||
onReset?: () => void,
|
||||
initialValues?: Object,
|
||||
disabledWhenValidating?: boolean,
|
||||
}
|
||||
|
||||
type State = {
|
||||
|
@ -34,6 +33,13 @@ type PageProps = {
|
|||
prepareNextInitialProps: (values: Object) => {},
|
||||
}
|
||||
|
||||
const transitionProps = {
|
||||
timeout: {
|
||||
enter: 350,
|
||||
exit: 0,
|
||||
},
|
||||
}
|
||||
|
||||
class GnoStepper extends React.PureComponent<Props, State> {
|
||||
static Page = ({ children }: PageProps) => children
|
||||
|
||||
|
@ -70,7 +76,11 @@ class GnoStepper extends React.PureComponent<Props, State> {
|
|||
const activePageProps = this.getPageProps(pages)
|
||||
const { children, ...props } = activePageProps
|
||||
|
||||
return children(props)
|
||||
return children({ ...props, updateInitialProps: this.updateInitialProps })
|
||||
}
|
||||
|
||||
updateInitialProps = (initialValues) => {
|
||||
this.setState({ values: initialValues })
|
||||
}
|
||||
|
||||
validate = (values: Object) => {
|
||||
|
@ -96,10 +106,17 @@ class GnoStepper extends React.PureComponent<Props, State> {
|
|||
}))
|
||||
}
|
||||
|
||||
previous = () =>
|
||||
this.setState(state => ({
|
||||
previous = () => {
|
||||
const firstPage = this.state.page === 0
|
||||
|
||||
if (firstPage) {
|
||||
return history.goBack()
|
||||
}
|
||||
|
||||
return this.setState(state => ({
|
||||
page: Math.max(state.page - 1, 0),
|
||||
}))
|
||||
}
|
||||
|
||||
handleSubmit = async (values: Object) => {
|
||||
const { children, onSubmit } = this.props
|
||||
|
@ -112,47 +129,50 @@ class GnoStepper extends React.PureComponent<Props, State> {
|
|||
return this.next(values)
|
||||
}
|
||||
|
||||
isLastPage = page => page === this.props.steps.length - 1
|
||||
|
||||
render() {
|
||||
const {
|
||||
steps, children, finishedTransaction, finishedButton, classes, disabledWhenValidating = false,
|
||||
steps, children, classes, disabledWhenValidating = false,
|
||||
} = this.props
|
||||
const { page, values } = this.state
|
||||
const activePage = this.getActivePageFrom(children)
|
||||
const isLastPage = page === steps.length - 1
|
||||
const finished = React.cloneElement(React.Children.only(finishedButton), { onClick: this.onReset })
|
||||
const lastPage = this.isLastPage(page)
|
||||
const penultimate = this.isLastPage(page + 1)
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Stepper classes={{ root: classes.root }} activeStep={page} alternativeLabel>
|
||||
{steps.map(label => (
|
||||
<FormStep key={label}>
|
||||
<StepLabel>{label}</StepLabel>
|
||||
</FormStep>
|
||||
))}
|
||||
</Stepper>
|
||||
<GnoForm
|
||||
onSubmit={this.handleSubmit}
|
||||
initialValues={values}
|
||||
padding={15}
|
||||
validation={this.validate}
|
||||
render={activePage}
|
||||
>
|
||||
{(submitting: boolean, validating: boolean) => {
|
||||
{(submitting: boolean, validating: boolean, ...rest: any) => {
|
||||
const disabled = disabledWhenValidating ? submitting || validating : submitting
|
||||
const controls = (
|
||||
<React.Fragment>
|
||||
<Hairline />
|
||||
<Controls
|
||||
disabled={disabled}
|
||||
onPrevious={this.previous}
|
||||
firstPage={page === 0}
|
||||
lastPage={lastPage}
|
||||
penultimate={penultimate}
|
||||
/>
|
||||
</React.Fragment>
|
||||
)
|
||||
|
||||
return (
|
||||
<Row align="end" margin="lg" grow>
|
||||
<Col xs={12} center="xs">
|
||||
<Controls
|
||||
disabled={disabled}
|
||||
finishedTx={finishedTransaction}
|
||||
finishedButton={finished}
|
||||
onPrevious={this.previous}
|
||||
firstPage={page === 0}
|
||||
lastPage={isLastPage}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Stepper classes={{ root: classes.root }} activeStep={page} orientation="vertical">
|
||||
{steps.map(label => (
|
||||
<FormStep key={label}>
|
||||
<StepLabel>{label}</StepLabel>
|
||||
<StepContent TransitionProps={transitionProps}>
|
||||
{activePage(controls, ...rest)}
|
||||
</StepContent>
|
||||
</FormStep>
|
||||
))}
|
||||
</Stepper>
|
||||
)
|
||||
}}
|
||||
</GnoForm>
|
||||
|
|
|
@ -12,21 +12,19 @@ export type OnSubmit = (
|
|||
type Props = {
|
||||
onSubmit: OnSubmit,
|
||||
children: Function,
|
||||
padding: number,
|
||||
padding?: number,
|
||||
validation?: (values: Object) => Object | Promise<Object>,
|
||||
initialValues?: Object,
|
||||
render: Function,
|
||||
}
|
||||
|
||||
const stylesBasedOn = (padding: number): $Shape<CSSStyleDeclaration> => ({
|
||||
padding: `0 ${padding}%`,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flex: '1 0 auto',
|
||||
})
|
||||
|
||||
const GnoForm = ({
|
||||
onSubmit, validation, initialValues, children, padding, render,
|
||||
onSubmit, validation, initialValues, children, padding = 0,
|
||||
}: Props) => (
|
||||
<Form
|
||||
validate={validation}
|
||||
|
@ -34,8 +32,7 @@ const GnoForm = ({
|
|||
initialValues={initialValues}
|
||||
render={({ handleSubmit, ...rest }) => (
|
||||
<form onSubmit={handleSubmit} style={stylesBasedOn(padding)}>
|
||||
{render(rest)}
|
||||
{children(rest.submitting, rest.validating)}
|
||||
{children(rest.submitting, rest.validating, rest)}
|
||||
</form>
|
||||
)}
|
||||
/>
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
// @flow
|
||||
import React from 'react'
|
||||
import Select, { type SelectFieldProps } from '@material-ui/core/Select'
|
||||
import FormControl from '@material-ui/core/FormControl'
|
||||
import InputLabel from '@material-ui/core/InputLabel'
|
||||
import FormHelperText from '@material-ui/core/FormHelperText'
|
||||
|
||||
const style = {
|
||||
minWidth: '100%',
|
||||
}
|
||||
|
||||
const SelectInput = ({
|
||||
input: {
|
||||
name, value, onChange, ...restInput
|
||||
},
|
||||
meta,
|
||||
label,
|
||||
formControlProps,
|
||||
...rest
|
||||
}: SelectFieldProps) => {
|
||||
const showError = ((meta.submitError && !meta.dirtySinceLastSubmit) || meta.error) && meta.touched
|
||||
const inputProps = { ...restInput, name }
|
||||
|
||||
return (
|
||||
<FormControl
|
||||
{...formControlProps}
|
||||
error={showError}
|
||||
style={style}
|
||||
>
|
||||
<InputLabel htmlFor={name}>{label}</InputLabel>
|
||||
<Select
|
||||
{...rest}
|
||||
onChange={onChange}
|
||||
inputProps={inputProps}
|
||||
value={value}
|
||||
/>
|
||||
{ showError &&
|
||||
<FormHelperText>
|
||||
{meta.error || meta.submitError}
|
||||
</FormHelperText>
|
||||
}
|
||||
</FormControl>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export default SelectInput
|
|
@ -1,12 +1,23 @@
|
|||
// @flow
|
||||
import React from 'react'
|
||||
import MuiTextField, { TextFieldProps } from '@material-ui/core/TextField'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import { lg } from '~/theme/variables'
|
||||
|
||||
// Neded for solving a fix in Windows browsers
|
||||
const overflowStyle = {
|
||||
overflow: 'hidden',
|
||||
width: '100%',
|
||||
}
|
||||
|
||||
const styles = () => ({
|
||||
root: {
|
||||
paddingTop: lg,
|
||||
paddingBottom: '12px',
|
||||
lineHeight: 0,
|
||||
},
|
||||
})
|
||||
|
||||
class TextField extends React.PureComponent<TextFieldProps> {
|
||||
render() {
|
||||
const {
|
||||
|
@ -16,25 +27,33 @@ class TextField extends React.PureComponent<TextFieldProps> {
|
|||
meta,
|
||||
render,
|
||||
text,
|
||||
inputAdornment,
|
||||
classes,
|
||||
...rest
|
||||
} = this.props
|
||||
const helperText = value ? text : undefined
|
||||
const showError = (meta.touched || !meta.pristine) && !meta.valid
|
||||
const underline = meta.active || (meta.visited && !meta.valid)
|
||||
|
||||
const inputRoot = helperText ? classes.root : undefined
|
||||
const inputProps = { ...restInput, autoComplete: 'off' }
|
||||
const inputRootProps = { ...inputAdornment, disableUnderline: !underline, className: inputRoot }
|
||||
|
||||
return (
|
||||
<MuiTextField
|
||||
style={overflowStyle}
|
||||
{...rest}
|
||||
name={name}
|
||||
helperText={showError ? meta.error : helperText}
|
||||
helperText={showError ? meta.error : helperText || ' '} // blank in order to force to have helper text
|
||||
error={meta.error && (meta.touched || !meta.pristine)}
|
||||
inputProps={restInput}
|
||||
InputProps={inputRootProps}
|
||||
// eslint-disable-next-line
|
||||
inputProps={inputProps}
|
||||
onChange={onChange}
|
||||
value={value}
|
||||
fullWidth
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default TextField
|
||||
export default withStyles(styles)(TextField)
|
||||
|
|
|
@ -4,9 +4,13 @@ import { withStateHandlers } from 'recompose'
|
|||
export type Open = {
|
||||
open: boolean,
|
||||
toggle: () => void,
|
||||
clickAway: () => void,
|
||||
}
|
||||
|
||||
export default withStateHandlers(
|
||||
() => ({ open: false }),
|
||||
{ toggle: ({ open }) => () => ({ open: !open }) },
|
||||
{
|
||||
toggle: ({ open }) => () => ({ open: !open }),
|
||||
clickAway: () => () => ({ open: false }),
|
||||
},
|
||||
)
|
||||
|
|
|
@ -35,6 +35,7 @@ const Col = ({
|
|||
xs, sm, md, lg,
|
||||
start, center, end, top, middle, bottom, around, between,
|
||||
xsOffset, smOffset, mdOffset, lgOffset,
|
||||
className,
|
||||
...props
|
||||
}: Props) => {
|
||||
const colClassNames = cx(
|
||||
|
@ -58,7 +59,7 @@ const Col = ({
|
|||
lgOffset ? capitalize(lgOffset, 'lgOffset') : undefined,
|
||||
{ overflow },
|
||||
layout,
|
||||
props.className,
|
||||
className,
|
||||
)
|
||||
|
||||
return (
|
||||
|
|
|
@ -3,7 +3,7 @@ import * as React from 'react'
|
|||
import { type Size, getSize } from '~/theme/size'
|
||||
import { border } from '~/theme/variables'
|
||||
|
||||
const calculateStyleFrom = (margin: Size) => ({
|
||||
const calculateStyleFrom = (margin?: Size) => ({
|
||||
width: '100%',
|
||||
height: '1px',
|
||||
backgroundColor: border,
|
||||
|
@ -14,7 +14,7 @@ type Props = {
|
|||
margin?: Size,
|
||||
}
|
||||
|
||||
const Hairline = ({ margin = 'md' }: Props) => {
|
||||
const Hairline = ({ margin }: Props) => {
|
||||
const style = calculateStyleFrom(margin)
|
||||
|
||||
return <div style={style} />
|
||||
|
|
|
@ -13,18 +13,23 @@
|
|||
|
||||
.h2 {
|
||||
line-height: 28px;
|
||||
font-weight: $bolderFont;
|
||||
letter-spacing: -0.5px;
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
font-size: $(fontSizeHeadingMd)px;
|
||||
}
|
||||
|
||||
.h3 {
|
||||
line-height: 21px;
|
||||
font-weight: bold;
|
||||
font-weight: $bolderFont;
|
||||
letter-spacing: -0.5px;
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
font-size: $(fontSizeHeadingSm)px;
|
||||
}
|
||||
|
||||
.h4 {
|
||||
line-height: 21px;
|
||||
letter-spacing: -0.5px;
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
font-size: $(fontSizeHeadingXs)px;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,13 @@
|
|||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
flex-direction: column;
|
||||
padding: $xl;
|
||||
padding: 80px 200px 0px 200px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $(screenLg)px) {
|
||||
.page {
|
||||
padding: 80px $lg 0px $lg;
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import React from 'react'
|
||||
import Footer from '~/components/Footer'
|
||||
import Header from '~/components/Header'
|
||||
import { SharedSnackbarProvider } from '~/components/SharedSnackBar/Context'
|
||||
import styles from './index.scss'
|
||||
|
||||
type Props = {
|
||||
|
@ -9,11 +10,13 @@ type Props = {
|
|||
}
|
||||
|
||||
const PageFrame = ({ children }: Props) => (
|
||||
<div className={styles.frame}>
|
||||
<Header />
|
||||
{children}
|
||||
<Footer />
|
||||
</div>
|
||||
<SharedSnackbarProvider>
|
||||
<div className={styles.frame}>
|
||||
<Header />
|
||||
{children}
|
||||
<Footer />
|
||||
</div>
|
||||
</SharedSnackbarProvider>
|
||||
)
|
||||
|
||||
export default PageFrame
|
||||
|
|
|
@ -9,22 +9,23 @@ type Props = {
|
|||
align?: 'right' | 'center' | 'left',
|
||||
noMargin?: boolean,
|
||||
weight?: 'light' | 'regular' | 'bolder' | 'bold',
|
||||
size?: 'sm' | 'md' | 'lg' | 'xl',
|
||||
color?: 'soft' | 'medium' | 'dark' | 'white' | 'fancy' | 'primary' | 'warning',
|
||||
size?: 'sm' | 'md' | 'lg' | 'xl' | 'xxl',
|
||||
color?: 'soft' | 'medium' | 'dark' | 'white' | 'fancy' | 'primary' | 'secondary' | 'warning' | 'disabled',
|
||||
transform?: 'capitalize' | 'lowercase' | 'uppercase',
|
||||
children: React$Node,
|
||||
dot?: boolean,
|
||||
className?: string,
|
||||
}
|
||||
|
||||
class Paragraph extends React.PureComponent<Props> {
|
||||
render() {
|
||||
const {
|
||||
weight, children, color, align, size, transform, noMargin, className, ...props
|
||||
weight, children, color, align, size, transform, noMargin, className, dot, ...props
|
||||
} = this.props
|
||||
|
||||
return (
|
||||
<p
|
||||
className={cx(styles.paragraph, className, weight, { noMargin }, size, color, transform, align)}
|
||||
className={cx(styles.paragraph, className, weight, { noMargin }, { dot }, size, color, transform, align)}
|
||||
{...props}
|
||||
>
|
||||
{ children }
|
||||
|
|
|
@ -22,10 +22,19 @@
|
|||
.warning {
|
||||
color: $warning;
|
||||
}
|
||||
|
||||
.primary {
|
||||
color: $fontColor;
|
||||
}
|
||||
|
||||
.secondary {
|
||||
color: $secondary;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
color: $disabled;
|
||||
}
|
||||
|
||||
.white {
|
||||
color: white;
|
||||
}
|
||||
|
@ -74,6 +83,10 @@
|
|||
font-size: $extraLargeFontSize;
|
||||
}
|
||||
|
||||
.xxl {
|
||||
font-size: $xxlFontSize;
|
||||
}
|
||||
|
||||
.light {
|
||||
font-weight: $lightFont;
|
||||
}
|
||||
|
@ -88,4 +101,8 @@
|
|||
|
||||
.bold {
|
||||
font-weight: $boldFont;
|
||||
}
|
||||
}
|
||||
|
||||
.dot {
|
||||
display: list-item;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
// @flow
|
||||
import {
|
||||
TX_SERVICE_HOST,
|
||||
ENABLED_TX_SERVICE_MODULES,
|
||||
ENABLED_TX_SERVICE_REMOVAL_SENDER,
|
||||
SIGNATURES_VIA_METAMASK,
|
||||
} from '~/config/names'
|
||||
|
||||
const devConfig = {
|
||||
[TX_SERVICE_HOST]: 'http://localhost:8000/api/v1/',
|
||||
[ENABLED_TX_SERVICE_MODULES]: false,
|
||||
[ENABLED_TX_SERVICE_REMOVAL_SENDER]: false,
|
||||
[SIGNATURES_VIA_METAMASK]: false,
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
import { ensureOnce } from '~/utils/singleton'
|
||||
import {
|
||||
TX_SERVICE_HOST,
|
||||
ENABLED_TX_SERVICE_MODULES,
|
||||
ENABLED_TX_SERVICE_REMOVAL_SENDER,
|
||||
SIGNATURES_VIA_METAMASK,
|
||||
} from '~/config/names'
|
||||
|
@ -32,12 +31,6 @@ export const getTxServiceHost = () => {
|
|||
|
||||
export const getTxServiceUriFrom = (safeAddress: string) => `safes/${safeAddress}/transactions/`
|
||||
|
||||
export const allowedModulesInTxHistoryService = () => {
|
||||
const config = getConfig()
|
||||
|
||||
return config[ENABLED_TX_SERVICE_MODULES]
|
||||
}
|
||||
|
||||
export const allowedRemoveSenderInTxHistoryService = () => {
|
||||
const config = getConfig()
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// @flow
|
||||
|
||||
export const TX_SERVICE_HOST = 'tsh'
|
||||
export const ENABLED_TX_SERVICE_MODULES = 'tsm'
|
||||
export const ENABLED_TX_SERVICE_REMOVAL_SENDER = 'trs'
|
||||
export const SIGNATURES_VIA_METAMASK = 'svm'
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
// @flow
|
||||
import {
|
||||
TX_SERVICE_HOST,
|
||||
ENABLED_TX_SERVICE_MODULES,
|
||||
ENABLED_TX_SERVICE_REMOVAL_SENDER,
|
||||
SIGNATURES_VIA_METAMASK,
|
||||
} from '~/config/names'
|
||||
|
||||
const prodConfig = {
|
||||
[TX_SERVICE_HOST]: 'https://safe-transaction-history.dev.gnosisdev.com/api/v1/',
|
||||
[ENABLED_TX_SERVICE_MODULES]: false,
|
||||
[ENABLED_TX_SERVICE_REMOVAL_SENDER]: false,
|
||||
[SIGNATURES_VIA_METAMASK]: false,
|
||||
}
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
// @flow
|
||||
import {
|
||||
TX_SERVICE_HOST,
|
||||
ENABLED_TX_SERVICE_MODULES,
|
||||
ENABLED_TX_SERVICE_REMOVAL_SENDER,
|
||||
SIGNATURES_VIA_METAMASK,
|
||||
} from '~/config/names'
|
||||
|
||||
const testConfig = {
|
||||
[TX_SERVICE_HOST]: 'http://localhost:8000/api/v1/',
|
||||
[ENABLED_TX_SERVICE_MODULES]: false,
|
||||
[ENABLED_TX_SERVICE_REMOVAL_SENDER]: false,
|
||||
[SIGNATURES_VIA_METAMASK]: false,
|
||||
}
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
// @flow
|
||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||
import { getGnosisSafeContract, getCreateDailyLimitExtensionContract } from '~/logic/contracts/safeContracts'
|
||||
import { type DailyLimitProps } from '~/routes/safe/store/model/dailyLimit'
|
||||
|
||||
export const LIMIT_POSITION = 0
|
||||
export const SPENT_TODAY_POS = 1
|
||||
|
||||
|
||||
export const getDailyLimitModuleFrom = async (safeAddress: string) => {
|
||||
const web3 = getWeb3()
|
||||
const gnosisSafe = getGnosisSafeContract(web3).at(safeAddress)
|
||||
|
||||
const modules = await gnosisSafe.getModules()
|
||||
const dailyAddress = modules[0]
|
||||
|
||||
const dailyLimitModule = getCreateDailyLimitExtensionContract(web3).at(dailyAddress)
|
||||
if (await dailyLimitModule.manager.call() !== gnosisSafe.address) {
|
||||
throw new Error('Using an extension of different safe')
|
||||
}
|
||||
|
||||
return dailyLimitModule
|
||||
}
|
||||
|
||||
export const getDailyLimitFrom = async (safeAddress: string, tokenAddress: number): Promise<DailyLimitProps> => {
|
||||
const web3 = getWeb3()
|
||||
const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress)
|
||||
|
||||
const dailyLimitEth = await dailyLimitModule.dailyLimits(tokenAddress)
|
||||
|
||||
const limit = web3.fromWei(dailyLimitEth[LIMIT_POSITION].valueOf(), 'ether').toString()
|
||||
const spentToday = web3.fromWei(dailyLimitEth[SPENT_TODAY_POS].valueOf(), 'ether').toString()
|
||||
|
||||
return { value: Number(limit), spentToday: Number(spentToday) }
|
||||
}
|
||||
|
||||
export const getDailyLimitAddress = async (safeAddress: string) => {
|
||||
const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress)
|
||||
|
||||
return dailyLimitModule.address
|
||||
}
|
||||
|
||||
export const getEditDailyLimitData = async (safeAddress: string, token: number, dailyLimit: number) => {
|
||||
const web3 = getWeb3()
|
||||
const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress)
|
||||
const dailyLimitInWei = web3.toWei(dailyLimit, 'ether')
|
||||
return dailyLimitModule.contract.changeDailyLimit.getData(token, dailyLimitInWei)
|
||||
}
|
|
@ -3,43 +3,14 @@ import contract from 'truffle-contract'
|
|||
import { ensureOnce } from '~/utils/singleton'
|
||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||
import { promisify } from '~/utils/promisify'
|
||||
import GnosisSafeSol from '#/GnosisSafeTeamEdition.json'
|
||||
import GnosisPersonalSafeSol from '#/GnosisSafePersonalEdition.json'
|
||||
import GnosisSafeSol from '#/GnosisSafe.json'
|
||||
import ProxyFactorySol from '#/ProxyFactory.json'
|
||||
import CreateAndAddModules from '#/CreateAndAddModules.json'
|
||||
import DailyLimitModule from '#/DailyLimitModule.json'
|
||||
import { calculateGasOf, calculateGasPrice, EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
||||
import { signaturesViaMetamask } from '~/config'
|
||||
import { calculateGasOf, calculateGasPrice } from '~/logic/wallets/ethTransactions'
|
||||
|
||||
let proxyFactoryMaster
|
||||
let createAndAddModuleMaster
|
||||
let safeMaster
|
||||
let dailyLimitMaster
|
||||
|
||||
const createModuleDataWrapper = () => {
|
||||
const web3 = getWeb3()
|
||||
// eslint-disable-next-line
|
||||
return web3.eth.contract([{"constant":false,"inputs":[{"name":"data","type":"bytes"}],"name":"setup","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}])
|
||||
}
|
||||
|
||||
const getModuleDataWrapper = ensureOnce(createModuleDataWrapper)
|
||||
|
||||
function createAndAddModulesData(dataArray) {
|
||||
const ModuleDataWrapper = getModuleDataWrapper()
|
||||
|
||||
const mw = ModuleDataWrapper.at(1)
|
||||
// Remove method id (10) and position of data in payload (64)
|
||||
return dataArray.reduce((acc, data) => acc + mw.setup.getData(data).substr(74), EMPTY_DATA)
|
||||
}
|
||||
|
||||
const createGnosisSafeContract = (web3: any) => {
|
||||
if (signaturesViaMetamask()) {
|
||||
const gnosisSafe = contract(GnosisPersonalSafeSol)
|
||||
gnosisSafe.setProvider(web3.currentProvider)
|
||||
|
||||
return gnosisSafe
|
||||
}
|
||||
|
||||
const gnosisSafe = contract(GnosisSafeSol)
|
||||
gnosisSafe.setProvider(web3.currentProvider)
|
||||
|
||||
|
@ -53,24 +24,8 @@ const createProxyFactoryContract = (web3: any) => {
|
|||
return proxyFactory
|
||||
}
|
||||
|
||||
const createAddExtensionContract = (web3: any) => {
|
||||
const createAndAddModule = contract(CreateAndAddModules)
|
||||
createAndAddModule.setProvider(web3.currentProvider)
|
||||
|
||||
return createAndAddModule
|
||||
}
|
||||
|
||||
const createDailyLimitExtensionContract = (web3: any) => {
|
||||
const dailyLimitModule = contract(DailyLimitModule)
|
||||
dailyLimitModule.setProvider(web3.currentProvider)
|
||||
|
||||
return dailyLimitModule
|
||||
}
|
||||
|
||||
export const getGnosisSafeContract = ensureOnce(createGnosisSafeContract)
|
||||
const getCreateProxyFactoryContract = ensureOnce(createProxyFactoryContract)
|
||||
const getCreateAddExtensionContract = ensureOnce(createAddExtensionContract)
|
||||
export const getCreateDailyLimitExtensionContract = ensureOnce(createDailyLimitExtensionContract)
|
||||
|
||||
const instanciateMasterCopies = async () => {
|
||||
const web3 = getWeb3()
|
||||
|
@ -79,17 +34,9 @@ const instanciateMasterCopies = async () => {
|
|||
const ProxyFactory = getCreateProxyFactoryContract(web3)
|
||||
proxyFactoryMaster = await ProxyFactory.deployed()
|
||||
|
||||
// Create AddExtension Master Copy
|
||||
const CreateAndAddExtension = getCreateAddExtensionContract(web3)
|
||||
createAndAddModuleMaster = await CreateAndAddExtension.deployed()
|
||||
|
||||
// Initialize safe master copy
|
||||
const GnosisSafe = getGnosisSafeContract(web3)
|
||||
safeMaster = await GnosisSafe.deployed()
|
||||
|
||||
// Initialize extension master copy
|
||||
const DailyLimitExtension = getCreateDailyLimitExtensionContract(web3)
|
||||
dailyLimitMaster = await DailyLimitExtension.deployed()
|
||||
}
|
||||
|
||||
// ONLY USED IN TEST ENVIRONMENT
|
||||
|
@ -101,43 +48,18 @@ const createMasterCopies = async () => {
|
|||
const ProxyFactory = getCreateProxyFactoryContract(web3)
|
||||
proxyFactoryMaster = await ProxyFactory.new({ from: userAccount, gas: '5000000' })
|
||||
|
||||
const CreateAndAddExtension = getCreateAddExtensionContract(web3)
|
||||
createAndAddModuleMaster = await CreateAndAddExtension.new({ from: userAccount, gas: '5000000' })
|
||||
|
||||
const GnosisSafe = getGnosisSafeContract(web3)
|
||||
safeMaster = await GnosisSafe.new([userAccount], 1, 0, 0, { from: userAccount, gas: '5000000' })
|
||||
|
||||
const DailyLimitExtension = getCreateDailyLimitExtensionContract(web3)
|
||||
dailyLimitMaster = await DailyLimitExtension.new([], [], { from: userAccount, gas: '5000000' })
|
||||
safeMaster = await GnosisSafe.new({ from: userAccount, gas: '6000000' })
|
||||
}
|
||||
|
||||
export const initContracts = ensureOnce(process.env.NODE_ENV === 'test' ? createMasterCopies : instanciateMasterCopies)
|
||||
|
||||
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, moduleData)
|
||||
|
||||
const modulesCreationData = createAndAddModulesData([proxyFactoryData])
|
||||
|
||||
const createAndAddModuleData = createAndAddModuleMaster.contract.createAndAddModules
|
||||
.getData(proxyFactoryMaster.address, modulesCreationData)
|
||||
|
||||
return safeMaster.contract.setup
|
||||
.getData(accounts, numConfirmations, createAndAddModuleMaster.address, createAndAddModuleData)
|
||||
}
|
||||
|
||||
export const deploySafeContract = async (
|
||||
safeAccounts: string[],
|
||||
numConfirmations: number,
|
||||
dailyLimit: number,
|
||||
userAccount: string,
|
||||
) => {
|
||||
const gnosisSafeData = await getSafeDataBasedOn(safeAccounts, numConfirmations, dailyLimit)
|
||||
const gnosisSafeData = await safeMaster.contract.setup.getData(safeAccounts, numConfirmations, 0, '0x')
|
||||
const proxyFactoryData = proxyFactoryMaster.contract.createProxy.getData(safeMaster.address, gnosisSafeData)
|
||||
const gas = await calculateGasOf(proxyFactoryData, userAccount, proxyFactoryMaster.address)
|
||||
const gasPrice = await calculateGasPrice()
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// @flow
|
||||
import { List } from 'immutable'
|
||||
import { calculateGasOf, checkReceiptStatus, calculateGasPrice } from '~/logic/wallets/ethTransactions'
|
||||
import { type Operation, submitOperation } from '~/logic/safe/safeTxHistory'
|
||||
import { getDailyLimitModuleFrom } from '~/logic/contracts/dailyLimitContracts'
|
||||
import { getSafeEthereumInstance } from '~/logic/safe/safeFrontendOperations'
|
||||
import { generateMetamaskSignature, generateTxGasEstimateFrom, estimateDataGas } from '~/logic/safe/safeTxSigner'
|
||||
import { buildSignaturesFrom } from '~/logic/safe/safeTxSigner'
|
||||
import { generateMetamaskSignature, generateTxGasEstimateFrom, estimateDataGas } from '~/logic/safe/safeTxSignerEIP712'
|
||||
import { storeSignature, getSignaturesFrom } from '~/utils/localStorage/signatures'
|
||||
import { signaturesViaMetamask } from '~/config'
|
||||
|
||||
|
@ -19,18 +20,23 @@ export const approveTransaction = async (
|
|||
const gasPrice = await calculateGasPrice()
|
||||
|
||||
if (signaturesViaMetamask()) {
|
||||
// return executeTransaction(safeAddress, to, valueInWei, data, operation, nonce, sender)
|
||||
const safe = await getSafeEthereumInstance(safeAddress)
|
||||
const txGasEstimate = await generateTxGasEstimateFrom(safe, safeAddress, data, to, valueInWei, operation)
|
||||
const signature =
|
||||
await generateMetamaskSignature(safe, safeAddress, sender, to, valueInWei, nonce, data, operation, txGasEstimate)
|
||||
storeSignature(safeAddress, nonce, signature)
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
const gnosisSafe = await getSafeEthereumInstance(safeAddress)
|
||||
const txData = gnosisSafe.contract.approveTransactionWithParameters.getData(to, valueInWei, data, operation, nonce)
|
||||
const gas = await calculateGasOf(txData, sender, safeAddress)
|
||||
const txReceipt = await gnosisSafe
|
||||
.approveTransactionWithParameters(to, valueInWei, data, operation, nonce, { from: sender, gas, gasPrice })
|
||||
const contractTxHash = await gnosisSafe.getTransactionHash(to, valueInWei, data, operation, 0, 0, 0, 0, 0, nonce)
|
||||
|
||||
const approveData = gnosisSafe.contract.approveHash.getData(contractTxHash)
|
||||
const gas = await calculateGasOf(approveData, sender, safeAddress)
|
||||
const txReceipt = await gnosisSafe.approveHash(contractTxHash, { from: sender, gas, gasPrice })
|
||||
|
||||
const txHash = txReceipt.tx
|
||||
await checkReceiptStatus(txHash)
|
||||
|
||||
|
@ -47,6 +53,7 @@ export const executeTransaction = async (
|
|||
operation: Operation,
|
||||
nonce: number,
|
||||
sender: string,
|
||||
ownersWhoHasSigned: List<string>,
|
||||
) => {
|
||||
const gasPrice = await calculateGasPrice()
|
||||
|
||||
|
@ -58,21 +65,22 @@ export const executeTransaction = async (
|
|||
storeSignature(safeAddress, nonce, signature)
|
||||
|
||||
const sigs = getSignaturesFrom(safeAddress, nonce)
|
||||
|
||||
const threshold = await safe.getThreshold()
|
||||
const gas = await estimateDataGas(safe, to, valueInWei, data, operation, txGasEstimate, 0, nonce, Number(threshold))
|
||||
const gas =
|
||||
await estimateDataGas(safe, to, valueInWei, data, operation, txGasEstimate, 0, nonce, Number(threshold), 0)
|
||||
const numOwners = await safe.getOwners()
|
||||
const gasIncludingRemovingStoreUpfront = gas + txGasEstimate + (numOwners.length * 15000)
|
||||
|
||||
const txReceipt = await safe.execTransactionAndPaySubmitter(
|
||||
const txReceipt = await safe.execTransaction(
|
||||
to,
|
||||
valueInWei,
|
||||
data,
|
||||
operation,
|
||||
txGasEstimate,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, // dataGasEstimate
|
||||
0, // gasPrice
|
||||
0, // txGasToken
|
||||
0, // refundReceiver
|
||||
sigs,
|
||||
{ from: sender, gas: gasIncludingRemovingStoreUpfront, gasPrice },
|
||||
)
|
||||
|
@ -85,17 +93,23 @@ export const executeTransaction = async (
|
|||
}
|
||||
|
||||
const gnosisSafe = await getSafeEthereumInstance(safeAddress)
|
||||
const txConfirmationData =
|
||||
gnosisSafe.contract.execTransactionIfApproved.getData(to, valueInWei, data, operation, nonce)
|
||||
const signatures = buildSignaturesFrom(ownersWhoHasSigned, sender)
|
||||
const txExecutionData =
|
||||
gnosisSafe.contract.execTransaction.getData(to, valueInWei, data, operation, 0, 0, 0, 0, 0, signatures)
|
||||
const gas = await calculateGasOf(txExecutionData, sender, safeAddress)
|
||||
const numOwners = await gnosisSafe.getOwners()
|
||||
const gas = await calculateGasOf(txConfirmationData, sender, safeAddress)
|
||||
const gasIncludingRemovingStoreUpfront = gas + (numOwners.length * 15000)
|
||||
const txReceipt = await gnosisSafe.execTransactionIfApproved(
|
||||
const txReceipt = await gnosisSafe.execTransaction(
|
||||
to,
|
||||
valueInWei,
|
||||
data,
|
||||
operation,
|
||||
nonce,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
signatures,
|
||||
{ from: sender, gas: gasIncludingRemovingStoreUpfront, gasPrice },
|
||||
)
|
||||
const txHash = txReceipt.tx
|
||||
|
@ -105,33 +119,3 @@ export const executeTransaction = async (
|
|||
|
||||
return txHash
|
||||
}
|
||||
|
||||
export const executeDailyLimit = async (
|
||||
safeAddress: string,
|
||||
to: string,
|
||||
nonce: number,
|
||||
valueInWei: number,
|
||||
sender: string,
|
||||
) => {
|
||||
const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress)
|
||||
const dailyLimitData = dailyLimitModule.contract.executeDailyLimit.getData(0, to, valueInWei)
|
||||
const gas = await calculateGasOf(dailyLimitData, sender, dailyLimitModule.address)
|
||||
const gasPrice = await calculateGasPrice()
|
||||
|
||||
try {
|
||||
const txReceipt = await dailyLimitModule.executeDailyLimit(0, to, valueInWei, { from: sender, gas, gasPrice })
|
||||
await checkReceiptStatus(txReceipt.tx)
|
||||
|
||||
return Promise.resolve(txReceipt.tx)
|
||||
} catch (err) {
|
||||
return Promise.reject(new Error(err))
|
||||
}
|
||||
|
||||
/*
|
||||
// Temporarily disabled for daily limit operations
|
||||
const operation = 0 // CALL for all currencies
|
||||
const data = '' // empty for ETH
|
||||
|
||||
await submitOperation(safeAddress, to, Number(valueInWei), data, operation, nonce, txReceipt.tx, sender, 'execution')
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// @flow
|
||||
import { List } from 'immutable'
|
||||
import { type Transaction } from '~/routes/safe/store/model/transaction'
|
||||
import { executeDailyLimit, executeTransaction, approveTransaction } from '~/logic/safe/safeBlockchainOperations'
|
||||
import { executeTransaction, approveTransaction } from '~/logic/safe/safeBlockchainOperations'
|
||||
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||
import { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/WithdrawForm'
|
||||
import { type Safe } from '~/routes/safe/store/model/safe'
|
||||
import { getGnosisSafeContract } from '~/logic/contracts/safeContracts'
|
||||
import { storeSubject } from '~/utils/localStorage/transactions'
|
||||
|
@ -47,7 +47,7 @@ export const createTransaction = async (
|
|||
const isExecution = hasOneOwner(safe) || threshold === 1
|
||||
|
||||
const txHash = isExecution
|
||||
? await executeTransaction(safeAddress, to, valueInWei, data, CALL, nonce, sender)
|
||||
? await executeTransaction(safeAddress, to, valueInWei, data, CALL, nonce, sender, List([]))
|
||||
: await approveTransaction(safeAddress, to, valueInWei, data, CALL, nonce, sender)
|
||||
|
||||
storeSubject(safeAddress, nonce, name)
|
||||
|
@ -61,6 +61,7 @@ export const processTransaction = async (
|
|||
alreadyConfirmed: number,
|
||||
sender: string,
|
||||
threshold: number,
|
||||
usersConfirmed: List<string>,
|
||||
) => {
|
||||
const nonce = tx.get('nonce')
|
||||
const valueInWei = tx.get('value')
|
||||
|
@ -70,21 +71,8 @@ export const processTransaction = async (
|
|||
|
||||
const thresholdReached = threshold === alreadyConfirmed + 1
|
||||
const txHash = thresholdReached
|
||||
? await executeTransaction(safeAddress, to, valueInWei, data, CALL, nonce, sender)
|
||||
? await executeTransaction(safeAddress, to, valueInWei, data, CALL, nonce, sender, usersConfirmed)
|
||||
: await approveTransaction(safeAddress, to, valueInWei, data, CALL, nonce, sender)
|
||||
|
||||
return txHash
|
||||
}
|
||||
|
||||
export const withdraw = async (values: Object, safe: Safe, sender: string): Promise<void> => {
|
||||
const safeAddress = safe.get('address')
|
||||
const destination = values[DESTINATION_PARAM]
|
||||
const valueInEth = values[VALUE_PARAM]
|
||||
const valueInWei = getWeb3().toWei(valueInEth, 'ether')
|
||||
const nonce = Date.now()
|
||||
const txHash = await executeDailyLimit(safeAddress, destination, nonce, valueInWei, sender)
|
||||
|
||||
storeSubject(safeAddress, nonce, `Withdraw movement of ${valueInEth}`)
|
||||
|
||||
return txHash
|
||||
}
|
||||
|
|
|
@ -18,7 +18,8 @@ const calculateBodyFrom = async (
|
|||
type: TxServiceType,
|
||||
) => {
|
||||
const gnosisSafe = await getSafeEthereumInstance(safeAddress)
|
||||
const contractTransactionHash = await gnosisSafe.getTransactionHash(to, valueInWei, data, operation, nonce)
|
||||
const contractTransactionHash =
|
||||
await gnosisSafe.getTransactionHash(to, valueInWei, data, operation, 0, 0, 0, 0, 0, nonce)
|
||||
|
||||
return JSON.stringify({
|
||||
to: getWeb3().toChecksumAddress(to),
|
||||
|
@ -26,6 +27,11 @@ const calculateBodyFrom = async (
|
|||
data,
|
||||
operation,
|
||||
nonce,
|
||||
safeTxGas: 0,
|
||||
dataGas: 0,
|
||||
gasPrice: 0,
|
||||
gasToken: null,
|
||||
refundReceiver: null,
|
||||
contractTransactionHash,
|
||||
transactionHash,
|
||||
sender: getWeb3().toChecksumAddress(sender),
|
||||
|
|
|
@ -1,161 +1,17 @@
|
|||
// @flow
|
||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||
import { promisify } from '~/utils/promisify'
|
||||
import { BigNumber } from 'bignumber.js'
|
||||
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
||||
import { getSignaturesFrom } from '~/utils/localStorage/signatures'
|
||||
import { List } from 'immutable'
|
||||
|
||||
const estimateDataGasCosts = (data) => {
|
||||
const reducer = (accumulator, currentValue) => {
|
||||
if (currentValue === EMPTY_DATA) {
|
||||
return accumulator + 0
|
||||
}
|
||||
const generateSignatureFrom = (account: string) =>
|
||||
`000000000000000000000000${account.replace('0x', '')}000000000000000000000000000000000000000000000000000000000000000001`
|
||||
|
||||
if (currentValue === '00') {
|
||||
return accumulator + 4
|
||||
}
|
||||
export const buildSignaturesFrom = (ownersWhoHasSigned: List<string>, sender: string) => {
|
||||
const signatures = ownersWhoHasSigned.push(sender)
|
||||
const orderedSignatures = signatures.sort() // JS by default sorts in a non case-senstive way
|
||||
|
||||
return accumulator + 68
|
||||
}
|
||||
let sigs = '0x'
|
||||
orderedSignatures.forEach((owner: string) => {
|
||||
sigs += generateSignatureFrom(owner)
|
||||
})
|
||||
|
||||
return data.match(/.{2}/g).reduce(reducer, 0)
|
||||
}
|
||||
|
||||
|
||||
export const estimateDataGas = (
|
||||
safe: any,
|
||||
to: string,
|
||||
valueInWei: number,
|
||||
data: string,
|
||||
operation: number,
|
||||
txGasEstimate: number,
|
||||
gasToken: number,
|
||||
nonce: number,
|
||||
signatureCount: number,
|
||||
) => {
|
||||
// numbers < 256 are 192 -> 31 * 4 + 68
|
||||
// numbers < 65k are 256 -> 30 * 4 + 2 * 68
|
||||
// For signature array length and dataGasEstimate we already calculated
|
||||
// the 0 bytes so we just add 64 for each non-zero byte
|
||||
const gasPrice = 0 // no need to get refund when we submit txs to metamask
|
||||
const signatureCost = signatureCount * (68 + 2176 + 2176) // array count (3 -> r, s, v) * signature count
|
||||
|
||||
const sigs = getSignaturesFrom(safe.address, nonce)
|
||||
const payload = safe.contract.execTransactionAndPaySubmitter
|
||||
.getData(to, valueInWei, data, operation, txGasEstimate, 0, gasPrice, gasToken, sigs)
|
||||
|
||||
let dataGasEstimate = estimateDataGasCosts(payload) + signatureCost
|
||||
if (dataGasEstimate > 65536) {
|
||||
dataGasEstimate += 64
|
||||
} else {
|
||||
dataGasEstimate += 128
|
||||
}
|
||||
return dataGasEstimate + 34000 // Add aditional gas costs (e.g. base tx costs, transfer costs)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export const generateTxGasEstimateFrom = async (
|
||||
safe: any,
|
||||
safeAddress: string,
|
||||
data: string,
|
||||
to: string,
|
||||
valueInWei: number,
|
||||
operation: number,
|
||||
) => {
|
||||
try {
|
||||
const estimateData = safe.contract.requiredTxGas.getData(to, valueInWei, data, operation)
|
||||
const estimateResponse = await promisify(cb => getWeb3().eth.call({
|
||||
to: safeAddress,
|
||||
from: safeAddress,
|
||||
data: estimateData,
|
||||
}, cb))
|
||||
const txGasEstimate = new BigNumber(estimateResponse.substring(138), 16)
|
||||
|
||||
// Add 10k else we will fail in case of nested calls
|
||||
return Promise.resolve(txGasEstimate.toNumber() + 10000)
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line
|
||||
console.log("Error calculating tx gas estimation " + error)
|
||||
return Promise.resolve(0)
|
||||
}
|
||||
}
|
||||
|
||||
const generateTypedDataFrom = async (
|
||||
safe: any,
|
||||
safeAddress: string,
|
||||
to: string,
|
||||
valueInWei: number,
|
||||
nonce: number,
|
||||
data: string,
|
||||
operation: number,
|
||||
txGasEstimate: number,
|
||||
) => {
|
||||
const txGasToken = 0
|
||||
// const threshold = await safe.getThreshold()
|
||||
// estimateDataGas(safe, to, valueInWei, data, operation, txGasEstimate, txGasToken, nonce, threshold)
|
||||
const dataGasEstimate = 0
|
||||
const gasPrice = 0
|
||||
const typedData = {
|
||||
types: {
|
||||
EIP712Domain: [
|
||||
{
|
||||
type: 'address',
|
||||
name: 'verifyingContract',
|
||||
},
|
||||
],
|
||||
PersonalSafeTx: [
|
||||
{ type: 'address', name: 'to' },
|
||||
{ type: 'uint256', name: 'value' },
|
||||
{ type: 'bytes', name: 'data' },
|
||||
{ type: 'uint8', name: 'operation' },
|
||||
{ type: 'uint256', name: 'safeTxGas' },
|
||||
{ type: 'uint256', name: 'dataGas' },
|
||||
{ type: 'uint256', name: 'gasPrice' },
|
||||
{ type: 'address', name: 'gasToken' },
|
||||
{ type: 'uint256', name: 'nonce' },
|
||||
],
|
||||
},
|
||||
domain: {
|
||||
verifyingContract: safeAddress,
|
||||
},
|
||||
primaryType: 'PersonalSafeTx',
|
||||
message: {
|
||||
to,
|
||||
value: valueInWei,
|
||||
data,
|
||||
operation,
|
||||
safeTxGas: txGasEstimate,
|
||||
dataGas: dataGasEstimate,
|
||||
gasPrice,
|
||||
gasToken: txGasToken,
|
||||
nonce,
|
||||
},
|
||||
}
|
||||
|
||||
return typedData
|
||||
}
|
||||
|
||||
export const generateMetamaskSignature = async (
|
||||
safe: any,
|
||||
safeAddress: string,
|
||||
sender: string,
|
||||
to: string,
|
||||
valueInWei: number,
|
||||
nonce: number,
|
||||
data: string,
|
||||
operation: number,
|
||||
txGasEstimate: number,
|
||||
) => {
|
||||
const web3 = getWeb3()
|
||||
const typedData =
|
||||
await generateTypedDataFrom(safe, safeAddress, to, valueInWei, nonce, data, operation, txGasEstimate)
|
||||
const signedTypedData = {
|
||||
jsonrpc: '2.0',
|
||||
method: 'eth_signTypedData',
|
||||
params: [sender, typedData],
|
||||
id: Date.now(),
|
||||
}
|
||||
const txSignedResponse = await promisify(cb => web3.currentProvider.sendAsync(signedTypedData, cb))
|
||||
|
||||
return txSignedResponse.result.replace(EMPTY_DATA, '')
|
||||
return sigs
|
||||
}
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
// @flow
|
||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||
import { promisify } from '~/utils/promisify'
|
||||
import { BigNumber } from 'bignumber.js'
|
||||
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
||||
import { getSignaturesFrom } from '~/utils/localStorage/signatures'
|
||||
|
||||
const estimateDataGasCosts = (data) => {
|
||||
const reducer = (accumulator, currentValue) => {
|
||||
if (currentValue === EMPTY_DATA) {
|
||||
return accumulator + 0
|
||||
}
|
||||
|
||||
if (currentValue === '00') {
|
||||
return accumulator + 4
|
||||
}
|
||||
|
||||
return accumulator + 68
|
||||
}
|
||||
|
||||
return data.match(/.{2}/g).reduce(reducer, 0)
|
||||
}
|
||||
|
||||
|
||||
export const estimateDataGas = (
|
||||
safe: any,
|
||||
to: string,
|
||||
valueInWei: number,
|
||||
data: string,
|
||||
operation: number,
|
||||
txGasEstimate: number,
|
||||
gasToken: number,
|
||||
nonce: number,
|
||||
signatureCount: number,
|
||||
refundReceiver: number,
|
||||
) => {
|
||||
// numbers < 256 are 192 -> 31 * 4 + 68
|
||||
// numbers < 65k are 256 -> 30 * 4 + 2 * 68
|
||||
// For signature array length and dataGasEstimate we already calculated
|
||||
// the 0 bytes so we just add 64 for each non-zero byte
|
||||
const gasPrice = 0 // no need to get refund when we submit txs to metamask
|
||||
const signatureCost = signatureCount * (68 + 2176 + 2176) // array count (3 -> r, s, v) * signature count
|
||||
|
||||
const sigs = getSignaturesFrom(safe.address, nonce)
|
||||
const payload = safe.contract.execTransaction
|
||||
.getData(to, valueInWei, data, operation, txGasEstimate, 0, gasPrice, gasToken, refundReceiver, sigs)
|
||||
|
||||
let dataGasEstimate = estimateDataGasCosts(payload) + signatureCost
|
||||
if (dataGasEstimate > 65536) {
|
||||
dataGasEstimate += 64
|
||||
} else {
|
||||
dataGasEstimate += 128
|
||||
}
|
||||
return dataGasEstimate + 34000 // Add aditional gas costs (e.g. base tx costs, transfer costs)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export const generateTxGasEstimateFrom = async (
|
||||
safe: any,
|
||||
safeAddress: string,
|
||||
data: string,
|
||||
to: string,
|
||||
valueInWei: number,
|
||||
operation: number,
|
||||
) => {
|
||||
try {
|
||||
const estimateData = safe.contract.requiredTxGas.getData(to, valueInWei, data, operation)
|
||||
const estimateResponse = await promisify(cb => getWeb3().eth.call({
|
||||
to: safeAddress,
|
||||
from: safeAddress,
|
||||
data: estimateData,
|
||||
}, cb))
|
||||
const txGasEstimate = new BigNumber(estimateResponse.substring(138), 16)
|
||||
|
||||
// Add 10k else we will fail in case of nested calls
|
||||
return Promise.resolve(txGasEstimate.toNumber() + 10000)
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line
|
||||
console.log("Error calculating tx gas estimation " + error)
|
||||
return Promise.resolve(0)
|
||||
}
|
||||
}
|
||||
|
||||
const generateTypedDataFrom = async (
|
||||
safe: any,
|
||||
safeAddress: string,
|
||||
to: string,
|
||||
valueInWei: number,
|
||||
nonce: number,
|
||||
data: string,
|
||||
operation: number,
|
||||
txGasEstimate: number,
|
||||
) => {
|
||||
const txGasToken = 0
|
||||
// const threshold = await safe.getThreshold()
|
||||
// estimateDataGas(safe, to, valueInWei, data, operation, txGasEstimate, txGasToken, nonce, threshold)
|
||||
const dataGasEstimate = 0
|
||||
const gasPrice = 0
|
||||
const refundReceiver = 0
|
||||
const typedData = {
|
||||
types: {
|
||||
EIP712Domain: [
|
||||
{
|
||||
type: 'address',
|
||||
name: 'verifyingContract',
|
||||
},
|
||||
],
|
||||
SafeTx: [
|
||||
{ type: 'address', name: 'to' },
|
||||
{ type: 'uint256', name: 'value' },
|
||||
{ type: 'bytes', name: 'data' },
|
||||
{ type: 'uint8', name: 'operation' },
|
||||
{ type: 'uint256', name: 'safeTxGas' },
|
||||
{ type: 'uint256', name: 'dataGas' },
|
||||
{ type: 'uint256', name: 'gasPrice' },
|
||||
{ type: 'address', name: 'gasToken' },
|
||||
{ type: 'address', name: 'refundReceiver' },
|
||||
{ type: 'uint256', name: 'nonce' },
|
||||
],
|
||||
},
|
||||
domain: {
|
||||
verifyingContract: safeAddress,
|
||||
},
|
||||
primaryType: 'SafeTx',
|
||||
message: {
|
||||
to,
|
||||
value: Number(valueInWei),
|
||||
data,
|
||||
operation,
|
||||
safeTxGas: txGasEstimate,
|
||||
dataGas: dataGasEstimate,
|
||||
gasPrice,
|
||||
gasToken: txGasToken,
|
||||
refundReceiver,
|
||||
nonce: Number(nonce),
|
||||
},
|
||||
}
|
||||
|
||||
return typedData
|
||||
}
|
||||
|
||||
export const generateMetamaskSignature = async (
|
||||
safe: any,
|
||||
safeAddress: string,
|
||||
sender: string,
|
||||
to: string,
|
||||
valueInWei: number,
|
||||
nonce: number,
|
||||
data: string,
|
||||
operation: number,
|
||||
txGasEstimate: number,
|
||||
) => {
|
||||
const web3 = getWeb3()
|
||||
const typedData =
|
||||
await generateTypedDataFrom(safe, safeAddress, to, valueInWei, nonce, data, operation, txGasEstimate)
|
||||
|
||||
const jsonTypedData = JSON.stringify(typedData)
|
||||
const signedTypedData = {
|
||||
method: 'eth_signTypedData_v3',
|
||||
// To change once Metamask fixes their status
|
||||
// https://github.com/MetaMask/metamask-extension/pull/5368
|
||||
// https://github.com/MetaMask/metamask-extension/issues/5366
|
||||
params: [jsonTypedData, sender],
|
||||
from: sender,
|
||||
}
|
||||
const txSignedResponse = await promisify(cb => web3.currentProvider.sendAsync(signedTypedData, cb))
|
||||
|
||||
return txSignedResponse.result.replace(EMPTY_DATA, '')
|
||||
}
|
|
@ -33,7 +33,9 @@ export const ETHEREUM_NETWORK_IDS = {
|
|||
42: ETHEREUM_NETWORK.KOVAN,
|
||||
}
|
||||
|
||||
export const openInEtherScan = (address: string, network: string) => () => {
|
||||
export const openTxInEtherScan = (tx: string, network: string) => `https://${network}.etherscan.io/tx/${tx}`
|
||||
|
||||
export const openAddressInEtherScan = (address: string, network: string) => () => {
|
||||
window.open(`https://${network}.etherscan.io/address/${address}`)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// @flow
|
||||
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||
import { getProviderInfo } from '~/logic/wallets/getWeb3'
|
||||
import { getProviderInfo, ETHEREUM_NETWORK_IDS, ETHEREUM_NETWORK } from '~/logic/wallets/getWeb3'
|
||||
import type { ProviderProps } from '~/logic/wallets/store/model/provider'
|
||||
import { makeProvider } from '~/logic/wallets/store/model/provider'
|
||||
import addProvider from './addProvider'
|
||||
|
||||
export const processProviderResponse = (dispatch: ReduxDispatch<*>, response: ProviderProps) => {
|
||||
export const processProviderResponse = (dispatch: ReduxDispatch<*>, provider: ProviderProps) => {
|
||||
const {
|
||||
name, available, loaded, account, network,
|
||||
} = response
|
||||
} = provider
|
||||
|
||||
const walletRecord = makeProvider({
|
||||
name, available, loaded, account, network,
|
||||
|
@ -17,8 +17,33 @@ export const processProviderResponse = (dispatch: ReduxDispatch<*>, response: Pr
|
|||
dispatch(addProvider(walletRecord))
|
||||
}
|
||||
|
||||
export default () => async (dispatch: ReduxDispatch<*>) => {
|
||||
const response: ProviderProps = await getProviderInfo()
|
||||
const SUCCESS_MSG = 'Wallet connected sucessfully'
|
||||
const UNLOCK_MSG = 'Unlock your wallet to connect'
|
||||
const WRONG_NETWORK = 'You are connected to wrong network. Please use RINKEBY'
|
||||
export const WALLET_ERROR_MSG = 'Error connecting to your wallet'
|
||||
|
||||
processProviderResponse(dispatch, response)
|
||||
const handleProviderNotification = (openSnackbar: Function, provider: ProviderProps) => {
|
||||
const { loaded, available, network } = provider
|
||||
|
||||
if (!loaded) {
|
||||
openSnackbar(WALLET_ERROR_MSG, 'error')
|
||||
return
|
||||
}
|
||||
|
||||
if (ETHEREUM_NETWORK_IDS[network] !== ETHEREUM_NETWORK.RINKEBY) {
|
||||
openSnackbar(WRONG_NETWORK, 'error')
|
||||
return
|
||||
}
|
||||
|
||||
const msg = available ? SUCCESS_MSG : UNLOCK_MSG
|
||||
const variant = available ? 'success' : 'warning'
|
||||
openSnackbar(msg, variant)
|
||||
}
|
||||
|
||||
export default (openSnackbar: Function) => async (dispatch: ReduxDispatch<*>) => {
|
||||
const provider: ProviderProps = await getProviderInfo()
|
||||
|
||||
handleProviderNotification(openSnackbar, provider)
|
||||
|
||||
processProviderResponse(dispatch, provider)
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import type { Dispatch as ReduxDispatch } from 'redux'
|
|||
import { makeProvider, type ProviderProps, type Provider } from '~/logic/wallets/store/model/provider'
|
||||
import addProvider from './addProvider'
|
||||
|
||||
export default () => async (dispatch: ReduxDispatch<*>) => {
|
||||
export default (openSnackbar: Function) => async (dispatch: ReduxDispatch<*>) => {
|
||||
const providerProps: ProviderProps = {
|
||||
name: '',
|
||||
available: false,
|
||||
|
@ -13,5 +13,7 @@ export default () => async (dispatch: ReduxDispatch<*>) => {
|
|||
}
|
||||
|
||||
const provider: Provider = makeProvider(providerProps)
|
||||
openSnackbar('Wallet disconnected succesfully', 'info')
|
||||
|
||||
dispatch(addProvider(provider))
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import Loadable from 'react-loadable'
|
|||
import { Switch, Redirect, Route } from 'react-router-dom'
|
||||
import Loader from '~/components/Loader'
|
||||
import Welcome from './welcome/container'
|
||||
import { SAFELIST_ADDRESS, OPEN_ADDRESS, SAFE_PARAM_ADDRESS, WELCOME_ADDRESS, SETTINS_ADDRESS } from './routes'
|
||||
import { SAFELIST_ADDRESS, OPEN_ADDRESS, SAFE_PARAM_ADDRESS, WELCOME_ADDRESS, SETTINS_ADDRESS, OPENING_ADDRESS } from './routes'
|
||||
|
||||
const Safe = Loadable({
|
||||
loader: () => import('./safe/container'),
|
||||
|
@ -26,6 +26,11 @@ const Open = Loadable({
|
|||
loading: Loader,
|
||||
})
|
||||
|
||||
const Opening = Loadable({
|
||||
loader: () => import('./opening/container'),
|
||||
loading: Loader,
|
||||
})
|
||||
|
||||
const SAFE_ADDRESS = `${SAFELIST_ADDRESS}/:${SAFE_PARAM_ADDRESS}`
|
||||
const SAFE_SETTINGS = `${SAFE_ADDRESS}${SETTINS_ADDRESS}`
|
||||
|
||||
|
@ -39,6 +44,7 @@ const Routes = () => (
|
|||
<Route exact path={SAFELIST_ADDRESS} component={SafeList} />
|
||||
<Route exact path={SAFE_ADDRESS} component={Safe} />
|
||||
<Route exact path={SAFE_SETTINGS} component={Settings} />
|
||||
<Route exact path={OPENING_ADDRESS} component={Opening} />
|
||||
</Switch>
|
||||
)
|
||||
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import CircularProgress from '@material-ui/core/CircularProgress'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Bold from '~/components/layout/Bold'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import Pre from '~/components/layout/Pre'
|
||||
import Row from '~/components/layout/Row'
|
||||
|
||||
type FormProps = {
|
||||
submitting: boolean,
|
||||
}
|
||||
|
||||
type Props = {
|
||||
address: string,
|
||||
tx: Object,
|
||||
}
|
||||
|
||||
export const DEPLOYED_COMPONENT_ID = 'deployedSafeComponent'
|
||||
|
||||
const Deployment = ({ address, tx }: Props) => (
|
||||
<Block className={DEPLOYED_COMPONENT_ID}>
|
||||
<Paragraph><Bold>Deployed safe to: </Bold>{address}</Paragraph>
|
||||
<Pre>
|
||||
{JSON.stringify(tx, null, 2) }
|
||||
</Pre>
|
||||
</Block>
|
||||
)
|
||||
|
||||
export default ({ address, tx }: Props) => ({ submitting }: FormProps) => {
|
||||
const txFinished = !!address
|
||||
|
||||
return (
|
||||
<Block>
|
||||
{ !txFinished &&
|
||||
<React.Fragment>
|
||||
<Paragraph align="center" size="lg">
|
||||
You are about to create a Safe for keeping your funds more secure.
|
||||
</Paragraph>
|
||||
<Paragraph align="center" size="lg">
|
||||
Remember to check you have enough funds in your wallet.
|
||||
</Paragraph>
|
||||
</React.Fragment>
|
||||
}
|
||||
<Row>
|
||||
<Col xs={12} center={submitting ? 'xs' : undefined} margin="lg">
|
||||
{ submitting
|
||||
? <CircularProgress size={50} />
|
||||
: txFinished && <Deployment address={address} tx={tx} />
|
||||
}
|
||||
</Col>
|
||||
</Row>
|
||||
</Block>
|
||||
)
|
||||
}
|
|
@ -1,56 +1,82 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import Stepper from '~/components/Stepper'
|
||||
import Confirmation from '~/routes/open/components/FormConfirmation'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Heading from '~/components/layout/Heading'
|
||||
import Row from '~/components/layout/Row'
|
||||
import IconButton from '@material-ui/core/IconButton'
|
||||
import Review from '~/routes/open/components/ReviewInformation'
|
||||
import SafeFields, { safeFieldsValidation } from '~/routes/open/components/SafeForm'
|
||||
import { SAFELIST_ADDRESS } from '~/routes/routes'
|
||||
import Link from '~/components/layout/Link'
|
||||
import ChevronLeft from '@material-ui/icons/ChevronLeft'
|
||||
import SafeNameField from '~/routes/open/components/SafeNameForm'
|
||||
import SafeThresholdField, { safeFieldsValidation } from '~/routes/open/components/SafeThresholdForm'
|
||||
import SafeOwnersFields from '~/routes/open/components/SafeOwnersForm'
|
||||
import { getOwnerNameBy, getOwnerAddressBy, FIELD_CONFIRMATIONS } from '~/routes/open/components/fields'
|
||||
import { history } from '~/store'
|
||||
import { secondary } from '~/theme/variables'
|
||||
|
||||
const getSteps = () => [
|
||||
'Fill Safe Form', 'Review Information', 'Deploy it',
|
||||
'Start', 'Owners', 'Confirmations', 'Review',
|
||||
]
|
||||
|
||||
const initialValuesFrom = (userAccount: string) => ({
|
||||
owner0Address: userAccount,
|
||||
[getOwnerNameBy(0)]: 'My Metamask (me)',
|
||||
[getOwnerAddressBy(0)]: userAccount,
|
||||
[FIELD_CONFIRMATIONS]: '1',
|
||||
})
|
||||
|
||||
type Props = {
|
||||
provider: string,
|
||||
userAccount: string,
|
||||
safeAddress: string,
|
||||
safeTx: string,
|
||||
network: string,
|
||||
onCallSafeContractSubmit: (values: Object) => Promise<void>,
|
||||
}
|
||||
|
||||
const iconStyle = {
|
||||
color: secondary,
|
||||
width: '32px',
|
||||
height: '32px',
|
||||
}
|
||||
|
||||
const back = () => {
|
||||
history.goBack()
|
||||
}
|
||||
|
||||
const Layout = ({
|
||||
provider, userAccount, safeAddress, safeTx, onCallSafeContractSubmit,
|
||||
provider, userAccount, onCallSafeContractSubmit, network,
|
||||
}: Props) => {
|
||||
const steps = getSteps()
|
||||
const initialValues = initialValuesFrom(userAccount)
|
||||
const finishedButton = <Stepper.FinishButton title="VISIT SAFES" component={Link} to={SAFELIST_ADDRESS} />
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{ provider
|
||||
? (
|
||||
<Stepper
|
||||
finishedButton={finishedButton}
|
||||
finishedTransaction={!!safeAddress}
|
||||
onSubmit={onCallSafeContractSubmit}
|
||||
steps={steps}
|
||||
initialValues={initialValues}
|
||||
>
|
||||
<Stepper.Page validate={safeFieldsValidation}>
|
||||
{ SafeFields }
|
||||
</Stepper.Page>
|
||||
<Stepper.Page>
|
||||
{ Review }
|
||||
</Stepper.Page>
|
||||
<Stepper.Page address={safeAddress} tx={safeTx}>
|
||||
{ Confirmation }
|
||||
</Stepper.Page>
|
||||
</Stepper>
|
||||
<Block>
|
||||
<Row align="center">
|
||||
<IconButton onClick={back} style={iconStyle} disableRipple>
|
||||
<ChevronLeft />
|
||||
</IconButton>
|
||||
<Heading tag="h2">Create New Safe</Heading>
|
||||
</Row>
|
||||
<Stepper
|
||||
onSubmit={onCallSafeContractSubmit}
|
||||
steps={steps}
|
||||
initialValues={initialValues}
|
||||
>
|
||||
<Stepper.Page>
|
||||
{ SafeNameField }
|
||||
</Stepper.Page>
|
||||
<Stepper.Page>
|
||||
{ SafeOwnersFields }
|
||||
</Stepper.Page>
|
||||
<Stepper.Page validate={safeFieldsValidation}>
|
||||
{ SafeThresholdField }
|
||||
</Stepper.Page>
|
||||
<Stepper.Page network={network}>
|
||||
{ Review }
|
||||
</Stepper.Page>
|
||||
</Stepper>
|
||||
</Block>
|
||||
)
|
||||
: <div>No metamask detected</div>
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ storiesOf('Routes /open', module)
|
|||
return (
|
||||
<State store={store}>
|
||||
<Component
|
||||
network="rinkeby"
|
||||
provider={provider}
|
||||
userAccount={userAccount}
|
||||
safeAddress={store.get('safeAddress')}
|
||||
|
|
|
@ -2,50 +2,158 @@
|
|||
import * as React from 'react'
|
||||
import { getNamesFrom, getAccountsFrom } from '~/routes/open/utils/safeDataExtractor'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Bold from '~/components/layout/Bold'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import OpenInNew from '@material-ui/icons/OpenInNew'
|
||||
import Identicon from '~/components/Identicon'
|
||||
import OpenPaper from '~/components/Stepper/OpenPaper'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Heading from '~/components/layout/Heading'
|
||||
import Row from '~/components/layout/Row'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import { FIELD_NAME, FIELD_CONFIRMATIONS, FIELD_DAILY_LIMIT } from '../fields'
|
||||
import { sm, md, lg, border, secondary, background } from '~/theme/variables'
|
||||
import Hairline from '~/components/layout/Hairline'
|
||||
import { openAddressInEtherScan } from '~/logic/wallets/getWeb3'
|
||||
import { FIELD_NAME, FIELD_CONFIRMATIONS, getNumOwnersFrom } from '../fields'
|
||||
|
||||
type FormProps = {
|
||||
values: Object,
|
||||
const openIconStyle = {
|
||||
height: '16px',
|
||||
color: secondary,
|
||||
}
|
||||
|
||||
const ReviewInformation = () => ({ values }: FormProps) => {
|
||||
const styles = () => ({
|
||||
root: {
|
||||
minHeight: '300px',
|
||||
},
|
||||
details: {
|
||||
padding: lg,
|
||||
borderRight: `solid 1px ${border}`,
|
||||
height: '100%',
|
||||
},
|
||||
info: {
|
||||
backgroundColor: background,
|
||||
padding: lg,
|
||||
justifyContent: 'center',
|
||||
textAlign: 'center',
|
||||
flexDirection: 'column',
|
||||
},
|
||||
owners: {
|
||||
padding: lg,
|
||||
},
|
||||
name: {
|
||||
textOverflow: 'ellipsis',
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
},
|
||||
owner: {
|
||||
padding: md,
|
||||
alignItems: 'center',
|
||||
},
|
||||
user: {
|
||||
justifyContent: 'left',
|
||||
},
|
||||
open: {
|
||||
paddingLeft: sm,
|
||||
width: 'auto',
|
||||
'&:hover': {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
type LayoutProps = {
|
||||
network: string,
|
||||
}
|
||||
|
||||
type Props = LayoutProps & {
|
||||
values: Object,
|
||||
classes: Object,
|
||||
}
|
||||
|
||||
const ReviewComponent = ({ values, classes, network }: Props) => {
|
||||
const names = getNamesFrom(values)
|
||||
const addresses = getAccountsFrom(values)
|
||||
const numOwners = getNumOwnersFrom(values)
|
||||
|
||||
return (
|
||||
<Block>
|
||||
<Heading tag="h2">Review the Safe information</Heading>
|
||||
<Paragraph>
|
||||
<Bold>Safe Name: </Bold> {values[FIELD_NAME]}
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Bold>Required confirmations: </Bold> {values[FIELD_CONFIRMATIONS]}
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Bold>Daily limit: </Bold> {values[FIELD_DAILY_LIMIT]} ETH
|
||||
</Paragraph>
|
||||
<Heading tag="h3">Owners</Heading>
|
||||
{ names.map((name, index) => (
|
||||
<Row key={`name${(index)}`} margin="md">
|
||||
<Col xs={11} xsOffset={1}margin="sm">
|
||||
<Block>
|
||||
<Paragraph noMargin>{name}</Paragraph>
|
||||
<React.Fragment>
|
||||
<Row className={classes.root}>
|
||||
<Col xs={4} layout="column">
|
||||
<Block className={classes.details}>
|
||||
<Block margin="lg">
|
||||
<Paragraph size="lg" color="primary" noMargin>
|
||||
Details
|
||||
</Paragraph>
|
||||
</Block>
|
||||
</Col>
|
||||
<Col xs={11} xsOffset={1} margin="sm">
|
||||
<Block>
|
||||
<Paragraph noMargin>{addresses[index]}</Paragraph>
|
||||
<Block margin="lg">
|
||||
<Paragraph size="sm" color="disabled" noMargin>
|
||||
Name of new Safe
|
||||
</Paragraph>
|
||||
<Paragraph size="lg" color="primary" noMargin weight="bolder" className={classes.name}>
|
||||
{values[FIELD_NAME]}
|
||||
</Paragraph>
|
||||
</Block>
|
||||
</Col>
|
||||
</Row>
|
||||
))}
|
||||
</Block>
|
||||
<Block margin="lg">
|
||||
<Paragraph size="sm" color="disabled" noMargin>
|
||||
Any transaction requires the confirmation of:
|
||||
</Paragraph>
|
||||
<Paragraph size="lg" color="primary" noMargin weight="bolder">
|
||||
{`${values[FIELD_CONFIRMATIONS]} out of ${numOwners} owners`}
|
||||
</Paragraph>
|
||||
</Block>
|
||||
</Block>
|
||||
</Col>
|
||||
<Col xs={8} layout="column">
|
||||
<Block className={classes.owners}>
|
||||
<Paragraph size="lg" color="primary" noMargin>
|
||||
{`${numOwners} Safe owners`}
|
||||
</Paragraph>
|
||||
</Block>
|
||||
<Hairline />
|
||||
{ names.map((name, index) => (
|
||||
<React.Fragment key={`name${(index)}`}>
|
||||
<Row className={classes.owner}>
|
||||
<Col xs={1} align="center">
|
||||
<Identicon address={addresses[index]} diameter={32} />
|
||||
</Col>
|
||||
<Col xs={11}>
|
||||
<Block className={classes.name}>
|
||||
<Paragraph size="lg" noMargin >{name}</Paragraph>
|
||||
<Block align="center" className={classes.user}>
|
||||
<Paragraph size="md" color="disabled" noMargin>{addresses[index]}</Paragraph>
|
||||
<OpenInNew
|
||||
className={classes.open}
|
||||
style={openIconStyle}
|
||||
onClick={openAddressInEtherScan(addresses[index], network)}
|
||||
/>
|
||||
</Block>
|
||||
</Block>
|
||||
</Col>
|
||||
</Row>
|
||||
<Hairline />
|
||||
</React.Fragment>
|
||||
))}
|
||||
</Col>
|
||||
</Row>
|
||||
<Row className={classes.info} align="center">
|
||||
<Paragraph noMargin color="primary" size="md">
|
||||
{'You\'re about to create a new Safe.'}
|
||||
</Paragraph>
|
||||
<Paragraph noMargin color="primary" size="md">
|
||||
Make sure you have enough ETH in your wallet client to fund this transaction.
|
||||
</Paragraph>
|
||||
</Row>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default ReviewInformation
|
||||
const ReviewPage = withStyles(styles)(ReviewComponent)
|
||||
|
||||
const Review = ({ network }: LayoutProps) => (controls: React$Node, { values }: Object) => (
|
||||
<React.Fragment>
|
||||
<OpenPaper controls={controls} padding={false}>
|
||||
<ReviewPage network={network} values={values} />
|
||||
</OpenPaper>
|
||||
</React.Fragment>
|
||||
)
|
||||
|
||||
|
||||
export default Review
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import Field from '~/components/forms/Field'
|
||||
import TextField from '~/components/forms/TextField'
|
||||
import { composeValidators, minValue, mustBeInteger, required } from '~/components/forms/validator'
|
||||
import Block from '~/components/layout/Block'
|
||||
import { FIELD_CONFIRMATIONS } from '~/routes/open/components/fields'
|
||||
|
||||
const Confirmations = () => (
|
||||
<Block margin="md">
|
||||
<Field
|
||||
name={FIELD_CONFIRMATIONS}
|
||||
component={TextField}
|
||||
type="text"
|
||||
validate={composeValidators(
|
||||
required,
|
||||
mustBeInteger,
|
||||
minValue(1),
|
||||
)}
|
||||
placeholder="Required confirmations*"
|
||||
text="Required confirmations"
|
||||
/>
|
||||
</Block>
|
||||
)
|
||||
|
||||
export default Confirmations
|
|
@ -1,73 +0,0 @@
|
|||
// @flow
|
||||
import TextField from '~/components/forms/TextField'
|
||||
import * as React from 'react'
|
||||
import * as TestUtils from 'react-dom/test-utils'
|
||||
import Layout from '~/routes/open/components/Layout'
|
||||
import { FIELD_CONFIRMATIONS, FIELD_OWNERS } from '~/routes/open/components/fields'
|
||||
import { getProviderInfo } from '~/logic/wallets/getWeb3'
|
||||
import Wrapper from '~/test/utils/Wrapper'
|
||||
import { CONFIRMATIONS_ERROR } from '~/routes/open/components/SafeForm'
|
||||
|
||||
const onSubmitMock = async (): Promise<void> => {}
|
||||
|
||||
describe('React DOM TESTS > Create Safe form', () => {
|
||||
let open
|
||||
let fieldOwners
|
||||
let fieldConfirmations
|
||||
beforeEach(async () => {
|
||||
// init app web3 instance
|
||||
await getProviderInfo()
|
||||
|
||||
open = TestUtils.renderIntoDocument((
|
||||
<Wrapper>
|
||||
<Layout
|
||||
provider="METAMASK"
|
||||
userAccount="foo"
|
||||
safeAddress=""
|
||||
safeTx=""
|
||||
onCallSafeContractSubmit={onSubmitMock}
|
||||
/>
|
||||
</Wrapper>
|
||||
))
|
||||
|
||||
const inputs = TestUtils.scryRenderedDOMComponentsWithTag(open, 'input')
|
||||
const indexOwners = 1
|
||||
const indexConfirmations = 2
|
||||
fieldOwners = inputs[indexOwners]
|
||||
fieldConfirmations = inputs[indexConfirmations]
|
||||
|
||||
expect(fieldOwners.name).toEqual(FIELD_OWNERS)
|
||||
expect(fieldConfirmations.name).toEqual(FIELD_CONFIRMATIONS)
|
||||
})
|
||||
|
||||
it('should not allow to continue if confirmations are higher than owners', async () => {
|
||||
// GIVEN
|
||||
TestUtils.Simulate.change(fieldOwners, { target: { value: '1' } })
|
||||
|
||||
// WHEN
|
||||
TestUtils.Simulate.change(fieldConfirmations, { target: { value: '2' } })
|
||||
|
||||
// THEN
|
||||
const muiFields = TestUtils.scryRenderedComponentsWithType(open, TextField)
|
||||
expect(6).toEqual(muiFields.length)
|
||||
const confirmationsField = muiFields[4]
|
||||
|
||||
expect(confirmationsField.props.meta.valid).toBe(false)
|
||||
expect(confirmationsField.props.meta.error).toBe(CONFIRMATIONS_ERROR)
|
||||
})
|
||||
|
||||
it('should raise error when confirmations are 012 and number of owners are 2', async () => {
|
||||
// GIVEN
|
||||
TestUtils.Simulate.change(fieldOwners, { target: { value: '2' } })
|
||||
// WHEN
|
||||
TestUtils.Simulate.change(fieldConfirmations, { target: { value: '014' } })
|
||||
|
||||
// THEN
|
||||
const muiFields = TestUtils.scryRenderedComponentsWithType(open, TextField)
|
||||
expect(8).toEqual(muiFields.length)
|
||||
const confirmationsField = muiFields[6]
|
||||
|
||||
expect(confirmationsField.props.meta.valid).toBe(false)
|
||||
expect(confirmationsField.props.meta.error).toBe(CONFIRMATIONS_ERROR)
|
||||
})
|
||||
})
|
|
@ -1,22 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import Field from '~/components/forms/Field'
|
||||
import TextField from '~/components/forms/TextField'
|
||||
import { composeValidators, mustBeFloat, required, minValue } from '~/components/forms/validator'
|
||||
import Block from '~/components/layout/Block'
|
||||
import { FIELD_DAILY_LIMIT } from '~/routes/open/components/fields'
|
||||
|
||||
const DailyLimit = () => (
|
||||
<Block margin="md">
|
||||
<Field
|
||||
name={FIELD_DAILY_LIMIT}
|
||||
component={TextField}
|
||||
type="text"
|
||||
validate={composeValidators(required, mustBeFloat, minValue(0))}
|
||||
placeholder="Daily Limit*"
|
||||
text="Daily Limit"
|
||||
/>
|
||||
</Block>
|
||||
)
|
||||
|
||||
export default DailyLimit
|
|
@ -1,22 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import Field from '~/components/forms/Field'
|
||||
import TextField from '~/components/forms/TextField'
|
||||
import { required } from '~/components/forms/validator'
|
||||
import Block from '~/components/layout/Block'
|
||||
import { FIELD_NAME } from '~/routes/open/components/fields'
|
||||
|
||||
const Name = () => (
|
||||
<Block margin="md">
|
||||
<Field
|
||||
name={FIELD_NAME}
|
||||
component={TextField}
|
||||
type="text"
|
||||
validate={required}
|
||||
placeholder="Safe name*"
|
||||
text="Safe name"
|
||||
/>
|
||||
</Block>
|
||||
)
|
||||
|
||||
export default Name
|
|
@ -1,86 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import Field from '~/components/forms/Field'
|
||||
import TextField from '~/components/forms/TextField'
|
||||
import {
|
||||
composeValidators,
|
||||
minValue,
|
||||
maxValue,
|
||||
mustBeInteger,
|
||||
mustBeEthereumAddress,
|
||||
required,
|
||||
uniqueAddress,
|
||||
} from '~/components/forms/validator'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Heading from '~/components/layout/Heading'
|
||||
import Row from '~/components/layout/Row'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import { FIELD_OWNERS, getOwnerNameBy, getOwnerAddressBy } from '~/routes/open/components/fields'
|
||||
|
||||
type Props = {
|
||||
numOwners: number,
|
||||
otherAccounts: string[],
|
||||
}
|
||||
|
||||
const MAX_NUMBER_OWNERS = 50
|
||||
|
||||
const getAddressValidators = (addresses: string[], position: number) => {
|
||||
const copy = addresses.slice()
|
||||
copy.splice(position, 1)
|
||||
|
||||
return composeValidators(required, mustBeEthereumAddress, uniqueAddress(copy))
|
||||
}
|
||||
|
||||
const Owners = (props: Props) => {
|
||||
const { numOwners, otherAccounts } = props
|
||||
const validNumber = numOwners && Number.isInteger(Number(numOwners))
|
||||
const renderOwners = validNumber && Number(numOwners) <= MAX_NUMBER_OWNERS
|
||||
|
||||
return (
|
||||
<Block margin="md">
|
||||
<Heading tag="h3">Owners</Heading>
|
||||
<Block margin="sm">
|
||||
<Field
|
||||
name={FIELD_OWNERS}
|
||||
component={TextField}
|
||||
type="text"
|
||||
validate={composeValidators(required, mustBeInteger, maxValue(MAX_NUMBER_OWNERS), minValue(1))}
|
||||
placeholder="Number of owners*"
|
||||
text="Number of owners"
|
||||
/>
|
||||
</Block>
|
||||
{ renderOwners && [...Array(Number(numOwners))].map((x, index) => (
|
||||
<Row key={`owner${(index)}`}>
|
||||
<Col xs={11} xsOffset={1}>
|
||||
<Block margin="sm">
|
||||
<Paragraph weight="bold">Owner Nº {index + 1}</Paragraph>
|
||||
<Block margin="sm">
|
||||
<Field
|
||||
name={getOwnerNameBy(index)}
|
||||
component={TextField}
|
||||
type="text"
|
||||
validate={required}
|
||||
placeholder="Owner Name*"
|
||||
text="Owner Name"
|
||||
/>
|
||||
</Block>
|
||||
<Block margin="sm">
|
||||
<Field
|
||||
name={getOwnerAddressBy(index)}
|
||||
component={TextField}
|
||||
type="text"
|
||||
validate={getAddressValidators(otherAccounts, index)}
|
||||
placeholder="Owner Address*"
|
||||
text="Owner Address"
|
||||
/>
|
||||
</Block>
|
||||
</Block>
|
||||
</Col>
|
||||
</Row>
|
||||
)) }
|
||||
</Block>
|
||||
)
|
||||
}
|
||||
|
||||
export default Owners
|
|
@ -1,61 +0,0 @@
|
|||
// @flow
|
||||
import TextField from '~/components/forms/TextField'
|
||||
import * as React from 'react'
|
||||
import * as TestUtils from 'react-dom/test-utils'
|
||||
import GnoForm from '~/components/forms/GnoForm'
|
||||
import { FIELD_OWNERS } from '~/routes/open/components/fields'
|
||||
import { getAccountsFrom } from '~/routes/open/utils/safeDataExtractor'
|
||||
import { getProviderInfo } from '~/logic/wallets/getWeb3'
|
||||
import Wrapper from '~/test/utils/Wrapper'
|
||||
import { ADDRESS_REPEATED_ERROR } from '~/components/forms/validator'
|
||||
import Owners from './index'
|
||||
|
||||
const onSubmitMock = () => {}
|
||||
const childrenMock = () => {}
|
||||
|
||||
describe('React DOM TESTS > Create Safe form', () => {
|
||||
beforeEach(async () => {
|
||||
// init app web3 instance
|
||||
await getProviderInfo()
|
||||
})
|
||||
|
||||
it('should not allow to continue if owners addresses are duplicated', async () => {
|
||||
// GIVEN
|
||||
const open = TestUtils.renderIntoDocument((
|
||||
<Wrapper>
|
||||
<GnoForm
|
||||
onSubmit={onSubmitMock}
|
||||
padding={15}
|
||||
render={({ values }) => (
|
||||
<Owners
|
||||
numOwners={values.owners}
|
||||
otherAccounts={getAccountsFrom(values)}
|
||||
/>
|
||||
)}
|
||||
>
|
||||
{childrenMock}
|
||||
</GnoForm>
|
||||
</Wrapper>
|
||||
))
|
||||
|
||||
let inputs = TestUtils.scryRenderedDOMComponentsWithTag(open, 'input')
|
||||
const fieldOwners = inputs[0]
|
||||
expect(fieldOwners.name).toEqual(FIELD_OWNERS)
|
||||
TestUtils.Simulate.change(fieldOwners, { target: { value: '2' } })
|
||||
|
||||
// WHEN
|
||||
inputs = TestUtils.scryRenderedDOMComponentsWithTag(open, 'input')
|
||||
const firstOwnerAddress = inputs[2]
|
||||
TestUtils.Simulate.change(firstOwnerAddress, { target: { value: '0xC21aC257Db500a87c65Daa980432F216A719bA30' } })
|
||||
const secondOwnerAddress = inputs[4]
|
||||
TestUtils.Simulate.change(secondOwnerAddress, { target: { value: '0xC21aC257Db500a87c65Daa980432F216A719bA30' } })
|
||||
|
||||
// THEN
|
||||
const muiFields = TestUtils.scryRenderedComponentsWithType(open, TextField)
|
||||
expect(5).toEqual(muiFields.length)
|
||||
const secondAddressField = muiFields[4]
|
||||
|
||||
expect(secondAddressField.props.meta.valid).toBe(false)
|
||||
expect(secondAddressField.props.meta.error).toBe(ADDRESS_REPEATED_ERROR)
|
||||
})
|
||||
})
|
|
@ -1,31 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Heading from '~/components/layout/Heading'
|
||||
import { getAccountsFrom } from '~/routes/open/utils/safeDataExtractor'
|
||||
import Name from './Name'
|
||||
import Owners from './Owners'
|
||||
import Confirmations from './Confirmations'
|
||||
import DailyLimit from './DailyLimit'
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
export default () => ({ values }: Object) => (
|
||||
<Block margin="md">
|
||||
<Heading tag="h2" margin="lg">Deploy a new Safe</Heading>
|
||||
<Name />
|
||||
<Owners numOwners={values.owners} otherAccounts={getAccountsFrom(values)} />
|
||||
<Confirmations />
|
||||
<DailyLimit />
|
||||
</Block>
|
||||
)
|
|
@ -0,0 +1,81 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Field from '~/components/forms/Field'
|
||||
import TextField from '~/components/forms/TextField'
|
||||
import { required } from '~/components/forms/validator'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Row from '~/components/layout/Row'
|
||||
import { FIELD_NAME } from '~/routes/open/components/fields'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import OpenPaper from '~/components/Stepper/OpenPaper'
|
||||
import { sm, secondary } from '~/theme/variables'
|
||||
|
||||
type Props = {
|
||||
classes: Object,
|
||||
}
|
||||
|
||||
const styles = () => ({
|
||||
root: {
|
||||
display: 'flex',
|
||||
maxWidth: '440px',
|
||||
},
|
||||
text: {
|
||||
flexWrap: 'nowrap',
|
||||
},
|
||||
dot: {
|
||||
marginRight: sm,
|
||||
},
|
||||
links: {
|
||||
'&>a': {
|
||||
color: secondary,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const SafeName = ({ classes }: Props) => (
|
||||
<React.Fragment>
|
||||
<Block margin="lg">
|
||||
<Paragraph noMargin size="md" color="primary" weight="light" className={classes.links}>
|
||||
This setup will create a Safe with one or more owners. Optionally give the Safe a local name.
|
||||
By continuing you consent with the <a rel="noopener noreferrer" href="https://safe.gnosis.io/terms" target="_blank">terms of use</a> and <a rel="noopener noreferrer" href="https://safe.gnosis.io/privacy" target="_blank">privacy policy</a>.
|
||||
</Paragraph>
|
||||
</Block>
|
||||
<Row margin="md" className={classes.text}>
|
||||
<Paragraph noMargin className={classes.dot} color="secondary">
|
||||
●
|
||||
</Paragraph>
|
||||
<Paragraph noMargin size="md" color="primary" weight="bolder">
|
||||
I understand that my funds are held securely in my Safe. They cannot be accessed by Gnosis.
|
||||
</Paragraph>
|
||||
</Row>
|
||||
<Row margin="md">
|
||||
<Paragraph noMargin className={classes.dot} color="secondary">
|
||||
●
|
||||
</Paragraph>
|
||||
<Paragraph noMargin size="md" color="primary" weight="bolder">
|
||||
My Safe is a smart contract on the Ethereum blockchain.
|
||||
</Paragraph>
|
||||
</Row>
|
||||
<Block margin="lg" className={classes.root}>
|
||||
<Field
|
||||
name={FIELD_NAME}
|
||||
component={TextField}
|
||||
type="text"
|
||||
validate={required}
|
||||
placeholder="Name of the new Safe"
|
||||
text="Safe name"
|
||||
/>
|
||||
</Block>
|
||||
</React.Fragment>
|
||||
)
|
||||
|
||||
const SafeNameForm = withStyles(styles)(SafeName)
|
||||
|
||||
const SafeNamePage = () => (controls: React$Node) => (
|
||||
<OpenPaper controls={controls} container={600}>
|
||||
<SafeNameForm />
|
||||
</OpenPaper>
|
||||
)
|
||||
|
||||
export default SafeNamePage
|
|
@ -0,0 +1,199 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Field from '~/components/forms/Field'
|
||||
import TextField from '~/components/forms/TextField'
|
||||
import { required, composeValidators, uniqueAddress, mustBeEthereumAddress } from '~/components/forms/validator'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Button from '~/components/layout/Button'
|
||||
import Row from '~/components/layout/Row'
|
||||
import Col from '~/components/layout/Col'
|
||||
import IconButton from '@material-ui/core/IconButton'
|
||||
import Delete from '@material-ui/icons/Delete'
|
||||
import InputAdornment from '@material-ui/core/InputAdornment'
|
||||
import CheckCircle from '@material-ui/icons/CheckCircle'
|
||||
import { getOwnerNameBy, getOwnerAddressBy } from '~/routes/open/components/fields'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import OpenPaper from '~/components/Stepper/OpenPaper'
|
||||
import { getAccountsFrom } from '~/routes/open/utils/safeDataExtractor'
|
||||
import Hairline from '~/components/layout/Hairline'
|
||||
import { md, lg, sm } from '~/theme/variables'
|
||||
|
||||
type Props = {
|
||||
classes: Object,
|
||||
otherAccounts: string[],
|
||||
errors: Object,
|
||||
values: Object,
|
||||
updateInitialProps: (initialValues: Object) => void,
|
||||
}
|
||||
|
||||
type State = {
|
||||
numOwners: number,
|
||||
}
|
||||
|
||||
const styles = () => ({
|
||||
root: {
|
||||
display: 'flex',
|
||||
},
|
||||
title: {
|
||||
padding: `${md} ${lg}`,
|
||||
},
|
||||
owner: {
|
||||
padding: `0 ${lg}`,
|
||||
},
|
||||
header: {
|
||||
padding: `${sm} ${lg}`,
|
||||
},
|
||||
name: {
|
||||
marginRight: `${sm}`,
|
||||
},
|
||||
trash: {
|
||||
top: '5px',
|
||||
},
|
||||
add: {
|
||||
justifyContent: 'center',
|
||||
},
|
||||
check: {
|
||||
color: '#03AE60',
|
||||
height: '20px',
|
||||
},
|
||||
})
|
||||
|
||||
const getAddressValidators = (addresses: string[], position: number) => {
|
||||
const copy = addresses.slice()
|
||||
copy.splice(position, 1)
|
||||
|
||||
return composeValidators(required, mustBeEthereumAddress, uniqueAddress(copy))
|
||||
}
|
||||
|
||||
const noErrorsOn = (name: string, errors: Object) => errors[name] === undefined
|
||||
|
||||
export const ADD_OWNER_BUTTON = '+ ADD ANOTHER OWNER'
|
||||
|
||||
export const calculateValuesAfterRemoving = (index: number, notRemovedOwners: number, values: Object) => {
|
||||
const initialValues = { ...values }
|
||||
const numOwnersAfterRemoving = notRemovedOwners - 1
|
||||
// muevo indices
|
||||
for (let i = index; i < numOwnersAfterRemoving; i += 1) {
|
||||
initialValues[getOwnerNameBy(i)] = values[getOwnerNameBy(i + 1)]
|
||||
initialValues[getOwnerAddressBy(i)] = values[getOwnerAddressBy(i + 1)]
|
||||
}
|
||||
|
||||
delete initialValues[getOwnerNameBy(numOwnersAfterRemoving)]
|
||||
delete initialValues[getOwnerAddressBy(numOwnersAfterRemoving)]
|
||||
|
||||
return initialValues
|
||||
}
|
||||
|
||||
class SafeOwners extends React.Component<Props, State> {
|
||||
state = {
|
||||
numOwners: 1,
|
||||
}
|
||||
|
||||
onRemoveRow = (index: number) => () => {
|
||||
const { values } = this.props
|
||||
const { numOwners } = this.state
|
||||
const initialValues = calculateValuesAfterRemoving(index, numOwners, values)
|
||||
this.props.updateInitialProps(initialValues)
|
||||
|
||||
|
||||
this.setState(state => ({
|
||||
numOwners: state.numOwners - 1,
|
||||
}))
|
||||
}
|
||||
|
||||
onAddOwner = () => {
|
||||
this.setState(state => ({
|
||||
numOwners: state.numOwners + 1,
|
||||
}))
|
||||
}
|
||||
|
||||
render() {
|
||||
const { classes, errors, otherAccounts } = this.props
|
||||
const { numOwners } = this.state
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Block className={classes.title}>
|
||||
<Paragraph noMargin size="md" color="primary" weight="light">
|
||||
Specify the owners of the Safe.
|
||||
</Paragraph>
|
||||
</Block>
|
||||
<Hairline />
|
||||
<Row className={classes.header}>
|
||||
<Col xs={4}>NAME</Col>
|
||||
<Col xs={8}>ADDRESS</Col>
|
||||
</Row>
|
||||
<Hairline />
|
||||
<Block margin="md">
|
||||
{ [...Array(Number(numOwners))].map((x, index) => {
|
||||
const addressName = getOwnerAddressBy(index)
|
||||
|
||||
return (
|
||||
<Row key={`owner${(index)}`} className={classes.owner}>
|
||||
<Col xs={4}>
|
||||
<Field
|
||||
className={classes.name}
|
||||
name={getOwnerNameBy(index)}
|
||||
component={TextField}
|
||||
type="text"
|
||||
validate={required}
|
||||
placeholder="Owner Name*"
|
||||
text="Owner Name"
|
||||
/>
|
||||
</Col>
|
||||
<Col xs={7}>
|
||||
<Field
|
||||
name={addressName}
|
||||
component={TextField}
|
||||
inputAdornment={noErrorsOn(addressName, errors) && {
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">
|
||||
<CheckCircle className={classes.check} />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
type="text"
|
||||
validate={getAddressValidators(otherAccounts, index)}
|
||||
placeholder="Owner Address*"
|
||||
text="Owner Address"
|
||||
/>
|
||||
</Col>
|
||||
<Col xs={1} center="xs" middle="xs">
|
||||
{ index > 0 &&
|
||||
<IconButton aria-label="Delete" onClick={this.onRemoveRow(index)} className={classes.trash}>
|
||||
<Delete />
|
||||
</IconButton>
|
||||
}
|
||||
</Col>
|
||||
</Row>
|
||||
)
|
||||
}) }
|
||||
</Block>
|
||||
<Row align="center" grow className={classes.add} margin="xl">
|
||||
<Button color="secondary" onClick={this.onAddOwner}>
|
||||
{ADD_OWNER_BUTTON}
|
||||
</Button>
|
||||
</Row>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const SafeOwnersForm = withStyles(styles)(SafeOwners)
|
||||
|
||||
const SafeOwnersPage = ({ updateInitialProps }: Object) => (controls: React$Node, { values, errors }: Object) => (
|
||||
<React.Fragment>
|
||||
<OpenPaper controls={controls} padding={false}>
|
||||
<SafeOwnersForm
|
||||
otherAccounts={getAccountsFrom(values)}
|
||||
errors={errors}
|
||||
updateInitialProps={updateInitialProps}
|
||||
values={values}
|
||||
/>
|
||||
</OpenPaper>
|
||||
</React.Fragment>
|
||||
)
|
||||
|
||||
|
||||
export default SafeOwnersPage
|
|
@ -0,0 +1,89 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import MenuItem from '@material-ui/core/MenuItem'
|
||||
import Field from '~/components/forms/Field'
|
||||
import SelectField from '~/components/forms/SelectField'
|
||||
import { composeValidators, minValue, mustBeInteger, required } from '~/components/forms/validator'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Row from '~/components/layout/Row'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import OpenPaper from '~/components/Stepper/OpenPaper'
|
||||
import { FIELD_CONFIRMATIONS, getNumOwnersFrom } from '~/routes/open/components/fields'
|
||||
import { md } from '~/theme/variables'
|
||||
|
||||
type Props = {
|
||||
classes: Object,
|
||||
values: Object,
|
||||
}
|
||||
|
||||
const styles = () => ({
|
||||
owners: {
|
||||
paddingLeft: md,
|
||||
},
|
||||
})
|
||||
|
||||
export const CONFIRMATIONS_ERROR = 'Number of confirmations can not be higher than the number of owners'
|
||||
|
||||
export const safeFieldsValidation = (values: Object) => {
|
||||
const errors = {}
|
||||
|
||||
const numOwners = getNumOwnersFrom(values)
|
||||
if (numOwners < Number.parseInt(values[FIELD_CONFIRMATIONS], 10)) {
|
||||
errors[FIELD_CONFIRMATIONS] = CONFIRMATIONS_ERROR
|
||||
}
|
||||
|
||||
return errors
|
||||
}
|
||||
|
||||
const SafeThreshold = ({ classes, values }: Props) => {
|
||||
const numOwners = getNumOwnersFrom(values)
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Block margin="xs">
|
||||
<Paragraph noMargin size="md" color="primary" weight="bolder">
|
||||
Any transaction requires the confirmation of:
|
||||
</Paragraph>
|
||||
</Block>
|
||||
<Row margin="xl" align="center">
|
||||
<Col xs={2}>
|
||||
<Field
|
||||
name={FIELD_CONFIRMATIONS}
|
||||
component={SelectField}
|
||||
validate={composeValidators(
|
||||
required,
|
||||
mustBeInteger,
|
||||
minValue(1),
|
||||
)}
|
||||
>
|
||||
{
|
||||
[...Array(Number(numOwners))].map((x, index) => (
|
||||
<MenuItem key={`selectOwner${index}`} value={`${index + 1}`}>{index + 1}</MenuItem>
|
||||
))
|
||||
}
|
||||
</Field>
|
||||
</Col>
|
||||
<Col xs={10}>
|
||||
<Paragraph size="lg" color="primary" noMargin className={classes.owners}>
|
||||
out of {numOwners} owner(s)
|
||||
</Paragraph>
|
||||
</Col>
|
||||
</Row>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
const SafeThresholdForm = withStyles(styles)(SafeThreshold)
|
||||
|
||||
const SafeOwnersPage = () => (controls: React$Node, { values }: Object) => (
|
||||
<React.Fragment>
|
||||
<OpenPaper controls={controls} container={450}>
|
||||
<SafeThresholdForm values={values} />
|
||||
</OpenPaper>
|
||||
</React.Fragment>
|
||||
)
|
||||
|
||||
|
||||
export default SafeOwnersPage
|
|
@ -2,7 +2,12 @@
|
|||
export const FIELD_NAME: string = 'name'
|
||||
export const FIELD_CONFIRMATIONS: string = 'confirmations'
|
||||
export const FIELD_OWNERS: string = 'owners'
|
||||
export const FIELD_DAILY_LIMIT: string = 'limit'
|
||||
|
||||
export const getOwnerNameBy = (index: number) => `owner${index}Name`
|
||||
export const getOwnerAddressBy = (index: number) => `owner${index}Address`
|
||||
|
||||
export const getNumOwnersFrom = (values: Object) => {
|
||||
const accounts = Object.keys(values).sort().filter(key => /^owner\d+Name$/.test(key))
|
||||
|
||||
return accounts.length
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import Page from '~/components/layout/Page'
|
||||
import { getAccountsFrom, getThresholdFrom, getNamesFrom, getSafeNameFrom, getDailyLimitFrom } from '~/routes/open/utils/safeDataExtractor'
|
||||
import { getAccountsFrom, getThresholdFrom, getNamesFrom, getSafeNameFrom } from '~/routes/open/utils/safeDataExtractor'
|
||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||
import { getGnosisSafeContract, deploySafeContract, initContracts } from '~/logic/contracts/safeContracts'
|
||||
import { checkReceiptStatus } from '~/logic/wallets/ethTransactions'
|
||||
import { history } from '~/store'
|
||||
import { OPENING_ADDRESS, stillInOpeningView, SAFELIST_ADDRESS } from '~/routes/routes'
|
||||
import selector from './selector'
|
||||
import actions, { type Actions, type AddSafe } from './actions'
|
||||
import Layout from '../components/Layout'
|
||||
|
@ -14,11 +15,11 @@ import Layout from '../components/Layout'
|
|||
type Props = Actions & {
|
||||
provider: string,
|
||||
userAccount: string,
|
||||
network: string,
|
||||
}
|
||||
|
||||
export type OpenState = {
|
||||
safeAddress: string,
|
||||
safeTx: string,
|
||||
}
|
||||
|
||||
export const createSafe = async (values: Object, userAccount: string, addSafe: AddSafe): Promise<OpenState> => {
|
||||
|
@ -26,38 +27,40 @@ export const createSafe = async (values: Object, userAccount: string, addSafe: A
|
|||
const numConfirmations = getThresholdFrom(values)
|
||||
const name = getSafeNameFrom(values)
|
||||
const owners = getNamesFrom(values)
|
||||
const dailyLimit = getDailyLimitFrom(values)
|
||||
|
||||
const web3 = getWeb3()
|
||||
const GnosisSafe = getGnosisSafeContract(web3)
|
||||
|
||||
await initContracts()
|
||||
const safe = await deploySafeContract(accounts, numConfirmations, dailyLimit, userAccount)
|
||||
const safe = await deploySafeContract(accounts, numConfirmations, userAccount)
|
||||
checkReceiptStatus(safe.tx)
|
||||
|
||||
const param = safe.logs[1].args.proxy
|
||||
const param = safe.logs[0].args.proxy
|
||||
const safeContract = GnosisSafe.at(param)
|
||||
|
||||
addSafe(name, safeContract.address, numConfirmations, dailyLimit, owners, accounts)
|
||||
addSafe(name, safeContract.address, numConfirmations, owners, accounts)
|
||||
|
||||
if (stillInOpeningView()) {
|
||||
const url = {
|
||||
pathname: `${SAFELIST_ADDRESS}/${safeContract.address}`,
|
||||
state: {
|
||||
name,
|
||||
tx: safe.tx,
|
||||
},
|
||||
}
|
||||
|
||||
history.push(url)
|
||||
}
|
||||
|
||||
// returning info for testing purposes, in app is fully async
|
||||
return { safeAddress: safeContract.address, safeTx: safe }
|
||||
}
|
||||
|
||||
class Open extends React.Component<Props, OpenState> {
|
||||
constructor() {
|
||||
super()
|
||||
|
||||
this.state = {
|
||||
safeAddress: '',
|
||||
safeTx: '',
|
||||
}
|
||||
}
|
||||
|
||||
class Open extends React.Component<Props> {
|
||||
onCallSafeContractSubmit = async (values) => {
|
||||
try {
|
||||
const { userAccount, addSafe } = this.props
|
||||
const safeInstance = await createSafe(values, userAccount, addSafe)
|
||||
this.setState(safeInstance)
|
||||
createSafe(values, userAccount, addSafe)
|
||||
history.push(OPENING_ADDRESS)
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line
|
||||
console.log('Error while creating the Safe' + error)
|
||||
|
@ -65,16 +68,14 @@ class Open extends React.Component<Props, OpenState> {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { safeAddress, safeTx } = this.state
|
||||
const { provider, userAccount } = this.props
|
||||
const { provider, userAccount, network } = this.props
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<Layout
|
||||
network={network}
|
||||
provider={provider}
|
||||
userAccount={userAccount}
|
||||
safeAddress={safeAddress}
|
||||
safeTx={safeTx}
|
||||
onCallSafeContractSubmit={this.onCallSafeContractSubmit}
|
||||
/>
|
||||
</Page>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
// @flow
|
||||
import { createStructuredSelector } from 'reselect'
|
||||
import { providerNameSelector, userAccountSelector } from '~/logic/wallets/store/selectors'
|
||||
import { providerNameSelector, userAccountSelector, networkSelector } from '~/logic/wallets/store/selectors'
|
||||
|
||||
export default createStructuredSelector({
|
||||
provider: providerNameSelector,
|
||||
network: networkSelector,
|
||||
userAccount: userAccountSelector,
|
||||
})
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
// @flow
|
||||
export const getDailyLimitFrom = (values: Object): number => Number(values.limit)
|
||||
|
||||
export const getAccountsFrom = (values: Object): string[] => {
|
||||
const accounts = Object.keys(values).sort().filter(key => /^owner\d+Address$/.test(key))
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// @flow
|
||||
import { storiesOf } from '@storybook/react'
|
||||
import * as React from 'react'
|
||||
import styles from '~/components/layout/PageFrame/index.scss'
|
||||
import { ETHEREUM_NETWORK } from '~/logic/wallets/getWeb3'
|
||||
import Component from './component'
|
||||
|
||||
const FrameDecorator = story => (
|
||||
<div className={styles.frame}>
|
||||
{ story() }
|
||||
</div>
|
||||
)
|
||||
|
||||
storiesOf('Routes /opening', module)
|
||||
.addDecorator(FrameDecorator)
|
||||
.add('View while safe is being deployed', () => (
|
||||
<Component
|
||||
name="Super Vault 2000"
|
||||
tx="0xed163e50e2e85695f5edafeba51d6be1758549858d12611ed4dcc96feaa19fc9"
|
||||
network={ETHEREUM_NETWORK.RINKEBY}
|
||||
/>
|
||||
))
|
||||
.add('Load this view without a tx', () => (
|
||||
<Component
|
||||
network={ETHEREUM_NETWORK.UNKNOWN}
|
||||
/>
|
||||
))
|
|
@ -0,0 +1,12 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="111" height="91" viewBox="0 0 111 91">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<g fill="#A2A8BA">
|
||||
<path d="M6.535 81.666h9.8V78.4h-9.8v3.266zm64.131-6.535h-67.4V3.266H94.73l.003 47.754c.203-.004.403-.015.608-.015.898 0 1.785.051 2.659.144V0H0v78.4h3.265v6.535H19.6V78.4h51.202c-.097-.888-.15-1.79-.15-2.705 0-.189.01-.376.014-.564z"/>
|
||||
<path d="M9.8 68.582L9.816 9.8l78.385.015v4.885h-1.635a1.64 1.64 0 0 0-1.635 1.634c0 .9.736 1.635 1.635 1.635H88.2v1.634h-1.635a1.64 1.64 0 0 0-1.635 1.635c0 .9.736 1.635 1.635 1.635H88.2v29.184c1.06-.32 2.15-.572 3.266-.748V22.866c.899 0 1.634-.736 1.634-1.634 0-.9-.735-1.635-1.634-1.635v-1.635a1.64 1.64 0 0 0 1.634-1.635c0-.9-.735-1.635-1.634-1.635V9.816a3.284 3.284 0 0 0-3.281-3.285H9.816a3.283 3.283 0 0 0-3.281 3.285v58.766a3.283 3.283 0 0 0 3.28 3.284H70.95c.173-1.114.423-2.2.74-3.26L9.8 68.582z"/>
|
||||
<path d="M60.435 42.466A3.276 3.276 0 0 1 57.17 39.2a3.276 3.276 0 0 1 3.265-3.266 3.277 3.277 0 0 1 3.266 3.266 3.276 3.276 0 0 1-3.266 3.265m0-9.8a6.533 6.533 0 0 0-6.535 6.535 6.534 6.534 0 0 0 6.535 6.535 6.535 6.535 0 0 0 0-13.069"/>
|
||||
<path d="M75.136 40.832h1.55a16.242 16.242 0 0 1-3.61 8.689l-1.095-1.095a1.633 1.633 0 0 0-2.305 0 1.634 1.634 0 0 0 0 2.305l1.095 1.095a16.303 16.303 0 0 1-8.69 3.61l.004-1.535c0-.9-.735-1.635-1.634-1.635-.9 0-1.635.736-1.635 1.635v1.55a16.249 16.249 0 0 1-8.69-3.61l1.095-1.095a1.631 1.631 0 0 0 0-2.304 1.63 1.63 0 0 0-2.305 0l-1.095 1.095a16.303 16.303 0 0 1-3.61-8.69l1.524.004c.9 0 1.634-.735 1.634-1.635s-.734-1.634-1.634-1.634h-1.55a16.25 16.25 0 0 1 3.61-8.69l1.095 1.094c.325.325.734.475 1.16.475.424 0 .834-.165 1.159-.475a1.63 1.63 0 0 0 0-2.305l-1.095-1.095a16.309 16.309 0 0 1 8.69-3.61l-.003 1.524c0 .9.734 1.635 1.634 1.635.9 0 1.635-.734 1.635-1.635v-1.55a16.254 16.254 0 0 1 8.69 3.61l-1.095 1.095a1.63 1.63 0 0 0 0 2.304c.326.326.735.475 1.16.475a1.67 1.67 0 0 0 1.16-.475l1.095-1.094a16.3 16.3 0 0 1 3.61 8.69l-1.554-.004c-.9 0-1.635.734-1.635 1.634a1.65 1.65 0 0 0 1.635 1.647M74.3 25.347c-.015-.016-.035-.016-.05-.035-3.56-3.525-8.426-5.71-13.816-5.71-5.39 0-10.256 2.189-13.8 5.7-.016.014-.035.014-.05.033-.016.015-.016.034-.035.05-3.53 3.557-5.715 8.426-5.715 13.816 0 5.39 2.19 10.256 5.7 13.8.015.016.015.034.034.05.016.015.035.015.05.034 3.557 3.526 8.426 5.716 13.816 5.716 5.39 0 10.256-2.19 13.8-5.7.016-.016.035-.016.051-.035.015-.015.015-.034.034-.049 3.525-3.56 5.716-8.427 5.716-13.816 0-5.39-2.19-10.26-5.701-13.804-.015-.016-.015-.035-.034-.05M17.966 22.862c-.9 0-1.635.735-1.635 1.634v32.666c0 .9.734 1.635 1.635 1.635.899 0 1.634-.735 1.634-1.635v-1.634c.9 0 1.635-.736 1.635-1.635 0-.9-.735-1.635-1.635-1.635V29.4c.9 0 1.635-.734 1.635-1.634 0-.9-.735-1.635-1.635-1.635v-1.635c0-.898-.735-1.634-1.634-1.634M26.135 22.866c-.9 0-1.635.735-1.635 1.634v1.636c-.9 0-1.635.734-1.635 1.634 0 .9.736 1.634 1.635 1.634V52.27c-.9 0-1.635.735-1.635 1.634 0 .9.736 1.636 1.635 1.636v1.634c0 .9.735 1.635 1.635 1.635s1.634-.735 1.634-1.635L27.765 24.5c0-.899-.734-1.634-1.63-1.634"/>
|
||||
</g>
|
||||
<path stroke="#467EE5" stroke-width="3" d="M93.756 58.266c-8.466 0-15.361 6.896-15.361 15.362 0 8.466 6.895 15.36 15.361 15.36 8.466 0 15.361-6.894 15.361-15.36s-6.895-15.362-15.361-15.362z"/>
|
||||
<path fill="#467EE5" fill-rule="nonzero" d="M93.68 68.471h-3.06v10.313h8.39v-3.06h-5.33z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.3 KiB |
|
@ -0,0 +1,82 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import Block from '~/components/layout/Block'
|
||||
import OpenInNew from '@material-ui/icons/OpenInNew'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import LinearProgress from '@material-ui/core/LinearProgress'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Img from '~/components/layout/Img'
|
||||
import Page from '~/components/layout/Page'
|
||||
import { openTxInEtherScan } from '~/logic/wallets/getWeb3'
|
||||
import { mediumFontSize, secondary, xs } from '~/theme/variables'
|
||||
import { type SelectorProps } from '../container/selector'
|
||||
|
||||
type Props = SelectorProps & {
|
||||
name: string,
|
||||
tx: string,
|
||||
classes: Object,
|
||||
}
|
||||
|
||||
const vault = require('../assets/vault.svg')
|
||||
|
||||
const styles = {
|
||||
page: {
|
||||
letterSpacing: '-1px',
|
||||
},
|
||||
icon: {
|
||||
height: mediumFontSize,
|
||||
color: secondary,
|
||||
},
|
||||
follow: {
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
marginTop: xs,
|
||||
},
|
||||
etherscan: {
|
||||
color: secondary,
|
||||
textDecoration: 'underline',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
marginLeft: xs,
|
||||
fontWeight: 'bolder',
|
||||
},
|
||||
}
|
||||
|
||||
const Opening = ({
|
||||
classes,
|
||||
name = 'Safe creation process',
|
||||
tx,
|
||||
network,
|
||||
}: Props) => (
|
||||
<Page align="center">
|
||||
<Paragraph className={classes.page} color="secondary" size="xxl" weight="bolder" align="center">
|
||||
{name}
|
||||
</Paragraph>
|
||||
<Block margin="lg" align="center">
|
||||
<Img src={vault} height={90} alt="Vault" />
|
||||
</Block>
|
||||
<Block margin="lg">
|
||||
<LinearProgress color="secondary" />
|
||||
</Block>
|
||||
<Block margin="md">
|
||||
<Paragraph className={classes.page} noMargin size="xl" align="center">
|
||||
Transaction submitted
|
||||
</Paragraph>
|
||||
<Paragraph className={classes.page} noMargin size="xl" align="center" weight="bolder">
|
||||
Deploying your new Safe...
|
||||
</Paragraph>
|
||||
</Block>
|
||||
<Block margin="md">
|
||||
<Paragraph size="md" align="center" weight="light" noMargin>
|
||||
This process should take a couple of minutes. <br />
|
||||
</Paragraph>
|
||||
{ tx &&
|
||||
<Paragraph className={classes.follow} size="md" align="center" weight="light" noMargin>
|
||||
Follow progress on <a href={openTxInEtherScan(tx, network)} target="_blank" rel="noopener noreferrer" className={classes.etherscan}>Etherscan.io<OpenInNew className={classes.icon} /></a>
|
||||
</Paragraph>
|
||||
}
|
||||
</Block>
|
||||
</Page>
|
||||
)
|
||||
|
||||
export default withStyles(styles)(Opening)
|
|
@ -0,0 +1,6 @@
|
|||
// @flow
|
||||
import { connect } from 'react-redux'
|
||||
import selector from './selector'
|
||||
import Layout from '../component'
|
||||
|
||||
export default connect(selector)(Layout)
|
|
@ -0,0 +1,11 @@
|
|||
// @flow
|
||||
import { createStructuredSelector } from 'reselect'
|
||||
import { networkSelector } from '~/logic/wallets/store/selectors'
|
||||
|
||||
export type SelectorProps = {
|
||||
network: string,
|
||||
}
|
||||
|
||||
export default createStructuredSelector({
|
||||
network: networkSelector,
|
||||
})
|
|
@ -1,6 +1,14 @@
|
|||
// @flow
|
||||
import { history } from '~/store'
|
||||
|
||||
export const SAFE_PARAM_ADDRESS = 'address'
|
||||
export const SAFELIST_ADDRESS = '/safes'
|
||||
export const OPEN_ADDRESS = '/open'
|
||||
export const WELCOME_ADDRESS = '/welcome'
|
||||
export const SETTINS_ADDRESS = '/settings'
|
||||
export const OPENING_ADDRESS = '/opening'
|
||||
|
||||
export const stillInOpeningView = () => {
|
||||
const path = history.location.pathname
|
||||
return path === OPENING_ADDRESS
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import Field from '~/components/forms/Field'
|
||||
import OpenPaper from '~/components/Stepper/OpenPaper'
|
||||
import TextField from '~/components/forms/TextField'
|
||||
import Checkbox from '~/components/forms/Checkbox'
|
||||
import { composeValidators, required, mustBeEthereumAddress, uniqueAddress } from '~/components/forms/validator'
|
||||
|
@ -29,8 +30,8 @@ type Props = {
|
|||
addresses: string[]
|
||||
}
|
||||
|
||||
const AddOwnerForm = ({ addresses, numOwners, threshold }: Props) => () => (
|
||||
<Block margin="md">
|
||||
const AddOwnerForm = ({ addresses, numOwners, threshold }: Props) => (controls: React$Node) => (
|
||||
<OpenPaper controls={controls}>
|
||||
<Heading tag="h2" margin="lg">
|
||||
Add Owner
|
||||
</Heading>
|
||||
|
@ -65,7 +66,7 @@ const AddOwnerForm = ({ addresses, numOwners, threshold }: Props) => () => (
|
|||
/>
|
||||
<Block>Increase threshold?</Block>
|
||||
</Block>
|
||||
</Block>
|
||||
</OpenPaper>
|
||||
)
|
||||
|
||||
export default AddOwnerForm
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue