Repository: vyperlang/vyper

Issue:
Log topic and data allow byte array longer than 32 bytes.
### What's your issue about?
When packing data/topic for log, if the the actual argument is a byte array variable, there is no check for the actual length of the variable.
e.g.,
```
MyLog: __log__({arg1: indexed(bytes<=2000)})

@public
def foo():
    a: bytes<=100
    log.MyLog(a)
```
This program should be rejected by is not.

### How can it be fixed?

Add check in event_sig, pack_arg_by_32 and pack_logging_topic.

#### Cute Animal Picture
![image](https://user-images.githubusercontent.com/5641590/33631206-753fab08-d9cf-11e7-89b4-f2d71f844453.png)




Discussion:
Strictly speaking, `bytes<=100` maintains the invariant of the space provided by the log, e.g `bytes<=2000`

I could see a scenario where you might want to bundle things together inside a larger allocation of bytes (you might not know the shape of the bundle beforehand). Not sure if this affects verification, in my mind all that you're verifying is the size in bytes is not exceeded. My 2 wei
@fubuloubu I was told by @DavidKnott that 32 byte topics is an evm constraint while 32 byte data is a Viper constraint. The length of a topic should not exceed 32 bytes (This is enforced on string literals, seehttps://github.com/ethereum/viper/blob/b0cec59d24051e3bb3577475211c277e78c68a23/viper/parser/parser.py#L665)

Resolving patch:
diff --git a/viper/signatures/event_signature.py b/viper/signatures/event_signature.py
--- a/viper/signatures/event_signature.py
+++ b/viper/signatures/event_signature.py
@@ -39,9 +39,9 @@ def from_declaration(cls, code):
                     else:
                         raise VariableDeclarationException("Only indexed keyword is allowed", arg)
                 else:
-                    if hasattr(typ, 'left') and typ.left.id == 'bytes' and typ.comparators[0].n > 32:
-                        raise VariableDeclarationException("Can only log a maximum of 32 bytes at a time.")
                     indexed_list.append(False)
+                if hasattr(typ, 'left') and typ.left.id == 'bytes' and typ.comparators[0].n > 32:
+                    raise VariableDeclarationException("Can only log a maximum of 32 bytes at a time.")
                 if topics_count > 4:
                     raise VariableDeclarationException("Maximum of 3 topics {} given".format(topics_count - 1), arg)
                 if not isinstance(arg, str):


Test patch:
diff --git a/tests/parser/features/test_logging.py b/tests/parser/features/test_logging.py
--- a/tests/parser/features/test_logging.py
+++ b/tests/parser/features/test_logging.py
@@ -640,3 +640,21 @@ def set_list():
     c.set_list()
     c.foo()
     assert get_last_log(t, c)["_value"] == [1.33, 2.33, 3.33, 4.33]
+
+
+def test_logging_fails_when_declartation_is_too_big(assert_tx_failed, get_contract_with_gas_estimation):
+    code = """
+Bar: __log__({_value: indexed(bytes <= 33)})
+"""
+    assert_tx_failed(lambda: get_contract_with_gas_estimation(code), VariableDeclarationException)
+
+
+def test_logging_fails_when_input_is_too_big(assert_tx_failed, get_contract_with_gas_estimation):
+    code = """
+Bar: __log__({_value: indexed(bytes <= 32)})
+
+@public
+def foo(inp: bytes <= 33):
+    log.Bar(inp)
+"""
+    assert_tx_failed(lambda: get_contract_with_gas_estimation(code), TypeMismatchException)