Repository: crytic/slither

Issue:
Type conversion failure when assigning YUL variable to string literal
The following contract causes an exception:
```
contract YULAssignStringLiteral {
    function f() public {
        assembly 
        { 
            let x := "oh_god_solidity" 
        }
    }
}
```

Output:
```
ERROR:root:Traceback (most recent call last):
  File "c:\users\x\documents\github\slither\slither\__main__.py", line 610, in main_impl
    (slither_instances, results_detectors, results_printers, number_contracts) = process_all(filename, args,
  File "c:\users\x\documents\github\slither\slither\__main__.py", line 67, in process_all
    (slither, current_results_detectors, current_results_printers, current_analyzed_count) = process_single(
  File "c:\users\x\documents\github\slither\slither\__main__.py", line 53, in process_single
    slither = Slither(target,
  File "c:\users\x\documents\github\slither\slither\slither.py", line 86, in __init__
    self._parser.analyze_contracts()
  File "c:\users\x\documents\github\slither\slither\solc_parsing\slitherSolc.py", line 345, in analyze_contracts
    self._convert_to_slithir()
  File "c:\users\x\documents\github\slither\slither\solc_parsing\slitherSolc.py", line 489, in _convert_to_slithir
    func.generate_slithir_and_analyze()
  File "c:\users\x\documents\github\slither\slither\core\declarations\function.py", line 1652, in generate_slithir_and_analyze
    node.slithir_generation()
  File "c:\users\x\documents\github\slither\slither\core\cfg\node.py", line 702, in slithir_generation
    self._irs = convert_expression(expression, self)
  File "c:\users\x\documents\github\slither\slither\slithir\convert.py", line 64, in convert_expression
    visitor = ExpressionToSlithIR(expression, node)
  File "c:\users\x\documents\github\slither\slither\visitors\slithir\expression_to_slithir.py", line 103, in __init__
    self._visit_expression(self.expression)
  File "c:\users\x\documents\github\slither\slither\visitors\expression\expression.py", line 45, in _visit_expression
    self._visit_assignement_operation(expression)
  File "c:\users\x\documents\github\slither\slither\visitors\expression\expression.py", line 101, in _visit_assignement_operation
    self._visit_expression(expression.expression_right)
  File "c:\users\x\documents\github\slither\slither\visitors\expression\expression.py", line 95, in _visit_expression
    self._post_visit(expression)
  File "c:\users\x\documents\github\slither\slither\visitors\expression\expression.py", line 286, in _post_visit
    self._post_literal(expression)
  File "c:\users\x\documents\github\slither\slither\visitors\slithir\expression_to_slithir.py", line 312, in _post_literal
    cst = Constant(expression.value, expression.type, expression.subdenomination)
  File "c:\users\x\documents\github\slither\slither\slithir\variables\constant.py", line 35, in __init__
    self._val = int(Decimal(val))
decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>]
```


Discussion:
Slightly different exception if it's a return value, something to keep in mind when refactoring:
```
contract YULReturnStringLiteral  {
    function f() public returns (bytes32 x) {
        assembly {
            x := "abcdef"
        }
    }
}

```
Output:
```
ERROR:root:Error in .\yul_return_string_literal.sol
ERROR:root:Traceback (most recent call last):
  File "c:\users\x\documents\github\slither\slither\__main__.py", line 610, in main_impl
    (slither_instances, results_detectors, results_printers, number_contracts) = process_all(filename, args,
  File "c:\users\x\documents\github\slither\slither\__main__.py", line 67, in process_all
    (slither, current_results_detectors, current_results_printers, current_analyzed_count) = process_single(
  File "c:\users\x\documents\github\slither\slither\__main__.py", line 53, in process_single
    slither = Slither(target,
  File "c:\users\x\documents\github\slither\slither\slither.py", line 86, in __init__
    self._parser.analyze_contracts()
  File "c:\users\x\documents\github\slither\slither\solc_parsing\slitherSolc.py", line 345, in analyze_contracts
    self._convert_to_slithir()
  File "c:\users\x\documents\github\slither\slither\solc_parsing\slitherSolc.py", line 489, in _convert_to_slithir
    func.generate_slithir_and_analyze()
  File "c:\users\x\documents\github\slither\slither\core\declarations\function.py", line 1652, in generate_slithir_and_analyze
    node.slithir_generation()
  File "c:\users\x\documents\github\slither\slither\core\cfg\node.py", line 702, in slithir_generation
    self._irs = convert_expression(expression, self)
  File "c:\users\x\documents\github\slither\slither\slithir\convert.py", line 64, in convert_expression
    visitor = ExpressionToSlithIR(expression, node)
  File "c:\users\x\documents\github\slither\slither\visitors\slithir\expression_to_slithir.py", line 103, in __init__
    self._visit_expression(self.expression)
  File "c:\users\x\documents\github\slither\slither\visitors\expression\expression.py", line 45, in _visit_expression
    self._visit_assignement_operation(expression)
  File "c:\users\x\documents\github\slither\slither\visitors\expression\expression.py", line 101, in _visit_assignement_operation
    self._visit_expression(expression.expression_right)
  File "c:\users\x\documents\github\slither\slither\visitors\expression\expression.py", line 95, in _visit_expression
    self._post_visit(expression)
  File "c:\users\x\documents\github\slither\slither\visitors\expression\expression.py", line 286, in _post_visit
    self._post_literal(expression)
  File "c:\users\x\documents\github\slither\slither\visitors\slithir\expression_to_slithir.py", line 312, in _post_literal
    cst = Constant(expression.value, expression.type, expression.subdenomination)
  File "c:\users\x\documents\github\slither\slither\slithir\variables\constant.py", line 30, in __init__
    self._val = int(Decimal(base) * (10 ** int(expo)))
decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>]
```

Resolving patch:
diff --git a/slither/solc_parsing/yul/parse_yul.py b/slither/solc_parsing/yul/parse_yul.py
--- a/slither/solc_parsing/yul/parse_yul.py
+++ b/slither/solc_parsing/yul/parse_yul.py
@@ -679,13 +679,16 @@ def parse_yul_identifier(root: YulScope, _node: YulNode, ast: Dict) -> Optional[
 
 
 def parse_yul_literal(_root: YulScope, _node: YulNode, ast: Dict) -> Optional[Expression]:
-    type_ = ast["type"]
+    kind = ast["kind"]
     value = ast["value"]
 
-    if not type_:
-        type_ = "bool" if value in ["true", "false"] else "uint256"
+    if not kind:
+        kind = "bool" if value in ["true", "false"] else "uint256"
 
-    return Literal(value, ElementaryType(type_))
+    if kind == "number":
+        kind = "uint256"
+
+    return Literal(value, ElementaryType(kind))
 
 
 def parse_yul_typed_name(root: YulScope, _node: YulNode, ast: Dict) -> Optional[Expression]:


Test patch: