Vyper: reversed order of side effects for some operations
Description
Vyper is a Pythonic Smart Contract Language. For the following (probably non-exhaustive) list of expressions, the compiler evaluates the arguments from right to left instead of left to right. unsafe_add, unsafe_sub, unsafe_mul, unsafe_div, pow_mod256, |, &, ^ (bitwise operators), bitwise_or (deprecated), bitwise_and (deprecated), bitwise_xor (deprecated), raw_call, <, >, <=, >=, ==, !=, in, not in (when lhs and rhs are enums). This behaviour becomes a problem when the evaluation of one of the arguments produces side effects that other arguments depend on. The following expressions can produce side-effect: state modifying external call , state modifying internal call, raw_call, pop() when used on a Dynamic Array stored in the storage, create_minimal_proxy_to, create_copy_of, create_from_blueprint. This issue has not yet been patched. Users are advised to make sure that the arguments of the expression do not produce side effects or, if one does, that no other argument is dependent on those side effects.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Vyper compiler evaluates arguments right-to-left for certain built-in operators, causing potential side-effect ordering issues that can lead to incorrect contract behavior.
Vulnerability
Description
The Vyper smart contract compiler evaluates arguments from right to left for a specific set of built-in operators and functions, including unsafe_add, unsafe_sub, unsafe_mul, unsafe_div, pow_mod256, bitwise operators, raw_call, comparison operators, and in/not in when used with enums [1]. This behavior contradicts the expected left-to-right evaluation order and becomes problematic when an argument produces side effects that other arguments depend on [3].
Exploitation
Conditions
An attacker can exploit this issue by crafting a contract where one argument to such an expression performs a state-modifying operation (e.g., a state-changing external or internal call, raw_call, pop() on a storage dynamic array, or proxy creation functions) while another argument reads or depends on the modified state [1]. Because the rightmost argument is evaluated first, the side effect occurs before the left argument is evaluated, leading to unexpected state changes.
Impact
If exploited, this evaluation order discrepancy can result in incorrect contract behavior, such as wrong arithmetic results, unintended state mutations, or logic errors that could be leveraged to drain funds or manipulate contract state. The issue affects any contract using the listed operators with side-effect-producing arguments [3].
Mitigation
Status
As of the publication date, the issue has not been patched [1]. A pull request (PR #4157) has been opened to add a compiler panic for potential evaluation order issues, but a full codegen fix is still pending [4]. Users are advised to ensure that arguments to the affected expressions do not produce side effects, or if they do, that no other argument depends on those side effects [1].
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
vyperPyPI | <= 0.4.2 | — |
Affected products
1Patches
0No patches discovered yet.
Vulnerability mechanics
AI mechanics synthesis has not run for this CVE yet.
References
7- github.com/advisories/GHSA-g2xh-c426-v8mfghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-40015ghsaADVISORY
- github.com/pypa/advisory-database/tree/main/vulns/vyper/PYSEC-2023-167.yamlghsaWEB
- github.com/vyperlang/vyper/issues/3604ghsaWEB
- github.com/vyperlang/vyper/issues/4019ghsaWEB
- github.com/vyperlang/vyper/pull/4157ghsaWEB
- github.com/vyperlang/vyper/security/advisories/GHSA-g2xh-c426-v8mfghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.