add token contracts for testing purposes and refactor TokenMovements utils

This commit is contained in:
mmv 2019-05-31 17:58:35 +04:00
parent bfa5a52bc4
commit 6902bad091
33 changed files with 52063 additions and 1850 deletions

View File

@ -0,0 +1,148 @@
{
"contractName": "DevDependenciesGetter",
"abi": [],
"metadata": "{\"compiler\":{\"version\":\"0.5.8+commit.23d335f2\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"methods\":{}},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"/home/mmv/work/safe-react/contracts/DevDependencies.sol\":\"DevDependenciesGetter\"},\"evmVersion\":\"petersburg\",\"libraries\":{},\"optimizer\":{\"enabled\":true,\"runs\":500},\"remappings\":[]},\"sources\":{\"/home/mmv/work/safe-react/contracts/DevDependencies.sol\":{\"keccak256\":\"0xc649617f3c51e58509bdd0910726bd84a52f232b6aaf5790ac72f6e84ccb1b58\",\"urls\":[\"bzzr://57b15b2fd6a6a15523665a1f369e8b395a5649504f807114fedff42cf1b430b3\"]},\"/home/mmv/work/safe-react/src/test/contracts/TokenOMG.sol\":{\"keccak256\":\"0x099d05859e51af8b24539b47e0d181a17409d51063263f8a8d53280818c69d4d\",\"urls\":[\"bzzr://4eb926d078f8111367c3a180e7eb99f36528b95c871e1004c626f1cb5487f5dc\"]},\"/home/mmv/work/safe-react/src/test/contracts/TokenRDN.sol\":{\"keccak256\":\"0xbd1fc040f6b4f7b68bb7e6b745d02c571d7baf992c5a3a34d57392f624d7043c\",\"urls\":[\"bzzr://fdd020e4fe5f62e961acccce8733276ad3aca6dbe7ccff3f860476774cf6bdab\"]},\"@gnosis.pm/util-contracts/contracts/GnosisStandardToken.sol\":{\"keccak256\":\"0xdec5028208406e811c449a04e2932f7efeae629388cb6124550b8b048a645556\",\"urls\":[\"bzzr://f3d13a708f543b3ce72745cab321e6daf25d935fd12ba55a4152f1113eb6d5e4\"]},\"@gnosis.pm/util-contracts/contracts/Math.sol\":{\"keccak256\":\"0x857768cd0d460e33778dcde29e997b539640bbf37ea23832213b2e5039147ea5\",\"urls\":[\"bzzr://628f7e63a0d6a092aad389b70cc55d6d9c10cd9753f3644d5ea9dc75a3314a8e\"]},\"@gnosis.pm/util-contracts/contracts/Proxy.sol\":{\"keccak256\":\"0x2ff8795110cceafcab1010f157a4dd33e46378bb88fbdc3c313a6f0d62e3444f\",\"urls\":[\"bzzr://66d77feaf648ca17dd620f3e27463b4b6e6031fec7ccd64dfffc4c30bd57b467\"]},\"@gnosis.pm/util-contracts/contracts/Token.sol\":{\"keccak256\":\"0x364778f634c900ed83553e17ef1284bd33fa68a738e668f664b4a0fa675bb586\",\"urls\":[\"bzzr://cb31caaf3364dbf5d688adb10de074284845b142c26d23a47b09ee510dd4a432\"]}},\"version\":1}",
"bytecode": "0x6080604052348015600f57600080fd5b50603580601d6000396000f3fe6080604052600080fdfea165627a7a723058205e4f8760788b4c49e4643557d735f7312e842b538cebaa480b66c5e3577d34cb0029",
"deployedBytecode": "0x6080604052600080fdfea165627a7a723058205e4f8760788b4c49e4643557d735f7312e842b538cebaa480b66c5e3577d34cb0029",
"sourceMap": "116:33:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;116:33:0;;;;;;;",
"deployedSourceMap": "116:33:0:-;;;;;",
"source": "pragma solidity ^0.5.2;\n\nimport \"../src/test/contracts/TokenOMG.sol\";\nimport \"../src/test/contracts/TokenRDN.sol\";\n\ncontract DevDependenciesGetter {}",
"sourcePath": "/home/mmv/work/safe-react/contracts/DevDependencies.sol",
"ast": {
"absolutePath": "/home/mmv/work/safe-react/contracts/DevDependencies.sol",
"exportedSymbols": {
"DevDependenciesGetter": [
4
]
},
"id": 5,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1,
"literals": [
"solidity",
"^",
"0.5",
".2"
],
"nodeType": "PragmaDirective",
"src": "0:23:0"
},
{
"absolutePath": "/home/mmv/work/safe-react/src/test/contracts/TokenOMG.sol",
"file": "../src/test/contracts/TokenOMG.sol",
"id": 2,
"nodeType": "ImportDirective",
"scope": 5,
"sourceUnit": 90,
"src": "25:44:0",
"symbolAliases": [],
"unitAlias": ""
},
{
"absolutePath": "/home/mmv/work/safe-react/src/test/contracts/TokenRDN.sol",
"file": "../src/test/contracts/TokenRDN.sol",
"id": 3,
"nodeType": "ImportDirective",
"scope": 5,
"sourceUnit": 118,
"src": "70:44:0",
"symbolAliases": [],
"unitAlias": ""
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": null,
"fullyImplemented": true,
"id": 4,
"linearizedBaseContracts": [
4
],
"name": "DevDependenciesGetter",
"nodeType": "ContractDefinition",
"nodes": [],
"scope": 5,
"src": "116:33:0"
}
],
"src": "0:149:0"
},
"legacyAST": {
"absolutePath": "/home/mmv/work/safe-react/contracts/DevDependencies.sol",
"exportedSymbols": {
"DevDependenciesGetter": [
4
]
},
"id": 5,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1,
"literals": [
"solidity",
"^",
"0.5",
".2"
],
"nodeType": "PragmaDirective",
"src": "0:23:0"
},
{
"absolutePath": "/home/mmv/work/safe-react/src/test/contracts/TokenOMG.sol",
"file": "../src/test/contracts/TokenOMG.sol",
"id": 2,
"nodeType": "ImportDirective",
"scope": 5,
"sourceUnit": 90,
"src": "25:44:0",
"symbolAliases": [],
"unitAlias": ""
},
{
"absolutePath": "/home/mmv/work/safe-react/src/test/contracts/TokenRDN.sol",
"file": "../src/test/contracts/TokenRDN.sol",
"id": 3,
"nodeType": "ImportDirective",
"scope": 5,
"sourceUnit": 118,
"src": "70:44:0",
"symbolAliases": [],
"unitAlias": ""
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": null,
"fullyImplemented": true,
"id": 4,
"linearizedBaseContracts": [
4
],
"name": "DevDependenciesGetter",
"nodeType": "ContractDefinition",
"nodes": [],
"scope": 5,
"src": "116:33:0"
}
],
"src": "0:149:0"
},
"compiler": {
"name": "solc",
"version": "0.5.8+commit.23d335f2.Emscripten.clang"
},
"networks": {},
"schemaVersion": "3.0.10",
"updatedAt": "2019-05-31T13:47:05.338Z",
"devdoc": {
"methods": {}
},
"userdoc": {
"methods": {}
}
}

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

