concat built-in can corrupt memory in vyper
Description
Vyper is a Pythonic Smart Contract Language for the Ethereum Virtual Machine. The concat built-in can write over the bounds of the memory buffer that was allocated for it and thus overwrite existing valid data. The root cause is that the build_IR for concat doesn't properly adhere to the API of copy functions (for >=0.3.2 the copy_bytes function). A contract search was performed and no vulnerable contracts were found in production. The buffer overflow can result in the change of semantics of the contract. The overflow is length-dependent and thus it might go unnoticed during contract testing. However, certainly not all usages of concat will result in overwritten valid data as we require it to be in an internal function and close to the return statement where other memory allocations don't occur. This issue has been addressed in 0.4.0.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Buffer overflow in Vyper's concat built-in can corrupt memory, altering contract semantics; fixed in 0.4.0.
CVE-2024-22419 describes a buffer overflow vulnerability in the concat built-in function of the Vyper smart contract language. The root cause is that the build_IR for concat does not properly adhere to the API of copy functions (specifically copy_bytes in versions >=0.3.2), leading to writes beyond the allocated memory buffer [1][2].
To be exploited, the overflow requires specific conditions: the concat operation must be used within an internal function and placed close to a return statement where other memory allocations are unlikely. The overflow is length-dependent, so it may not manifest in all uses and could go unnoticed during testing [1][2].
The impact is that the buffer overflow can corrupt valid memory data, leading to unexpected changes in contract behavior. This could alter the semantics of the contract, potentially causing financial loss or unintended state changes [1][2]. However, a contract search found no vulnerable contracts in production [1].
The issue has been addressed in Vyper version 0.4.0, with a specific commit that adjusts the buffer allocation to respect the copy_bytes API (commit 55e18f6) [2][4]. Developers should upgrade to version 0.4.0 or later to mitigate the vulnerability [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.3.0, < 0.4.0 | 0.4.0 |
Affected products
1Patches
155e18f6d128bfix: concat buffer bug (#3738)
2 files changed · +69 −6
tests/functional/builtins/codegen/test_concat.py+64 −0 modified@@ -55,6 +55,70 @@ def krazykonkat(z: Bytes[10]) -> Bytes[25]: print("Passed third concat test") +def test_concat_buffer(get_contract): + # GHSA-2q8v-3gqq-4f8p + code = """ +@internal +def bar() -> uint256: + sss: String[2] = concat("a", "b") + return 1 + + +@external +def foo() -> int256: + a: int256 = -1 + b: uint256 = self.bar() + return a + """ + c = get_contract(code) + assert c.foo() == -1 + + +def test_concat_buffer2(get_contract): + # GHSA-2q8v-3gqq-4f8p + code = """ +i: immutable(int256) + +@external +def __init__(): + i = -1 + s: String[2] = concat("a", "b") + +@external +def foo() -> int256: + return i + """ + c = get_contract(code) + assert c.foo() == -1 + + +def test_concat_buffer3(get_contract): + # GHSA-2q8v-3gqq-4f8p + code = """ +s: String[1] +s2: String[33] +s3: String[34] + +@external +def __init__(): + self.s = "a" + self.s2 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # 33*'a' + +@internal +def bar() -> uint256: + self.s3 = concat(self.s, self.s2) + return 1 + +@external +def foo() -> int256: + i: int256 = -1 + b: uint256 = self.bar() + return i + """ + c = get_contract(code) + assert c.foo() == -1 + + def test_concat_bytes32(get_contract_with_gas_estimation): test_concat_bytes32 = """ @external
vyper/builtins/functions.py+5 −6 modified@@ -543,13 +543,12 @@ def build_IR(self, expr, context): else: ret_typ = BytesT(dst_maxlen) + # respect API of copy_bytes + bufsize = dst_maxlen + 32 + buf = context.new_internal_variable(BytesT(bufsize)) + # Node representing the position of the output in memory - dst = IRnode.from_list( - context.new_internal_variable(ret_typ), - typ=ret_typ, - location=MEMORY, - annotation="concat destination", - ) + dst = IRnode.from_list(buf, typ=ret_typ, location=MEMORY, annotation="concat destination") ret = ["seq"] # stack item representing our current offset in the dst buffer
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-2q8v-3gqq-4f8pghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-22419ghsaADVISORY
- github.com/pypa/advisory-database/tree/main/vulns/vyper/PYSEC-2024-103.yamlghsaWEB
- github.com/vyperlang/vyper/commit/55e18f6d128b2da8986adbbcccf1cd59a4b9ad6fghsax_refsource_MISCWEB
- github.com/vyperlang/vyper/issues/3737ghsax_refsource_MISCWEB
- github.com/vyperlang/vyper/security/advisories/GHSA-2q8v-3gqq-4f8pghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.