vyper Version (output of vyper --version OR linkable commit hash vyperlang/vyper@): vyperlang/vyper@b43fface148b45cbd2c90b5d24f77398a63745b5
Issue Description
The order of evaluation in Vyper is specified as left-to-right; in the
same order as the expressions appear in the the source code.
Due to the way IR nodes that match directly EVM opcodes are
converted to assembly, for some built-ins and operators, it is known
that it might not be the case as described in
GHSA-g2xh-c426-v8mf.
The compiler uses a pattern cache_when_complex to cache the result
of a complex expression and avoid double evaluation. However, this
pattern appears to be problematic regarding the order of evaluation.
Given an IR node that has multiple children that should be
evaluated in a specific order, it might be that not all
children are cached. A cached complex child would hence be
evaluated before any non-cached children independently of
their order in the source code. This behavior is notably seen
in assignments given that make_setter() caches src but not
dst.
A more subtle issue is that the compiler might cache all
children of an IR node, however, one or multiple nodes are not
considered as complex and their evaluation is inlined.
although in that case, a non-complex node cannot have side
effects, its evaluation can still read (e.g a SLOAD) side
effects from a complex node that was cached and evaluated
first. This case appears to be problematic for the slice()
and extract32() built-ins.
Another issue regarding the order of evaluation is that the order of
evaluation of the kwargs passed to built-ins and call expressions do
not follow the order of the source code.
POC
The following examples show multiple cases where the order of evaluation
is right-to-left.
Version Information
vyper --version
OR linkable commit hash vyperlang/vyper@Issue Description
The order of evaluation in Vyper is specified as left-to-right; in the same order as the expressions appear in the the source code.
Due to the way IR nodes that match directly EVM opcodes are converted to assembly, for some built-ins and operators, it is known that it might not be the case as described in GHSA-g2xh-c426-v8mf.
The compiler uses a pattern
cache_when_complex
to cache the result of a complex expression and avoid double evaluation. However, this pattern appears to be problematic regarding the order of evaluation.Another issue regarding the order of evaluation is that the order of evaluation of the kwargs passed to built-ins and call expressions do not follow the order of the source code.
POC
The following examples show multiple cases where the order of evaluation is right-to-left.