We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Slither misses some obvious dependency relations
```

pragma solidity ^0.4.24;

contract SlitherBug {
  uint256 rID_;
  bool public activated_ = false;

  modifier isHuman() {
    require(msg.sender == tx.origin, "sorry humans only");
    _;
  }
  
  // Function not vulnerable to re-entrancy attack

    function withdraw()
    isHuman()
    public {
        uint256 _rID = rID_;
  }
}

```


In the above contract slither outputs empty dependencies for the local varaible `_rID`. which is wrong. `_rID` is dependent on the state variable `_rID`.

My code to extract the dependency:

```
from slither.slither import Slither
import slither

slither_obj = Slither('slither_bug.sol')

for contract in slither_obj.contracts:
	if contract.name == 'SlitherBug':
		cont = contract

for function in cont.functions:
	if function.name == 'withdraw':
		func = function

node = func.nodes[1]

dep = slither.analyses.data_dependency.data_dependency.get_dependencies(node.irs[0].lvalue, func)

print(dep)
```

If I remove the line `require(msg.sender == tx.origin, "sorry humans only");` from the `modifier isHuman()` it outputs the state variable `_rID` as dependency; which is valid. 

Possibly a slither bug. Can you please look into this issue?

Slither misses some obvious dependency relations
```

pragma solidity ^0.4.24;

contract SlitherBug {
  uint256 rID_;
  bool public activated_ = false;

  modifier isHuman() {
    require(msg.sender == tx.origin, "sorry humans only");
    _;
  }
  
  // Function not vulnerable to re-entrancy attack

    function withdraw()
    isHuman()
    public {
        uint256 _rID = rID_;
  }
}

```


In the above contract slither outputs empty dependencies for the local varaible `_rID`. which is wrong. `_rID` is dependent on the state variable `_rID`.

My code to extract the dependency:

```
from slither.slither import Slither
import slither

slither_obj = Slither('slither_bug.sol')

for contract in slither_obj.contracts:
	if contract.name == 'SlitherBug':
		cont = contract

for function in cont.functions:
	if function.name == 'withdraw':
		func = function

node = func.nodes[1]

dep = slither.analyses.data_dependency.data_dependency.get_dependencies(node.irs[0].lvalue, func)

print(dep)
```

If I remove the line `require(msg.sender == tx.origin, "sorry humans only");` from the `modifier isHuman()` it outputs the state variable `_rID` as dependency; which is valid. 

