Summary
When looping over a range of the form range(start, start + N), if start is negative, the execution will always revert.
Details
This issue is caused by an incorrect assertion inserted by the code generation of the range (stmt.parse_For_range()):
|
_, hi = start.typ.int_bounds |
|
start = clamp("le", start, hi + 1 - rounds) |
This assertion was introduced in 3de1415 to fix GHSA-6r8q-pfpv-7cgj. The issue arises when start is signed, instead of using sle, le is used and start is interpreted as an unsigned integer for the comparison. If it is a negative number, its 255th bit is set to 1 and is hence interpreted as a very large unsigned integer making the assertion always fail.
PoC
@external
def foo():
x:int256 = min_value(int256)
# revert when it should not since we have the following assertion that fails:
# [assert, [le, min_value(int256), max_value(int256) + 1 - 10]],
for i in range(x, x + 10):
pass
Patches
patched in v0.4.0, specifically, #3679 disallows this form of range().
Impact
Any contract having a range(start, start + N) where start is a signed integer with the possibility for start to be negative is affected. If a call goes through the loop while supplying a negative start the execution will revert.
Summary
When looping over a
rangeof the formrange(start, start + N), ifstartis negative, the execution will always revert.Details
This issue is caused by an incorrect assertion inserted by the code generation of the range (
stmt.parse_For_range()):vyper/vyper/codegen/stmt.py
Lines 286 to 287 in 9136169
This assertion was introduced in 3de1415 to fix GHSA-6r8q-pfpv-7cgj. The issue arises when
startis signed, instead of usingsle,leis used andstartis interpreted as an unsigned integer for the comparison. If it is a negative number, its 255th bit is set to1and is hence interpreted as a very large unsigned integer making the assertion always fail.PoC
Patches
patched in v0.4.0, specifically, #3679 disallows this form of
range().Impact
Any contract having a
range(start, start + N)wherestartis a signed integer with the possibility forstartto be negative is affected. If a call goes through the loop while supplying a negativestartthe execution will revert.