CVE-2025-47774: Vyper's `slice()` may elide side-effects when output length is 0
Impact the slice() builtin can elide side effects when the output length is 0, and the source bytestring is a builtin (msg.data or <address>.code). the reason is that for these source locations, the check that length >= 1 is skipped: https://github.com/vyperlang/vyper/blob/68b68c4b30c5ef2f312b4674676170b8a6eaa316/vyper/builtins/functions.py#L315-L319
the result is that a 0-length bytestring constructed with slice can be passed to makebytearraycopier, which elides evaluation of its source argument when the max length is 0: https://github.com/vyperlang/vyper/blob/68b68c4b30c5ef2f312b4674676170b8a6eaa316/vyper/codegen/core.py#L189-L191
the impact is that side effects in the start argument may be elided when the length argument is 0, e.g. slice(msg.data, self.dosideeffect(), 0).
the following example illustrates how the issue would look in user code vyper counter: public(uint256)
@external def test() -> Bytes[10]: b: Bytes[10] = slice(msg.data, self.sideeffect(), 0) return b
def sideeffect() -> uint256: self.counter += 1 return 0
the severity assigned is low, since this is not a very useful pattern and unlikely to be found in user code.
Patches
the fix is tracked in https://github.com/vyperlang/vyper/pull/4645, which disallows any invocation of slice() with length 0, including for the ad hoc locations discussed in this advisory.
Workarounds Is there a way for users to fix or remediate the vulnerability without upgrading?
References Are there any links users can visit to find out more?
Other sources
Vyper is the Pythonic Programming Language for the Ethereum Virtual Machine. In versions up to and including 0.4.2rc1, the slice() builtin can elide side effects when the output length is 0, and the source bytestring is a builtin (msg.data or <address>.code). The reason is that for these source locations, the check that length >= 1 is skipped. The result is that a 0-length bytestring constructed with slice can be passed to makebytearraycopier, which elides evaluation of its source argument when the max length is 0. The impact is that side effects in the start argument may be elided when the length argument is 0, e.g. slice(msg.data, self.dosideeffect(), 0). The fix in pull request 4645 disallows any invocation of slice() with length 0, including for the ad hoc locations discussed in this advisory. The fix is expected to be part of version 0.4.2.
— MITRE
Affected Software
Event History
Frequently Asked Questions
What is the severity of CVE-2025-47774?
The severity of CVE-2025-47774 is considered high due to the potential elision of side effects in smart contracts.
How do I fix CVE-2025-47774?
To fix CVE-2025-47774, upgrade to Vyper version 0.4.2rc2 or later where this issue has been addressed.
What are the affected versions in CVE-2025-47774?
CVE-2025-47774 affects Vyper versions up to and including 0.4.2rc1.
What is the main issue caused by CVE-2025-47774?
The main issue caused by CVE-2025-47774 is that the `slice()` builtin can unintentionally elide side effects when the output length is 0.
Who is impacted by CVE-2025-47774?
Developers using Vyper versions up to 0.4.2rc1 for Ethereum smart contracts are impacted by CVE-2025-47774.