View File

@ -0,0 +1,983 @@
{
"contractName": "Proxied",
"abi": [
{
"constant": true,
"inputs": [],
"name": "masterCopy",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
],
"metadata": "{\"compiler\":{\"version\":\"0.5.8+commit.23d335f2\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"constant\":true,\"inputs\":[],\"name\":\"masterCopy\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Alan Lu - <alan@gnosis.pm>\",\"methods\":{},\"title\":\"Proxied - indicates that a contract will be proxied. Also defines storage requirements for Proxy.\"},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"@gnosis.pm/util-contracts/contracts/Proxy.sol\":\"Proxied\"},\"evmVersion\":\"petersburg\",\"libraries\":{},\"optimizer\":{\"enabled\":true,\"runs\":500},\"remappings\":[]},\"sources\":{\"@gnosis.pm/util-contracts/contracts/Proxy.sol\":{\"keccak256\":\"0x2ff8795110cceafcab1010f157a4dd33e46378bb88fbdc3c313a6f0d62e3444f\",\"urls\":[\"bzzr://66d77feaf648ca17dd620f3e27463b4b6e6031fec7ccd64dfffc4c30bd57b467\"]}},\"version\":1}",
"bytecode": "0x6080604052348015600f57600080fd5b5060a48061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063a619486e14602d575b600080fd5b6033605c565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b60005473ffffffffffffffffffffffffffffffffffffffff168156fea165627a7a7230582030927156db8f845fed095b245b70d15291cf8c9a8cdd88be16cdf598edc721190029",
"deployedBytecode": "0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063a619486e14602d575b600080fd5b6033605c565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b60005473ffffffffffffffffffffffffffffffffffffffff168156fea165627a7a7230582030927156db8f845fed095b245b70d15291cf8c9a8cdd88be16cdf598edc721190029",
"sourceMap": "173:51:6:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;173:51:6;;;;;;;",
"deployedSourceMap": "173:51:6:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;173:51:6;;;;;;;;;;;;;;;;;;;196:25;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;:::o",
"source": "pragma solidity ^0.5.2;\n\n/// @title Proxied - indicates that a contract will be proxied. Also defines storage requirements for Proxy.\n/// @author Alan Lu - <alan@gnosis.pm>\ncontract Proxied {\n address public masterCopy;\n}\n\n/// @title Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.\n/// @author Stefan George - <stefan@gnosis.pm>\ncontract Proxy is Proxied {\n /// @dev Constructor function sets address of master copy contract.\n /// @param _masterCopy Master copy address.\n constructor(address _masterCopy) public {\n require(_masterCopy != address(0), \"The master copy is required\");\n masterCopy = _masterCopy;\n }\n\n /// @dev Fallback function forwards all transactions and returns all received return data.\n function() external payable {\n address _masterCopy = masterCopy;\n assembly {\n calldatacopy(0, 0, calldatasize)\n let success := delegatecall(not(0), _masterCopy, 0, calldatasize, 0, 0)\n returndatacopy(0, 0, returndatasize)\n switch success\n case 0 {\n revert(0, returndatasize)\n }\n default {\n return(0, returndatasize)\n }\n }\n }\n}\n",
"sourcePath": "@gnosis.pm/util-contracts/contracts/Proxy.sol",
"ast": {
"absolutePath": "@gnosis.pm/util-contracts/contracts/Proxy.sol",
"exportedSymbols": {
"Proxied": [
1463
],
"Proxy": [
1494
]
},
"id": 1495,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1460,
"literals": [
"solidity",
"^",
"0.5",
".2"
],
"nodeType": "PragmaDirective",
"src": "0:23:6"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title Proxied - indicates that a contract will be proxied. Also defines storage requirements for Proxy.\n @author Alan Lu - <alan@gnosis.pm>",
"fullyImplemented": true,
"id": 1463,
"linearizedBaseContracts": [
1463
],
"name": "Proxied",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 1462,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1463,
"src": "196:25:6",
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1461,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "196:7:6",
"stateMutability": "nonpayable",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "public"
}
],
"scope": 1495,
"src": "173:51:6"
},
{
"baseContracts": [
{
"arguments": null,
"baseName": {
"contractScope": null,
"id": 1464,
"name": "Proxied",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1463,
"src": "408:7:6",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxied_$1463",
"typeString": "contract Proxied"
}
},
"id": 1465,
"nodeType": "InheritanceSpecifier",
"src": "408:7:6"
}
],
"contractDependencies": [
1463
],
"contractKind": "contract",
"documentation": "@title Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.\n @author Stefan George - <stefan@gnosis.pm>",
"fullyImplemented": true,
"id": 1494,
"linearizedBaseContracts": [
1494,
1463
],
"name": "Proxy",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1483,
"nodeType": "Block",
"src": "582:116:6",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 1475,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 1471,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1467,
"src": "600:11:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "BinaryOperation",
"operator": "!=",
"rightExpression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"hexValue": "30",
"id": 1473,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "623:1:6",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_0_by_1",
"typeString": "int_const 0"
},
"value": "0"
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_rational_0_by_1",
"typeString": "int_const 0"
}
],
"id": 1472,
"isConstant": false,
"isLValue": false,
"isPure": true,
"lValueRequested": false,
"nodeType": "ElementaryTypeNameExpression",
"src": "615:7:6",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_address_$",
"typeString": "type(address)"
},
"typeName": "address"
},
"id": 1474,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "typeConversion",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "615:10:6",
"typeDescriptions": {
"typeIdentifier": "t_address_payable",
"typeString": "address payable"
}
},
"src": "600:25:6",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
{
"argumentTypes": null,
"hexValue": "546865206d617374657220636f7079206973207265717569726564",
"id": 1476,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "627:29:6",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_2e9921edd8141a51172691d5d51dd1cbeb601d8d4953527c9d36e0bffd20fed9",
"typeString": "literal_string \"The master copy is required\""
},
"value": "The master copy is required"
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_bool",
"typeString": "bool"
},
{
"typeIdentifier": "t_stringliteral_2e9921edd8141a51172691d5d51dd1cbeb601d8d4953527c9d36e0bffd20fed9",
"typeString": "literal_string \"The master copy is required\""
}
],
"id": 1470,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
1581,
1582
],
"referencedDeclaration": 1582,
"src": "592:7:6",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 1477,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "592:65:6",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 1478,
"nodeType": "ExpressionStatement",
"src": "592:65:6"
},
{
"expression": {
"argumentTypes": null,
"id": 1481,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 1479,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1462,
"src": "667:10:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 1480,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1467,
"src": "680:11:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "667:24:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"id": 1482,
"nodeType": "ExpressionStatement",
"src": "667:24:6"
}
]
},
"documentation": "@dev Constructor function sets address of master copy contract.\n @param _masterCopy Master copy address.",
"id": 1484,
"implemented": true,
"kind": "constructor",
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1468,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1467,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1484,
"src": "554:19:6",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1466,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "554:7:6",
"stateMutability": "nonpayable",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "553:21:6"
},
"returnParameters": {
"id": 1469,
"nodeType": "ParameterList",
"parameters": [],
"src": "582:0:6"
},
"scope": 1494,
"src": "542:156:6",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
},
{
"body": {
"id": 1492,
"nodeType": "Block",
"src": "827:462:6",
"statements": [
{
"assignments": [
1488
],
"declarations": [
{
"constant": false,
"id": 1488,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1492,
"src": "837:19:6",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1487,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "837:7:6",
"stateMutability": "nonpayable",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
}
],
"id": 1490,
"initialValue": {
"argumentTypes": null,
"id": 1489,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1462,
"src": "859:10:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "VariableDeclarationStatement",
"src": "837:32:6"
},
{
"externalReferences": [
{
"_masterCopy": {
"declaration": 1488,
"isOffset": false,
"isSlot": false,
"src": "983:11:6",
"valueSize": 1
}
}
],
"id": 1491,
"nodeType": "InlineAssembly",
"operations": "{\n calldatacopy(0, 0, calldatasize())\n let success := delegatecall(not(0), _masterCopy, 0, calldatasize(), 0, 0)\n returndatacopy(0, 0, returndatasize())\n switch success\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n}",
"src": "879:404:6"
}
]
},
"documentation": "@dev Fallback function forwards all transactions and returns all received return data.",
"id": 1493,
"implemented": true,
"kind": "fallback",
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1485,
"nodeType": "ParameterList",
"parameters": [],
"src": "807:2:6"
},
"returnParameters": {
"id": 1486,
"nodeType": "ParameterList",
"parameters": [],
"src": "827:0:6"
},
"scope": 1494,
"src": "799:490:6",
"stateMutability": "payable",
"superFunction": null,
"visibility": "external"
}
],
"scope": 1495,
"src": "390:901:6"
}
],
"src": "0:1292:6"
},
"legacyAST": {
"absolutePath": "@gnosis.pm/util-contracts/contracts/Proxy.sol",
"exportedSymbols": {
"Proxied": [
1463
],
"Proxy": [
1494
]
},
"id": 1495,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1460,
"literals": [
"solidity",
"^",
"0.5",
".2"
],
"nodeType": "PragmaDirective",
"src": "0:23:6"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": "@title Proxied - indicates that a contract will be proxied. Also defines storage requirements for Proxy.\n @author Alan Lu - <alan@gnosis.pm>",
"fullyImplemented": true,
"id": 1463,
"linearizedBaseContracts": [
1463
],
"name": "Proxied",
"nodeType": "ContractDefinition",
"nodes": [
{
"constant": false,
"id": 1462,
"name": "masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1463,
"src": "196:25:6",
"stateVariable": true,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1461,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "196:7:6",
"stateMutability": "nonpayable",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "public"
}
],
"scope": 1495,
"src": "173:51:6"
},
{
"baseContracts": [
{
"arguments": null,
"baseName": {
"contractScope": null,
"id": 1464,
"name": "Proxied",
"nodeType": "UserDefinedTypeName",
"referencedDeclaration": 1463,
"src": "408:7:6",
"typeDescriptions": {
"typeIdentifier": "t_contract$_Proxied_$1463",
"typeString": "contract Proxied"
}
},
"id": 1465,
"nodeType": "InheritanceSpecifier",
"src": "408:7:6"
}
],
"contractDependencies": [
1463
],
"contractKind": "contract",
"documentation": "@title Proxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.\n @author Stefan George - <stefan@gnosis.pm>",
"fullyImplemented": true,
"id": 1494,
"linearizedBaseContracts": [
1494,
1463
],
"name": "Proxy",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 1483,
"nodeType": "Block",
"src": "582:116:6",
"statements": [
{
"expression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"id": 1475,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 1471,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1467,
"src": "600:11:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "BinaryOperation",
"operator": "!=",
"rightExpression": {
"argumentTypes": null,
"arguments": [
{
"argumentTypes": null,
"hexValue": "30",
"id": 1473,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "623:1:6",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_rational_0_by_1",
"typeString": "int_const 0"
},
"value": "0"
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_rational_0_by_1",
"typeString": "int_const 0"
}
],
"id": 1472,
"isConstant": false,
"isLValue": false,
"isPure": true,
"lValueRequested": false,
"nodeType": "ElementaryTypeNameExpression",
"src": "615:7:6",
"typeDescriptions": {
"typeIdentifier": "t_type$_t_address_$",
"typeString": "type(address)"
},
"typeName": "address"
},
"id": 1474,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "typeConversion",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "615:10:6",
"typeDescriptions": {
"typeIdentifier": "t_address_payable",
"typeString": "address payable"
}
},
"src": "600:25:6",
"typeDescriptions": {
"typeIdentifier": "t_bool",
"typeString": "bool"
}
},
{
"argumentTypes": null,
"hexValue": "546865206d617374657220636f7079206973207265717569726564",
"id": 1476,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "string",
"lValueRequested": false,
"nodeType": "Literal",
"src": "627:29:6",
"subdenomination": null,
"typeDescriptions": {
"typeIdentifier": "t_stringliteral_2e9921edd8141a51172691d5d51dd1cbeb601d8d4953527c9d36e0bffd20fed9",
"typeString": "literal_string \"The master copy is required\""
},
"value": "The master copy is required"
}
],
"expression": {
"argumentTypes": [
{
"typeIdentifier": "t_bool",
"typeString": "bool"
},
{
"typeIdentifier": "t_stringliteral_2e9921edd8141a51172691d5d51dd1cbeb601d8d4953527c9d36e0bffd20fed9",
"typeString": "literal_string \"The master copy is required\""
}
],
"id": 1470,
"name": "require",
"nodeType": "Identifier",
"overloadedDeclarations": [
1581,
1582
],
"referencedDeclaration": 1582,
"src": "592:7:6",
"typeDescriptions": {
"typeIdentifier": "t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$",
"typeString": "function (bool,string memory) pure"
}
},
"id": 1477,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "592:65:6",
"typeDescriptions": {
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
}
},
"id": 1478,
"nodeType": "ExpressionStatement",
"src": "592:65:6"
},
{
"expression": {
"argumentTypes": null,
"id": 1481,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftHandSide": {
"argumentTypes": null,
"id": 1479,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1462,
"src": "667:10:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide": {
"argumentTypes": null,
"id": 1480,
"name": "_masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1467,
"src": "680:11:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"src": "667:24:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"id": 1482,
"nodeType": "ExpressionStatement",
"src": "667:24:6"
}
]
},
"documentation": "@dev Constructor function sets address of master copy contract.\n @param _masterCopy Master copy address.",
"id": 1484,
"implemented": true,
"kind": "constructor",
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1468,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 1467,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1484,
"src": "554:19:6",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1466,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "554:7:6",
"stateMutability": "nonpayable",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "553:21:6"
},
"returnParameters": {
"id": 1469,
"nodeType": "ParameterList",
"parameters": [],
"src": "582:0:6"
},
"scope": 1494,
"src": "542:156:6",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
},
{
"body": {
"id": 1492,
"nodeType": "Block",
"src": "827:462:6",
"statements": [
{
"assignments": [
1488
],
"declarations": [
{
"constant": false,
"id": 1488,
"name": "_masterCopy",
"nodeType": "VariableDeclaration",
"scope": 1492,
"src": "837:19:6",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
},
"typeName": {
"id": 1487,
"name": "address",
"nodeType": "ElementaryTypeName",
"src": "837:7:6",
"stateMutability": "nonpayable",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"value": null,
"visibility": "internal"
}
],
"id": 1490,
"initialValue": {
"argumentTypes": null,
"id": 1489,
"name": "masterCopy",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 1462,
"src": "859:10:6",
"typeDescriptions": {
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"nodeType": "VariableDeclarationStatement",
"src": "837:32:6"
},
{
"externalReferences": [
{
"_masterCopy": {
"declaration": 1488,
"isOffset": false,
"isSlot": false,
"src": "983:11:6",
"valueSize": 1
}
}
],
"id": 1491,
"nodeType": "InlineAssembly",
"operations": "{\n calldatacopy(0, 0, calldatasize())\n let success := delegatecall(not(0), _masterCopy, 0, calldatasize(), 0, 0)\n returndatacopy(0, 0, returndatasize())\n switch success\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n}",
"src": "879:404:6"
}
]
},
"documentation": "@dev Fallback function forwards all transactions and returns all received return data.",
"id": 1493,
"implemented": true,
"kind": "fallback",
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 1485,
"nodeType": "ParameterList",
"parameters": [],
"src": "807:2:6"
},
"returnParameters": {
"id": 1486,
"nodeType": "ParameterList",
"parameters": [],
"src": "827:0:6"
},
"scope": 1494,
"src": "799:490:6",
"stateMutability": "payable",
"superFunction": null,
"visibility": "external"
}
],
"scope": 1495,
"src": "390:901:6"
}
],
"src": "0:1292:6"
},
"compiler": {
"name": "solc",
"version": "0.5.8+commit.23d335f2.Emscripten.clang"
},
"networks": {},
"schemaVersion": "3.0.10",
"updatedAt": "2019-05-31T13:47:05.362Z",
"devdoc": {
"author": "Alan Lu - <alan@gnosis.pm>",
"methods": {},
"title": "Proxied - indicates that a contract will be proxied. Also defines storage requirements for Proxy."
},
"userdoc": {
"methods": {}
}
}

