Low Risk
https://github.com/vyperlang/vyper/blob/3b310d5292c4d1448e673d7b3adb223f9353260e/vyper/codegen/core.py#L1049-L1070
The compiler enforces that blocks have 1 exit point. This invariant isn't checked inside for loop
.
The compiler checks that function bodies and if statements have 1 exit point: https://github.com/vyperlang/vyper/blob/3b310d5292c4d1448e673d7b3adb223f9353260e/vyper/codegen/core.py#L1049-L1070
However, as we can see in the code the For
node isn't validated. Thus, contract like the following one compile fine:
@external
def returning_all_nigt_long() -> uint256:
a: uint256 = 10
for i in range(10):
return 11
a = 20
return 12
return a
But contracts like the following one don't compile:
@external
def i_have_so_many_exit_point_omg() -> uint256:
a: uint256 = 10
if a < 20:
return 0
a = 20
return 11111111111111
return 101019291
The compilation fails with:
vyper.exceptions.StructureException: Too too many exit statements (return, raise or selfdestruct).
contract "vyper_contracts/Test.vy:4", function "i_have_so_many_exit_point_omg", line 4:4
3 a: uint256 = 10
---> 4 if a < 20:
-----------^
5 return 0
The single exit point is an invariant that is broken for for loops. This could be problematic if the later stages of the compilation relied on this invariant. However, such case wasn't discovered. As such we consider it as a confusing inconsistency.
Manual review.
Extend the validation for a single exit to contain also for
loops.