Possibly a slither bug. Can you please look into this issue?


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `slither/analyses/data_dependency/data_dependency.py`
Content:
```
1 """
2     Compute the data depenency between all the SSA variables
3 """
4 from slither.core.declarations import (Contract, Enum, Function,
5                                        SolidityFunction, SolidityVariable,
6                                        SolidityVariableComposed, Structure)
7 from slither.slithir.operations import Index, OperationWithLValue, InternalCall
8 from slither.slithir.variables import (Constant, LocalIRVariable,
9                                        ReferenceVariable, ReferenceVariableSSA,
10                                        StateIRVariable, TemporaryVariable,
11                                        TemporaryVariableSSA, TupleVariableSSA)
12 from slither.core.solidity_types.type import Type
13 
14 ###################################################################################
15 ###################################################################################
16 # region User APIs
17 ###################################################################################
18 ###################################################################################
19 
20 def is_dependent(variable, source, context, only_unprotected=False):
21     '''
22     Args:
23         variable (Variable)
24         source (Variable)
25         context (Contract|Function)
26         only_unprotected (bool): True only unprotected function are considered
27     Returns:
28         bool
29     '''
30     assert isinstance(context, (Contract, Function))
31     if isinstance(variable, Constant):
32         return False
33     if variable == source:
34         return True
35     context = context.context
36 
37     if only_unprotected:
38         return variable in context[KEY_NON_SSA_UNPROTECTED] and source in context[KEY_NON_SSA_UNPROTECTED][variable]
39     return variable in context[KEY_NON_SSA] and source in context[KEY_NON_SSA][variable]
40 
41 def is_dependent_ssa(variable, source, context, only_unprotected=False):
42     '''
43     Args:
44         variable (Variable)
45         taint (Variable)
46         context (Contract|Function)
47         only_unprotected (bool): True only unprotected function are considered
48     Returns:
49         bool
50     '''
51     assert isinstance(context, (Contract, Function))
52     context = context.context
53     if isinstance(variable, Constant):
54         return False
55     if variable == source:
56         return True
57     if only_unprotected:
58         return variable in context[KEY_SSA_UNPROTECTED] and source in context[KEY_SSA_UNPROTECTED][variable]
59     return variable in context[KEY_SSA] and source in context[KEY_SSA][variable]
60 
61 GENERIC_TAINT = {SolidityVariableComposed('msg.sender'),
62                  SolidityVariableComposed('msg.value'),
63                  SolidityVariableComposed('msg.data'),
64                  SolidityVariableComposed('tx.origin')}
65 
66 def is_tainted(variable, context, only_unprotected=False, ignore_generic_taint=False):
67     '''
68         Args:
69         variable
70         context (Contract|Function)
71         only_unprotected (bool): True only unprotected function are considered
72     Returns:
73         bool
74     '''
75     assert isinstance(context, (Contract, Function))
76     assert isinstance(only_unprotected, bool)
77     if isinstance(variable, Constant):
78         return False
79     slither = context.slither
80     taints = slither.context[KEY_INPUT]
81     if not ignore_generic_taint:
82         taints |= GENERIC_TAINT
83     return variable in taints or any(is_dependent(variable, t, context, only_unprotected) for t in taints)
84 
85 def is_tainted_ssa(variable, context, only_unprotected=False, ignore_generic_taint=False):
86     '''
87     Args:
88         variable
89         context (Contract|Function)
90         only_unprotected (bool): True only unprotected function are considered
91     Returns:
92         bool
93     '''
94     assert isinstance(context, (Contract, Function))
95     assert isinstance(only_unprotected, bool)
96     if isinstance(variable, Constant):
97         return False
98     slither = context.slither
99     taints = slither.context[KEY_INPUT_SSA]
100     if not ignore_generic_taint:
101         taints |= GENERIC_TAINT
102     return variable in taints or any(is_dependent_ssa(variable, t, context, only_unprotected) for t in taints)
103 
104 
105 def get_dependencies(variable, context, only_unprotected=False):
106     '''
107     Args:
108         variable
109         context (Contract|Function)
110         only_unprotected (bool): True only unprotected function are considered
111     Returns:
112         list(Variable)
113     '''
114     assert isinstance(context, (Contract, Function))
115     assert isinstance(only_unprotected, bool)
116     if only_unprotected:
117         return context.context[KEY_NON_SSA].get(variable, [])
118     return context.context[KEY_NON_SSA_UNPROTECTED].get(variable, [])
119 
120 # endregion
121 ###################################################################################
122 ###################################################################################
123 # region Module constants
124 ###################################################################################
125 ###################################################################################
126 
127 KEY_SSA = "DATA_DEPENDENCY_SSA"
128 KEY_NON_SSA = "DATA_DEPENDENCY"
129 
130 # Only for unprotected functions
131 KEY_SSA_UNPROTECTED = "DATA_DEPENDENCY_SSA_UNPROTECTED"
132 KEY_NON_SSA_UNPROTECTED = "DATA_DEPENDENCY_UNPROTECTED"
133 
134 KEY_INPUT = "DATA_DEPENDENCY_INPUT"
135 KEY_INPUT_SSA = "DATA_DEPENDENCY_INPUT_SSA"
136 
137 
138 # endregion
139 ###################################################################################
140 ###################################################################################
141 # region Debug
142 ###################################################################################
143 ###################################################################################
144 
145 def pprint_dependency(context):
146     print('#### SSA ####')
147     context = context.context
148     for k, values in context[KEY_SSA].items():
149         print('{} ({}):'.format(k, id(k)))
150         for v in values:
151             print('\t- {}'.format(v))
152 
153     print('#### NON SSA ####')
154     for k, values in context[KEY_NON_SSA].items():
155         print('{} ({}):'.format(k, hex(id(k))))
156         for v in values:
157             print('\t- {} ({})'.format(v, hex(id(v))))
158 
159 # endregion
160 ###################################################################################
161 ###################################################################################
162 # region Analyses
163 ###################################################################################
164 ###################################################################################
165 
166 def compute_dependency(slither):
167 
168     slither.context[KEY_INPUT] = set()
169     slither.context[KEY_INPUT_SSA] = set()
170 
171     for contract in slither.contracts:
172         compute_dependency_contract(contract, slither)
173 
174 def compute_dependency_contract(contract, slither):
175     if KEY_SSA in contract.context:
176         return
177 
178     contract.context[KEY_SSA] = dict()
179     contract.context[KEY_SSA_UNPROTECTED] = dict()
180 
181     for function in contract.all_functions_called:
182         compute_dependency_function(function)
183 
184         propagate_function(contract, function, KEY_SSA, KEY_NON_SSA)
185         propagate_function(contract,
186                            function,
187                            KEY_SSA_UNPROTECTED,
188                            KEY_NON_SSA_UNPROTECTED)
189 
190         if function.visibility in ['public', 'external']:
191             [slither.context[KEY_INPUT].add(p) for p in function.parameters]
192             [slither.context[KEY_INPUT_SSA].add(p) for p in function.parameters_ssa]
193 
194     propagate_contract(contract, KEY_SSA, KEY_NON_SSA)
195     propagate_contract(contract, KEY_SSA_UNPROTECTED, KEY_NON_SSA_UNPROTECTED)
196 
197 def propagate_function(contract, function, context_key, context_key_non_ssa):
198     transitive_close_dependencies(function, context_key, context_key_non_ssa)
199     # Propage data dependency
200     data_depencencies = function.context[context_key]
201     for (key, values) in data_depencencies.items():
202         if not key in contract.context[context_key]:
203             contract.context[context_key][key] = set(values)
204         else:
205             contract.context[context_key][key].union(values)
206 
207 def transitive_close_dependencies(context, context_key, context_key_non_ssa):
208     # transitive closure
209     changed = True
210     while changed:
211         changed = False
212         # Need to create new set() as its changed during iteration
213         data_depencencies = {k: set([v for v in values]) for k, values in context.context[context_key].items()}
214         for key, items in data_depencencies.items():
215             for item in items:
216                 if item in data_depencencies:
217                     additional_items = context.context[context_key][item]
218                     for additional_item in additional_items:
219                         if not additional_item in items and additional_item != key:
220                             changed = True
221                             context.context[context_key][key].add(additional_item)
222     context.context[context_key_non_ssa] = convert_to_non_ssa(context.context[context_key])
223 
224 
225 def propagate_contract(contract, context_key, context_key_non_ssa):
226     transitive_close_dependencies(contract, context_key, context_key_non_ssa)
227 
228 def add_dependency(lvalue, function, ir, is_protected):
229     if not lvalue in function.context[KEY_SSA]:
230         function.context[KEY_SSA][lvalue] = set()
231         if not is_protected:
232             function.context[KEY_SSA_UNPROTECTED][lvalue] = set()
233     if isinstance(ir, Index):
234         read = [ir.variable_left]
235     elif isinstance(ir, InternalCall):
236         read = ir.function.return_values_ssa
237     else:
238         read = ir.read
239     [function.context[KEY_SSA][lvalue].add(v) for v in read if not isinstance(v, Constant)]
240     if not is_protected:
241         [function.context[KEY_SSA_UNPROTECTED][lvalue].add(v) for v in read if not isinstance(v, Constant)]
242 
243 
244 def compute_dependency_function(function):
245     if KEY_SSA in function.context:
246         return
247 
248     function.context[KEY_SSA] = dict()
249     function.context[KEY_SSA_UNPROTECTED] = dict()
250 
251     is_protected = function.is_protected()
252     for node in function.nodes:
253         for ir in node.irs_ssa:
254             if isinstance(ir, OperationWithLValue) and ir.lvalue:
255                 if isinstance(ir.lvalue, LocalIRVariable) and ir.lvalue.is_storage:
256                     continue
257                 if isinstance(ir.lvalue, ReferenceVariable):
258                     lvalue = ir.lvalue.points_to
259                     if lvalue:
260                         add_dependency(lvalue, function, ir, is_protected)
261                 add_dependency(ir.lvalue, function, ir, is_protected)
262 
263     function.context[KEY_NON_SSA] = convert_to_non_ssa(function.context[KEY_SSA])
264     function.context[KEY_NON_SSA_UNPROTECTED] = convert_to_non_ssa(function.context[KEY_SSA_UNPROTECTED])
265 
266 def convert_variable_to_non_ssa(v):
267     if isinstance(v, (LocalIRVariable, StateIRVariable, TemporaryVariableSSA, ReferenceVariableSSA, TupleVariableSSA)):
268         return v.non_ssa_version
269     assert isinstance(v, (Constant, SolidityVariable, Contract, Enum, SolidityFunction, Structure, Function, Type))
270     return v
271 
272 def convert_to_non_ssa(data_depencies):
273     # Need to create new set() as its changed during iteration
274     ret = dict()
275     for (k, values) in data_depencies.items():
276         var = convert_variable_to_non_ssa(k)
277         if not var in ret:
278             ret[var] = set()
279         ret[var] = ret[var].union(set([convert_variable_to_non_ssa(v) for v in
280                                        values]))
281 
282     return ret
283
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/slither/analyses/data_dependency/data_dependency.py b/slither/analyses/data_dependency/data_dependency.py
--- a/slither/analyses/data_dependency/data_dependency.py
+++ b/slither/analyses/data_dependency/data_dependency.py
@@ -114,8 +114,8 @@
     assert isinstance(context, (Contract, Function))
     assert isinstance(only_unprotected, bool)
     if only_unprotected:
-        return context.context[KEY_NON_SSA].get(variable, [])
-    return context.context[KEY_NON_SSA_UNPROTECTED].get(variable, [])
+        return context.context[KEY_NON_SSA_UNPROTECTED].get(variable, [])
+    return context.context[KEY_NON_SSA].get(variable, [])
 
 # endregion
 ###################################################################################

{"golden_diff": "diff --git a/slither/analyses/data_dependency/data_dependency.py b/slither/analyses/data_dependency/data_dependency.py\n--- a/slither/analyses/data_dependency/data_dependency.py\n+++ b/slither/analyses/data_dependency/data_dependency.py\n@@ -114,8 +114,8 @@\n     assert isinstance(context, (Contract, Function))\n     assert isinstance(only_unprotected, bool)\n     if only_unprotected:\n-        return context.context[KEY_NON_SSA].get(variable, [])\n-    return context.context[KEY_NON_SSA_UNPROTECTED].get(variable, [])\n+        return context.context[KEY_NON_SSA_UNPROTECTED].get(variable, [])\n+    return context.context[KEY_NON_SSA].get(variable, [])\n \n # endregion\n ###################################################################################\n", "issue": "Slither misses some obvious dependency relations\n```\r\n\r\npragma solidity ^0.4.24;\r\n\r\ncontract SlitherBug {\r\n  uint256 rID_;\r\n  bool public activated_ = false;\r\n\r\n  modifier isHuman() {\r\n    require(msg.sender == tx.origin, \"sorry humans only\");\r\n    _;\r\n  }\r\n  \r\n  // Function not vulnerable to re-entrancy attack\r\n\r\n    function withdraw()\r\n    isHuman()\r\n    public {\r\n        uint256 _rID = rID_;\r\n  }\r\n}\r\n\r\n```\r\n\r\n\r\nIn the above contract slither outputs empty dependencies for the local varaible `_rID`. which is wrong. `_rID` is dependent on the state variable `_rID`.\r\n\r\nMy code to extract the dependency:\r\n\r\n```\r\nfrom slither.slither import Slither\r\nimport slither\r\n\r\nslither_obj = Slither('slither_bug.sol')\r\n\r\nfor contract in slither_obj.contracts:\r\n\tif contract.name == 'SlitherBug':\r\n\t\tcont = contract\r\n\r\nfor function in cont.functions:\r\n\tif function.name == 'withdraw':\r\n\t\tfunc = function\r\n\r\nnode = func.nodes[1]\r\n\r\ndep = slither.analyses.data_dependency.data_dependency.get_dependencies(node.irs[0].lvalue, func)\r\n\r\nprint(dep)\r\n```\r\n\r\nIf I remove the line `require(msg.sender == tx.origin, \"sorry humans only\");` from the `modifier isHuman()` it outputs the state variable `_rID` as dependency; which is valid. \r\n\r\nPossibly a slither bug. Can you please look into this issue?\r\n\nSlither misses some obvious dependency relations\n```\r\n\r\npragma solidity ^0.4.24;\r\n\r\ncontract SlitherBug {\r\n  uint256 rID_;\r\n  bool public activated_ = false;\r\n\r\n  modifier isHuman() {\r\n    require(msg.sender == tx.origin, \"sorry humans only\");\r\n    _;\r\n  }\r\n  \r\n  // Function not vulnerable to re-entrancy attack\r\n\r\n    function withdraw()\r\n    isHuman()\r\n    public {\r\n        uint256 _rID = rID_;\r\n  }\r\n}\r\n\r\n```\r\n\r\n\r\nIn the above contract slither outputs empty dependencies for the local varaible `_rID`. which is wrong. `_rID` is dependent on the state variable `_rID`.\r\n\r\nMy code to extract the dependency:\r\n\r\n```\r\nfrom slither.slither import Slither\r\nimport slither\r\n\r\nslither_obj = Slither('slither_bug.sol')\r\n\r\nfor contract in slither_obj.contracts:\r\n\tif contract.name == 'SlitherBug':\r\n\t\tcont = contract\r\n\r\nfor function in cont.functions:\r\n\tif function.name == 'withdraw':\r\n\t\tfunc = function\r\n\r\nnode = func.nodes[1]\r\n\r\ndep = slither.analyses.data_dependency.data_dependency.get_dependencies(node.irs[0].lvalue, func)\r\n\r\nprint(dep)\r\n```\r\n\r\nIf I remove the line `require(msg.sender == tx.origin, \"sorry humans only\");` from the `modifier isHuman()` it outputs the state variable `_rID` as dependency; which is valid. \r\n\r\nPossibly a slither bug. Can you please look into this issue?\r\n\n", "before_files": [{"content": "\"\"\"\n    Compute the data depenency between all the SSA variables\n\"\"\"\nfrom slither.core.declarations import (Contract, Enum, Function,\n                                       SolidityFunction, SolidityVariable,\n                                       SolidityVariableComposed, Structure)\nfrom slither.slithir.operations import Index, OperationWithLValue, InternalCall\nfrom slither.slithir.variables import (Constant, LocalIRVariable,\n                                       ReferenceVariable, ReferenceVariableSSA,\n                                       StateIRVariable, TemporaryVariable,\n                                       TemporaryVariableSSA, TupleVariableSSA)\nfrom slither.core.solidity_types.type import Type\n\n###################################################################################\n###################################################################################\n# region User APIs\n###################################################################################\n###################################################################################\n\ndef is_dependent(variable, source, context, only_unprotected=False):\n    '''\n    Args:\n        variable (Variable)\n        source (Variable)\n        context (Contract|Function)\n        only_unprotected (bool): True only unprotected function are considered\n    Returns:\n        bool\n    '''\n    assert isinstance(context, (Contract, Function))\n    if isinstance(variable, Constant):\n        return False\n    if variable == source:\n        return True\n    context = context.context\n\n    if only_unprotected:\n        return variable in context[KEY_NON_SSA_UNPROTECTED] and source in context[KEY_NON_SSA_UNPROTECTED][variable]\n    return variable in context[KEY_NON_SSA] and source in context[KEY_NON_SSA][variable]\n\ndef is_dependent_ssa(variable, source, context, only_unprotected=False):\n    '''\n    Args:\n        variable (Variable)\n        taint (Variable)\n        context (Contract|Function)\n        only_unprotected (bool): True only unprotected function are considered\n    Returns:\n        bool\n    '''\n    assert isinstance(context, (Contract, Function))\n    context = context.context\n    if isinstance(variable, Constant):\n        return False\n    if variable == source:\n        return True\n    if only_unprotected:\n        return variable in context[KEY_SSA_UNPROTECTED] and source in context[KEY_SSA_UNPROTECTED][variable]\n    return variable in context[KEY_SSA] and source in context[KEY_SSA][variable]\n\nGENERIC_TAINT = {SolidityVariableComposed('msg.sender'),\n                 SolidityVariableComposed('msg.value'),\n                 SolidityVariableComposed('msg.data'),\n                 SolidityVariableComposed('tx.origin')}\n\ndef is_tainted(variable, context, only_unprotected=False, ignore_generic_taint=False):\n    '''\n        Args:\n        variable\n        context (Contract|Function)\n        only_unprotected (bool): True only unprotected function are considered\n    Returns:\n        bool\n    '''\n    assert isinstance(context, (Contract, Function))\n    assert isinstance(only_unprotected, bool)\n    if isinstance(variable, Constant):\n        return False\n    slither = context.slither\n    taints = slither.context[KEY_INPUT]\n    if not ignore_generic_taint:\n        taints |= GENERIC_TAINT\n    return variable in taints or any(is_dependent(variable, t, context, only_unprotected) for t in taints)\n\ndef is_tainted_ssa(variable, context, only_unprotected=False, ignore_generic_taint=False):\n    '''\n    Args:\n        variable\n        context (Contract|Function)\n        only_unprotected (bool): True only unprotected function are considered\n    Returns:\n        bool\n    '''\n    assert isinstance(context, (Contract, Function))\n    assert isinstance(only_unprotected, bool)\n    if isinstance(variable, Constant):\n        return False\n    slither = context.slither\n    taints = slither.context[KEY_INPUT_SSA]\n    if not ignore_generic_taint:\n        taints |= GENERIC_TAINT\n    return variable in taints or any(is_dependent_ssa(variable, t, context, only_unprotected) for t in taints)\n\n\ndef get_dependencies(variable, context, only_unprotected=False):\n    '''\n    Args:\n        variable\n        context (Contract|Function)\n        only_unprotected (bool): True only unprotected function are considered\n    Returns:\n        list(Variable)\n    '''\n    assert isinstance(context, (Contract, Function))\n    assert isinstance(only_unprotected, bool)\n    if only_unprotected:\n        return context.context[KEY_NON_SSA].get(variable, [])\n    return context.context[KEY_NON_SSA_UNPROTECTED].get(variable, [])\n\n# endregion\n###################################################################################\n###################################################################################\n# region Module constants\n###################################################################################\n###################################################################################\n\nKEY_SSA = \"DATA_DEPENDENCY_SSA\"\nKEY_NON_SSA = \"DATA_DEPENDENCY\"\n\n# Only for unprotected functions\nKEY_SSA_UNPROTECTED = \"DATA_DEPENDENCY_SSA_UNPROTECTED\"\nKEY_NON_SSA_UNPROTECTED = \"DATA_DEPENDENCY_UNPROTECTED\"\n\nKEY_INPUT = \"DATA_DEPENDENCY_INPUT\"\nKEY_INPUT_SSA = \"DATA_DEPENDENCY_INPUT_SSA\"\n\n\n# endregion\n###################################################################################\n###################################################################################\n# region Debug\n###################################################################################\n###################################################################################\n\ndef pprint_dependency(context):\n    print('#### SSA ####')\n    context = context.context\n    for k, values in context[KEY_SSA].items():\n        print('{} ({}):'.format(k, id(k)))\n        for v in values:\n            print('\\t- {}'.format(v))\n\n    print('#### NON SSA ####')\n    for k, values in context[KEY_NON_SSA].items():\n        print('{} ({}):'.format(k, hex(id(k))))\n        for v in values:\n            print('\\t- {} ({})'.format(v, hex(id(v))))\n\n# endregion\n###################################################################################\n###################################################################################\n# region Analyses\n###################################################################################\n###################################################################################\n\ndef compute_dependency(slither):\n\n    slither.context[KEY_INPUT] = set()\n    slither.context[KEY_INPUT_SSA] = set()\n\n    for contract in slither.contracts:\n        compute_dependency_contract(contract, slither)\n\ndef compute_dependency_contract(contract, slither):\n    if KEY_SSA in contract.context:\n        return\n\n    contract.context[KEY_SSA] = dict()\n    contract.context[KEY_SSA_UNPROTECTED] = dict()\n\n    for function in contract.all_functions_called:\n        compute_dependency_function(function)\n\n        propagate_function(contract, function, KEY_SSA, KEY_NON_SSA)\n        propagate_function(contract,\n                           function,\n                           KEY_SSA_UNPROTECTED,\n                           KEY_NON_SSA_UNPROTECTED)\n\n        if function.visibility in ['public', 'external']:\n            [slither.context[KEY_INPUT].add(p) for p in function.parameters]\n            [slither.context[KEY_INPUT_SSA].add(p) for p in function.parameters_ssa]\n\n    propagate_contract(contract, KEY_SSA, KEY_NON_SSA)\n    propagate_contract(contract, KEY_SSA_UNPROTECTED, KEY_NON_SSA_UNPROTECTED)\n\ndef propagate_function(contract, function, context_key, context_key_non_ssa):\n    transitive_close_dependencies(function, context_key, context_key_non_ssa)\n    # Propage data dependency\n    data_depencencies = function.context[context_key]\n    for (key, values) in data_depencencies.items():\n        if not key in contract.context[context_key]:\n            contract.context[context_key][key] = set(values)\n        else:\n            contract.context[context_key][key].union(values)\n\ndef transitive_close_dependencies(context, context_key, context_key_non_ssa):\n    # transitive closure\n    changed = True\n    while changed:\n        changed = False\n        # Need to create new set() as its changed during iteration\n        data_depencencies = {k: set([v for v in values]) for k, values in context.context[context_key].items()}\n        for key, items in data_depencencies.items():\n            for item in items:\n                if item in data_depencencies:\n                    additional_items = context.context[context_key][item]\n                    for additional_item in additional_items:\n                        if not additional_item in items and additional_item != key:\n                            changed = True\n                            context.context[context_key][key].add(additional_item)\n    context.context[context_key_non_ssa] = convert_to_non_ssa(context.context[context_key])\n\n\ndef propagate_contract(contract, context_key, context_key_non_ssa):\n    transitive_close_dependencies(contract, context_key, context_key_non_ssa)\n\ndef add_dependency(lvalue, function, ir, is_protected):\n    if not lvalue in function.context[KEY_SSA]:\n        function.context[KEY_SSA][lvalue] = set()\n        if not is_protected:\n            function.context[KEY_SSA_UNPROTECTED][lvalue] = set()\n    if isinstance(ir, Index):\n        read = [ir.variable_left]\n    elif isinstance(ir, InternalCall):\n        read = ir.function.return_values_ssa\n    else:\n        read = ir.read\n    [function.context[KEY_SSA][lvalue].add(v) for v in read if not isinstance(v, Constant)]\n    if not is_protected:\n        [function.context[KEY_SSA_UNPROTECTED][lvalue].add(v) for v in read if not isinstance(v, Constant)]\n\n\ndef compute_dependency_function(function):\n    if KEY_SSA in function.context:\n        return\n\n    function.context[KEY_SSA] = dict()\n    function.context[KEY_SSA_UNPROTECTED] = dict()\n\n    is_protected = function.is_protected()\n    for node in function.nodes:\n        for ir in node.irs_ssa:\n            if isinstance(ir, OperationWithLValue) and ir.lvalue:\n                if isinstance(ir.lvalue, LocalIRVariable) and ir.lvalue.is_storage:\n                    continue\n                if isinstance(ir.lvalue, ReferenceVariable):\n                    lvalue = ir.lvalue.points_to\n                    if lvalue:\n                        add_dependency(lvalue, function, ir, is_protected)\n                add_dependency(ir.lvalue, function, ir, is_protected)\n\n    function.context[KEY_NON_SSA] = convert_to_non_ssa(function.context[KEY_SSA])\n    function.context[KEY_NON_SSA_UNPROTECTED] = convert_to_non_ssa(function.context[KEY_SSA_UNPROTECTED])\n\ndef convert_variable_to_non_ssa(v):\n    if isinstance(v, (LocalIRVariable, StateIRVariable, TemporaryVariableSSA, ReferenceVariableSSA, TupleVariableSSA)):\n        return v.non_ssa_version\n    assert isinstance(v, (Constant, SolidityVariable, Contract, Enum, SolidityFunction, Structure, Function, Type))\n    return v\n\ndef convert_to_non_ssa(data_depencies):\n    # Need to create new set() as its changed during iteration\n    ret = dict()\n    for (k, values) in data_depencies.items():\n        var = convert_variable_to_non_ssa(k)\n        if not var in ret:\n            ret[var] = set()\n        ret[var] = ret[var].union(set([convert_variable_to_non_ssa(v) for v in\n                                       values]))\n\n    return ret\n", "path": "slither/analyses/data_dependency/data_dependency.py"}], "after_files": [{"content": "\"\"\"\n    Compute the data depenency between all the SSA variables\n\"\"\"\nfrom slither.core.declarations import (Contract, Enum, Function,\n                                       SolidityFunction, SolidityVariable,\n                                       SolidityVariableComposed, Structure)\nfrom slither.slithir.operations import Index, OperationWithLValue, InternalCall\nfrom slither.slithir.variables import (Constant, LocalIRVariable,\n                                       ReferenceVariable, ReferenceVariableSSA,\n                                       StateIRVariable, TemporaryVariable,\n                                       TemporaryVariableSSA, TupleVariableSSA)\nfrom slither.core.solidity_types.type import Type\n\n###################################################################################\n###################################################################################\n# region User APIs\n###################################################################################\n###################################################################################\n\ndef is_dependent(variable, source, context, only_unprotected=False):\n    '''\n    Args:\n        variable (Variable)\n        source (Variable)\n        context (Contract|Function)\n        only_unprotected (bool): True only unprotected function are considered\n    Returns:\n        bool\n    '''\n    assert isinstance(context, (Contract, Function))\n    if isinstance(variable, Constant):\n        return False\n    if variable == source:\n        return True\n    context = context.context\n\n    if only_unprotected:\n        return variable in context[KEY_NON_SSA_UNPROTECTED] and source in context[KEY_NON_SSA_UNPROTECTED][variable]\n    return variable in context[KEY_NON_SSA] and source in context[KEY_NON_SSA][variable]\n\ndef is_dependent_ssa(variable, source, context, only_unprotected=False):\n    '''\n    Args:\n        variable (Variable)\n        taint (Variable)\n        context (Contract|Function)\n        only_unprotected (bool): True only unprotected function are considered\n    Returns:\n        bool\n    '''\n    assert isinstance(context, (Contract, Function))\n    context = context.context\n    if isinstance(variable, Constant):\n        return False\n    if variable == source:\n        return True\n    if only_unprotected:\n        return variable in context[KEY_SSA_UNPROTECTED] and source in context[KEY_SSA_UNPROTECTED][variable]\n    return variable in context[KEY_SSA] and source in context[KEY_SSA][variable]\n\nGENERIC_TAINT = {SolidityVariableComposed('msg.sender'),\n                 SolidityVariableComposed('msg.value'),\n                 SolidityVariableComposed('msg.data'),\n                 SolidityVariableComposed('tx.origin')}\n\ndef is_tainted(variable, context, only_unprotected=False, ignore_generic_taint=False):\n    '''\n        Args:\n        variable\n        context (Contract|Function)\n        only_unprotected (bool): True only unprotected function are considered\n    Returns:\n        bool\n    '''\n    assert isinstance(context, (Contract, Function))\n    assert isinstance(only_unprotected, bool)\n    if isinstance(variable, Constant):\n        return False\n    slither = context.slither\n    taints = slither.context[KEY_INPUT]\n    if not ignore_generic_taint:\n        taints |= GENERIC_TAINT\n    return variable in taints or any(is_dependent(variable, t, context, only_unprotected) for t in taints)\n\ndef is_tainted_ssa(variable, context, only_unprotected=False, ignore_generic_taint=False):\n    '''\n    Args:\n        variable\n        context (Contract|Function)\n        only_unprotected (bool): True only unprotected function are considered\n    Returns:\n        bool\n    '''\n    assert isinstance(context, (Contract, Function))\n    assert isinstance(only_unprotected, bool)\n    if isinstance(variable, Constant):\n        return False\n    slither = context.slither\n    taints = slither.context[KEY_INPUT_SSA]\n    if not ignore_generic_taint:\n        taints |= GENERIC_TAINT\n    return variable in taints or any(is_dependent_ssa(variable, t, context, only_unprotected) for t in taints)\n\n\ndef get_dependencies(variable, context, only_unprotected=False):\n    '''\n    Args:\n        variable\n        context (Contract|Function)\n        only_unprotected (bool): True only unprotected function are considered\n    Returns:\n        list(Variable)\n    '''\n    assert isinstance(context, (Contract, Function))\n    assert isinstance(only_unprotected, bool)\n    if only_unprotected:\n        return context.context[KEY_NON_SSA_UNPROTECTED].get(variable, [])\n    return context.context[KEY_NON_SSA].get(variable, [])\n\n# endregion\n###################################################################################\n###################################################################################\n# region Module constants\n###################################################################################\n###################################################################################\n\nKEY_SSA = \"DATA_DEPENDENCY_SSA\"\nKEY_NON_SSA = \"DATA_DEPENDENCY\"\n\n# Only for unprotected functions\nKEY_SSA_UNPROTECTED = \"DATA_DEPENDENCY_SSA_UNPROTECTED\"\nKEY_NON_SSA_UNPROTECTED = \"DATA_DEPENDENCY_UNPROTECTED\"\n\nKEY_INPUT = \"DATA_DEPENDENCY_INPUT\"\nKEY_INPUT_SSA = \"DATA_DEPENDENCY_INPUT_SSA\"\n\n\n# endregion\n###################################################################################\n###################################################################################\n# region Debug\n###################################################################################\n###################################################################################\n\ndef pprint_dependency(context):\n    print('#### SSA ####')\n    context = context.context\n    for k, values in context[KEY_SSA].items():\n        print('{} ({}):'.format(k, id(k)))\n        for v in values:\n            print('\\t- {}'.format(v))\n\n    print('#### NON SSA ####')\n    for k, values in context[KEY_NON_SSA].items():\n        print('{} ({}):'.format(k, hex(id(k))))\n        for v in values:\n            print('\\t- {} ({})'.format(v, hex(id(v))))\n\n# endregion\n###################################################################################\n###################################################################################\n# region Analyses\n###################################################################################\n###################################################################################\n\ndef compute_dependency(slither):\n\n    slither.context[KEY_INPUT] = set()\n    slither.context[KEY_INPUT_SSA] = set()\n\n    for contract in slither.contracts:\n        compute_dependency_contract(contract, slither)\n\ndef compute_dependency_contract(contract, slither):\n    if KEY_SSA in contract.context:\n        return\n\n    contract.context[KEY_SSA] = dict()\n    contract.context[KEY_SSA_UNPROTECTED] = dict()\n\n    for function in contract.all_functions_called:\n        compute_dependency_function(function)\n\n        propagate_function(contract, function, KEY_SSA, KEY_NON_SSA)\n        propagate_function(contract,\n                           function,\n                           KEY_SSA_UNPROTECTED,\n                           KEY_NON_SSA_UNPROTECTED)\n\n        if function.visibility in ['public', 'external']:\n            [slither.context[KEY_INPUT].add(p) for p in function.parameters]\n            [slither.context[KEY_INPUT_SSA].add(p) for p in function.parameters_ssa]\n\n    propagate_contract(contract, KEY_SSA, KEY_NON_SSA)\n    propagate_contract(contract, KEY_SSA_UNPROTECTED, KEY_NON_SSA_UNPROTECTED)\n\ndef propagate_function(contract, function, context_key, context_key_non_ssa):\n    transitive_close_dependencies(function, context_key, context_key_non_ssa)\n    # Propage data dependency\n    data_depencencies = function.context[context_key]\n    for (key, values) in data_depencencies.items():\n        if not key in contract.context[context_key]:\n            contract.context[context_key][key] = set(values)\n        else:\n            contract.context[context_key][key].union(values)\n\ndef transitive_close_dependencies(context, context_key, context_key_non_ssa):\n    # transitive closure\n    changed = True\n    while changed:\n        changed = False\n        # Need to create new set() as its changed during iteration\n        data_depencencies = {k: set([v for v in values]) for k, values in context.context[context_key].items()}\n        for key, items in data_depencencies.items():\n            for item in items:\n                if item in data_depencencies:\n                    additional_items = context.context[context_key][item]\n                    for additional_item in additional_items:\n                        if not additional_item in items and additional_item != key:\n                            changed = True\n                            context.context[context_key][key].add(additional_item)\n    context.context[context_key_non_ssa] = convert_to_non_ssa(context.context[context_key])\n\n\ndef propagate_contract(contract, context_key, context_key_non_ssa):\n    transitive_close_dependencies(contract, context_key, context_key_non_ssa)\n\ndef add_dependency(lvalue, function, ir, is_protected):\n    if not lvalue in function.context[KEY_SSA]:\n        function.context[KEY_SSA][lvalue] = set()\n        if not is_protected:\n            function.context[KEY_SSA_UNPROTECTED][lvalue] = set()\n    if isinstance(ir, Index):\n        read = [ir.variable_left]\n    elif isinstance(ir, InternalCall):\n        read = ir.function.return_values_ssa\n    else:\n        read = ir.read\n    [function.context[KEY_SSA][lvalue].add(v) for v in read if not isinstance(v, Constant)]\n    if not is_protected:\n        [function.context[KEY_SSA_UNPROTECTED][lvalue].add(v) for v in read if not isinstance(v, Constant)]\n\n\ndef compute_dependency_function(function):\n    if KEY_SSA in function.context:\n        return\n\n    function.context[KEY_SSA] = dict()\n    function.context[KEY_SSA_UNPROTECTED] = dict()\n\n    is_protected = function.is_protected()\n    for node in function.nodes:\n        for ir in node.irs_ssa:\n            if isinstance(ir, OperationWithLValue) and ir.lvalue:\n                if isinstance(ir.lvalue, LocalIRVariable) and ir.lvalue.is_storage:\n                    continue\n                if isinstance(ir.lvalue, ReferenceVariable):\n                    lvalue = ir.lvalue.points_to\n                    if lvalue:\n                        add_dependency(lvalue, function, ir, is_protected)\n                add_dependency(ir.lvalue, function, ir, is_protected)\n\n    function.context[KEY_NON_SSA] = convert_to_non_ssa(function.context[KEY_SSA])\n    function.context[KEY_NON_SSA_UNPROTECTED] = convert_to_non_ssa(function.context[KEY_SSA_UNPROTECTED])\n\ndef convert_variable_to_non_ssa(v):\n    if isinstance(v, (LocalIRVariable, StateIRVariable, TemporaryVariableSSA, ReferenceVariableSSA, TupleVariableSSA)):\n        return v.non_ssa_version\n    assert isinstance(v, (Constant, SolidityVariable, Contract, Enum, SolidityFunction, Structure, Function, Type))\n    return v\n\ndef convert_to_non_ssa(data_depencies):\n    # Need to create new set() as its changed during iteration\n    ret = dict()\n    for (k, values) in data_depencies.items():\n        var = convert_variable_to_non_ssa(k)\n        if not var in ret:\n            ret[var] = set()\n        ret[var] = ret[var].union(set([convert_variable_to_non_ssa(v) for v in\n                                       values]))\n\n    return ret\n", "path": "slither/analyses/data_dependency/data_dependency.py"}]}