1006
build/contracts/Proxy.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1865
build/contracts/Token.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,6 @@
pragma solidity ^0.5.2;
import "../src/test/contracts/TokenOMG.sol";
import "../src/test/contracts/TokenRDN.sol";
contract DevDependenciesGetter {}

23
contracts/Migrations.sol Normal file
View File

@ -0,0 +1,23 @@
pragma solidity ^0.5.2;
contract Migrations {
address public owner;
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _;
}
constructor () public {
owner = msg.sender;
}
function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}
function upgrade(address new_address) public restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}

View File

@ -14,7 +14,7 @@ module.exports = {
'<rootDir>/config/jest/LocalStorageMock.js',
'<rootDir>/config/jest/Web3Mock.js',
],
setupFilesAfterEnv: ['<rootDir>/config/jest/jest.setup.js', 'react-testing-library/cleanup-after-each'],
setupFilesAfterEnv: ['<rootDir>/config/jest/jest.setup.js', '@testing-library/react/cleanup-after-each'],
testEnvironment: 'node',
testMatch: ['<rootDir>/src/**/__tests__/**/*.js?(x)', '<rootDir>/src/**/?(*.)(spec|test).js?(x)'],
testURL: 'http://localhost:8000',

View File

@ -0,0 +1,4 @@
// @flow
const Migrations = artifacts.require('./Migrations.sol')
module.exports = deployer => deployer.deploy(Migrations)

