Merge pull request #48 from gnosis/feature/WA-232-display-token-funds
WA-232 - Feature display token funds
This commit is contained in:
commit
5e8cbff632
|
@ -101,6 +101,7 @@
|
|||
"webpack-manifest-plugin": "^2.0.0-rc.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@gnosis.pm/util-contracts": "^0.2.14",
|
||||
"@material-ui/core": "^1.2.1",
|
||||
"@material-ui/icons": "^1.1.0",
|
||||
"final-form": "^4.2.1",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -52,8 +52,8 @@
|
|||
],
|
||||
"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:11;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:11;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:11;;;;;;;;;;;;;;;;;;;;;;;1302:118;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1302:118:11;;;;;;;;;;;;;;;;;;;;;;;;;;;1426:104;1492:7;1522:1;1515:8;;1426:104;:::o;1302:118::-;1373:7;1403:10;;;;;;;;;;;1396:17;;1302:118;:::o",
|
||||
"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",
|
||||
"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",
|
||||
"ast": {
|
||||
|
@ -82,7 +82,7 @@
|
|||
"id": 2,
|
||||
"nodeType": "ImportDirective",
|
||||
"scope": 24,
|
||||
"sourceUnit": 1612,
|
||||
"sourceUnit": 2989,
|
||||
"src": "24:21:0",
|
||||
"symbolAliases": [],
|
||||
"unitAlias": ""
|
||||
|
@ -96,10 +96,10 @@
|
|||
"id": 3,
|
||||
"name": "Proxy",
|
||||
"nodeType": "UserDefinedTypeName",
|
||||
"referencedDeclaration": 1611,
|
||||
"referencedDeclaration": 2988,
|
||||
"src": "392:5:0",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_contract$_Proxy_$1611",
|
||||
"typeIdentifier": "t_contract$_Proxy_$2988",
|
||||
"typeString": "contract Proxy"
|
||||
}
|
||||
},
|
||||
|
@ -109,7 +109,7 @@
|
|||
}
|
||||
],
|
||||
"contractDependencies": [
|
||||
1611
|
||||
2988
|
||||
],
|
||||
"contractKind": "contract",
|
||||
"documentation": "@title Delegate Constructor Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract. It is possible to send along initialization data with the constructor.\n @author Stefan George - <stefan@gnosis.pm>\n @author Richard Meissner - <richard@gnosis.pm>",
|
||||
|
@ -117,7 +117,7 @@
|
|||
"id": 23,
|
||||
"linearizedBaseContracts": [
|
||||
23,
|
||||
1611
|
||||
2988
|
||||
],
|
||||
"name": "DelegateConstructorProxy",
|
||||
"nodeType": "ContractDefinition",
|
||||
|
@ -264,10 +264,10 @@
|
|||
"name": "Proxy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 1611,
|
||||
"referencedDeclaration": 2988,
|
||||
"src": "662:5:0",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_type$_t_contract$_Proxy_$1611_$",
|
||||
"typeIdentifier": "t_type$_t_contract$_Proxy_$2988_$",
|
||||
"typeString": "type(contract Proxy)"
|
||||
}
|
||||
},
|
||||
|
@ -382,7 +382,7 @@
|
|||
"id": 2,
|
||||
"nodeType": "ImportDirective",
|
||||
"scope": 24,
|
||||
"sourceUnit": 1612,
|
||||
"sourceUnit": 2989,
|
||||
"src": "24:21:0",
|
||||
"symbolAliases": [],
|
||||
"unitAlias": ""
|
||||
|
@ -396,10 +396,10 @@
|
|||
"id": 3,
|
||||
"name": "Proxy",
|
||||
"nodeType": "UserDefinedTypeName",
|
||||
"referencedDeclaration": 1611,
|
||||
"referencedDeclaration": 2988,
|
||||
"src": "392:5:0",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_contract$_Proxy_$1611",
|
||||
"typeIdentifier": "t_contract$_Proxy_$2988",
|
||||
"typeString": "contract Proxy"
|
||||
}
|
||||
},
|
||||
|
@ -409,7 +409,7 @@
|
|||
}
|
||||
],
|
||||
"contractDependencies": [
|
||||
1611
|
||||
2988
|
||||
],
|
||||
"contractKind": "contract",
|
||||
"documentation": "@title Delegate Constructor Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract. It is possible to send along initialization data with the constructor.\n @author Stefan George - <stefan@gnosis.pm>\n @author Richard Meissner - <richard@gnosis.pm>",
|
||||
|
@ -417,7 +417,7 @@
|
|||
"id": 23,
|
||||
"linearizedBaseContracts": [
|
||||
23,
|
||||
1611
|
||||
2988
|
||||
],
|
||||
"name": "DelegateConstructorProxy",
|
||||
"nodeType": "ContractDefinition",
|
||||
|
@ -564,10 +564,10 @@
|
|||
"name": "Proxy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 1611,
|
||||
"referencedDeclaration": 2988,
|
||||
"src": "662:5:0",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_type$_t_contract$_Proxy_$1611_$",
|
||||
"typeIdentifier": "t_type$_t_contract$_Proxy_$2988_$",
|
||||
"typeString": "type(contract Proxy)"
|
||||
}
|
||||
},
|
||||
|
@ -662,5 +662,5 @@
|
|||
},
|
||||
"networks": {},
|
||||
"schemaVersion": "2.0.0",
|
||||
"updatedAt": "2018-06-18T14:44:09.445Z"
|
||||
"updatedAt": "2018-06-29T09:01:22.054Z"
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -3,29 +3,29 @@
|
|||
"abi": [],
|
||||
"bytecode": "0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a72305820641ab8b295edfaa2b1c8a8e0ae7d17ea2f4c8b95ea27e45d8947ed9a4799ca1f0029",
|
||||
"deployedBytecode": "0x6080604052600080fd00a165627a7a72305820641ab8b295edfaa2b1c8a8e0ae7d17ea2f4c8b95ea27e45d8947ed9a4799ca1f0029",
|
||||
"sourceMap": "115:95:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;115:95:0;;;;;;;",
|
||||
"deployedSourceMap": "115:95:0:-;;;;;",
|
||||
"sourceMap": "115:95:1:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;115:95:1;;;;;;;",
|
||||
"deployedSourceMap": "115:95:1:-;;;;;",
|
||||
"source": "pragma solidity 0.4.24;\n\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract Enum {\n enum Operation {\n Call,\n DelegateCall,\n Create\n }\n}\n",
|
||||
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Enum.sol",
|
||||
"ast": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Enum.sol",
|
||||
"exportedSymbols": {
|
||||
"Enum": [
|
||||
6
|
||||
30
|
||||
]
|
||||
},
|
||||
"id": 7,
|
||||
"id": 31,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1,
|
||||
"id": 25,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:0"
|
||||
"src": "0:23:1"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
|
@ -33,66 +33,66 @@
|
|||
"contractKind": "contract",
|
||||
"documentation": "@title Enum - Collection of enums\n @author Richard Meissner - <richard@gnosis.pm>",
|
||||
"fullyImplemented": true,
|
||||
"id": 6,
|
||||
"id": 30,
|
||||
"linearizedBaseContracts": [
|
||||
6
|
||||
30
|
||||
],
|
||||
"name": "Enum",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"canonicalName": "Enum.Operation",
|
||||
"id": 5,
|
||||
"id": 29,
|
||||
"members": [
|
||||
{
|
||||
"id": 2,
|
||||
"id": 26,
|
||||
"name": "Call",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "160:4:0"
|
||||
"src": "160:4:1"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 27,
|
||||
"name": "DelegateCall",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "174:12:0"
|
||||
"src": "174:12:1"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 28,
|
||||
"name": "Create",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "196:6:0"
|
||||
"src": "196:6:1"
|
||||
}
|
||||
],
|
||||
"name": "Operation",
|
||||
"nodeType": "EnumDefinition",
|
||||
"src": "135:73:0"
|
||||
"src": "135:73:1"
|
||||
}
|
||||
],
|
||||
"scope": 7,
|
||||
"src": "115:95:0"
|
||||
"scope": 31,
|
||||
"src": "115:95:1"
|
||||
}
|
||||
],
|
||||
"src": "0:211:0"
|
||||
"src": "0:211:1"
|
||||
},
|
||||
"legacyAST": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/Enum.sol",
|
||||
"exportedSymbols": {
|
||||
"Enum": [
|
||||
6
|
||||
30
|
||||
]
|
||||
},
|
||||
"id": 7,
|
||||
"id": 31,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1,
|
||||
"id": 25,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:0"
|
||||
"src": "0:23:1"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
|
@ -100,46 +100,46 @@
|
|||
"contractKind": "contract",
|
||||
"documentation": "@title Enum - Collection of enums\n @author Richard Meissner - <richard@gnosis.pm>",
|
||||
"fullyImplemented": true,
|
||||
"id": 6,
|
||||
"id": 30,
|
||||
"linearizedBaseContracts": [
|
||||
6
|
||||
30
|
||||
],
|
||||
"name": "Enum",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"canonicalName": "Enum.Operation",
|
||||
"id": 5,
|
||||
"id": 29,
|
||||
"members": [
|
||||
{
|
||||
"id": 2,
|
||||
"id": 26,
|
||||
"name": "Call",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "160:4:0"
|
||||
"src": "160:4:1"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": 27,
|
||||
"name": "DelegateCall",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "174:12:0"
|
||||
"src": "174:12:1"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": 28,
|
||||
"name": "Create",
|
||||
"nodeType": "EnumValue",
|
||||
"src": "196:6:0"
|
||||
"src": "196:6:1"
|
||||
}
|
||||
],
|
||||
"name": "Operation",
|
||||
"nodeType": "EnumDefinition",
|
||||
"src": "135:73:0"
|
||||
"src": "135:73:1"
|
||||
}
|
||||
],
|
||||
"scope": 7,
|
||||
"src": "115:95:0"
|
||||
"scope": 31,
|
||||
"src": "115:95:1"
|
||||
}
|
||||
],
|
||||
"src": "0:211:0"
|
||||
"src": "0:211:1"
|
||||
},
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
|
@ -147,5 +147,5 @@
|
|||
},
|
||||
"networks": {},
|
||||
"schemaVersion": "2.0.0",
|
||||
"updatedAt": "2018-06-20T07:57:26.985Z"
|
||||
"updatedAt": "2018-06-29T09:01:22.054Z"
|
||||
}
|
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
|
@ -18,38 +18,38 @@
|
|||
],
|
||||
"bytecode": "0x608060405234801561001057600080fd5b50610276806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637de7edef14610046575b600080fd5b34801561005257600080fd5b50610087600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610089565b005b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff1614151515610207576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a72305820243ca7a44eb0464a47c14309cc3a29e407df6e966674981a787df22c0d9280220029",
|
||||
"deployedBytecode": "0x608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637de7edef14610046575b600080fd5b34801561005257600080fd5b50610087600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610089565b005b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610152576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207481526020017f68697320636f6e7472616374000000000000000000000000000000000000000081525060400191505060405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff1614151515610207576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001807f496e76616c6964206d617374657220636f707920616464726573732070726f7681526020017f696465640000000000000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a72305820243ca7a44eb0464a47c14309cc3a29e407df6e966674981a787df22c0d9280220029",
|
||||
"sourceMap": "203:673:4:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;203:673:4;;;;;;;",
|
||||
"deployedSourceMap": "203:673:4:-;;;;;;;;;;;;;;;;;;;;;;;;626:248;;8:9:-1;5:2;;;30:1;27;20:12;5:2;626:248:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;244:4:8;222:27;;:10;:27;;;214:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;791:1:4;776:11;:16;;;;768:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;856:11;843:10;;:24;;;;;;;;;;;;;;;;;;626:248;:::o",
|
||||
"sourceMap": "203:673:5:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;203:673:5;;;;;;;",
|
||||
"deployedSourceMap": "203:673:5:-;;;;;;;;;;;;;;;;;;;;;;;;626:248;;8:9:-1;5:2;;;30:1;27;20:12;5:2;626:248:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;244:4:16;222:27;;:10;:27;;;214:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;791:1:5;776:11;:16;;;;768:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;856:11;843:10;;:24;;;;;;;;;;;;;;;;;;626:248;:::o",
|
||||
"source": "pragma solidity 0.4.24;\nimport \"./SelfAuthorized.sol\";\n\n\n/// @title MasterCopy - Base for master copy contracts (should always be first super contract)\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract MasterCopy is SelfAuthorized {\n // masterCopy always needs to be first declared variable, to ensure that it is at the same location as in the Proxy contract.\n // It should also always be ensured that the address is stored alone (uses a full word)\n address masterCopy;\n\n /// @dev Allows to upgrade the contract. This can only be done via a Safe transaction.\n /// @param _masterCopy New contract address.\n function changeMasterCopy(address _masterCopy)\n public\n authorized\n {\n // Master copy address cannot be null.\n require(_masterCopy != 0, \"Invalid master copy address provided\");\n masterCopy = _masterCopy;\n }\n}\n",
|
||||
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/MasterCopy.sol",
|
||||
"ast": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/MasterCopy.sol",
|
||||
"exportedSymbols": {
|
||||
"MasterCopy": [
|
||||
608
|
||||
632
|
||||
]
|
||||
},
|
||||
"id": 609,
|
||||
"id": 633,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 583,
|
||||
"id": 607,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:4"
|
||||
"src": "0:23:5"
|
||||
},
|
||||
{
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
|
||||
"file": "./SelfAuthorized.sol",
|
||||
"id": 584,
|
||||
"id": 608,
|
||||
"nodeType": "ImportDirective",
|
||||
"scope": 609,
|
||||
"sourceUnit": 1450,
|
||||
"src": "24:30:4",
|
||||
"scope": 633,
|
||||
"sourceUnit": 3066,
|
||||
"src": "24:30:5",
|
||||
"symbolAliases": [],
|
||||
"unitAlias": ""
|
||||
},
|
||||
|
@ -59,42 +59,42 @@
|
|||
"arguments": null,
|
||||
"baseName": {
|
||||
"contractScope": null,
|
||||
"id": 585,
|
||||
"id": 609,
|
||||
"name": "SelfAuthorized",
|
||||
"nodeType": "UserDefinedTypeName",
|
||||
"referencedDeclaration": 1449,
|
||||
"src": "226:14:4",
|
||||
"referencedDeclaration": 3065,
|
||||
"src": "226:14:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1449",
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$3065",
|
||||
"typeString": "contract SelfAuthorized"
|
||||
}
|
||||
},
|
||||
"id": 586,
|
||||
"id": 610,
|
||||
"nodeType": "InheritanceSpecifier",
|
||||
"src": "226:14:4"
|
||||
"src": "226:14:5"
|
||||
}
|
||||
],
|
||||
"contractDependencies": [
|
||||
1449
|
||||
3065
|
||||
],
|
||||
"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": 608,
|
||||
"id": 632,
|
||||
"linearizedBaseContracts": [
|
||||
608,
|
||||
1449
|
||||
632,
|
||||
3065
|
||||
],
|
||||
"name": "MasterCopy",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 588,
|
||||
"id": 612,
|
||||
"name": "masterCopy",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 608,
|
||||
"src": "465:18:4",
|
||||
"scope": 632,
|
||||
"src": "465:18:5",
|
||||
"stateVariable": true,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -102,10 +102,10 @@
|
|||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 587,
|
||||
"id": 611,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "465:7:4",
|
||||
"src": "465:7:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -116,9 +116,9 @@
|
|||
},
|
||||
{
|
||||
"body": {
|
||||
"id": 606,
|
||||
"id": 630,
|
||||
"nodeType": "Block",
|
||||
"src": "711:163:4",
|
||||
"src": "711:163:5",
|
||||
"statements": [
|
||||
{
|
||||
"expression": {
|
||||
|
@ -130,19 +130,19 @@
|
|||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
},
|
||||
"id": 598,
|
||||
"id": 622,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
"lValueRequested": false,
|
||||
"leftExpression": {
|
||||
"argumentTypes": null,
|
||||
"id": 596,
|
||||
"id": 620,
|
||||
"name": "_masterCopy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 590,
|
||||
"src": "776:11:4",
|
||||
"referencedDeclaration": 614,
|
||||
"src": "776:11:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -153,14 +153,14 @@
|
|||
"rightExpression": {
|
||||
"argumentTypes": null,
|
||||
"hexValue": "30",
|
||||
"id": 597,
|
||||
"id": 621,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "number",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "791:1:4",
|
||||
"src": "791:1:5",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_rational_0_by_1",
|
||||
|
@ -168,7 +168,7 @@
|
|||
},
|
||||
"value": "0"
|
||||
},
|
||||
"src": "776:16:4",
|
||||
"src": "776:16:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
|
@ -177,14 +177,14 @@
|
|||
{
|
||||
"argumentTypes": null,
|
||||
"hexValue": "496e76616c6964206d617374657220636f707920616464726573732070726f7669646564",
|
||||
"id": 599,
|
||||
"id": 623,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "string",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "794:38:4",
|
||||
"src": "794:38:5",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_stringliteral_108d84599042957b954e89d43b52f80be89321dfc114a37800028eba58dafc87",
|
||||
|
@ -204,21 +204,21 @@
|
|||
"typeString": "literal_string \"Invalid master copy address provided\""
|
||||
}
|
||||
],
|
||||
"id": 595,
|
||||
"id": 619,
|
||||
"name": "require",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [
|
||||
1776,
|
||||
1777
|
||||
4039,
|
||||
4040
|
||||
],
|
||||
"referencedDeclaration": 1777,
|
||||
"src": "768:7:4",
|
||||
"referencedDeclaration": 4040,
|
||||
"src": "768:7:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
|
||||
"typeString": "function (bool,string memory) pure"
|
||||
}
|
||||
},
|
||||
"id": 600,
|
||||
"id": 624,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -226,32 +226,32 @@
|
|||
"lValueRequested": false,
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "768:65:4",
|
||||
"src": "768:65:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_tuple$__$",
|
||||
"typeString": "tuple()"
|
||||
}
|
||||
},
|
||||
"id": 601,
|
||||
"id": 625,
|
||||
"nodeType": "ExpressionStatement",
|
||||
"src": "768:65:4"
|
||||
"src": "768:65:5"
|
||||
},
|
||||
{
|
||||
"expression": {
|
||||
"argumentTypes": null,
|
||||
"id": 604,
|
||||
"id": 628,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
"lValueRequested": false,
|
||||
"leftHandSide": {
|
||||
"argumentTypes": null,
|
||||
"id": 602,
|
||||
"id": 626,
|
||||
"name": "masterCopy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 588,
|
||||
"src": "843:10:4",
|
||||
"referencedDeclaration": 612,
|
||||
"src": "843:10:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -261,68 +261,68 @@
|
|||
"operator": "=",
|
||||
"rightHandSide": {
|
||||
"argumentTypes": null,
|
||||
"id": 603,
|
||||
"id": 627,
|
||||
"name": "_masterCopy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 590,
|
||||
"src": "856:11:4",
|
||||
"referencedDeclaration": 614,
|
||||
"src": "856:11:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"src": "843:24:4",
|
||||
"src": "843:24:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"id": 605,
|
||||
"id": 629,
|
||||
"nodeType": "ExpressionStatement",
|
||||
"src": "843:24:4"
|
||||
"src": "843:24:5"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": "@dev Allows to upgrade the contract. This can only be done via a Safe transaction.\n @param _masterCopy New contract address.",
|
||||
"id": 607,
|
||||
"id": 631,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
"modifiers": [
|
||||
{
|
||||
"arguments": null,
|
||||
"id": 593,
|
||||
"id": 617,
|
||||
"modifierName": {
|
||||
"argumentTypes": null,
|
||||
"id": 592,
|
||||
"id": 616,
|
||||
"name": "authorized",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 1448,
|
||||
"src": "696:10:4",
|
||||
"referencedDeclaration": 3064,
|
||||
"src": "696:10:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_modifier$__$",
|
||||
"typeString": "modifier ()"
|
||||
}
|
||||
},
|
||||
"nodeType": "ModifierInvocation",
|
||||
"src": "696:10:4"
|
||||
"src": "696:10:5"
|
||||
}
|
||||
],
|
||||
"name": "changeMasterCopy",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 591,
|
||||
"id": 615,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 590,
|
||||
"id": 614,
|
||||
"name": "_masterCopy",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 607,
|
||||
"src": "652:19:4",
|
||||
"scope": 631,
|
||||
"src": "652:19:5",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -330,10 +330,10 @@
|
|||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 589,
|
||||
"id": 613,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "652:7:4",
|
||||
"src": "652:7:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -343,56 +343,56 @@
|
|||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "651:21:4"
|
||||
"src": "651:21:5"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 594,
|
||||
"id": 618,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "711:0:4"
|
||||
"src": "711:0:5"
|
||||
},
|
||||
"scope": 608,
|
||||
"src": "626:248:4",
|
||||
"scope": 632,
|
||||
"src": "626:248:5",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 609,
|
||||
"src": "203:673:4"
|
||||
"scope": 633,
|
||||
"src": "203:673:5"
|
||||
}
|
||||
],
|
||||
"src": "0:877:4"
|
||||
"src": "0:877:5"
|
||||
},
|
||||
"legacyAST": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/MasterCopy.sol",
|
||||
"exportedSymbols": {
|
||||
"MasterCopy": [
|
||||
608
|
||||
632
|
||||
]
|
||||
},
|
||||
"id": 609,
|
||||
"id": 633,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 583,
|
||||
"id": 607,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:4"
|
||||
"src": "0:23:5"
|
||||
},
|
||||
{
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
|
||||
"file": "./SelfAuthorized.sol",
|
||||
"id": 584,
|
||||
"id": 608,
|
||||
"nodeType": "ImportDirective",
|
||||
"scope": 609,
|
||||
"sourceUnit": 1450,
|
||||
"src": "24:30:4",
|
||||
"scope": 633,
|
||||
"sourceUnit": 3066,
|
||||
"src": "24:30:5",
|
||||
"symbolAliases": [],
|
||||
"unitAlias": ""
|
||||
},
|
||||
|
@ -402,42 +402,42 @@
|
|||
"arguments": null,
|
||||
"baseName": {
|
||||
"contractScope": null,
|
||||
"id": 585,
|
||||
"id": 609,
|
||||
"name": "SelfAuthorized",
|
||||
"nodeType": "UserDefinedTypeName",
|
||||
"referencedDeclaration": 1449,
|
||||
"src": "226:14:4",
|
||||
"referencedDeclaration": 3065,
|
||||
"src": "226:14:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1449",
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$3065",
|
||||
"typeString": "contract SelfAuthorized"
|
||||
}
|
||||
},
|
||||
"id": 586,
|
||||
"id": 610,
|
||||
"nodeType": "InheritanceSpecifier",
|
||||
"src": "226:14:4"
|
||||
"src": "226:14:5"
|
||||
}
|
||||
],
|
||||
"contractDependencies": [
|
||||
1449
|
||||
3065
|
||||
],
|
||||
"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": 608,
|
||||
"id": 632,
|
||||
"linearizedBaseContracts": [
|
||||
608,
|
||||
1449
|
||||
632,
|
||||
3065
|
||||
],
|
||||
"name": "MasterCopy",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 588,
|
||||
"id": 612,
|
||||
"name": "masterCopy",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 608,
|
||||
"src": "465:18:4",
|
||||
"scope": 632,
|
||||
"src": "465:18:5",
|
||||
"stateVariable": true,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -445,10 +445,10 @@
|
|||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 587,
|
||||
"id": 611,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "465:7:4",
|
||||
"src": "465:7:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -459,9 +459,9 @@
|
|||
},
|
||||
{
|
||||
"body": {
|
||||
"id": 606,
|
||||
"id": 630,
|
||||
"nodeType": "Block",
|
||||
"src": "711:163:4",
|
||||
"src": "711:163:5",
|
||||
"statements": [
|
||||
{
|
||||
"expression": {
|
||||
|
@ -473,19 +473,19 @@
|
|||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
},
|
||||
"id": 598,
|
||||
"id": 622,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
"lValueRequested": false,
|
||||
"leftExpression": {
|
||||
"argumentTypes": null,
|
||||
"id": 596,
|
||||
"id": 620,
|
||||
"name": "_masterCopy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 590,
|
||||
"src": "776:11:4",
|
||||
"referencedDeclaration": 614,
|
||||
"src": "776:11:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -496,14 +496,14 @@
|
|||
"rightExpression": {
|
||||
"argumentTypes": null,
|
||||
"hexValue": "30",
|
||||
"id": 597,
|
||||
"id": 621,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "number",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "791:1:4",
|
||||
"src": "791:1:5",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_rational_0_by_1",
|
||||
|
@ -511,7 +511,7 @@
|
|||
},
|
||||
"value": "0"
|
||||
},
|
||||
"src": "776:16:4",
|
||||
"src": "776:16:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
|
@ -520,14 +520,14 @@
|
|||
{
|
||||
"argumentTypes": null,
|
||||
"hexValue": "496e76616c6964206d617374657220636f707920616464726573732070726f7669646564",
|
||||
"id": 599,
|
||||
"id": 623,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "string",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "794:38:4",
|
||||
"src": "794:38:5",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_stringliteral_108d84599042957b954e89d43b52f80be89321dfc114a37800028eba58dafc87",
|
||||
|
@ -547,21 +547,21 @@
|
|||
"typeString": "literal_string \"Invalid master copy address provided\""
|
||||
}
|
||||
],
|
||||
"id": 595,
|
||||
"id": 619,
|
||||
"name": "require",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [
|
||||
1776,
|
||||
1777
|
||||
4039,
|
||||
4040
|
||||
],
|
||||
"referencedDeclaration": 1777,
|
||||
"src": "768:7:4",
|
||||
"referencedDeclaration": 4040,
|
||||
"src": "768:7:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
|
||||
"typeString": "function (bool,string memory) pure"
|
||||
}
|
||||
},
|
||||
"id": 600,
|
||||
"id": 624,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -569,32 +569,32 @@
|
|||
"lValueRequested": false,
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "768:65:4",
|
||||
"src": "768:65:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_tuple$__$",
|
||||
"typeString": "tuple()"
|
||||
}
|
||||
},
|
||||
"id": 601,
|
||||
"id": 625,
|
||||
"nodeType": "ExpressionStatement",
|
||||
"src": "768:65:4"
|
||||
"src": "768:65:5"
|
||||
},
|
||||
{
|
||||
"expression": {
|
||||
"argumentTypes": null,
|
||||
"id": 604,
|
||||
"id": 628,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
"lValueRequested": false,
|
||||
"leftHandSide": {
|
||||
"argumentTypes": null,
|
||||
"id": 602,
|
||||
"id": 626,
|
||||
"name": "masterCopy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 588,
|
||||
"src": "843:10:4",
|
||||
"referencedDeclaration": 612,
|
||||
"src": "843:10:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -604,68 +604,68 @@
|
|||
"operator": "=",
|
||||
"rightHandSide": {
|
||||
"argumentTypes": null,
|
||||
"id": 603,
|
||||
"id": 627,
|
||||
"name": "_masterCopy",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 590,
|
||||
"src": "856:11:4",
|
||||
"referencedDeclaration": 614,
|
||||
"src": "856:11:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"src": "843:24:4",
|
||||
"src": "843:24:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"id": 605,
|
||||
"id": 629,
|
||||
"nodeType": "ExpressionStatement",
|
||||
"src": "843:24:4"
|
||||
"src": "843:24:5"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": "@dev Allows to upgrade the contract. This can only be done via a Safe transaction.\n @param _masterCopy New contract address.",
|
||||
"id": 607,
|
||||
"id": 631,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
"modifiers": [
|
||||
{
|
||||
"arguments": null,
|
||||
"id": 593,
|
||||
"id": 617,
|
||||
"modifierName": {
|
||||
"argumentTypes": null,
|
||||
"id": 592,
|
||||
"id": 616,
|
||||
"name": "authorized",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 1448,
|
||||
"src": "696:10:4",
|
||||
"referencedDeclaration": 3064,
|
||||
"src": "696:10:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_modifier$__$",
|
||||
"typeString": "modifier ()"
|
||||
}
|
||||
},
|
||||
"nodeType": "ModifierInvocation",
|
||||
"src": "696:10:4"
|
||||
"src": "696:10:5"
|
||||
}
|
||||
],
|
||||
"name": "changeMasterCopy",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 591,
|
||||
"id": 615,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 590,
|
||||
"id": 614,
|
||||
"name": "_masterCopy",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 607,
|
||||
"src": "652:19:4",
|
||||
"scope": 631,
|
||||
"src": "652:19:5",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -673,10 +673,10 @@
|
|||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 589,
|
||||
"id": 613,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "652:7:4",
|
||||
"src": "652:7:5",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -686,27 +686,27 @@
|
|||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "651:21:4"
|
||||
"src": "651:21:5"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 594,
|
||||
"id": 618,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "711:0:4"
|
||||
"src": "711:0:5"
|
||||
},
|
||||
"scope": 608,
|
||||
"src": "626:248:4",
|
||||
"scope": 632,
|
||||
"src": "626:248:5",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 609,
|
||||
"src": "203:673:4"
|
||||
"scope": 633,
|
||||
"src": "203:673:5"
|
||||
}
|
||||
],
|
||||
"src": "0:877:4"
|
||||
"src": "0:877:5"
|
||||
},
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
|
@ -714,5 +714,5 @@
|
|||
},
|
||||
"networks": {},
|
||||
"schemaVersion": "2.0.0",
|
||||
"updatedAt": "2018-06-20T07:57:27.004Z"
|
||||
"updatedAt": "2018-06-29T09:01:22.057Z"
|
||||
}
|
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
|
@ -18,29 +18,29 @@
|
|||
],
|
||||
"bytecode": "0x608060405234801561001057600080fd5b50610169806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638d80ff0a14610046575b600080fd5b34801561005257600080fd5b506100ad600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506100af565b005b805160205b81811015610138578083015160208201840151604083018501516080840186015160a085018701600085600081146100f357600181146101035761010e565b6000808585888a5af1915061010e565b6000808585895af491505b50600081141561011d57600080fd5b602080601f8501040260a001870196505050505050506100b4565b5050505600a165627a7a72305820c1abf4988401674d6d6a5ceca56de123817c61305360ceffe26ebab59a828b7d0029",
|
||||
"deployedBytecode": "0x608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638d80ff0a14610046575b600080fd5b34801561005257600080fd5b506100ad600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506100af565b005b805160205b81811015610138578083015160208201840151604083018501516080840186015160a085018701600085600081146100f357600181146101035761010e565b6000808585888a5af1915061010e565b6000808585895af491505b50600081141561011d57600080fd5b602080601f8501040260a001870196505050505050506100b4565b5050505600a165627a7a72305820c1abf4988401674d6d6a5ceca56de123817c61305360ceffe26ebab59a828b7d0029",
|
||||
"sourceMap": "253:1424:17:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;253:1424:17;;;;;;;",
|
||||
"deployedSourceMap": "253:1424:17:-;;;;;;;;;;;;;;;;;;;;;;;;695:980;;8:9:-1;5:2;;;30:1;27;20:12;5:2;695:980:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;870:12;864:19;905:4;922:737;936:6;933:1;930:13;922:737;;;1007:1;993:12;989:20;983:27;1068:4;1065:1;1061:12;1047;1043:31;1037:38;1136:4;1133:1;1129:12;1115;1111:31;1105:38;1209:4;1206:1;1202:12;1188;1184:31;1178:38;1270:4;1267:1;1263:12;1249;1245:31;1308:1;1333:9;1365:1;1360:66;;;;1448:1;1443:67;;;;1326:184;;1360:66;1422:1;1419;1407:10;1401:4;1394:5;1390:2;1385:3;1380:44;1369:55;;1360:66;;1443:67;1506:1;1503;1491:10;1485:4;1481:2;1476:3;1463:45;1452:56;;1326:184;;1542:1;1533:7;1530:14;1527:2;;;1557:1;1554;1547:12;1527:2;1638:4;1631;1624;1612:10;1608:21;1604:32;1600:43;1594:4;1590:54;1587:1;1583:62;1578:67;;948:711;;;;;;922:737;;;836:833;;;:::o",
|
||||
"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",
|
||||
"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": [
|
||||
1840
|
||||
3176
|
||||
]
|
||||
},
|
||||
"id": 1841,
|
||||
"id": 3177,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1832,
|
||||
"id": 3168,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:17"
|
||||
"src": "0:23:19"
|
||||
},
|
||||
{
|
||||
"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": 1840,
|
||||
"id": 3176,
|
||||
"linearizedBaseContracts": [
|
||||
1840
|
||||
3176
|
||||
],
|
||||
"name": "MultiSend",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 1838,
|
||||
"id": 3174,
|
||||
"nodeType": "Block",
|
||||
"src": "753:922:17",
|
||||
"src": "753:922:19",
|
||||
"statements": [
|
||||
{
|
||||
"externalReferences": [
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1834,
|
||||
"declaration": 3170,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "870:12:17",
|
||||
"src": "870:12:19",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1834,
|
||||
"declaration": 3170,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "993:12:17",
|
||||
"src": "993:12:19",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1834,
|
||||
"declaration": 3170,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1047:12:17",
|
||||
"src": "1047:12:19",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1834,
|
||||
"declaration": 3170,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1188:12:17",
|
||||
"src": "1188:12:19",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1834,
|
||||
"declaration": 3170,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1115:12:17",
|
||||
"src": "1115:12:19",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1834,
|
||||
"declaration": 3170,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1249:12:17",
|
||||
"src": "1249:12:19",
|
||||
"valueSize": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": 1837,
|
||||
"id": 3173,
|
||||
"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:17"
|
||||
"src": "827:848:19"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": "@dev Sends multiple transactions and reverts all if one fails.\n @param transactions Encoded transactions. Each transaction is encoded as a \n tuple(operation,address,uint256,bytes), where operation \n can be 0 for a call or 1 for a delegatecall. The bytes \n of all encoded transactions are concatenated to form the input.",
|
||||
"id": 1839,
|
||||
"id": 3175,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
|
@ -134,16 +134,16 @@
|
|||
"name": "multiSend",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 1835,
|
||||
"id": 3171,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1834,
|
||||
"id": 3170,
|
||||
"name": "transactions",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1839,
|
||||
"src": "714:18:17",
|
||||
"scope": 3175,
|
||||
"src": "714:18:19",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -151,10 +151,10 @@
|
|||
"typeString": "bytes"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1833,
|
||||
"id": 3169,
|
||||
"name": "bytes",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "714:5:17",
|
||||
"src": "714:5:19",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_storage_ptr",
|
||||
"typeString": "bytes"
|
||||
|
@ -164,47 +164,47 @@
|
|||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "713:20:17"
|
||||
"src": "713:20:19"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 1836,
|
||||
"id": 3172,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "753:0:17"
|
||||
"src": "753:0:19"
|
||||
},
|
||||
"scope": 1840,
|
||||
"src": "695:980:17",
|
||||
"scope": 3176,
|
||||
"src": "695:980:19",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 1841,
|
||||
"src": "253:1424:17"
|
||||
"scope": 3177,
|
||||
"src": "253:1424:19"
|
||||
}
|
||||
],
|
||||
"src": "0:1678:17"
|
||||
"src": "0:1678:19"
|
||||
},
|
||||
"legacyAST": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/libraries/MultiSend.sol",
|
||||
"exportedSymbols": {
|
||||
"MultiSend": [
|
||||
1840
|
||||
3176
|
||||
]
|
||||
},
|
||||
"id": 1841,
|
||||
"id": 3177,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1832,
|
||||
"id": 3168,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:17"
|
||||
"src": "0:23:19"
|
||||
},
|
||||
{
|
||||
"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": 1840,
|
||||
"id": 3176,
|
||||
"linearizedBaseContracts": [
|
||||
1840
|
||||
3176
|
||||
],
|
||||
"name": "MultiSend",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 1838,
|
||||
"id": 3174,
|
||||
"nodeType": "Block",
|
||||
"src": "753:922:17",
|
||||
"src": "753:922:19",
|
||||
"statements": [
|
||||
{
|
||||
"externalReferences": [
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1834,
|
||||
"declaration": 3170,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "870:12:17",
|
||||
"src": "870:12:19",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1834,
|
||||
"declaration": 3170,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "993:12:17",
|
||||
"src": "993:12:19",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1834,
|
||||
"declaration": 3170,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1047:12:17",
|
||||
"src": "1047:12:19",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1834,
|
||||
"declaration": 3170,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1188:12:17",
|
||||
"src": "1188:12:19",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1834,
|
||||
"declaration": 3170,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1115:12:17",
|
||||
"src": "1115:12:19",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transactions": {
|
||||
"declaration": 1834,
|
||||
"declaration": 3170,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1249:12:17",
|
||||
"src": "1249:12:19",
|
||||
"valueSize": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": 1837,
|
||||
"id": 3173,
|
||||
"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:17"
|
||||
"src": "827:848:19"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": "@dev Sends multiple transactions and reverts all if one fails.\n @param transactions Encoded transactions. Each transaction is encoded as a \n tuple(operation,address,uint256,bytes), where operation \n can be 0 for a call or 1 for a delegatecall. The bytes \n of all encoded transactions are concatenated to form the input.",
|
||||
"id": 1839,
|
||||
"id": 3175,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
|
@ -298,16 +298,16 @@
|
|||
"name": "multiSend",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 1835,
|
||||
"id": 3171,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 1834,
|
||||
"id": 3170,
|
||||
"name": "transactions",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 1839,
|
||||
"src": "714:18:17",
|
||||
"scope": 3175,
|
||||
"src": "714:18:19",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
|
@ -315,10 +315,10 @@
|
|||
"typeString": "bytes"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 1833,
|
||||
"id": 3169,
|
||||
"name": "bytes",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "714:5:17",
|
||||
"src": "714:5:19",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_storage_ptr",
|
||||
"typeString": "bytes"
|
||||
|
@ -328,27 +328,27 @@
|
|||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "713:20:17"
|
||||
"src": "713:20:19"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 1836,
|
||||
"id": 3172,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "753:0:17"
|
||||
"src": "753:0:19"
|
||||
},
|
||||
"scope": 1840,
|
||||
"src": "695:980:17",
|
||||
"scope": 3176,
|
||||
"src": "695:980:19",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 1841,
|
||||
"src": "253:1424:17"
|
||||
"scope": 3177,
|
||||
"src": "253:1424:19"
|
||||
}
|
||||
],
|
||||
"src": "0:1678:17"
|
||||
"src": "0:1678:19"
|
||||
},
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
|
@ -358,28 +358,16 @@
|
|||
"4": {
|
||||
"events": {},
|
||||
"links": {},
|
||||
"address": "0xe94c33a523bf201e412f601eff906eec0b1d21f5",
|
||||
"transactionHash": "0x1f04811d6fb97329f6e96a579587fe5a3abe9fe2f202d4b2e27adb78d3de1c48"
|
||||
"address": "0x7115893bc1477bc22f127bc2d82fcb4dd99e5838",
|
||||
"transactionHash": "0x1f321cf880f5ec5b189cb1ac1c1c1b71ef8d854fc059c345fea6e6129bb19645"
|
||||
},
|
||||
"1529327661534": {
|
||||
"1530013596495": {
|
||||
"events": {},
|
||||
"links": {},
|
||||
"address": "0xa2a1eb294e1191c1e374f9015a37db35c49e9f26",
|
||||
"transactionHash": "0x5cd2551fce05a8b864a085616ee54449fdddd56dcdebf1019bebd0839c69ef5f"
|
||||
},
|
||||
"1529333415702": {
|
||||
"events": {},
|
||||
"links": {},
|
||||
"address": "0xaba1a0da223a2a5e04158bd80b2af7671e27e2c6",
|
||||
"transactionHash": "0x6e7c0c3947a3a851738677ae63915781ce79fdfb0453030fc63bbcd346f2cf89"
|
||||
},
|
||||
"1529652204341": {
|
||||
"events": {},
|
||||
"links": {},
|
||||
"address": "0x2013688de17569d52fc4cd4fe5f18821d8b32b2a",
|
||||
"transactionHash": "0x2d7f72a94ced345c372040faa1f51a51f3e8da27a02dd04b9eefef487de3ba05"
|
||||
"address": "0x18a8eaa498a58752858e5a912c8ff136b0bc6c69",
|
||||
"transactionHash": "0x7da393438ee13b991e6d94278addb64e86b0c13101efb8a0f0f00d9f86ba51d0"
|
||||
}
|
||||
},
|
||||
"schemaVersion": "2.0.0",
|
||||
"updatedAt": "2018-06-22T07:24:16.274Z"
|
||||
"updatedAt": "2018-06-29T10:54:03.255Z"
|
||||
}
|
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
|
@ -0,0 +1,783 @@
|
|||
{
|
||||
"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:-;;;;;",
|
||||
"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",
|
||||
"ast": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SecuredTokenTransfer.sol",
|
||||
"exportedSymbols": {
|
||||
"SecuredTokenTransfer": [
|
||||
3048
|
||||
]
|
||||
},
|
||||
"id": 3049,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 3025,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:15"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"documentation": "@title SecuredTokenTransfer - Secure token transfer\n @author Richard Meissner - <richard@gnosis.pm>",
|
||||
"fullyImplemented": true,
|
||||
"id": 3048,
|
||||
"linearizedBaseContracts": [
|
||||
3048
|
||||
],
|
||||
"name": "SecuredTokenTransfer",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 3046,
|
||||
"nodeType": "Block",
|
||||
"src": "590:592:15",
|
||||
"statements": [
|
||||
{
|
||||
"assignments": [
|
||||
3037
|
||||
],
|
||||
"declarations": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 3037,
|
||||
"name": "data",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 3047,
|
||||
"src": "600:17:15",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "memory",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_memory_ptr",
|
||||
"typeString": "bytes"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 3036,
|
||||
"name": "bytes",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "600:5:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_storage_ptr",
|
||||
"typeString": "bytes"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"id": 3044,
|
||||
"initialValue": {
|
||||
"argumentTypes": null,
|
||||
"arguments": [
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"hexValue": "7472616e7366657228616464726573732c75696e7432353629",
|
||||
"id": 3040,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "string",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "644:27:15",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_stringliteral_a9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b",
|
||||
"typeString": "literal_string \"transfer(address,uint256)\""
|
||||
},
|
||||
"value": "transfer(address,uint256)"
|
||||
},
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"id": 3041,
|
||||
"name": "receiver",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 3029,
|
||||
"src": "673:8:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"id": 3042,
|
||||
"name": "amount",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 3031,
|
||||
"src": "683:6:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
}
|
||||
],
|
||||
"expression": {
|
||||
"argumentTypes": [
|
||||
{
|
||||
"typeIdentifier": "t_stringliteral_a9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b",
|
||||
"typeString": "literal_string \"transfer(address,uint256)\""
|
||||
},
|
||||
{
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
},
|
||||
{
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
],
|
||||
"expression": {
|
||||
"argumentTypes": null,
|
||||
"id": 3038,
|
||||
"name": "abi",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 4023,
|
||||
"src": "620:3:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_magic_abi",
|
||||
"typeString": "abi"
|
||||
}
|
||||
},
|
||||
"id": 3039,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"lValueRequested": false,
|
||||
"memberName": "encodeWithSignature",
|
||||
"nodeType": "MemberAccess",
|
||||
"referencedDeclaration": null,
|
||||
"src": "620:23:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$",
|
||||
"typeString": "function (string memory) pure returns (bytes memory)"
|
||||
}
|
||||
},
|
||||
"id": 3043,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
"kind": "functionCall",
|
||||
"lValueRequested": false,
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "620:70:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_memory_ptr",
|
||||
"typeString": "bytes memory"
|
||||
}
|
||||
},
|
||||
"nodeType": "VariableDeclarationStatement",
|
||||
"src": "600:90:15"
|
||||
},
|
||||
{
|
||||
"externalReferences": [
|
||||
{
|
||||
"transferred": {
|
||||
"declaration": 3034,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1061:11:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"declaration": 3037,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "857:4:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"token": {
|
||||
"declaration": 3027,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "824:5:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"declaration": 3037,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "838:4:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transferred": {
|
||||
"declaration": 3034,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1012:11:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transferred": {
|
||||
"declaration": 3034,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1148:11:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": 3045,
|
||||
"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"
|
||||
}
|
||||
]
|
||||
},
|
||||
"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": 3047,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
"modifiers": [],
|
||||
"name": "transferToken",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 3032,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 3027,
|
||||
"name": "token",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 3047,
|
||||
"src": "463:13:15",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 3026,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "463:7:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 3029,
|
||||
"name": "receiver",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 3047,
|
||||
"src": "487:16:15",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 3028,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "487:7:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 3031,
|
||||
"name": "amount",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 3047,
|
||||
"src": "513:14:15",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 3030,
|
||||
"name": "uint256",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "513:7:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "453:80:15"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 3035,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 3034,
|
||||
"name": "transferred",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 3047,
|
||||
"src": "568:16:15",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 3033,
|
||||
"name": "bool",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "568:4:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "567:18:15"
|
||||
},
|
||||
"scope": 3048,
|
||||
"src": "430:752:15",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"scope": 3049,
|
||||
"src": "133:1051:15"
|
||||
}
|
||||
],
|
||||
"src": "0:1185:15"
|
||||
},
|
||||
"legacyAST": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SecuredTokenTransfer.sol",
|
||||
"exportedSymbols": {
|
||||
"SecuredTokenTransfer": [
|
||||
3048
|
||||
]
|
||||
},
|
||||
"id": 3049,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 3025,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:15"
|
||||
},
|
||||
{
|
||||
"baseContracts": [],
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"documentation": "@title SecuredTokenTransfer - Secure token transfer\n @author Richard Meissner - <richard@gnosis.pm>",
|
||||
"fullyImplemented": true,
|
||||
"id": 3048,
|
||||
"linearizedBaseContracts": [
|
||||
3048
|
||||
],
|
||||
"name": "SecuredTokenTransfer",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 3046,
|
||||
"nodeType": "Block",
|
||||
"src": "590:592:15",
|
||||
"statements": [
|
||||
{
|
||||
"assignments": [
|
||||
3037
|
||||
],
|
||||
"declarations": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 3037,
|
||||
"name": "data",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 3047,
|
||||
"src": "600:17:15",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "memory",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_memory_ptr",
|
||||
"typeString": "bytes"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 3036,
|
||||
"name": "bytes",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "600:5:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_storage_ptr",
|
||||
"typeString": "bytes"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"id": 3044,
|
||||
"initialValue": {
|
||||
"argumentTypes": null,
|
||||
"arguments": [
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"hexValue": "7472616e7366657228616464726573732c75696e7432353629",
|
||||
"id": 3040,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "string",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "644:27:15",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_stringliteral_a9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b",
|
||||
"typeString": "literal_string \"transfer(address,uint256)\""
|
||||
},
|
||||
"value": "transfer(address,uint256)"
|
||||
},
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"id": 3041,
|
||||
"name": "receiver",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 3029,
|
||||
"src": "673:8:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"id": 3042,
|
||||
"name": "amount",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 3031,
|
||||
"src": "683:6:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
}
|
||||
],
|
||||
"expression": {
|
||||
"argumentTypes": [
|
||||
{
|
||||
"typeIdentifier": "t_stringliteral_a9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b",
|
||||
"typeString": "literal_string \"transfer(address,uint256)\""
|
||||
},
|
||||
{
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
},
|
||||
{
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
],
|
||||
"expression": {
|
||||
"argumentTypes": null,
|
||||
"id": 3038,
|
||||
"name": "abi",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 4023,
|
||||
"src": "620:3:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_magic_abi",
|
||||
"typeString": "abi"
|
||||
}
|
||||
},
|
||||
"id": 3039,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"lValueRequested": false,
|
||||
"memberName": "encodeWithSignature",
|
||||
"nodeType": "MemberAccess",
|
||||
"referencedDeclaration": null,
|
||||
"src": "620:23:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_function_abiencodewithsignature_pure$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$",
|
||||
"typeString": "function (string memory) pure returns (bytes memory)"
|
||||
}
|
||||
},
|
||||
"id": 3043,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
"kind": "functionCall",
|
||||
"lValueRequested": false,
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "620:70:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bytes_memory_ptr",
|
||||
"typeString": "bytes memory"
|
||||
}
|
||||
},
|
||||
"nodeType": "VariableDeclarationStatement",
|
||||
"src": "600:90:15"
|
||||
},
|
||||
{
|
||||
"externalReferences": [
|
||||
{
|
||||
"transferred": {
|
||||
"declaration": 3034,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1061:11:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"declaration": 3037,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "857:4:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"token": {
|
||||
"declaration": 3027,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "824:5:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"declaration": 3037,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "838:4:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transferred": {
|
||||
"declaration": 3034,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1012:11:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"transferred": {
|
||||
"declaration": 3034,
|
||||
"isOffset": false,
|
||||
"isSlot": false,
|
||||
"src": "1148:11:15",
|
||||
"valueSize": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": 3045,
|
||||
"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"
|
||||
}
|
||||
]
|
||||
},
|
||||
"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": 3047,
|
||||
"implemented": true,
|
||||
"isConstructor": false,
|
||||
"isDeclaredConst": false,
|
||||
"modifiers": [],
|
||||
"name": "transferToken",
|
||||
"nodeType": "FunctionDefinition",
|
||||
"parameters": {
|
||||
"id": 3032,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 3027,
|
||||
"name": "token",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 3047,
|
||||
"src": "463:13:15",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 3026,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "463:7:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 3029,
|
||||
"name": "receiver",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 3047,
|
||||
"src": "487:16:15",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 3028,
|
||||
"name": "address",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "487:7:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"id": 3031,
|
||||
"name": "amount",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 3047,
|
||||
"src": "513:14:15",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 3030,
|
||||
"name": "uint256",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "513:7:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "453:80:15"
|
||||
},
|
||||
"payable": false,
|
||||
"returnParameters": {
|
||||
"id": 3035,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [
|
||||
{
|
||||
"constant": false,
|
||||
"id": 3034,
|
||||
"name": "transferred",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 3047,
|
||||
"src": "568:16:15",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
},
|
||||
"typeName": {
|
||||
"id": 3033,
|
||||
"name": "bool",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "568:4:15",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
}
|
||||
},
|
||||
"value": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"src": "567:18:15"
|
||||
},
|
||||
"scope": 3048,
|
||||
"src": "430:752:15",
|
||||
"stateMutability": "nonpayable",
|
||||
"superFunction": null,
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"scope": 3049,
|
||||
"src": "133:1051:15"
|
||||
}
|
||||
],
|
||||
"src": "0:1185:15"
|
||||
},
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
"version": "0.4.24+commit.e67f0147.Emscripten.clang"
|
||||
},
|
||||
"networks": {},
|
||||
"schemaVersion": "2.0.0",
|
||||
"updatedAt": "2018-06-29T09:01:22.084Z"
|
||||
}
|
|
@ -3,29 +3,29 @@
|
|||
"abi": [],
|
||||
"bytecode": "0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a72305820ec80f1b4520aa5197e4181778f1e2e4fc460002d4a40e2e8e6709c8986067c220029",
|
||||
"deployedBytecode": "0x6080604052600080fd00a165627a7a72305820ec80f1b4520aa5197e4181778f1e2e4fc460002d4a40e2e8e6709c8986067c220029",
|
||||
"sourceMap": "152:166:8:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;152:166:8;;;;;;;",
|
||||
"deployedSourceMap": "152:166:8:-;;;;;",
|
||||
"sourceMap": "152:166:16:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;152:166:16;;;;;;;",
|
||||
"deployedSourceMap": "152:166:16:-;;;;;",
|
||||
"source": "pragma solidity 0.4.24;\n\n\n/// @title SelfAuthorized - authorizes current contract to perform actions\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract SelfAuthorized {\n modifier authorized() {\n require(msg.sender == address(this), \"Method can only be called from this contract\");\n _;\n }\n}\n",
|
||||
"sourcePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
|
||||
"ast": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
|
||||
"exportedSymbols": {
|
||||
"SelfAuthorized": [
|
||||
1449
|
||||
3065
|
||||
]
|
||||
},
|
||||
"id": 1450,
|
||||
"id": 3066,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1434,
|
||||
"id": 3050,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:8"
|
||||
"src": "0:23:16"
|
||||
},
|
||||
{
|
||||
"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": 1449,
|
||||
"id": 3065,
|
||||
"linearizedBaseContracts": [
|
||||
1449
|
||||
3065
|
||||
],
|
||||
"name": "SelfAuthorized",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 1447,
|
||||
"id": 3063,
|
||||
"nodeType": "Block",
|
||||
"src": "204:112:8",
|
||||
"src": "204:112:16",
|
||||
"statements": [
|
||||
{
|
||||
"expression": {
|
||||
|
@ -56,7 +56,7 @@
|
|||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
},
|
||||
"id": 1442,
|
||||
"id": 3058,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -65,18 +65,18 @@
|
|||
"argumentTypes": null,
|
||||
"expression": {
|
||||
"argumentTypes": null,
|
||||
"id": 1437,
|
||||
"id": 3053,
|
||||
"name": "msg",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 1773,
|
||||
"src": "222:3:8",
|
||||
"referencedDeclaration": 4036,
|
||||
"src": "222:3:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_magic_message",
|
||||
"typeString": "msg"
|
||||
}
|
||||
},
|
||||
"id": 1438,
|
||||
"id": 3054,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -84,7 +84,7 @@
|
|||
"memberName": "sender",
|
||||
"nodeType": "MemberAccess",
|
||||
"referencedDeclaration": null,
|
||||
"src": "222:10:8",
|
||||
"src": "222:10:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -97,14 +97,14 @@
|
|||
"arguments": [
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"id": 1440,
|
||||
"id": 3056,
|
||||
"name": "this",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 1788,
|
||||
"src": "244:4:8",
|
||||
"referencedDeclaration": 4055,
|
||||
"src": "244:4:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1449",
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$3065",
|
||||
"typeString": "contract SelfAuthorized"
|
||||
}
|
||||
}
|
||||
|
@ -112,24 +112,24 @@
|
|||
"expression": {
|
||||
"argumentTypes": [
|
||||
{
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1449",
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$3065",
|
||||
"typeString": "contract SelfAuthorized"
|
||||
}
|
||||
],
|
||||
"id": 1439,
|
||||
"id": 3055,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"lValueRequested": false,
|
||||
"nodeType": "ElementaryTypeNameExpression",
|
||||
"src": "236:7:8",
|
||||
"src": "236:7:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_type$_t_address_$",
|
||||
"typeString": "type(address)"
|
||||
},
|
||||
"typeName": "address"
|
||||
},
|
||||
"id": 1441,
|
||||
"id": 3057,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -137,13 +137,13 @@
|
|||
"lValueRequested": false,
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "236:13:8",
|
||||
"src": "236:13:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"src": "222:27:8",
|
||||
"src": "222:27:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
|
@ -152,14 +152,14 @@
|
|||
{
|
||||
"argumentTypes": null,
|
||||
"hexValue": "4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207468697320636f6e7472616374",
|
||||
"id": 1443,
|
||||
"id": 3059,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "string",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "251:46:8",
|
||||
"src": "251:46:16",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_stringliteral_c4780ef0a1d41d59bac8c510cf9ada421bccf2b90f75a8e4ba2e8c09e8d72733",
|
||||
|
@ -179,21 +179,21 @@
|
|||
"typeString": "literal_string \"Method can only be called from this contract\""
|
||||
}
|
||||
],
|
||||
"id": 1436,
|
||||
"id": 3052,
|
||||
"name": "require",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [
|
||||
1776,
|
||||
1777
|
||||
4039,
|
||||
4040
|
||||
],
|
||||
"referencedDeclaration": 1777,
|
||||
"src": "214:7:8",
|
||||
"referencedDeclaration": 4040,
|
||||
"src": "214:7:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
|
||||
"typeString": "function (bool,string memory) pure"
|
||||
}
|
||||
},
|
||||
"id": 1444,
|
||||
"id": 3060,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -201,62 +201,62 @@
|
|||
"lValueRequested": false,
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "214:84:8",
|
||||
"src": "214:84:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_tuple$__$",
|
||||
"typeString": "tuple()"
|
||||
}
|
||||
},
|
||||
"id": 1445,
|
||||
"id": 3061,
|
||||
"nodeType": "ExpressionStatement",
|
||||
"src": "214:84:8"
|
||||
"src": "214:84:16"
|
||||
},
|
||||
{
|
||||
"id": 1446,
|
||||
"id": 3062,
|
||||
"nodeType": "PlaceholderStatement",
|
||||
"src": "308:1:8"
|
||||
"src": "308:1:16"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": null,
|
||||
"id": 1448,
|
||||
"id": 3064,
|
||||
"name": "authorized",
|
||||
"nodeType": "ModifierDefinition",
|
||||
"parameters": {
|
||||
"id": 1435,
|
||||
"id": 3051,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "201:2:8"
|
||||
"src": "201:2:16"
|
||||
},
|
||||
"src": "182:134:8",
|
||||
"src": "182:134:16",
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"scope": 1450,
|
||||
"src": "152:166:8"
|
||||
"scope": 3066,
|
||||
"src": "152:166:16"
|
||||
}
|
||||
],
|
||||
"src": "0:319:8"
|
||||
"src": "0:319:16"
|
||||
},
|
||||
"legacyAST": {
|
||||
"absolutePath": "/Users/apanizo/git/gnosis/safe-contracts/contracts/SelfAuthorized.sol",
|
||||
"exportedSymbols": {
|
||||
"SelfAuthorized": [
|
||||
1449
|
||||
3065
|
||||
]
|
||||
},
|
||||
"id": 1450,
|
||||
"id": 3066,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1434,
|
||||
"id": 3050,
|
||||
"literals": [
|
||||
"solidity",
|
||||
"0.4",
|
||||
".24"
|
||||
],
|
||||
"nodeType": "PragmaDirective",
|
||||
"src": "0:23:8"
|
||||
"src": "0:23:16"
|
||||
},
|
||||
{
|
||||
"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": 1449,
|
||||
"id": 3065,
|
||||
"linearizedBaseContracts": [
|
||||
1449
|
||||
3065
|
||||
],
|
||||
"name": "SelfAuthorized",
|
||||
"nodeType": "ContractDefinition",
|
||||
"nodes": [
|
||||
{
|
||||
"body": {
|
||||
"id": 1447,
|
||||
"id": 3063,
|
||||
"nodeType": "Block",
|
||||
"src": "204:112:8",
|
||||
"src": "204:112:16",
|
||||
"statements": [
|
||||
{
|
||||
"expression": {
|
||||
|
@ -287,7 +287,7 @@
|
|||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
},
|
||||
"id": 1442,
|
||||
"id": 3058,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -296,18 +296,18 @@
|
|||
"argumentTypes": null,
|
||||
"expression": {
|
||||
"argumentTypes": null,
|
||||
"id": 1437,
|
||||
"id": 3053,
|
||||
"name": "msg",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 1773,
|
||||
"src": "222:3:8",
|
||||
"referencedDeclaration": 4036,
|
||||
"src": "222:3:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_magic_message",
|
||||
"typeString": "msg"
|
||||
}
|
||||
},
|
||||
"id": 1438,
|
||||
"id": 3054,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -315,7 +315,7 @@
|
|||
"memberName": "sender",
|
||||
"nodeType": "MemberAccess",
|
||||
"referencedDeclaration": null,
|
||||
"src": "222:10:8",
|
||||
"src": "222:10:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
|
@ -328,14 +328,14 @@
|
|||
"arguments": [
|
||||
{
|
||||
"argumentTypes": null,
|
||||
"id": 1440,
|
||||
"id": 3056,
|
||||
"name": "this",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 1788,
|
||||
"src": "244:4:8",
|
||||
"referencedDeclaration": 4055,
|
||||
"src": "244:4:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1449",
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$3065",
|
||||
"typeString": "contract SelfAuthorized"
|
||||
}
|
||||
}
|
||||
|
@ -343,24 +343,24 @@
|
|||
"expression": {
|
||||
"argumentTypes": [
|
||||
{
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$1449",
|
||||
"typeIdentifier": "t_contract$_SelfAuthorized_$3065",
|
||||
"typeString": "contract SelfAuthorized"
|
||||
}
|
||||
],
|
||||
"id": 1439,
|
||||
"id": 3055,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"lValueRequested": false,
|
||||
"nodeType": "ElementaryTypeNameExpression",
|
||||
"src": "236:7:8",
|
||||
"src": "236:7:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_type$_t_address_$",
|
||||
"typeString": "type(address)"
|
||||
},
|
||||
"typeName": "address"
|
||||
},
|
||||
"id": 1441,
|
||||
"id": 3057,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -368,13 +368,13 @@
|
|||
"lValueRequested": false,
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "236:13:8",
|
||||
"src": "236:13:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_address",
|
||||
"typeString": "address"
|
||||
}
|
||||
},
|
||||
"src": "222:27:8",
|
||||
"src": "222:27:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_bool",
|
||||
"typeString": "bool"
|
||||
|
@ -383,14 +383,14 @@
|
|||
{
|
||||
"argumentTypes": null,
|
||||
"hexValue": "4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d207468697320636f6e7472616374",
|
||||
"id": 1443,
|
||||
"id": 3059,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "string",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "251:46:8",
|
||||
"src": "251:46:16",
|
||||
"subdenomination": null,
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_stringliteral_c4780ef0a1d41d59bac8c510cf9ada421bccf2b90f75a8e4ba2e8c09e8d72733",
|
||||
|
@ -410,21 +410,21 @@
|
|||
"typeString": "literal_string \"Method can only be called from this contract\""
|
||||
}
|
||||
],
|
||||
"id": 1436,
|
||||
"id": 3052,
|
||||
"name": "require",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [
|
||||
1776,
|
||||
1777
|
||||
4039,
|
||||
4040
|
||||
],
|
||||
"referencedDeclaration": 1777,
|
||||
"src": "214:7:8",
|
||||
"referencedDeclaration": 4040,
|
||||
"src": "214:7:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
|
||||
"typeString": "function (bool,string memory) pure"
|
||||
}
|
||||
},
|
||||
"id": 1444,
|
||||
"id": 3060,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
|
@ -432,42 +432,42 @@
|
|||
"lValueRequested": false,
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "214:84:8",
|
||||
"src": "214:84:16",
|
||||
"typeDescriptions": {
|
||||
"typeIdentifier": "t_tuple$__$",
|
||||
"typeString": "tuple()"
|
||||
}
|
||||
},
|
||||
"id": 1445,
|
||||
"id": 3061,
|
||||
"nodeType": "ExpressionStatement",
|
||||
"src": "214:84:8"
|
||||
"src": "214:84:16"
|
||||
},
|
||||
{
|
||||
"id": 1446,
|
||||
"id": 3062,
|
||||
"nodeType": "PlaceholderStatement",
|
||||
"src": "308:1:8"
|
||||
"src": "308:1:16"
|
||||
}
|
||||
]
|
||||
},
|
||||
"documentation": null,
|
||||
"id": 1448,
|
||||
"id": 3064,
|
||||
"name": "authorized",
|
||||
"nodeType": "ModifierDefinition",
|
||||
"parameters": {
|
||||
"id": 1435,
|
||||
"id": 3051,
|
||||
"nodeType": "ParameterList",
|
||||
"parameters": [],
|
||||
"src": "201:2:8"
|
||||
"src": "201:2:16"
|
||||
},
|
||||
"src": "182:134:8",
|
||||
"src": "182:134:16",
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"scope": 1450,
|
||||
"src": "152:166:8"
|
||||
"scope": 3066,
|
||||
"src": "152:166:16"
|
||||
}
|
||||
],
|
||||
"src": "0:319:8"
|
||||
"src": "0:319:16"
|
||||
},
|
||||
"compiler": {
|
||||
"name": "solc",
|
||||
|
@ -475,5 +475,5 @@
|
|||
},
|
||||
"networks": {},
|
||||
"schemaVersion": "2.0.0",
|
||||
"updatedAt": "2018-06-20T07:57:27.027Z"
|
||||
"updatedAt": "2018-06-29T09:01:22.084Z"
|
||||
}
|
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
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Ebene_7" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||
<g id="ZWC4wa.tif">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M13.5,26c3.7-6.1,7.2-12,11.1-18.4C28.3,14,31.9,19.9,35.6,26c-3.7,2.2-7.4,4.4-11.1,6.6C20.9,30.4,17.2,28.2,13.5,26z
|
||||
M25.1,20.8c2.7,1.2,5.4,2.5,8.5,3.9c-2.9-4.8-5.6-9.3-8.5-14.1C25.1,14.2,25.1,17.4,25.1,20.8z M15.5,24.7
|
||||
c3.1-1.4,5.8-2.7,8.4-3.8c0-3.4,0-6.6,0-10.2C21,15.4,18.4,19.9,15.5,24.7z M33.8,25.9c-3-1.4-5.8-2.6-8.7-3.9c0,3.1,0,6,0,9.1
|
||||
C28,29.3,30.8,27.7,33.8,25.9z M23.9,22c-3,1.4-5.7,2.6-8.6,3.9c3,1.8,5.8,3.4,8.6,5.1C23.9,27.9,23.9,25,23.9,22z"/>
|
||||
<path d="M24.5,33.3c3.5-2,6.9-4,12.1-7.1c-4.9,6.9-8.4,11.8-12.1,17.1C20.8,38,17.2,33,12.4,26.2C17.8,29.4,21.2,31.4,24.5,33.3z
|
||||
M25.1,40.7c2.7-3.8,5.1-7.3,7.9-11.2c-3,1.8-5.5,3.3-7.9,4.7C25.1,36.4,25.1,38.4,25.1,40.7z M23.9,34.2
|
||||
c-2.4-1.4-4.9-2.9-7.9-4.7c2.8,4,5.2,7.4,7.9,11.1C23.9,38.3,23.9,36.4,23.9,34.2z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -4,7 +4,6 @@ import FormStep from '@material-ui/core/Step'
|
|||
import StepLabel from '@material-ui/core/StepLabel'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import * as React from 'react'
|
||||
import type { FormApi } from 'react-final-form'
|
||||
import GnoForm from '~/components/forms/GnoForm'
|
||||
import Button from '~/components/layout/Button'
|
||||
import Col from '~/components/layout/Col'
|
||||
|
@ -21,7 +20,7 @@ type Props = {
|
|||
initialValues?: Object,
|
||||
children: React$Node,
|
||||
onReset?: () => void,
|
||||
onSubmit: (values: Object, form: FormApi, callback: ?(errors: ?Object) => void) => ?Object | Promise<?Object> | void,
|
||||
onSubmit: (values: Object) => Promise<void>,
|
||||
}
|
||||
|
||||
type State = {
|
||||
|
|
|
@ -3,12 +3,14 @@ import * as React from 'react'
|
|||
import { type FormApi } from 'final-form'
|
||||
import { Form } from 'react-final-form'
|
||||
|
||||
export type OnSubmit = (
|
||||
values: Object,
|
||||
form: FormApi,
|
||||
callback: ?(errors: ?Object) => ?Object
|
||||
) => ?Object | Promise<?Object> | void
|
||||
|
||||
type Props = {
|
||||
onSubmit: (
|
||||
values: Object,
|
||||
form: FormApi,
|
||||
callback: ?(errors: ?Object) => ?Object
|
||||
) => ?Object | Promise<?Object> | void,
|
||||
onSubmit: OnSubmit,
|
||||
children: Function,
|
||||
padding: number,
|
||||
validation?: (values: Object) => Object | Promise<Object>,
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
// @flow
|
||||
import { getWeb3 } from '~/wallets/getWeb3'
|
||||
import { type FieldValidator } from 'final-form'
|
||||
|
||||
type Field = boolean | string
|
||||
type Field = boolean | string | null | typeof undefined
|
||||
|
||||
export const required = (value: Field) => (value ? undefined : 'Required')
|
||||
|
||||
|
@ -48,7 +49,7 @@ export const ADDRESS_REPEATED_ERROR = 'Address already introduced'
|
|||
export const uniqueAddress = (addresses: string[]) => (value: string) =>
|
||||
(addresses.includes(value) ? ADDRESS_REPEATED_ERROR : undefined)
|
||||
|
||||
export const composeValidators = (...validators: Function[]) => (value: Field) =>
|
||||
export const composeValidators = (...validators: Function[]): FieldValidator => (value: Field) =>
|
||||
validators.reduce((error, validator) => error || validator(value), undefined)
|
||||
|
||||
export const inLimit = (limit: number, base: number, baseText: string) => (value: string) => {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import type { FormApi } from 'react-final-form'
|
||||
import Stepper from '~/components/Stepper'
|
||||
import Confirmation from '~/routes/open/components/FormConfirmation'
|
||||
import Review from '~/routes/open/components/ReviewInformation'
|
||||
|
@ -21,8 +20,7 @@ type Props = {
|
|||
userAccount: string,
|
||||
safeAddress: string,
|
||||
safeTx: string,
|
||||
onCallSafeContractSubmit: (values: Object, form: FormApi, callback: ?(errors: ?Object) => void)
|
||||
=> ?Object | Promise<?Object> | void,
|
||||
onCallSafeContractSubmit: (values: Object) => Promise<void>,
|
||||
}
|
||||
|
||||
const Layout = ({
|
||||
|
|
|
@ -26,7 +26,7 @@ storiesOf('Routes /open', module)
|
|||
getProviderInfo()
|
||||
const provider = 'METAMASK'
|
||||
const userAccount = '0x03db1a8b26d08df23337e9276a36b474510f0023'
|
||||
const onCallSafeContractSubmit = async (values: Object) => {
|
||||
const onCallSafeContractSubmit = async (values: Object): Promise<void> => {
|
||||
const accounts = getAccountsFrom(values)
|
||||
const numConfirmations = getThresholdFrom(values)
|
||||
const data = {
|
||||
|
|
|
@ -8,7 +8,7 @@ import { getProviderInfo } from '~/wallets/getWeb3'
|
|||
import Wrapper from '~/test/utils/Wrapper'
|
||||
import { CONFIRMATIONS_ERROR } from '~/routes/open/components/SafeForm'
|
||||
|
||||
const obSubmitMock = () => {}
|
||||
const onSubmitMock = async (): Promise<void> => {}
|
||||
|
||||
describe('React DOM TESTS > Create Safe form', () => {
|
||||
let open
|
||||
|
@ -25,7 +25,7 @@ describe('React DOM TESTS > Create Safe form', () => {
|
|||
userAccount="foo"
|
||||
safeAddress=""
|
||||
safeTx=""
|
||||
onCallSafeContractSubmit={obSubmitMock}
|
||||
onCallSafeContractSubmit={onSubmitMock}
|
||||
/>
|
||||
</Wrapper>
|
||||
))
|
||||
|
|
|
@ -16,12 +16,12 @@ type Props = Actions & {
|
|||
userAccount: string,
|
||||
}
|
||||
|
||||
type State = {
|
||||
export type OpenState = {
|
||||
safeAddress: string,
|
||||
safeTx: string,
|
||||
}
|
||||
|
||||
const createSafe = async (values: Object, userAccount: string, addSafe: AddSafe): Promise<State> => {
|
||||
export const createSafe = async (values: Object, userAccount: string, addSafe: AddSafe): Promise<OpenState> => {
|
||||
const accounts = getAccountsFrom(values)
|
||||
const numConfirmations = getThresholdFrom(values)
|
||||
const name = getSafeNameFrom(values)
|
||||
|
@ -43,7 +43,7 @@ const createSafe = async (values: Object, userAccount: string, addSafe: AddSafe)
|
|||
return { safeAddress: safeContract.address, safeTx: safe }
|
||||
}
|
||||
|
||||
class Open extends React.Component<Props, State> {
|
||||
class Open extends React.Component<Props, OpenState> {
|
||||
constructor() {
|
||||
super()
|
||||
|
||||
|
|
|
@ -7,11 +7,11 @@ import GnoSafe from './Safe'
|
|||
type Props = SelectorProps
|
||||
|
||||
const Layout = ({
|
||||
safe, balance, provider, userAddress,
|
||||
safe, balances, provider, userAddress,
|
||||
}: Props) => (
|
||||
<React.Fragment>
|
||||
{ safe
|
||||
? <GnoSafe safe={safe} balance={balance} userAddress={userAddress} />
|
||||
? <GnoSafe safe={safe} balances={balances} userAddress={userAddress} />
|
||||
: <NoSafe provider={provider} text="Not found safe" />
|
||||
}
|
||||
</React.Fragment>
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
// @flow
|
||||
import { storiesOf } from '@storybook/react'
|
||||
import * as React from 'react'
|
||||
import { Map } from 'immutable'
|
||||
import styles from '~/components/layout/PageFrame/index.scss'
|
||||
import { SafeFactory } from '~/routes/safe/store/test/builder/safe.builder'
|
||||
import { makeBalance } from '~/routes/safe/store/model/balance'
|
||||
import Component from './Layout'
|
||||
|
||||
|
||||
|
@ -12,6 +14,15 @@ const FrameDecorator = story => (
|
|||
</div>
|
||||
)
|
||||
|
||||
const ethBalance = makeBalance({
|
||||
address: '0',
|
||||
name: 'Ether',
|
||||
symbol: 'ETH',
|
||||
decimals: 18,
|
||||
logoUrl: 'assets/icons/icon_etherTokens.svg',
|
||||
funds: '2',
|
||||
})
|
||||
|
||||
storiesOf('Routes /safe:address', module)
|
||||
.addDecorator(FrameDecorator)
|
||||
.add('Safe undefined being connected', () => (
|
||||
|
@ -19,7 +30,7 @@ storiesOf('Routes /safe:address', module)
|
|||
userAddress="foo"
|
||||
safe={undefined}
|
||||
provider="METAMASK"
|
||||
balance="0"
|
||||
balances={Map()}
|
||||
fetchBalance={() => {}}
|
||||
/>
|
||||
))
|
||||
|
@ -28,7 +39,7 @@ storiesOf('Routes /safe:address', module)
|
|||
userAddress="foo"
|
||||
safe={undefined}
|
||||
provider=""
|
||||
balance="0"
|
||||
balances={Map()}
|
||||
fetchBalance={() => {}}
|
||||
/>
|
||||
))
|
||||
|
@ -40,7 +51,7 @@ storiesOf('Routes /safe:address', module)
|
|||
userAddress="foo"
|
||||
safe={safe}
|
||||
provider="METAMASK"
|
||||
balance="2"
|
||||
balances={Map().set('ETH', ethBalance)}
|
||||
fetchBalance={() => {}}
|
||||
/>
|
||||
)
|
||||
|
@ -53,7 +64,7 @@ storiesOf('Routes /safe:address', module)
|
|||
userAddress="foo"
|
||||
safe={safe}
|
||||
provider="METAMASK"
|
||||
balance="2"
|
||||
balances={Map().set('ETH', ethBalance)}
|
||||
fetchBalance={() => {}}
|
||||
/>
|
||||
)
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import ListItem from '@material-ui/core/ListItem'
|
||||
import ListItemText from '@material-ui/core/ListItemText'
|
||||
import Avatar from '@material-ui/core/Avatar'
|
||||
import AccountBalance from '@material-ui/icons/AccountBalance'
|
||||
|
||||
type Props = {
|
||||
balance: string,
|
||||
}
|
||||
|
||||
const Balance = ({ balance }: Props) => (
|
||||
<ListItem>
|
||||
<Avatar>
|
||||
<AccountBalance />
|
||||
</Avatar>
|
||||
<ListItemText primary="Balance" secondary={`${balance} ETH`} />
|
||||
</ListItem>
|
||||
)
|
||||
|
||||
export default Balance
|
|
@ -0,0 +1,66 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import AccountBalance from '@material-ui/icons/AccountBalance'
|
||||
import Avatar from '@material-ui/core/Avatar'
|
||||
import Collapse from '@material-ui/core/Collapse'
|
||||
import IconButton from '@material-ui/core/IconButton'
|
||||
import List from '@material-ui/core/List'
|
||||
import Img from '~/components/layout/Img'
|
||||
import ListItem from '@material-ui/core/ListItem'
|
||||
import ListItemIcon from '@material-ui/core/ListItemIcon'
|
||||
import ListItemText from '@material-ui/core/ListItemText'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import ExpandLess from '@material-ui/icons/ExpandLess'
|
||||
import ExpandMore from '@material-ui/icons/ExpandMore'
|
||||
import { Map } from 'immutable'
|
||||
import openHoc, { type Open } from '~/components/hoc/OpenHoc'
|
||||
import { type WithStyles } from '~/theme/mui'
|
||||
import { type Balance } from '~/routes/safe/store/model/balance'
|
||||
|
||||
type Props = Open & WithStyles & {
|
||||
balances: Map<string, Balance>,
|
||||
}
|
||||
|
||||
const styles = {
|
||||
nested: {
|
||||
paddingLeft: '40px',
|
||||
},
|
||||
}
|
||||
|
||||
const BalanceComponent = openHoc(({
|
||||
open, toggle, balances, classes,
|
||||
}: Props) => (
|
||||
<React.Fragment>
|
||||
<ListItem onClick={toggle}>
|
||||
<Avatar>
|
||||
<AccountBalance />
|
||||
</Avatar>
|
||||
<ListItemText primary="Balance" secondary="List of different token balances" />
|
||||
<ListItemIcon>
|
||||
{open
|
||||
? <IconButton disableRipple><ExpandLess /></IconButton>
|
||||
: <IconButton disableRipple><ExpandMore /></IconButton>
|
||||
}
|
||||
</ListItemIcon>
|
||||
</ListItem>
|
||||
<Collapse in={open} timeout="auto">
|
||||
<List component="div" disablePadding>
|
||||
{balances.valueSeq().map((balance: Balance) => {
|
||||
const symbol = balance.get('symbol')
|
||||
const name = balance.get('name')
|
||||
|
||||
return (
|
||||
<ListItem key={symbol} className={classes.nested}>
|
||||
<ListItemIcon>
|
||||
<Img src={balance.get('logoUrl')} height={30} alt={name} />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={name} secondary={`${balance.get('funds')} ${symbol}`} />
|
||||
</ListItem>
|
||||
)
|
||||
})}
|
||||
</List>
|
||||
</Collapse>
|
||||
</React.Fragment>
|
||||
))
|
||||
|
||||
export default withStyles(styles)(BalanceComponent)
|
|
@ -11,7 +11,7 @@ type Props = {
|
|||
dailyLimit: DailyLimit,
|
||||
onWithdraw: () => void,
|
||||
onEditDailyLimit: () => void,
|
||||
balance: string,
|
||||
balance: number,
|
||||
}
|
||||
export const EDIT_WITHDRAW = 'Edit'
|
||||
export const WITHDRAW_BUTTON_TEXT = 'Withdraw'
|
||||
|
@ -26,7 +26,7 @@ const DailyLimitComponent = ({
|
|||
const limit = dailyLimit.get('value')
|
||||
const spentToday = dailyLimit.get('spentToday')
|
||||
|
||||
const disabled = spentToday >= limit || Number(balance) === 0
|
||||
const disabled = spentToday >= limit || balance === 0
|
||||
const text = `${limit} ETH (spent today: ${spentToday} ETH)`
|
||||
|
||||
return (
|
||||
|
|
|
@ -7,7 +7,7 @@ import Button from '~/components/layout/Button'
|
|||
import ListItemText from '~/components/List/ListItemText'
|
||||
|
||||
type Props = {
|
||||
balance: string,
|
||||
balance: number,
|
||||
onAddTx: () => void,
|
||||
onSeeTxs: () => void,
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ const addStyle = {
|
|||
|
||||
const DailyLimitComponent = ({ balance, onAddTx, onSeeTxs }: Props) => {
|
||||
const text = `Available ${balance} ETH`
|
||||
const disabled = Number(balance) <= 0
|
||||
const disabled = balance <= 0
|
||||
|
||||
return (
|
||||
<ListItem>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// @flow
|
||||
import List from '@material-ui/core/List'
|
||||
import * as React from 'react'
|
||||
import { Map } from 'immutable'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Bold from '~/components/layout/Bold'
|
||||
|
@ -7,7 +9,7 @@ import Img from '~/components/layout/Img'
|
|||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import Row from '~/components/layout/Row'
|
||||
import { type Safe } from '~/routes/safe/store/model/safe'
|
||||
import List from '@material-ui/core/List'
|
||||
import { type Balance } from '~/routes/safe/store/model/balance'
|
||||
|
||||
import Withdraw from '~/routes/safe/component/Withdraw'
|
||||
import Transactions from '~/routes/safe/component/Transactions'
|
||||
|
@ -18,7 +20,7 @@ import RemoveOwner from '~/routes/safe/component/RemoveOwner'
|
|||
import EditDailyLimit from '~/routes/safe/component/EditDailyLimit'
|
||||
|
||||
import Address from './Address'
|
||||
import Balance from './Balance'
|
||||
import BalanceInfo from './BalanceInfo'
|
||||
import Owners from './Owners'
|
||||
import Confirmations from './Confirmations'
|
||||
import DailyLimit from './DailyLimit'
|
||||
|
@ -28,7 +30,7 @@ const safeIcon = require('./assets/gnosis_safe.svg')
|
|||
|
||||
type SafeProps = {
|
||||
safe: Safe,
|
||||
balance: string,
|
||||
balances: Map<string, Balance>,
|
||||
userAddress: string,
|
||||
}
|
||||
|
||||
|
@ -40,6 +42,15 @@ const listStyle = {
|
|||
width: '100%',
|
||||
}
|
||||
|
||||
const getEthBalanceFrom = (balances: Map<string, Balance>) => {
|
||||
const ethBalance = balances.get('ETH')
|
||||
if (!ethBalance) {
|
||||
return 0
|
||||
}
|
||||
|
||||
return Number(ethBalance.get('funds'))
|
||||
}
|
||||
|
||||
class GnoSafe extends React.PureComponent<SafeProps, State> {
|
||||
state = {
|
||||
component: undefined,
|
||||
|
@ -59,9 +70,11 @@ class GnoSafe extends React.PureComponent<SafeProps, State> {
|
|||
}
|
||||
|
||||
onAddTx = () => {
|
||||
const { balance, safe } = this.props
|
||||
const { balances, safe } = this.props
|
||||
const ethBalance = getEthBalanceFrom(balances)
|
||||
|
||||
this.setState({
|
||||
component: <AddTransaction safe={safe} balance={Number(balance)} onReset={this.onListTransactions} />,
|
||||
component: <AddTransaction safe={safe} balance={Number(ethBalance)} onReset={this.onListTransactions} />,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -90,14 +103,15 @@ class GnoSafe extends React.PureComponent<SafeProps, State> {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { safe, balance, userAddress } = this.props
|
||||
const { safe, balances, userAddress } = this.props
|
||||
const { component } = this.state
|
||||
const ethBalance = getEthBalanceFrom(balances)
|
||||
|
||||
return (
|
||||
<Row grow>
|
||||
<Col sm={12} top="xs" md={5} margin="xl" overflow>
|
||||
<List style={listStyle}>
|
||||
<Balance balance={balance} />
|
||||
<BalanceInfo balances={balances} />
|
||||
<Owners
|
||||
owners={safe.owners}
|
||||
onAddOwner={this.onAddOwner}
|
||||
|
@ -106,8 +120,8 @@ class GnoSafe extends React.PureComponent<SafeProps, State> {
|
|||
/>
|
||||
<Confirmations confirmations={safe.get('threshold')} onEditThreshold={this.onEditThreshold} />
|
||||
<Address address={safe.get('address')} />
|
||||
<DailyLimit balance={balance} dailyLimit={safe.get('dailyLimit')} onWithdraw={this.onWithdraw} onEditDailyLimit={this.onEditDailyLimit} />
|
||||
<MultisigTx balance={balance} onAddTx={this.onAddTx} onSeeTxs={this.onListTransactions} />
|
||||
<DailyLimit balance={ethBalance} dailyLimit={safe.get('dailyLimit')} onWithdraw={this.onWithdraw} onEditDailyLimit={this.onEditDailyLimit} />
|
||||
<MultisigTx balance={ethBalance} onAddTx={this.onAddTx} onSeeTxs={this.onListTransactions} />
|
||||
</List>
|
||||
</Col>
|
||||
<Col sm={12} center="xs" md={7} margin="xl" layout="column">
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
// @flow
|
||||
import { List } from 'immutable'
|
||||
import { getWeb3 } from '~/wallets/getWeb3'
|
||||
import { getGnosisSafeContract, getCreateDailyLimitExtensionContract } from '~/wallets/safeContracts'
|
||||
import { type DailyLimitProps } from '~/routes/safe/store/model/dailyLimit'
|
||||
import { checkReceiptStatus, calculateGasOf, calculateGasPrice } from '~/wallets/ethTransactions'
|
||||
import { type Safe } from '~/routes/safe/store/model/safe'
|
||||
import { buildExecutedConfirmationFrom, storeTransaction } from '~/routes/safe/component/AddTransaction/createTransactions'
|
||||
import { type Confirmation } from '~/routes/safe/store/model/confirmation'
|
||||
|
||||
export const LIMIT_POSITION = 0
|
||||
export const SPENT_TODAY_POS = 1
|
||||
|
@ -44,7 +46,7 @@ export const getDailyLimitAddress = async (safeAddress: string) => {
|
|||
return dailyLimitModule.address
|
||||
}
|
||||
|
||||
export const getEditDailyLimitData = async (safeAddress: string, token: string, dailyLimit: string) => {
|
||||
export const getEditDailyLimitData = async (safeAddress: string, token: number, dailyLimit: number) => {
|
||||
const web3 = getWeb3()
|
||||
const dailyLimitModule = await getDailyLimitModuleFrom(safeAddress)
|
||||
const dailyLimitInWei = web3.toWei(dailyLimit, 'ether')
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// @flow
|
||||
import { aNewStore } from '~/store'
|
||||
import { addEtherTo } from '~/test/utils/etherMovements'
|
||||
import { addEtherTo } from '~/test/utils/tokenMovements'
|
||||
import { aDeployedSafe, executeWithdrawOn } from '~/routes/safe/store/test/builder/deployedSafe.builder'
|
||||
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
|
||||
import { safeSelector } from '~/routes/safe/store/selectors/index'
|
||||
import { type Match } from 'react-router-dom'
|
||||
|
||||
describe('Safe Blockchain Test', () => {
|
||||
let store
|
||||
|
@ -21,10 +22,12 @@ describe('Safe Blockchain Test', () => {
|
|||
// WHEN
|
||||
const match: Match = buildMathPropsFrom(safeAddress)
|
||||
const safe = safeSelector(store.getState(), { match })
|
||||
if (!safe) throw new Error()
|
||||
|
||||
await executeWithdrawOn(safe, value)
|
||||
await executeWithdrawOn(safe, value)
|
||||
|
||||
// THEN
|
||||
expect(executeWithdrawOn(safeAddress, value)).rejects.toThrow('VM Exception while processing transaction: revert')
|
||||
expect(executeWithdrawOn(safe, value)).rejects.toThrow('VM Exception while processing transaction: revert')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
// @flow
|
||||
import fetchSafe from '~/routes/safe/store/actions/fetchSafe'
|
||||
import fetchBalance from '~/routes/safe/store/actions/fetchBalance'
|
||||
import { fetchBalances } from '~/routes/safe/store/actions/fetchBalances'
|
||||
|
||||
export type Actions = {
|
||||
fetchSafe: typeof fetchSafe,
|
||||
fetchBalance: typeof fetchBalance,
|
||||
fetchBalances: typeof fetchBalances,
|
||||
}
|
||||
|
||||
export default {
|
||||
fetchSafe,
|
||||
fetchBalance,
|
||||
fetchBalances,
|
||||
}
|
||||
|
|
|
@ -14,16 +14,27 @@ type Props = Actions & SelectorProps & {
|
|||
class SafeView extends React.PureComponent<Props> {
|
||||
componentDidMount() {
|
||||
this.intervalId = setInterval(() => {
|
||||
const { safe, fetchSafe, fetchBalance } = this.props
|
||||
if (!safe) { return }
|
||||
const safeAddress: string = safe.get('address')
|
||||
fetchBalance(safeAddress)
|
||||
if (safe) {
|
||||
fetchSafe(safe)
|
||||
const { safe, fetchBalances, fetchSafe } = this.props
|
||||
if (!safe) {
|
||||
return
|
||||
}
|
||||
const safeAddress = safe.get('address')
|
||||
fetchBalances(safeAddress)
|
||||
fetchSafe(safe)
|
||||
}, 1500)
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (prevProps.safe) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.props.safe) {
|
||||
const safeAddress = this.props.safe.get('address')
|
||||
this.props.fetchBalances(safeAddress)
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearInterval(this.intervalId)
|
||||
}
|
||||
|
@ -32,13 +43,13 @@ class SafeView extends React.PureComponent<Props> {
|
|||
|
||||
render() {
|
||||
const {
|
||||
safe, provider, balance, granted, userAddress,
|
||||
safe, provider, balances, granted, userAddress,
|
||||
} = this.props
|
||||
|
||||
return (
|
||||
<Page>
|
||||
{ granted
|
||||
? <Layout balance={balance} provider={provider} safe={safe} userAddress={userAddress} />
|
||||
? <Layout balances={balances} provider={provider} safe={safe} userAddress={userAddress} />
|
||||
: <NoRights />
|
||||
}
|
||||
</Page>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @flow
|
||||
import { List } from 'immutable'
|
||||
import { List, Map } from 'immutable'
|
||||
import { createSelector, createStructuredSelector, type Selector } from 'reselect'
|
||||
import { balanceSelector, safeSelector, type RouterProps, type SafeSelectorProps } from '~/routes/safe/store/selectors'
|
||||
import { providerNameSelector, userAccountSelector } from '~/wallets/store/selectors/index'
|
||||
|
@ -7,11 +7,12 @@ import { type Safe } from '~/routes/safe/store/model/safe'
|
|||
import { type Owner } from '~/routes/safe/store/model/owner'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
import { sameAddress } from '~/wallets/ethAddresses'
|
||||
import { type Balance } from '~/routes/safe/store/model/balance'
|
||||
|
||||
export type SelectorProps = {
|
||||
safe: SafeSelectorProps,
|
||||
provider: string,
|
||||
balance: string,
|
||||
balances: Map<string, Balance>,
|
||||
userAddress: string,
|
||||
}
|
||||
|
||||
|
@ -39,7 +40,7 @@ export const grantedSelector: Selector<GlobalState, RouterProps, boolean> = crea
|
|||
export default createStructuredSelector({
|
||||
safe: safeSelector,
|
||||
provider: providerNameSelector,
|
||||
balance: balanceSelector,
|
||||
balances: balanceSelector,
|
||||
granted: grantedSelector,
|
||||
userAddress: userAccountSelector,
|
||||
})
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
// @flow
|
||||
import { createAction } from 'redux-actions'
|
||||
|
||||
export const ADD_BALANCE = 'ADD_BALANCE'
|
||||
|
||||
type BalanceProps = {
|
||||
safeAddress: string,
|
||||
funds: string,
|
||||
}
|
||||
|
||||
const addBalance = createAction(
|
||||
ADD_BALANCE,
|
||||
(safeAddress: string, funds: string): BalanceProps => ({
|
||||
safeAddress,
|
||||
funds,
|
||||
}),
|
||||
)
|
||||
|
||||
export default addBalance
|
|
@ -0,0 +1,21 @@
|
|||
// @flow
|
||||
import { Map } from 'immutable'
|
||||
import { createAction } from 'redux-actions'
|
||||
import { type Balance } from '~/routes/safe/store/model/balance'
|
||||
|
||||
export const ADD_BALANCES = 'ADD_BALANCES'
|
||||
|
||||
type BalanceProps = {
|
||||
safeAddress: string,
|
||||
balances: Map<string, Balance>,
|
||||
}
|
||||
|
||||
const addBalances = createAction(
|
||||
ADD_BALANCES,
|
||||
(safeAddress: string, balances: Map<string, Balance>): BalanceProps => ({
|
||||
safeAddress,
|
||||
balances,
|
||||
}),
|
||||
)
|
||||
|
||||
export default addBalances
|
|
@ -1,11 +0,0 @@
|
|||
// @flow
|
||||
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||
import { getBalanceInEtherOf } from '~/wallets/getWeb3'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
import addBalance from './addBalance'
|
||||
|
||||
export default (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalState>) => {
|
||||
const balance = await getBalanceInEtherOf(safeAddress)
|
||||
|
||||
return dispatch(addBalance(safeAddress, balance))
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
// @flow
|
||||
import { Map } from 'immutable'
|
||||
import contract from 'truffle-contract'
|
||||
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||
import StandardToken from '@gnosis.pm/util-contracts/build/contracts/StandardToken.json'
|
||||
import { getBalanceInEtherOf, getWeb3 } from '~/wallets/getWeb3'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
import { makeBalance, type Balance, type BalanceProps } from '~/routes/safe/store/model/balance'
|
||||
import logo from '~/assets/icons/icon_etherTokens.svg'
|
||||
import addBalances from './addBalances'
|
||||
|
||||
export const calculateBalanceOf = async (tokenAddress: string, address: string) => {
|
||||
const web3 = getWeb3()
|
||||
const erc20Token = await contract(StandardToken)
|
||||
erc20Token.setProvider(web3.currentProvider)
|
||||
|
||||
return erc20Token.at(tokenAddress)
|
||||
.then(instance => instance.balanceOf(address).then(funds => funds.toString()))
|
||||
.catch(() => '0')
|
||||
}
|
||||
|
||||
export const fetchBalances = (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalState>) => {
|
||||
const balance = await getBalanceInEtherOf(safeAddress)
|
||||
const ethBalance = makeBalance({
|
||||
address: '0',
|
||||
name: 'Ether',
|
||||
symbol: 'ETH',
|
||||
decimals: 18,
|
||||
logoUrl: logo,
|
||||
funds: balance,
|
||||
})
|
||||
|
||||
const header = new Headers({
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
})
|
||||
|
||||
const sentData = {
|
||||
mode: 'cors',
|
||||
header,
|
||||
}
|
||||
|
||||
const response = await fetch('https://gist.githubusercontent.com/rmeissner/98911fcf74b0ea9731e2dae2441c97a4/raw/', sentData)
|
||||
if (!response.ok) {
|
||||
throw new Error('Error querying safe balances')
|
||||
}
|
||||
|
||||
const json = await response.json()
|
||||
const balancesRecords = await Promise.all(json.map(async (item: BalanceProps) => {
|
||||
const funds = await calculateBalanceOf(item.address, safeAddress)
|
||||
return makeBalance({ ...item, funds })
|
||||
}))
|
||||
|
||||
const balances: Map<string, Balance> = Map().withMutations((map) => {
|
||||
balancesRecords.forEach(record => map.set(record.get('symbol'), record))
|
||||
map.set('ETH', ethBalance)
|
||||
})
|
||||
|
||||
return dispatch(addBalances(safeAddress, balances))
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// @flow
|
||||
import { Record } from 'immutable'
|
||||
import type { RecordFactory, RecordOf } from 'immutable'
|
||||
|
||||
export type BalanceProps = {
|
||||
address: string,
|
||||
name: string,
|
||||
symbol: string,
|
||||
decimals: number,
|
||||
logoUrl: string,
|
||||
funds: string,
|
||||
}
|
||||
|
||||
export const makeBalance: RecordFactory<BalanceProps> = Record({
|
||||
address: '',
|
||||
name: '',
|
||||
symbol: '',
|
||||
decimals: 0,
|
||||
logoUrl: '',
|
||||
funds: '0',
|
||||
})
|
||||
|
||||
export type Balance = RecordOf<BalanceProps>
|
|
@ -1,13 +1,20 @@
|
|||
// @flow
|
||||
import { Map } from 'immutable'
|
||||
import { handleActions, type ActionType } from 'redux-actions'
|
||||
import addBalance, { ADD_BALANCE } from '~/routes/safe/store/actions/addBalance'
|
||||
import addBalances, { ADD_BALANCES } from '~/routes/safe/store/actions/addBalances'
|
||||
import { type Balance } from '~/routes/safe/store/model/balance'
|
||||
|
||||
export const BALANCE_REDUCER_ID = 'balances'
|
||||
|
||||
export type State = Map<string, string>
|
||||
export type State = Map<string, Map<string, Balance>>
|
||||
|
||||
export default handleActions({
|
||||
[ADD_BALANCE]: (state: State, action: ActionType<typeof addBalance>): State =>
|
||||
state.set(action.payload.safeAddress, action.payload.funds),
|
||||
[ADD_BALANCES]: (state: State, action: ActionType<typeof addBalances>): State =>
|
||||
state.update(action.payload.safeAddress, (prevSafe: Map<string, Balance>) => {
|
||||
if (!prevSafe) {
|
||||
return action.payload.balances
|
||||
}
|
||||
|
||||
return prevSafe.equals(action.payload.balances) ? prevSafe : action.payload.balances
|
||||
}),
|
||||
}, Map())
|
||||
|
|
|
@ -10,6 +10,7 @@ import { BALANCE_REDUCER_ID } from '~/routes/safe/store/reducer/balances'
|
|||
import { type State as TransactionsState, TRANSACTIONS_REDUCER_ID } from '~/routes/safe/store/reducer/transactions'
|
||||
import { type Transaction } from '~/routes/safe/store/model/transaction'
|
||||
import { type Confirmation } from '~/routes/safe/store/model/confirmation'
|
||||
import { type Balance } from '~/routes/safe/store/model/balance'
|
||||
|
||||
export type RouterProps = {
|
||||
match: Match,
|
||||
|
@ -81,15 +82,15 @@ export const safeSelector: Selector<GlobalState, RouterProps, SafeSelectorProps>
|
|||
},
|
||||
)
|
||||
|
||||
export const balanceSelector: Selector<GlobalState, RouterProps, string> = createSelector(
|
||||
export const balanceSelector: Selector<GlobalState, RouterProps, Map<string, Balance>> = createSelector(
|
||||
balancesSelector,
|
||||
safeParamAddressSelector,
|
||||
(balances: Map<string, string>, address: string) => {
|
||||
(balances: Map<string, Map<string, Balance>>, address: string) => {
|
||||
if (!address) {
|
||||
return '0'
|
||||
return Map()
|
||||
}
|
||||
|
||||
return balances.get(address) || '0'
|
||||
return balances.get(address) || Map()
|
||||
},
|
||||
)
|
||||
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
// @flow
|
||||
import { BALANCE_REDUCER_ID } from '~/routes/safe/store/reducer/balances'
|
||||
import fetchBalance from '~/routes/safe/store/actions/fetchBalance'
|
||||
import { aNewStore } from '~/store'
|
||||
import { addEtherTo } from '~/test/utils/etherMovements'
|
||||
import { aDeployedSafe } from './builder/deployedSafe.builder'
|
||||
|
||||
const balanceReducerTests = () => {
|
||||
describe('Safe Actions[fetchBalance]', () => {
|
||||
let store
|
||||
beforeEach(async () => {
|
||||
store = aNewStore()
|
||||
})
|
||||
|
||||
it('reducer should return 0 to just deployed safe', async () => {
|
||||
// GIVEN
|
||||
const address = await aDeployedSafe(store)
|
||||
|
||||
// WHEN
|
||||
await store.dispatch(fetchBalance(address))
|
||||
|
||||
// THEN
|
||||
const balances = store.getState()[BALANCE_REDUCER_ID]
|
||||
expect(balances).not.toBe(undefined)
|
||||
expect(balances.get(address)).toBe('0')
|
||||
})
|
||||
|
||||
it('reducer should return 1.3456 ETH as funds to safe with 1.3456 ETH', async () => {
|
||||
// GIVEN
|
||||
const address = await aDeployedSafe(store)
|
||||
|
||||
// WHEN
|
||||
await addEtherTo(address, '1.3456')
|
||||
await store.dispatch(fetchBalance(address))
|
||||
|
||||
// THEN
|
||||
const balances = store.getState()[BALANCE_REDUCER_ID]
|
||||
expect(balances).not.toBe(undefined)
|
||||
expect(balances.get(address)).toBe('1.3456')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default balanceReducerTests
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import addBalance from '~/routes/safe/store/actions/addBalance'
|
||||
/*
|
||||
import addBalances from '~/routes/safe/store/actions/addBalances'
|
||||
import { aNewStore } from '~/store'
|
||||
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
|
||||
import { balanceSelector } from '../selectors'
|
||||
|
@ -26,7 +27,7 @@ const balanceSelectorTests = () => {
|
|||
const store = aNewStore()
|
||||
|
||||
// WHEN
|
||||
await store.dispatch(addBalance('bar', '1'))
|
||||
await store.dispatch(addBalances('bar', '1'))
|
||||
const balance = balanceSelector(store.getState(), { match })
|
||||
|
||||
// THEN
|
||||
|
@ -40,7 +41,7 @@ const balanceSelectorTests = () => {
|
|||
const store = aNewStore()
|
||||
|
||||
// WHEN
|
||||
await store.dispatch(addBalance(safeAddress, '1.3456'))
|
||||
await store.dispatch(addBalances(safeAddress, '1.3456'))
|
||||
const balance = balanceSelector(store.getState(), { match })
|
||||
|
||||
// THEN
|
||||
|
@ -50,3 +51,4 @@ const balanceSelectorTests = () => {
|
|||
}
|
||||
|
||||
export default balanceSelectorTests
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// @flow
|
||||
import balanceReducerTests from './balance.reducer'
|
||||
import safeReducerTests from './safe.reducer'
|
||||
import balanceSelectorTests from './balance.selector'
|
||||
// import balanceSelectorTests from './balance.selector'
|
||||
import safeSelectorTests from './safe.selector'
|
||||
import grantedSelectorTests from './granted.selector'
|
||||
import confirmationsSelectorTests from './confirmations.selector'
|
||||
|
@ -10,13 +9,12 @@ import transactionsSelectorTests from './transactions.selector'
|
|||
describe('Safe Test suite', () => {
|
||||
// ACTIONS AND REDUCERS
|
||||
safeReducerTests()
|
||||
balanceReducerTests()
|
||||
|
||||
// SAFE SELECTOR
|
||||
safeSelectorTests()
|
||||
|
||||
// BALANCE SELECTOR
|
||||
balanceSelectorTests()
|
||||
// balanceSelectorTests()
|
||||
|
||||
// GRANTED SELECTOR
|
||||
grantedSelectorTests()
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import TestUtils from 'react-dom/test-utils'
|
||||
import { Provider } from 'react-redux'
|
||||
import { ConnectedRouter } from 'react-router-redux'
|
||||
import Button from '~/components/layout/Button'
|
||||
import { aNewStore, history } from '~/store'
|
||||
import { addEtherTo } from '~/test/utils/etherMovements'
|
||||
import { aDeployedSafe } from '~/routes/safe/store/test/builder/deployedSafe.builder'
|
||||
import { SAFELIST_ADDRESS } from '~/routes/routes'
|
||||
import SafeView from '~/routes/safe/component/Safe'
|
||||
import AppRoutes from '~/routes'
|
||||
import AddTransactionComponent, { SEE_TXS_BUTTON_TEXT } from '~/routes/safe/component/AddTransaction'
|
||||
import TransactionsComponent from '~/routes/safe/component/Transactions'
|
||||
import TransactionComponent from '~/routes/safe/component/Transactions/Transaction'
|
||||
import { getBalanceInEtherOf } from '~/wallets/getWeb3'
|
||||
import { sleep } from '~/utils/timer'
|
||||
import { ADD_MULTISIG_BUTTON_TEXT } from '~/routes/safe/component/Safe/MultisigTx'
|
||||
import { safeTransactionsSelector } from '~/routes/safe/store/selectors/index'
|
||||
import { MOVE_FUNDS_INDEX } from '~/test/builder/safe.dom.utils'
|
||||
|
||||
describe('React DOM TESTS > Withdraw funds from safe', () => {
|
||||
let SafeDom
|
||||
let store
|
||||
let address
|
||||
beforeEach(async () => {
|
||||
// create store
|
||||
store = aNewStore()
|
||||
// deploy safe updating store
|
||||
address = await aDeployedSafe(store)
|
||||
// navigate to SAFE route
|
||||
history.push(`${SAFELIST_ADDRESS}/${address}`)
|
||||
SafeDom = TestUtils.renderIntoDocument((
|
||||
<Provider store={store}>
|
||||
<ConnectedRouter history={history}>
|
||||
<AppRoutes />
|
||||
</ConnectedRouter>
|
||||
</Provider>
|
||||
))
|
||||
})
|
||||
|
||||
it('should execute one transaction if safe has only one owner', async () => {
|
||||
// add funds to safe
|
||||
await addEtherTo(address, '0.1')
|
||||
const Safe = TestUtils.findRenderedComponentWithType(SafeDom, SafeView)
|
||||
|
||||
// $FlowFixMe
|
||||
const buttons = TestUtils.scryRenderedDOMComponentsWithTag(Safe, 'button')
|
||||
const addTxButton = buttons[MOVE_FUNDS_INDEX]
|
||||
expect(addTxButton.getElementsByTagName('span')[0].innerHTML).toEqual(ADD_MULTISIG_BUTTON_TEXT)
|
||||
|
||||
await sleep(1800) // Give time to enable Add button
|
||||
TestUtils.Simulate.click(addTxButton)
|
||||
await sleep(1800) // Give time to render the form
|
||||
const AddTransaction = TestUtils.findRenderedComponentWithType(SafeDom, AddTransactionComponent)
|
||||
|
||||
// $FlowFixMe
|
||||
const inputs = TestUtils.scryRenderedDOMComponentsWithTag(AddTransaction, 'input')
|
||||
const name = inputs[0]
|
||||
const destination = inputs[1]
|
||||
const amountInEth = inputs[2]
|
||||
TestUtils.Simulate.change(name, { target: { value: 'Buying betteries' } })
|
||||
TestUtils.Simulate.change(amountInEth, { target: { value: '0.01' } })
|
||||
TestUtils.Simulate.change(destination, { target: { value: store.getState().providers.account } })
|
||||
|
||||
// $FlowFixMe
|
||||
const form = TestUtils.findRenderedDOMComponentWithTag(AddTransaction, 'form')
|
||||
|
||||
TestUtils.Simulate.submit(form) // fill the form
|
||||
TestUtils.Simulate.submit(form) // confirming data
|
||||
await sleep(4000)
|
||||
|
||||
const safeBalance = await getBalanceInEtherOf(address)
|
||||
expect(safeBalance).toBe('0.09')
|
||||
|
||||
// $FlowFixMe
|
||||
const addTransactionButtons = TestUtils.scryRenderedComponentsWithType(AddTransaction, Button)
|
||||
expect(addTransactionButtons.length).toBe(1)
|
||||
const visitTxsButton = addTransactionButtons[0]
|
||||
|
||||
expect(visitTxsButton.props.children).toEqual(SEE_TXS_BUTTON_TEXT)
|
||||
|
||||
// NOW it is time to check the just executed transaction
|
||||
TestUtils.Simulate.click(TestUtils.scryRenderedDOMComponentsWithTag(visitTxsButton, 'button')[0])
|
||||
|
||||
const Transactions = TestUtils.findRenderedComponentWithType(SafeDom, TransactionsComponent)
|
||||
if (!Transactions) throw new Error()
|
||||
const Transaction = TestUtils.findRenderedComponentWithType(Transactions, TransactionComponent)
|
||||
if (!Transaction) throw new Error()
|
||||
|
||||
const paragraphs = TestUtils.scryRenderedDOMComponentsWithTag(Transaction, 'p')
|
||||
expect(paragraphs[2].innerHTML).toBe('Already executed')
|
||||
TestUtils.Simulate.click(paragraphs[2]) // expanded
|
||||
await sleep(1000) // Time to expand
|
||||
const paragraphsExpanded = TestUtils.scryRenderedDOMComponentsWithTag(Transaction, 'p')
|
||||
const txHashParagraph = paragraphsExpanded[3]
|
||||
|
||||
const transactions = safeTransactionsSelector(store.getState(), { safeAddress: address })
|
||||
const batteryTx = transactions.get(0)
|
||||
if (!batteryTx) throw new Error()
|
||||
expect(txHashParagraph.innerHTML).toBe(batteryTx.get('tx'))
|
||||
})
|
||||
})
|
|
@ -1,62 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import TestUtils from 'react-dom/test-utils'
|
||||
import { Provider } from 'react-redux'
|
||||
import { ConnectedRouter } from 'react-router-redux'
|
||||
import { aNewStore, history } from '~/store'
|
||||
import { aDeployedSafe } from '~/routes/safe/store/test/builder/deployedSafe.builder'
|
||||
import { SAFELIST_ADDRESS } from '~/routes/routes'
|
||||
import AppRoutes from '~/routes'
|
||||
import AddTransactionComponent from '~/routes/safe/component/AddTransaction'
|
||||
import { createMultisigTxFilling, addFundsTo, checkBalanceOf, listTxsOf, getListItemsFrom, expandTransactionOf, getTransactionFromReduxStore, confirmOwners } from '~/routes/safe/test/testMultisig'
|
||||
import { sleep } from '~/utils/timer'
|
||||
|
||||
const renderSafe = localStore => (
|
||||
TestUtils.renderIntoDocument((
|
||||
<Provider store={localStore}>
|
||||
<ConnectedRouter history={history}>
|
||||
<AppRoutes />
|
||||
</ConnectedRouter>
|
||||
</Provider>
|
||||
))
|
||||
)
|
||||
|
||||
describe('React DOM TESTS > Multisig transactions from safe [3 owners & 1 threshold] ', () => {
|
||||
let SafeDom
|
||||
let store
|
||||
let address
|
||||
beforeEach(async () => {
|
||||
// create store
|
||||
store = aNewStore()
|
||||
// deploy safe updating store
|
||||
address = await aDeployedSafe(store, 10, 1, 3)
|
||||
// navigate to SAFE route
|
||||
history.push(`${SAFELIST_ADDRESS}/${address}`)
|
||||
SafeDom = renderSafe(store)
|
||||
})
|
||||
|
||||
it('should execute transaction straight away', async () => {
|
||||
await addFundsTo(SafeDom, address)
|
||||
await checkBalanceOf(address, '0.1')
|
||||
await createMultisigTxFilling(SafeDom, AddTransactionComponent, store)
|
||||
await checkBalanceOf(address, '0.09')
|
||||
await listTxsOf(SafeDom)
|
||||
await sleep(2500)
|
||||
|
||||
await expandTransactionOf(SafeDom, 3, 1)
|
||||
await confirmOwners(SafeDom, 'Adolfo 1 Eth Account [Confirmed]', 'Adolfo 2 Eth Account [Not confirmed]', 'Adolfo 3 Eth Account [Not confirmed]')
|
||||
|
||||
const listItems = getListItemsFrom(SafeDom)
|
||||
|
||||
const status = listItems[2].props.secondary
|
||||
expect(status).toBe('Already executed')
|
||||
|
||||
const confirmed = listItems[3].props.secondary
|
||||
const tx = getTransactionFromReduxStore(store, address)
|
||||
if (!tx) throw new Error()
|
||||
expect(confirmed).toBe(tx.get('tx'))
|
||||
|
||||
const ownerTx = listItems[6].props.secondary
|
||||
expect(ownerTx).toBe('Confirmation hash: EXECUTED')
|
||||
})
|
||||
})
|
|
@ -1,104 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import TestUtils from 'react-dom/test-utils'
|
||||
import { Provider } from 'react-redux'
|
||||
import { ConnectedRouter } from 'react-router-redux'
|
||||
import { aNewStore, history } from '~/store'
|
||||
import { aDeployedSafe } from '~/routes/safe/store/test/builder/deployedSafe.builder'
|
||||
import { SAFELIST_ADDRESS } from '~/routes/routes'
|
||||
import AppRoutes from '~/routes'
|
||||
import { getWeb3 } from '~/wallets/getWeb3'
|
||||
import { sleep } from '~/utils/timer'
|
||||
import { promisify } from '~/utils/promisify'
|
||||
import AddTransactionComponent from '~/routes/safe/component/AddTransaction'
|
||||
import { processTransaction } from '~/routes/safe/component/Transactions/processTransactions'
|
||||
import { confirmationsTransactionSelector } from '~/routes/safe/store/selectors/index'
|
||||
import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions'
|
||||
import { createMultisigTxFilling, addFundsTo, checkBalanceOf, listTxsOf, getListItemsFrom, expandTransactionOf, getTransactionFromReduxStore, confirmOwners } from '~/routes/safe/test/testMultisig'
|
||||
|
||||
const renderSafe = localStore => (
|
||||
TestUtils.renderIntoDocument((
|
||||
<Provider store={localStore}>
|
||||
<ConnectedRouter history={history}>
|
||||
<AppRoutes />
|
||||
</ConnectedRouter>
|
||||
</Provider>
|
||||
))
|
||||
)
|
||||
|
||||
describe('React DOM TESTS > Multisig transactions from safe [3 owners & 3 threshold] ', () => {
|
||||
let SafeDom
|
||||
let store
|
||||
let address
|
||||
let accounts
|
||||
beforeEach(async () => {
|
||||
// create store
|
||||
store = aNewStore()
|
||||
// deploy safe updating store
|
||||
address = await aDeployedSafe(store, 10, 3, 3)
|
||||
// navigate to SAFE route
|
||||
history.push(`${SAFELIST_ADDRESS}/${address}`)
|
||||
SafeDom = renderSafe(store)
|
||||
accounts = await promisify(cb => getWeb3().eth.getAccounts(cb))
|
||||
})
|
||||
|
||||
|
||||
const getAlreadyConfirmed = () => {
|
||||
const tx = getTransactionFromReduxStore(store, address)
|
||||
if (!tx) throw new Error()
|
||||
const confirmed = confirmationsTransactionSelector(store.getState(), { transaction: tx })
|
||||
|
||||
return confirmed
|
||||
}
|
||||
|
||||
const makeConfirmation = async (executor) => {
|
||||
const alreadyConfirmed = getAlreadyConfirmed()
|
||||
const tx = getTransactionFromReduxStore(store, address)
|
||||
if (!tx) throw new Error()
|
||||
await processTransaction(address, tx, alreadyConfirmed, executor)
|
||||
await sleep(800)
|
||||
store.dispatch(fetchTransactions())
|
||||
sleep(1800)
|
||||
SafeDom = renderSafe(store)
|
||||
sleep(1800)
|
||||
await listTxsOf(SafeDom)
|
||||
sleep(800)
|
||||
await expandTransactionOf(SafeDom, 3, 3)
|
||||
sleep(800)
|
||||
}
|
||||
|
||||
it('should execute transaction after 2 owners have confirmed and the last one executed correctly', async () => {
|
||||
await addFundsTo(SafeDom, address)
|
||||
await createMultisigTxFilling(SafeDom, AddTransactionComponent, store)
|
||||
|
||||
await checkBalanceOf(address, '0.1')
|
||||
await listTxsOf(SafeDom)
|
||||
sleep(1400)
|
||||
const listItems = getListItemsFrom(SafeDom)
|
||||
|
||||
const status = listItems[2].props.secondary
|
||||
expect(status).toBe('1 of the 3 confirmations needed')
|
||||
|
||||
const confirmed = listItems[3].props.secondary
|
||||
expect(confirmed).toBe('Waiting for the rest of confirmations')
|
||||
|
||||
await expandTransactionOf(SafeDom, 3, 3)
|
||||
await confirmOwners(SafeDom, 'Adolfo 1 Eth Account [Confirmed]', 'Adolfo 2 Eth Account [Not confirmed]', 'Adolfo 3 Eth Account [Not confirmed]')
|
||||
|
||||
await makeConfirmation(accounts[1])
|
||||
await confirmOwners(SafeDom, 'Adolfo 1 Eth Account [Confirmed]', 'Adolfo 2 Eth Account [Confirmed]', 'Adolfo 3 Eth Account [Not confirmed]')
|
||||
|
||||
await makeConfirmation(accounts[2])
|
||||
await confirmOwners(SafeDom, 'Adolfo 1 Eth Account [Confirmed]', 'Adolfo 2 Eth Account [Confirmed]', 'Adolfo 3 Eth Account [Confirmed]')
|
||||
|
||||
const listItemsExecuted = getListItemsFrom(SafeDom)
|
||||
|
||||
const statusExecuted = listItemsExecuted[2].props.secondary
|
||||
expect(statusExecuted).toBe('Already executed')
|
||||
|
||||
const confirmedExecuted = listItemsExecuted[3].props.secondary
|
||||
const tx = getTransactionFromReduxStore(store, address)
|
||||
if (!tx) throw new Error()
|
||||
expect(confirmedExecuted).toBe(tx.get('tx'))
|
||||
})
|
||||
})
|
|
@ -3,9 +3,10 @@ import * as React from 'react'
|
|||
import TestUtils from 'react-dom/test-utils'
|
||||
import { Provider } from 'react-redux'
|
||||
import { ConnectedRouter } from 'react-router-redux'
|
||||
import { type Match } from 'react-router-dom'
|
||||
import Button from '~/components/layout/Button'
|
||||
import { aNewStore, history } from '~/store'
|
||||
import { addEtherTo } from '~/test/utils/etherMovements'
|
||||
import { addEtherTo } from '~/test/utils/tokenMovements'
|
||||
import { aDeployedSafe, executeWithdrawOn } from '~/routes/safe/store/test/builder/deployedSafe.builder'
|
||||
import { SAFELIST_ADDRESS } from '~/routes/routes'
|
||||
import SafeView from '~/routes/safe/component/Safe'
|
||||
|
@ -84,6 +85,7 @@ describe('React DOM TESTS > Withdraw funds from safe', () => {
|
|||
|
||||
const match: Match = buildMathPropsFrom(address)
|
||||
const safe = safeSelector(store.getState(), { match })
|
||||
if (!safe) throw new Error()
|
||||
await executeWithdrawOn(safe, 0.01)
|
||||
await executeWithdrawOn(safe, 0.01)
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import TestUtils from 'react-dom/test-utils'
|
|||
import { sleep } from '~/utils/timer'
|
||||
import { getBalanceInEtherOf } from '~/wallets/getWeb3'
|
||||
import { ADD_MULTISIG_BUTTON_TEXT, SEE_MULTISIG_BUTTON_TEXT } from '~/routes/safe/component/Safe/MultisigTx'
|
||||
import { addEtherTo } from '~/test/utils/etherMovements'
|
||||
import { addEtherTo } from '~/test/utils/tokenMovements'
|
||||
import SafeView from '~/routes/safe/component/Safe'
|
||||
import TransactionsComponent from '~/routes/safe/component/Transactions'
|
||||
import TransactionComponent from '~/routes/safe/component/Transactions/Transaction'
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
// @flow
|
||||
import TestUtils from 'react-dom/test-utils'
|
||||
import { store } from '~/store'
|
||||
import {
|
||||
FIELD_NAME,
|
||||
FIELD_OWNERS,
|
||||
FIELD_CONFIRMATIONS,
|
||||
FIELD_DAILY_LIMIT,
|
||||
getOwnerNameBy,
|
||||
getOwnerAddressBy,
|
||||
} from '~/routes/open/components/fields'
|
||||
import { DEPLOYED_COMPONENT_ID } from '~/routes/open/components/FormConfirmation'
|
||||
import { sleep } from '~/utils/timer'
|
||||
import { getProviderInfo } from '~/wallets/getWeb3'
|
||||
import { renderSafe } from '~/routes/safe/store/test/builder/deployedSafe.builder'
|
||||
|
||||
describe('React DOM TESTS > Create Safe form', () => {
|
||||
let open
|
||||
let provider
|
||||
beforeEach(async () => {
|
||||
provider = await getProviderInfo()
|
||||
open = await renderSafe(store)
|
||||
})
|
||||
|
||||
it('should create a 1 owner safe after rendering correctly the form', async () => {
|
||||
const inputs = TestUtils.scryRenderedDOMComponentsWithTag(open, 'input')
|
||||
const fieldName = inputs[0]
|
||||
expect(fieldName.name).toEqual(FIELD_NAME)
|
||||
|
||||
const fieldOwners = inputs[1]
|
||||
expect(fieldOwners.name).toEqual(FIELD_OWNERS)
|
||||
|
||||
const fieldConfirmations = inputs[2]
|
||||
expect(fieldConfirmations.name).toEqual(FIELD_CONFIRMATIONS)
|
||||
|
||||
const dailyLimitConfirmations = inputs[3]
|
||||
expect(dailyLimitConfirmations.name).toEqual(FIELD_DAILY_LIMIT)
|
||||
|
||||
TestUtils.Simulate.change(fieldOwners, { target: { value: '1' } })
|
||||
const inputsExpanded = TestUtils.scryRenderedDOMComponentsWithTag(open, 'input')
|
||||
|
||||
const ownerName = inputsExpanded[2]
|
||||
expect(ownerName.name).toEqual(getOwnerNameBy(0))
|
||||
const ownerAddress = inputsExpanded[3]
|
||||
expect(ownerAddress.name).toEqual(getOwnerAddressBy(0))
|
||||
expect(ownerAddress.value).toEqual(provider.account)
|
||||
|
||||
// WHEN
|
||||
TestUtils.Simulate.change(fieldName, { target: { value: 'Adolfo Safe' } })
|
||||
TestUtils.Simulate.change(fieldConfirmations, { target: { value: '1' } })
|
||||
TestUtils.Simulate.change(ownerName, { target: { value: 'Adolfo Eth Account' } })
|
||||
TestUtils.Simulate.change(dailyLimitConfirmations, { target: { value: '10' } })
|
||||
|
||||
const form = TestUtils.findRenderedDOMComponentWithTag(open, 'form')
|
||||
// One submit per step when creating a safe
|
||||
TestUtils.Simulate.submit(form) // fill the form
|
||||
TestUtils.Simulate.submit(form) // confirming data
|
||||
TestUtils.Simulate.submit(form) // Executing transaction
|
||||
|
||||
// giving some time to the component for updating its state with safe
|
||||
// before destroying its context
|
||||
await sleep(9000)
|
||||
|
||||
// THEN
|
||||
const deployed = TestUtils.findRenderedDOMComponentWithClass(open, DEPLOYED_COMPONENT_ID)
|
||||
|
||||
if (deployed) {
|
||||
const transaction = JSON.parse(deployed.getElementsByTagName('pre')[0].innerHTML)
|
||||
delete transaction.receipt.logsBloom
|
||||
// eslint-disable-next-line
|
||||
// console.log(transaction)
|
||||
}
|
||||
})
|
||||
})
|
|
@ -4,115 +4,33 @@ import { type Store } from 'redux'
|
|||
import TestUtils from 'react-dom/test-utils'
|
||||
import { Provider } from 'react-redux'
|
||||
import { ConnectedRouter } from 'react-router-redux'
|
||||
import { DEPLOYED_COMPONENT_ID } from '~/routes/open/components/FormConfirmation'
|
||||
import Open from '~/routes/open/container/Open'
|
||||
import SafeView from '~/routes/safe/component/Safe'
|
||||
import { aNewStore, history, type GlobalState } from '~/store'
|
||||
import { sleep } from '~/utils/timer'
|
||||
import { getProviderInfo, getWeb3 } from '~/wallets/getWeb3'
|
||||
import addProvider from '~/wallets/store/actions/addProvider'
|
||||
import { makeProvider } from '~/wallets/store/model/provider'
|
||||
import { getWeb3 } from '~/wallets/getWeb3'
|
||||
import AppRoutes from '~/routes'
|
||||
import { SAFELIST_ADDRESS } from '~/routes/routes'
|
||||
import { promisify } from '~/utils/promisify'
|
||||
import { addEtherTo } from '~/test/utils/etherMovements'
|
||||
|
||||
const fillOpenSafeForm = async (localStore: Store<GlobalState>) => {
|
||||
const provider = await getProviderInfo()
|
||||
const walletRecord = makeProvider(provider)
|
||||
localStore.dispatch(addProvider(walletRecord))
|
||||
|
||||
return (
|
||||
TestUtils.renderIntoDocument((
|
||||
<Provider store={localStore}>
|
||||
<ConnectedRouter history={history}>
|
||||
<Open />
|
||||
</ConnectedRouter>
|
||||
</Provider>
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
const deploySafe = async (safe: React$Component<{}>, dailyLimit: string, threshold: number, numOwners: number) => {
|
||||
expect(threshold).toBeLessThanOrEqual(numOwners)
|
||||
const inputs = TestUtils.scryRenderedDOMComponentsWithTag(safe, 'input')
|
||||
const fieldName = inputs[0]
|
||||
const fieldOwners = inputs[1]
|
||||
const fieldConfirmations = inputs[2]
|
||||
const fieldDailyLimit = inputs[3]
|
||||
|
||||
const web3 = getWeb3()
|
||||
const accounts = await promisify(cb => web3.eth.getAccounts(cb))
|
||||
TestUtils.Simulate.change(fieldOwners, { target: { value: `${numOwners}` } })
|
||||
await sleep(1500)
|
||||
const inputsExpanded = TestUtils.scryRenderedDOMComponentsWithTag(safe, 'input')
|
||||
expect(inputsExpanded.length).toBe((numOwners * 2) + 4) // 2 per owner + name, dailyLimit, confirmations, numOwners
|
||||
|
||||
for (let i = 0; i < numOwners; i += 1) {
|
||||
const nameIndex = (i * 2) + 2
|
||||
const addressIndex = (i * 2) + 3
|
||||
const ownerName = inputsExpanded[nameIndex]
|
||||
const account = inputsExpanded[addressIndex]
|
||||
|
||||
TestUtils.Simulate.change(ownerName, { target: { value: `Adolfo ${i + 1} Eth Account` } })
|
||||
TestUtils.Simulate.change(account, { target: { value: accounts[i] } })
|
||||
}
|
||||
|
||||
TestUtils.Simulate.change(fieldName, { target: { value: 'Adolfo Safe' } })
|
||||
TestUtils.Simulate.change(fieldConfirmations, { target: { value: `${threshold}` } })
|
||||
|
||||
TestUtils.Simulate.change(fieldDailyLimit, { target: { value: dailyLimit } })
|
||||
|
||||
const form = TestUtils.findRenderedDOMComponentWithTag(safe, 'form')
|
||||
|
||||
TestUtils.Simulate.submit(form) // fill the form
|
||||
TestUtils.Simulate.submit(form) // confirming data
|
||||
TestUtils.Simulate.submit(form) // Executing transaction
|
||||
|
||||
// giving some time to the component for updating its state with safe
|
||||
// before destroying its context
|
||||
await sleep(15000)
|
||||
|
||||
// THEN
|
||||
const deployed = TestUtils.findRenderedDOMComponentWithClass(safe, DEPLOYED_COMPONENT_ID)
|
||||
if (!deployed) {
|
||||
throw new Error()
|
||||
}
|
||||
|
||||
const transactionHash = JSON.parse(deployed.getElementsByTagName('pre')[0].innerHTML)
|
||||
delete transactionHash.receipt.logsBloom
|
||||
|
||||
return transactionHash
|
||||
}
|
||||
|
||||
const aDeployedSafe = async (
|
||||
specificStore: Store<GlobalState>,
|
||||
dailyLimit?: number = 0.5,
|
||||
threshold?: number = 1,
|
||||
numOwners?: number = 1,
|
||||
) => {
|
||||
const safe: React$Component<{}> = await fillOpenSafeForm(specificStore)
|
||||
const deployedSafe = await deploySafe(safe, `${dailyLimit}`, threshold, numOwners)
|
||||
|
||||
return deployedSafe.logs[1].args.proxy
|
||||
}
|
||||
import { addEtherTo } from '~/test/utils/tokenMovements'
|
||||
import { aMinedSafe } from '~/test/builder/safe.redux.builder'
|
||||
|
||||
export type DomSafe = {
|
||||
address: string,
|
||||
safeButtons: Element[],
|
||||
safe: React$Component<any, any>,
|
||||
accounts: string[],
|
||||
store: Store<GlobalState>,
|
||||
}
|
||||
|
||||
export const renderSafeInDom = async (
|
||||
owners: number,
|
||||
threshold: number,
|
||||
owners: number = 1,
|
||||
threshold: number = 1,
|
||||
dailyLimit: number = 0.5,
|
||||
): Promise<DomSafe> => {
|
||||
// create store
|
||||
const store = aNewStore()
|
||||
// deploy safe updating store
|
||||
const address = await aDeployedSafe(store, dailyLimit, threshold, owners)
|
||||
const address = await aMinedSafe(store, owners, threshold, dailyLimit)
|
||||
// have available accounts
|
||||
const accounts = await promisify(cb => getWeb3().eth.getAccounts(cb))
|
||||
// navigate to SAFE route
|
||||
|
|
|
@ -4,14 +4,16 @@ import ListItemText from '~/components/List/ListItemText/index'
|
|||
import { SEE_MULTISIG_BUTTON_TEXT } from '~/routes/safe/component/Safe/MultisigTx'
|
||||
import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions'
|
||||
import { sleep } from '~/utils/timer'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
|
||||
export const EXPAND_OWNERS_INDEX = 0
|
||||
export const ADD_OWNERS_INDEX = 1
|
||||
export const EDIT_THRESHOLD_INDEX = 2
|
||||
export const EDIT_INDEX = 3
|
||||
export const WITHDRAW_INDEX = 4
|
||||
export const MOVE_FUNDS_INDEX = 5
|
||||
export const LIST_TXS_INDEX = 6
|
||||
export const EXPAND_BALANCE_INDEX = 0
|
||||
export const EXPAND_OWNERS_INDEX = 1
|
||||
export const ADD_OWNERS_INDEX = 2
|
||||
export const EDIT_THRESHOLD_INDEX = 3
|
||||
export const EDIT_INDEX = 4
|
||||
export const WITHDRAW_INDEX = 5
|
||||
export const MOVE_FUNDS_INDEX = 6
|
||||
export const LIST_TXS_INDEX = 7
|
||||
|
||||
export const listTxsClickingOn = async (seeTxsButton: Element) => {
|
||||
expect(seeTxsButton.getElementsByTagName('span')[0].innerHTML).toEqual(SEE_MULTISIG_BUTTON_TEXT)
|
||||
|
@ -79,7 +81,7 @@ export const checkPendingTx = async (
|
|||
}
|
||||
}
|
||||
|
||||
export const refreshTransactions = async (store) => {
|
||||
export const refreshTransactions = async (store: Store<GlobalState>) => {
|
||||
await store.dispatch(fetchTransactions())
|
||||
await sleep(1500)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
// @flow
|
||||
import { makeSafe, type Safe } from '~/routes/safe/store/model/safe'
|
||||
import { buildOwnersFrom, buildDailyLimitFrom } from '~/routes/safe/store/actions'
|
||||
import { FIELD_NAME, FIELD_CONFIRMATIONS, FIELD_OWNERS, getOwnerNameBy, getOwnerAddressBy, FIELD_DAILY_LIMIT } from '~/routes/open/components/fields'
|
||||
import { getWeb3, getProviderInfo } from '~/wallets/getWeb3'
|
||||
import { promisify } from '~/utils/promisify'
|
||||
import addSafe from '~/routes/safe/store/actions/addSafe'
|
||||
import { createSafe, type OpenState } from '~/routes/open/container/Open'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
import { makeProvider } from '~/wallets/store/model/provider'
|
||||
import addProvider from '~/wallets/store/actions/addProvider'
|
||||
|
||||
class SafeBuilder {
|
||||
safe: Safe
|
||||
|
||||
constructor() {
|
||||
this.safe = makeSafe()
|
||||
}
|
||||
|
||||
withAddress(address: string) {
|
||||
this.safe = this.safe.set('address', address)
|
||||
return this
|
||||
}
|
||||
|
||||
withName(name: string) {
|
||||
this.safe = this.safe.set('name', name)
|
||||
return this
|
||||
}
|
||||
|
||||
withConfirmations(confirmations: number) {
|
||||
this.safe = this.safe.set('threshold', confirmations)
|
||||
return this
|
||||
}
|
||||
|
||||
withDailyLimit(limit: number, spentToday: number = 0) {
|
||||
const dailyLimit = buildDailyLimitFrom(limit, spentToday)
|
||||
this.safe = this.safe.set('dailyLimit', dailyLimit)
|
||||
return this
|
||||
}
|
||||
|
||||
withOwner(names: string[], adresses: string[]) {
|
||||
const owners = buildOwnersFrom(names, adresses)
|
||||
this.safe = this.safe.set('owners', owners)
|
||||
return this
|
||||
}
|
||||
|
||||
get() {
|
||||
return this.safe
|
||||
}
|
||||
}
|
||||
|
||||
const aSafe = () => new SafeBuilder()
|
||||
|
||||
export class SafeFactory {
|
||||
static oneOwnerSafe = (ownerAddress: string = '0x03db1a8b26d08df23337e9276a36b474510f0023') => aSafe()
|
||||
.withAddress('0x03db1a8b26d08df23337e9276a36b474510f0025')
|
||||
.withName('Adol ICO Safe')
|
||||
.withConfirmations(1)
|
||||
.withDailyLimit(10)
|
||||
.withOwner(['Adol Metamask'], [ownerAddress])
|
||||
.get()
|
||||
|
||||
static twoOwnersSafe = (firstOwner: string = '0x03db1a8b26d08df23337e9276a36b474510f0023', secondOwner: string = '0x03db1a8b26d08df23337e9276a36b474510f0024') => aSafe()
|
||||
.withAddress('0x03db1a8b26d08df23337e9276a36b474510f0026')
|
||||
.withName('Adol & Tobias Safe')
|
||||
.withConfirmations(2)
|
||||
.withOwner(
|
||||
['Adol Metamask', 'Tobias Metamask'],
|
||||
[firstOwner, secondOwner],
|
||||
)
|
||||
.withDailyLimit(10, 1.34)
|
||||
.get()
|
||||
|
||||
static dailyLimitSafe = (dailyLimit: number, spentToday: number) => aSafe()
|
||||
.withAddress('0x03db1a8b26d08df23337e9276a36b474510f0027')
|
||||
.withName('Adol & Tobias Safe')
|
||||
.withConfirmations(2)
|
||||
.withOwner(
|
||||
['Adol Metamask', 'Tobias Metamask'],
|
||||
['0x03db1a8b26d08df23337e9276a36b474510f0023', '0x03db1a8b26d08df23337e9276a36b474510f0024'],
|
||||
)
|
||||
.withDailyLimit(dailyLimit, spentToday)
|
||||
.get()
|
||||
}
|
||||
|
||||
export const aMinedSafe = async (
|
||||
store: Store<GlobalState>,
|
||||
owners: number = 1,
|
||||
threshold: number = 1,
|
||||
dailyLimit: number = 0.5,
|
||||
): Promise<string> => {
|
||||
const provider = await getProviderInfo()
|
||||
const walletRecord = makeProvider(provider)
|
||||
store.dispatch(addProvider(walletRecord))
|
||||
|
||||
const accounts = await promisify(cb => getWeb3().eth.getAccounts(cb))
|
||||
const form = {
|
||||
[FIELD_NAME]: 'Safe Name',
|
||||
[FIELD_CONFIRMATIONS]: `${threshold}`,
|
||||
[FIELD_OWNERS]: `${owners}`,
|
||||
[getOwnerNameBy(0)]: 'Adolfo 1 Eth Account',
|
||||
[getOwnerAddressBy(0)]: accounts[0],
|
||||
[FIELD_DAILY_LIMIT]: `${dailyLimit}`,
|
||||
}
|
||||
|
||||
const addSafeFn: any = (...args) => store.dispatch(addSafe(...args))
|
||||
const openSafeProps: OpenState = await createSafe(form, accounts[0], addSafeFn)
|
||||
|
||||
return openSafeProps.safeAddress
|
||||
}
|
||||
|
||||
export default aSafe
|
|
@ -0,0 +1,107 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { type Store } from 'redux'
|
||||
import TestUtils from 'react-dom/test-utils'
|
||||
import { Provider } from 'react-redux'
|
||||
import { ConnectedRouter } from 'react-router-redux'
|
||||
import { DEPLOYED_COMPONENT_ID } from '~/routes/open/components/FormConfirmation'
|
||||
import Open from '~/routes/open/container/Open'
|
||||
import { aNewStore, history, type GlobalState } from '~/store'
|
||||
import { sleep } from '~/utils/timer'
|
||||
import { getProviderInfo, getWeb3 } from '~/wallets/getWeb3'
|
||||
import addProvider from '~/wallets/store/actions/addProvider'
|
||||
import { makeProvider } from '~/wallets/store/model/provider'
|
||||
import { promisify } from '~/utils/promisify'
|
||||
|
||||
const fillOpenSafeForm = async (localStore: Store<GlobalState>) => {
|
||||
const provider = await getProviderInfo()
|
||||
const walletRecord = makeProvider(provider)
|
||||
localStore.dispatch(addProvider(walletRecord))
|
||||
|
||||
return (
|
||||
TestUtils.renderIntoDocument((
|
||||
<Provider store={localStore}>
|
||||
<ConnectedRouter history={history}>
|
||||
<Open />
|
||||
</ConnectedRouter>
|
||||
</Provider>
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
const deploySafe = async (safe: React$Component<{}>, dailyLimit: string, threshold: number, numOwners: number) => {
|
||||
expect(threshold).toBeLessThanOrEqual(numOwners)
|
||||
const inputs = TestUtils.scryRenderedDOMComponentsWithTag(safe, 'input')
|
||||
const fieldName = inputs[0]
|
||||
const fieldOwners = inputs[1]
|
||||
const fieldConfirmations = inputs[2]
|
||||
const fieldDailyLimit = inputs[3]
|
||||
|
||||
const web3 = getWeb3()
|
||||
const accounts = await promisify(cb => web3.eth.getAccounts(cb))
|
||||
TestUtils.Simulate.change(fieldOwners, { target: { value: `${numOwners}` } })
|
||||
await sleep(1500)
|
||||
const inputsExpanded = TestUtils.scryRenderedDOMComponentsWithTag(safe, 'input')
|
||||
expect(inputsExpanded.length).toBe((numOwners * 2) + 4) // 2 per owner + name, dailyLimit, confirmations, numOwners
|
||||
|
||||
for (let i = 0; i < numOwners; i += 1) {
|
||||
const nameIndex = (i * 2) + 2
|
||||
const addressIndex = (i * 2) + 3
|
||||
const ownerName = inputsExpanded[nameIndex]
|
||||
const account = inputsExpanded[addressIndex]
|
||||
|
||||
TestUtils.Simulate.change(ownerName, { target: { value: `Adolfo ${i + 1} Eth Account` } })
|
||||
TestUtils.Simulate.change(account, { target: { value: accounts[i] } })
|
||||
}
|
||||
|
||||
TestUtils.Simulate.change(fieldName, { target: { value: 'Adolfo Safe' } })
|
||||
TestUtils.Simulate.change(fieldConfirmations, { target: { value: `${threshold}` } })
|
||||
|
||||
TestUtils.Simulate.change(fieldDailyLimit, { target: { value: dailyLimit } })
|
||||
|
||||
const form = TestUtils.findRenderedDOMComponentWithTag(safe, 'form')
|
||||
|
||||
TestUtils.Simulate.submit(form) // fill the form
|
||||
TestUtils.Simulate.submit(form) // confirming data
|
||||
TestUtils.Simulate.submit(form) // Executing transaction
|
||||
|
||||
// giving some time to the component for updating its state with safe
|
||||
// before destroying its context
|
||||
await sleep(8000)
|
||||
|
||||
// THEN
|
||||
const deployed = TestUtils.findRenderedDOMComponentWithClass(safe, DEPLOYED_COMPONENT_ID)
|
||||
if (!deployed) {
|
||||
throw new Error()
|
||||
}
|
||||
|
||||
const transactionHash = JSON.parse(deployed.getElementsByTagName('pre')[0].innerHTML)
|
||||
delete transactionHash.receipt.logsBloom
|
||||
|
||||
return transactionHash
|
||||
}
|
||||
|
||||
const aDeployedSafe = async (
|
||||
specificStore: Store<GlobalState>,
|
||||
dailyLimit?: number = 0.5,
|
||||
threshold?: number = 1,
|
||||
numOwners?: number = 1,
|
||||
) => {
|
||||
const safe: React$Component<{}> = await fillOpenSafeForm(specificStore)
|
||||
const deployedSafe = await deploySafe(safe, `${dailyLimit}`, threshold, numOwners)
|
||||
|
||||
return deployedSafe.logs[1].args.proxy
|
||||
}
|
||||
|
||||
describe('DOM > Feature > CREATE a safe', () => {
|
||||
it('fills correctly the safe form with 4 owners, 4 threshold and 5 ETH as daily limit', async () => {
|
||||
const owners = 4
|
||||
const threshold = 4
|
||||
const dailyLimit = 5
|
||||
const store = aNewStore()
|
||||
const address = await aDeployedSafe(store, dailyLimit, threshold, owners)
|
||||
|
||||
expect(address).not.toBe(null)
|
||||
expect(address).not.toBe(undefined)
|
||||
})
|
||||
})
|
|
@ -9,7 +9,7 @@ import { sendRemoveOwnerForm, checkMinedRemoveOwnerTx, checkPendingRemoveOwnerTx
|
|||
import { checkMinedThresholdTx, sendChangeThresholdForm, checkThresholdOf } from '~/test/utils/transactions/threshold.helper'
|
||||
import { sendWithdrawForm, checkMinedWithdrawTx } from '~/test/utils/transactions/withdraw.helper'
|
||||
import { processTransaction } from '~/routes/safe/component/Transactions/processTransactions'
|
||||
import { checkBalanceOf } from '~/test/utils/etherMovements'
|
||||
import { checkBalanceOf } from '~/test/utils/tokenMovements'
|
||||
|
||||
describe('DOM > Feature > SAFE MULTISIG TX 1 Owner 1 Threshold', () => {
|
||||
let domSafe: DomSafe
|
|
@ -0,0 +1,87 @@
|
|||
// @flow
|
||||
import { Map } from 'immutable'
|
||||
import { BALANCE_REDUCER_ID } from '~/routes/safe/store/reducer/balances'
|
||||
import * as fetchBalancesAction from '~/routes/safe/store/actions/fetchBalances'
|
||||
import { aNewStore } from '~/store'
|
||||
import { aMinedSafe } from '~/test/builder/safe.redux.builder'
|
||||
import { type Balance, makeBalance } from '~/routes/safe/store/model/balance'
|
||||
import addBalances from '~/routes/safe/store/actions/addBalances'
|
||||
import { addEtherTo, addTknTo } from '~/test/utils/tokenMovements'
|
||||
|
||||
describe('Safe Actions[fetchBalance]', () => {
|
||||
let store
|
||||
let address: string
|
||||
beforeEach(async () => {
|
||||
store = aNewStore()
|
||||
address = await aMinedSafe(store)
|
||||
})
|
||||
|
||||
it('reducer should return 0 to just deployed safe', async () => {
|
||||
// GIVEN
|
||||
const tokenList = ['WE', '<3', 'GNO', 'OMG', 'RDN']
|
||||
|
||||
// WHEN
|
||||
await store.dispatch(fetchBalancesAction.fetchBalances(address))
|
||||
|
||||
// THEN
|
||||
const balances: Map<string, Map<string, Balance>> | typeof undefined = store.getState()[BALANCE_REDUCER_ID]
|
||||
if (!balances) throw new Error()
|
||||
|
||||
const safeBalances: Map<string, Balance> | typeof undefined = balances.get(address)
|
||||
if (!safeBalances) throw new Error()
|
||||
expect(safeBalances.size).toBe(6)
|
||||
|
||||
tokenList.forEach((token: string) => {
|
||||
const record = safeBalances.get(token)
|
||||
if (!record) throw new Error()
|
||||
expect(record.get('funds')).toBe('0')
|
||||
})
|
||||
})
|
||||
|
||||
it('reducer should return 0.03456 ETH as funds to safe with 0.03456 ETH', async () => {
|
||||
// WHEN
|
||||
await addEtherTo(address, '0.03456')
|
||||
await store.dispatch(fetchBalancesAction.fetchBalances(address))
|
||||
|
||||
// THEN
|
||||
const balances: Map<string, Map<string, Balance>> | typeof undefined = store.getState()[BALANCE_REDUCER_ID]
|
||||
if (!balances) throw new Error()
|
||||
|
||||
const safeBalances: Map<string, Balance> | typeof undefined = balances.get(address)
|
||||
if (!safeBalances) throw new Error()
|
||||
expect(safeBalances.size).toBe(6)
|
||||
|
||||
const ethBalance = safeBalances.get('ETH')
|
||||
if (!ethBalance) throw new Error()
|
||||
expect(ethBalance.get('funds')).toBe('0.03456')
|
||||
})
|
||||
|
||||
it('reducer should return 100 TKN when safe has 100 TKN', async () => {
|
||||
// GIVEN
|
||||
const numTokens = 100
|
||||
const tokenAddress = await addTknTo(address, numTokens)
|
||||
|
||||
// WHEN
|
||||
const fetchBalancesMock = jest.spyOn(fetchBalancesAction, 'fetchBalances')
|
||||
const funds = await fetchBalancesAction.calculateBalanceOf(tokenAddress, address)
|
||||
|
||||
const balances: Map<string, Balance> = Map().set('TKN', makeBalance({
|
||||
address: tokenAddress,
|
||||
name: 'Token',
|
||||
symbol: 'TKN',
|
||||
decimals: 18,
|
||||
logoUrl: 'https://github.com/TrustWallet/tokens/blob/master/images/0x6810e776880c02933d47db1b9fc05908e5386b96.png?raw=true',
|
||||
funds,
|
||||
}))
|
||||
fetchBalancesMock.mockImplementation(() => store.dispatch(addBalances(address, balances)))
|
||||
await store.dispatch(fetchBalancesAction.fetchBalances(address))
|
||||
fetchBalancesMock.mockRestore()
|
||||
|
||||
// THEN
|
||||
const safeBalances = store.getState()[BALANCE_REDUCER_ID].get(address)
|
||||
expect(safeBalances.size).toBe(1)
|
||||
|
||||
const tknBalance = safeBalances.get('TKN')
|
||||
expect(tknBalance.get('funds')).toBe(String(numTokens))
|
||||
})
|
||||
})
|
|
@ -3,7 +3,7 @@ import { getWeb3 } from '~/wallets/getWeb3'
|
|||
import abi from 'ethereumjs-abi'
|
||||
import { promisify } from '~/utils/promisify'
|
||||
|
||||
export const getErrorMessage = async (to, value, data, from) => {
|
||||
export const getErrorMessage = async (to: string, value: number, data: string, from: string) => {
|
||||
const web3 = getWeb3()
|
||||
const returnData = await promisify(cb => web3.eth.call({
|
||||
to, from, value, data,
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
// @flow
|
||||
import contract from 'truffle-contract'
|
||||
import { getProviderInfo, getBalanceInEtherOf, getWeb3 } from '~/wallets/getWeb3'
|
||||
import { promisify } from '~/utils/promisify'
|
||||
import withdraw, { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/withdraw'
|
||||
import { type Safe } from '~/routes/safe/store/model/safe'
|
||||
import Token from '#/test/Token.json'
|
||||
|
||||
export const addEtherTo = async (address: string, eth: string) => {
|
||||
const web3 = getWeb3()
|
||||
|
@ -10,7 +13,7 @@ export const addEtherTo = async (address: string, eth: string) => {
|
|||
return promisify(cb => web3.eth.sendTransaction(txData, cb))
|
||||
}
|
||||
|
||||
export const executeWithdrawOn = async (safeAddress: string, value: number) => {
|
||||
export const executeWithdrawOn = async (safe: Safe, value: number) => {
|
||||
const providerInfo = await getProviderInfo()
|
||||
const userAddress = providerInfo.account
|
||||
|
||||
|
@ -19,10 +22,21 @@ export const executeWithdrawOn = async (safeAddress: string, value: number) => {
|
|||
[VALUE_PARAM]: `${value}`,
|
||||
}
|
||||
|
||||
return withdraw(values, safeAddress, userAddress)
|
||||
return withdraw(values, safe, userAddress)
|
||||
}
|
||||
|
||||
export const checkBalanceOf = async (addressToTest: string, value: string) => {
|
||||
const safeBalance = await getBalanceInEtherOf(addressToTest)
|
||||
expect(safeBalance).toBe(value)
|
||||
}
|
||||
|
||||
export const addTknTo = async (safe: string, value: number) => {
|
||||
const web3 = getWeb3()
|
||||
const token = contract(Token)
|
||||
token.setProvider(web3.currentProvider)
|
||||
const accounts = await promisify(cb => getWeb3().eth.getAccounts(cb))
|
||||
const myToken = await token.new({ from: accounts[0], gas: '5000000' })
|
||||
await myToken.transfer(safe, value, { from: accounts[0], gas: '5000000' })
|
||||
|
||||
return myToken.address
|
||||
}
|
|
@ -3,7 +3,7 @@ import TestUtils from 'react-dom/test-utils'
|
|||
import { sleep } from '~/utils/timer'
|
||||
import { checkMinedTx, checkPendingTx } from '~/test/builder/safe.dom.utils'
|
||||
|
||||
export const sendMoveFundsForm = (
|
||||
export const sendMoveFundsForm = async (
|
||||
SafeDom: React$Component<any, any>,
|
||||
multisigButton: React$Component<any, any>,
|
||||
txName: string,
|
||||
|
@ -13,7 +13,7 @@ export const sendMoveFundsForm = (
|
|||
// load add multisig form component
|
||||
TestUtils.Simulate.click(multisigButton)
|
||||
// give time to re-render it
|
||||
sleep(600)
|
||||
await sleep(600)
|
||||
|
||||
// fill the form
|
||||
const inputs = TestUtils.scryRenderedDOMComponentsWithTag(SafeDom, 'input')
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// @flow
|
||||
import TestUtils from 'react-dom/test-utils'
|
||||
import { sleep } from '~/utils/timer'
|
||||
import { checkBalanceOf } from '~/test/utils/etherMovements'
|
||||
import { checkBalanceOf } from '~/test/utils/tokenMovements'
|
||||
import { checkMinedTx } from '~/test/builder/safe.dom.utils'
|
||||
|
||||
export const sendWithdrawForm = (
|
||||
|
@ -36,7 +36,7 @@ export const checkMinedWithdrawTx = async (
|
|||
Transaction: React$Component<any, any>,
|
||||
name: string,
|
||||
address: string,
|
||||
funds: number,
|
||||
funds: string,
|
||||
) => {
|
||||
await checkBalanceOf(address, funds)
|
||||
|
||||
|
|
12
yarn.lock
12
yarn.lock
|
@ -931,6 +931,10 @@
|
|||
lodash "^4.17.5"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@gnosis.pm/util-contracts@^0.2.14":
|
||||
version "0.2.14"
|
||||
resolved "https://registry.yarnpkg.com/@gnosis.pm/util-contracts/-/util-contracts-0.2.14.tgz#587cd6268a7d08dbc0d08b1c7bd375e19549d833"
|
||||
|
||||
"@material-ui/core@^1.2.1":
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-1.2.2.tgz#b074bdaa679d68af235b4d3f108f828ddcf6c1bc"
|
||||
|
@ -2921,14 +2925,14 @@ bignumber.js@^7.2.1:
|
|||
version "7.2.1"
|
||||
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f"
|
||||
|
||||
"bignumber.js@git+https://github.com/debris/bignumber.js#master":
|
||||
version "2.0.7"
|
||||
resolved "git+https://github.com/debris/bignumber.js#c7a38de919ed75e6fb6ba38051986e294b328df9"
|
||||
|
||||
"bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2":
|
||||
version "2.0.7"
|
||||
resolved "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2"
|
||||
|
||||
"bignumber.js@git+https://github.com/debris/bignumber.js.git#master":
|
||||
version "2.0.7"
|
||||
resolved "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9"
|
||||
|
||||
binary-extensions@^1.0.0:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205"
|
||||
|
|
Loading…
Reference in New Issue