Version
v0.4.4+commit.cd74ce4f5 (cd74ce4f57e3771aeeab8f061fa3be45bfe8a29c)
Description
A runtime-dependent expression is correctly rejected when used directly in a constant initializer, but is accepted when used as the index of a constant composite.
For example, this is rejected as expected:
B: constant(uint256) = block.number
However, this compiles successfully:
A: constant(uint256[2]) = [1, 2]
B: constant(uint256) = A[block.number]
The same occurs through a constant struct:
struct S:
xs: uint256[2]
A: constant(S) = S(xs=[1, 2])
B: constant(uint256) = A.xs[block.number]
Expected behavior
Both examples using block.number as an index should be rejected with StateAccessViolation, consistently with other runtime-dependent constant initializers.
Likely cause
check_modifiability does not have a recursive Subscript case. It falls through to get_expr_info(node). _ExprAnalyser.get_expr_info handles Subscript by copying the base expression's ExprInfo, including its modifiability:
if isinstance(node, vy_ast.Subscript):
info = self.get_expr_info(node.value)
return info.copy_with_type(t)
Consequently, a subscript whose base is constant is classified as constant without checking the index expression.
A possible fix is to make check_modifiability check both node.value and node.slice for Subscript, with regression tests covering direct constant arrays and fields of constant structs.
Version
v0.4.4+commit.cd74ce4f5(cd74ce4f57e3771aeeab8f061fa3be45bfe8a29c)Description
A runtime-dependent expression is correctly rejected when used directly in a constant initializer, but is accepted when used as the index of a constant composite.
For example, this is rejected as expected:
However, this compiles successfully:
The same occurs through a constant struct:
Expected behavior
Both examples using
block.numberas an index should be rejected withStateAccessViolation, consistently with other runtime-dependent constant initializers.Likely cause
check_modifiabilitydoes not have a recursiveSubscriptcase. It falls through toget_expr_info(node)._ExprAnalyser.get_expr_infohandlesSubscriptby copying the base expression'sExprInfo, including its modifiability:Consequently, a subscript whose base is constant is classified as constant without checking the index expression.
A possible fix is to make
check_modifiabilitycheck bothnode.valueandnode.sliceforSubscript, with regression tests covering direct constant arrays and fields of constant structs.