View File

@ -0,0 +1,21 @@
// @flow
/* eslint-disable no-console */
const TokenOMG = artifacts.require('TokenOMG')
const TokenRDN = artifacts.require('TokenRDN')
module.exports = (deployer, network) => {
let toBN
if (typeof web3.version === 'string') {
// 1.X.xx Web3
({ toBN } = web3.utils)
} else {
toBN = web3.toBigNumber
}
if (network === 'development') {
return deployer
.deploy(TokenOMG, toBN(50000).mul(toBN(10).pow(toBN(18))))
.then(() => deployer.deploy(TokenRDN, toBN(50000).mul(toBN(10).pow(toBN(18)))))
}
return console.log('Not running on development, skipping.')
}

View File

@ -35,7 +35,7 @@
"@material-ui/core": "4.0.1",
"@material-ui/icons": "4.0.1",
"@welldone-software/why-did-you-render": "^3.0.9",
"axios": "^0.18.0",
"axios": "0.19.0",
"bignumber.js": "9.0.0",
"connected-react-router": "^6.3.1",
"final-form": "4.13.0",
@ -47,7 +47,7 @@
"qrcode.react": "^0.9.3",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-final-form": "6.0.0",
"react-final-form": "6.0.1",
"react-final-form-listeners": "^1.0.2",
"react-hot-loader": "4.8.8",
"react-infinite-scroll-component": "^4.5.2",
@ -90,6 +90,7 @@
"@storybook/addon-knobs": "5.0.11",
"@storybook/addon-links": "5.0.11",
"@storybook/react": "5.0.11",
"@testing-library/react": "^8.0.1",
"autoprefixer": "9.5.1",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.0.1",
@ -111,7 +112,7 @@
"ethereumjs-abi": "^0.6.7",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"file-loader": "^3.0.1",
"flow-bin": "0.99.0",
"flow-bin": "0.99.1",
"fs-extra": "8.0.1",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.0.4",
@ -123,14 +124,13 @@
"postcss-simple-vars": "^5.0.2",
"pre-commit": "^1.2.2",
"prettier-eslint-cli": "^4.7.1",
"react-testing-library": "^7.0.1",
"run-with-testrpc": "0.3.1",
"storybook-host": "^5.0.3",
"storybook-router": "^0.3.3",
"style-loader": "^0.23.1",
"truffle": "5.0.19",
"truffle-contract": "4.0.17",
"truffle-solidity-loader": "0.1.18",
"truffle": "5.0.20",
"truffle-contract": "4.0.18",
"truffle-solidity-loader": "0.1.19",
"uglifyjs-webpack-plugin": "2.1.3",
"webpack": "4.32.2",
"webpack-bundle-analyzer": "3.3.2",

