Repository: vyperlang/vyper

Issue:
error with comparisons with the in statement with version v.0.3.5
### Version Information

* vyper Version: 0.3.5
* OS: Ubuntu 20.04.4 LTS
* Python Version : 3.9.9

### What's your issue about?

it seems there is an error with comparisons with the in statement with version v.0.3.5

the following code:
```vyper
@view
@external
def showError():
    adr1: address = 0xFbEEa1C75E4c4465CB2FCCc9c6d6afe984558E20
    adr2: address = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
    adr3: address = 0xFbEEa1C75E4c4465CB2FCCc9c6d6afe984558E20
    assert adr1 in [adr2,adr3], "error in comparison with in statement!"
```

works fine with version 0.3.4
adr1 in [adr2,adr3] == True --> this is correct!

with version 0.3.5 the assertion fails, but that is a bug because adr1 == adr3 so the result of the comparison should be true.
adr1 in [adr2,adr3] == False --> this is not correct!





Discussion:

Resolving patch:
diff --git a/vyper/codegen/expr.py b/vyper/codegen/expr.py
--- a/vyper/codegen/expr.py
+++ b/vyper/codegen/expr.py
@@ -420,12 +420,14 @@ def build_in_comparator(self):
             if right.value == "multi":
                 # empty list literals should be rejected at typechecking time
                 assert len(right.args) > 0
+                args = [unwrap_location(val) for val in right.args]
                 if isinstance(self.expr.op, vy_ast.In):
-                    checks = [["eq", left, val] for val in right.args]
+                    checks = [["eq", left, val] for val in args]
                     return b1.resolve(b2.resolve(Expr._logical_or(checks)))
                 if isinstance(self.expr.op, vy_ast.NotIn):
-                    checks = [["ne", left, val] for val in right.args]
+                    checks = [["ne", left, val] for val in args]
                     return b1.resolve(b2.resolve(Expr._logical_and(checks)))
+                return  # fail
 
             # general case: loop over the list and check each element
             # for equality


Test patch:
diff --git a/tests/parser/features/test_comparison.py b/tests/parser/features/test_comparison.py
new file mode 100644
--- /dev/null
+++ b/tests/parser/features/test_comparison.py
@@ -0,0 +1,48 @@
+# test syntactic comparisons
+# most tests under tests/ast/nodes/test_evaluate_compare.py
+import pytest
+
+
+def test_3034_verbatim(get_contract):
+    # test issue #3034 exactly
+    code = """
+@view
+@external
+def showError():
+    adr1: address = 0xFbEEa1C75E4c4465CB2FCCc9c6d6afe984558E20
+    adr2: address = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
+    adr3: address = 0xFbEEa1C75E4c4465CB2FCCc9c6d6afe984558E20
+    assert adr1 in [adr2,adr3], "error in comparison with in statement!"
+    """
+    c = get_contract(code)
+    c.showError()
+
+
+@pytest.mark.parametrize("invert", (True, False))
+def test_in_list(get_contract, invert):
+    # test slightly more complicated variations of #3034
+    INVERT = "not" if invert else ""
+    code = f"""
+SOME_ADDRESS: constant(address) = 0x22cb70ba2EC32347D9e32740fc14b2f3d038Ce8E
+@view
+@external
+def test_in(addr: address) -> bool:
+    x: address = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
+    y: address = 0xFbEEa1C75E4c4465CB2FCCc9c6d6afe984558E20
+    # in list which
+    return addr {INVERT} in [x, y, SOME_ADDRESS]
+    """
+    c = get_contract(code)
+    should_in = [
+        "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
+        "0xFbEEa1C75E4c4465CB2FCCc9c6d6afe984558E20",
+        "0x22cb70ba2EC32347D9e32740fc14b2f3d038Ce8E",
+    ]
+    should_not_in = [
+        "0x" + "00" * 20,
+        "0xfBeeA1C75E4C4465CB2fccC9C6d6AFe984558e21",  # y but last bit flipped
+    ]
+    for t in should_in:
+        assert c.test_in(t) is (True if not invert else False)
+    for t in should_not_in:
+        assert c.test_in(t) is (True if invert else False)