View File

@ -35,6 +35,23 @@ yarn start
## Running the tests
To run the test, you'll need to migrate contracts `safe-contracts` to the local ganache-cli
1. Migrating Safe Contracts:
```
git clone https://github.com/gnosis/safe-contracts.git
cd safe-contracts
yarn
ganache-cli -l 7000000
npx truffle compile
npx truffle migrate
```
2. Compiling Token Contracts for the tests:
Inside `safe-react` directory
```
npx truffle compile
```
3. Run the tests:
```
yarn test
```

View File

@ -1,6 +1,5 @@
// @flow
import * as React from 'react'
import contract from 'truffle-contract'
import { withStyles } from '@material-ui/core/styles'
import Field from '~/components/forms/Field'
import {

View File

@ -154,7 +154,7 @@ class Balances extends React.Component<Props, State> {
defaultFixed
>
{(sortedData: Array<BalanceRow>) => sortedData.map((row: any, index: number) => (
<TableRow tabIndex={-1} key={index} className={classes.hide}>
<TableRow tabIndex={-1} key={index} className={classes.hide} data-testid="balance-row">
{autoColumns.map((column: Column) => (
<TableCell key={column.id} style={cellWidth(column.width)} align={column.align} component="td">
{column.id === BALANCE_TABLE_ASSET_ID ? <AssetTableCell asset={row[column.id]} /> : row[column.id]}
@ -169,6 +169,7 @@ class Balances extends React.Component<Props, State> {
color="secondary"
className={classes.send}
onClick={() => this.showSendFunds(row.asset.name)}
data-testid="balance-send-btn"
>
<CallMade className={classNames(classes.leftIcon, classes.iconSmall)} />
Send

View File

@ -5,9 +5,9 @@ import SafeView from '~/routes/safe/components/Safe'
import { aNewStore, type GlobalState } from '~/store'
import { sleep } from '~/utils/timer'
import { getWeb3 } from '~/logic/wallets/getWeb3'
import { addEtherTo } from '~/test/utils/tokenMovements'
import { sendEtherTo } from '~/test/utils/tokenMovements'
import { aMinedSafe } from '~/test/builder/safe.redux.builder'
import { travelToSafe } from '~/test/builder/safe.dom.utils'
import { renderSafeView } from '~/test/builder/safe.dom.utils'
import { MOVE_FUNDS_BUTTON_TEXT } from '~/routes/safe/components/Safe/BalanceInfo'
export type DomSafe = {
@ -30,10 +30,10 @@ export const renderSafeInDom = async (owners: number = 1, threshold: number = 1)
// have available accounts
const accounts = await getWeb3().eth.getAccounts()
// navigate to SAFE route
const SafeDom = travelToSafe(store, address)
const SafeDom = renderSafeView(store, address)
// add funds to safe
await addEtherTo(address, '0.1')
await sendEtherTo(address, '0.1')
// wait until funds are displayed and buttons are enabled
await sleep(3000)

View File

@ -1,6 +1,7 @@
// @flow
import * as React from 'react'
import TestUtils from 'react-dom/test-utils'
import { render } from '@testing-library/react'
import ListItemText from '~/components/List/ListItemText/index'
import { SEE_MULTISIG_BUTTON_TEXT } from '~/routes/safe/components/Safe/MultisigTx'
import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions'
@ -92,7 +93,7 @@ export const refreshTransactions = async (store: Store<GlobalState>, safeAddress
await sleep(1500)
}
const createDom = (store: Store): React$Component<{}> => TestUtils.renderIntoDocument(
const renderApp = (store: Store) => render(
<Provider store={store}>
<ConnectedRouter history={history}>
<AppRoutes />
@ -100,17 +101,17 @@ const createDom = (store: Store): React$Component<{}> => TestUtils.renderIntoDoc
</Provider>,
)
export const travelToSafe = (store: Store, address: string): React$Component<{}> => {
export const renderSafeView = (store: Store, address: string) => {
history.push(`${SAFELIST_ADDRESS}/${address}`)
return createDom(store)
return renderApp(store)
}
export const travelToTokens = (store: Store, address: string): React$Component<{}> => {
const url = `${SAFELIST_ADDRESS}/${address}${SETTINS_ADDRESS}`
history.push(url)
return createDom(store)
return renderApp(store)
}
const INTERVAL = 500

View File

@ -0,0 +1,17 @@
pragma solidity ^0.5.2;
import "@gnosis.pm/util-contracts/contracts/GnosisStandardToken.sol";
contract TokenOMG is GnosisStandardToken {
string public constant symbol = "OMG";
string public constant name = "Omisego Token";
uint8 public constant decimals = 18;
constructor(
uint amount
)
public
{
balances[msg.sender] = amount;
}
}

View File

@ -0,0 +1,17 @@
pragma solidity ^0.5.2;
import "@gnosis.pm/util-contracts/contracts/GnosisStandardToken.sol";
contract TokenRDN is GnosisStandardToken {
string public constant symbol = "RDN";
string public constant name = "Raiden Token";
uint8 public constant decimals = 18;
constructor(
uint amount
)
public
{
balances[msg.sender] = amount;
}
}

View File

@ -1,7 +1,7 @@
// @flow
import * as React from 'react'
import { type Store } from 'redux'
import { render, fireEvent, cleanup } from 'react-testing-library'
import { render, fireEvent, cleanup } from '@testing-library/react'
import { Provider } from 'react-redux'
import { ConnectedRouter } from 'connected-react-router'
import { ADD_OWNER_BUTTON } from '~/routes/open/components/SafeOwnersForm'
@ -16,7 +16,7 @@ import { whenSafeDeployed } from './builder/safe.dom.utils'
afterEach(cleanup)
// https://github.com/testing-library/react-testing-library/issues/281
// https://github.com/testing-library/@testing-library/react/issues/281
const originalError = console.error
beforeAll(() => {
console.error = (...args) => {

View File

@ -1,16 +1,17 @@
// @flow
import TestUtils from 'react-dom/test-utils'
import { render, fireEvent, cleanup } from '@testing-library/react'
import * as fetchBalancesAction from '~/logic/tokens/store/actions/fetchTokens'
import { aNewStore } from '~/store'
import { aMinedSafe } from '~/test/builder/safe.redux.builder'
import { addTknTo, getFirstTokenContract } from '~/test/utils/tokenMovements'
import { EXPAND_BALANCE_INDEX, travelToSafe } from '~/test/builder/safe.dom.utils'
import { sendTokenTo, getFirstTokenContract } from '~/test/utils/tokenMovements'
import { EXPAND_BALANCE_INDEX, renderSafeView } from '~/test/builder/safe.dom.utils'
import { getWeb3 } from '~/logic/wallets/getWeb3'
import { sendMoveTokensForm, dispatchTknBalance } from '~/test/utils/transactions/moveTokens.helper'
import { sleep } from '~/utils/timer'
describe('DOM > Feature > SAFE ERC20 TOKENS', () => {
afterEach(cleanup)
describe('DOM > Feature > Funds', () => {
let store
let safeAddress: string
let accounts
@ -20,10 +21,10 @@ describe('DOM > Feature > SAFE ERC20 TOKENS', () => {
accounts = await getWeb3().eth.getAccounts()
})
it('sends ERC20 tokens', async () => {
it('Sends ETH', async () => {
// GIVEN
const numTokens = '100'
const tokenAddress = await addTknTo(safeAddress, numTokens)
const tokenAddress = await sendTokenTo(safeAddress, numTokens)
await dispatchTknBalance(store, tokenAddress, safeAddress)
// const StandardToken = await fetchBalancesAction.getStandardTokenContract()
@ -32,7 +33,39 @@ describe('DOM > Feature > SAFE ERC20 TOKENS', () => {
// console.log(await myToken.balanceOf(safeAddress))
// WHEN
const SafeDom = await travelToSafe(store, safeAddress)
const SafeDom = await renderSafeView(store, safeAddress)
await sleep(800)
const balanceRows = SafeDom.getAllByTestId('balance-row')
const buttons = TestUtils.scryRenderedDOMComponentsWithTag(SafeDom, 'button')
const expandBalance = buttons[EXPAND_BALANCE_INDEX]
const receiver = accounts[2]
await sendMoveTokensForm(SafeDom, expandBalance, 20, accounts[2])
// THEN
const safeFunds = await fetchBalancesAction.calculateBalanceOf(tokenAddress, safeAddress, 18)
expect(Number(safeFunds)).toBe(80)
const receiverFunds = await fetchBalancesAction.calculateBalanceOf(tokenAddress, receiver, 18)
expect(Number(receiverFunds)).toBe(20)
const token = await getFirstTokenContract(getWeb3(), accounts[0])
const nativeSafeFunds = await token.balanceOf(safeAddress)
expect(Number(nativeSafeFunds.valueOf())).toEqual(80 * 10 ** 18)
})
it('Sends Tokens', async () => {
// GIVEN
const numTokens = '100'
const tokenAddress = await sendTokenTo(safeAddress, numTokens)
await dispatchTknBalance(store, tokenAddress, safeAddress)
// const StandardToken = await fetchBalancesAction.getStandardTokenContract()
// const myToken = await StandardToken.at(tokenAddress)
// console.log(await myToken.allowance(safeAddress, accounts[2]))
// console.log(await myToken.balanceOf(safeAddress))
// WHEN
const SafeDom = await renderSafeView(store, safeAddress)
await sleep(800)
// $FlowFixMe
const buttons = TestUtils.scryRenderedDOMComponentsWithTag(SafeDom, 'button')
@ -50,25 +83,4 @@ describe('DOM > Feature > SAFE ERC20 TOKENS', () => {
const nativeSafeFunds = await token.balanceOf(safeAddress)
expect(Number(nativeSafeFunds.valueOf())).toEqual(80 * 10 ** 18)
})
it('disables send token button when balance is 0', async () => {
// GIVEN
const token = await getFirstTokenContract(getWeb3(), accounts[0])
await dispatchTknBalance(store, token.address, safeAddress)
// WHEN
const SafeDom = travelToSafe(store, safeAddress)
// $FlowFixMe
const buttons = TestUtils.scryRenderedDOMComponentsWithTag(SafeDom, 'button')
const expandBalance = buttons[EXPAND_BALANCE_INDEX]
TestUtils.Simulate.click(expandBalance)
await sleep(800)
// $FlowFixMe
const balanceButtons = TestUtils.scryRenderedDOMComponentsWithTag(SafeDom, 'button')
const tokenButton = balanceButtons[EXPAND_BALANCE_INDEX + 1] // expand button, and the next one is for sending
expect(tokenButton.hasAttribute('disabled')).toBe(true)
})
})

View File

@ -2,7 +2,7 @@
import * as React from 'react'
import { type Store } from 'redux'
import { Provider } from 'react-redux'
import { render, fireEvent, cleanup } from 'react-testing-library'
import { render, fireEvent, cleanup } from '@testing-library/react'
import { ConnectedRouter } from 'connected-react-router'
import Load from '~/routes/load/container/Load'
import { aNewStore, history, type GlobalState } from '~/store'
@ -15,7 +15,7 @@ import { whenSafeDeployed } from './builder/safe.dom.utils'
afterEach(cleanup)
// https://github.com/testing-library/react-testing-library/issues/281
// https://github.com/testing-library/@testing-library/react/issues/281
const originalError = console.error
beforeAll(() => {
console.error = (...args) => {

View File

@ -5,7 +5,7 @@ import { aNewStore } from '~/store'
import { aMinedSafe } from '~/test/builder/safe.redux.builder'
import { type Token } from '~/logic/tokens/store/model/token'
import { TOKEN_REDUCER_ID } from '~/logic/tokens/store/reducer/tokens'
import { addEtherTo, addTknTo } from '~/test/utils/tokenMovements'
import { sendEtherTo, sendTokenTo } from '~/test/utils/tokenMovements'
import { dispatchTknBalance } from '~/test/utils/transactions/moveTokens.helper'
import { ETH_ADDRESS } from '~/logic/tokens/utils/tokenHelpers'
@ -38,7 +38,7 @@ describe('Safe - redux balance property', () => {
it('reducer should return 0.03456 ETH as funds to safe with 0.03456 ETH', async () => {
// WHEN
await addEtherTo(address, '0.03456')
await sendEtherTo(address, '0.03456')
await store.dispatch(fetchTokensAction.fetchTokens(address))
// THEN
@ -57,7 +57,7 @@ describe('Safe - redux balance property', () => {
it('reducer should return 100 TKN when safe has 100 TKN', async () => {
// GIVEN
const numTokens = '100'
const tokenAddress = await addTknTo(address, numTokens)
const tokenAddress = await sendTokenTo(address, numTokens)
// WHEN
await dispatchTknBalance(store, tokenAddress, address)

View File

@ -4,7 +4,7 @@ import { List } from 'immutable'
import { getWeb3 } from '~/logic/wallets/getWeb3'
import { type Match } from 'react-router-dom'
import Checkbox from '@material-ui/core/Checkbox'
import { getFirstTokenContract, getSecondTokenContract, addTknTo } from '~/test/utils/tokenMovements'
import { getFirstTokenContract, getSecondTokenContract, sendTokenTo } from '~/test/utils/tokenMovements'
import { aNewStore } from '~/store'
import { aMinedSafe } from '~/test/builder/safe.redux.builder'
import { travelToTokens } from '~/test/builder/safe.dom.utils'
@ -76,8 +76,8 @@ describe('DOM > Feature > Enable and disable default tokens', () => {
// GIVEN
const store = aNewStore()
const safeAddress = await aMinedSafe(store)
await addTknTo(safeAddress, '50', firstErc20Token)
await addTknTo(safeAddress, '50', secondErc20Token)
await sendTokenTo(safeAddress, '50', firstErc20Token)
await sendTokenTo(safeAddress, '50', secondErc20Token)
await store.dispatch(fetchTokensModule.fetchTokens(safeAddress))
const match: Match = buildMathPropsFrom(safeAddress)

View File

@ -4,7 +4,7 @@ import { type Match } from 'react-router-dom'
import { getFirstTokenContract, getSecondTokenContract } from '~/test/utils/tokenMovements'
import { aNewStore } from '~/store'
import { aMinedSafe } from '~/test/builder/safe.redux.builder'
import { travelToSafe } from '~/test/builder/safe.dom.utils'
import { renderSafeView } from '~/test/builder/safe.dom.utils'
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
import { testToken } from '~/test/builder/tokens.dom.utils'
import * as fetchTokensModule from '~/logic/tokens/store/actions/fetchTokens'
@ -49,11 +49,11 @@ describe('DOM > Feature > Add new ERC 20 Tokens', () => {
// }
// const customAddTokensFn: any = (...args) => store.dispatch(addToken(...args))
// await addTokenFnc(values, customAddTokensFn, safeAddress)
// travelToSafe(store, safeAddress)
// renderSafeView(store, safeAddress)
// // WHEN
// const reloadedStore = aNewStore()
// await reloadedStore.dispatch(fetchTokensModule.fetchTokens(safeAddress))
// travelToSafe(reloadedStore, safeAddress) // reload
// renderSafeView(reloadedStore, safeAddress) // reload
// // THEN
// const match: Match = buildMathPropsFrom(safeAddress)
// const activeTokenList = activeTokensSelector(reloadedStore.getState(), { match })

View File

@ -4,7 +4,7 @@ import { type Match } from 'react-router-dom'
import { getFirstTokenContract, getSecondTokenContract } from '~/test/utils/tokenMovements'
import { aNewStore } from '~/store'
import { aMinedSafe } from '~/test/builder/safe.redux.builder'
import { travelToSafe } from '~/test/builder/safe.dom.utils'
import { renderSafeView } from '~/test/builder/safe.dom.utils'
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
import { testToken } from '~/test/builder/tokens.dom.utils'
import * as fetchTokensModule from '~/logic/tokens/store/actions/fetchTokens'
@ -76,7 +76,7 @@ describe('DOM > Feature > Add new ERC 20 Tokens', () => {
// // WHEN
// const reloadedStore = aNewStore()
// await reloadedStore.dispatch(fetchTokensModule.fetchTokens(safeAddress))
// travelToSafe(reloadedStore, safeAddress) // reload
// renderSafeView(reloadedStore, safeAddress) // reload
// // THEN
// checkTokensOf(reloadedStore, safeAddress)
// })

View File

@ -1,11 +1,12 @@
// @flow
import contract from 'truffle-contract'
import { getBalanceInEtherOf, getWeb3 } from '~/logic/wallets/getWeb3'
import Token from '#/test/TestToken.json'
import { ensureOnce } from '~/utils/singleton'
import { toNative } from '~/logic/wallets/tokens'
import TokenOMG from '../../../build/contracts/TokenOMG'
import TokenRDN from '../../../build/contracts/TokenRDN'
export const addEtherTo = async (address: string, eth: string) => {
export const sendEtherTo = async (address: string, eth: string) => {
const web3 = getWeb3()
const accounts = await web3.eth.getAccounts()
const txData = { from: accounts[0], to: address, value: web3.utils.toWei(eth, 'ether') }
@ -17,23 +18,34 @@ export const checkBalanceOf = async (addressToTest: string, value: string) => {
expect(safeBalance).toBe(value)
}
const createTokenContract = async (web3: any, executor: string) => {
const token = contract(Token)
const createTokenOMGContract = async (web3: any, creator: string) => {
const token = contract(TokenOMG)
const { toBN } = web3.utils
const amount = toBN(50000).mul(toBN(10).pow(toBN(18))).toString()
token.setProvider(web3.currentProvider)
return token.new({ from: executor, gas: '5000000' })
return token.new(amount, { from: creator })
}
export const getFirstTokenContract = ensureOnce(createTokenContract)
export const getSecondTokenContract = ensureOnce(createTokenContract)
const createTokenRDNContract = async (web3: any, creator: string) => {
const token = contract(TokenRDN)
const { toBN } = web3.utils
const amount = toBN(50000).mul(toBN(10).pow(toBN(18))).toString()
token.setProvider(web3.currentProvider)
export const addTknTo = async (safe: string, value: string, tokenContract?: any) => {
return token.new(amount, { from: creator })
}
export const getFirstTokenContract = ensureOnce(createTokenOMGContract)
export const getSecondTokenContract = ensureOnce(createTokenRDNContract)
export const sendTokenTo = async (safe: string, value: string, tokenContract?: any) => {
const web3 = getWeb3()
const accounts = await web3.eth.getAccounts()
const myToken = tokenContract || (await getFirstTokenContract(web3, accounts[0]))
const OMGToken = tokenContract || (await getFirstTokenContract(web3, accounts[0]))
const nativeValue = toNative(value, 18)
await myToken.transfer(safe, nativeValue.valueOf(), { from: accounts[0], gas: '5000000' })
await OMGToken.transfer(safe, nativeValue.valueOf(), { from: accounts[0], gas: '5000000' })
return myToken.address
return OMGToken.address
}

View File

@ -1,16 +1,18 @@
// @flow
module.exports = {
migrations_directory: "./migrations",
migrations_directory: './migrations',
networks: {
development: {
host: "localhost",
host: 'localhost',
port: 8545,
network_id: "*" //* Match any network id
}
network_id: '*', //* Match any network id
},
},
solc: {
optimizer: {
enabled: true,
runs: 500
}
}
};
runs: 500,
},
},
}

2805
yarn.lock

File diff suppressed because it is too large Load Diff