A significant bug has been uncovered in the Solidity programming language’s code generator, affecting a wide range of historical versions. The flaw, which involves the application of the delete operator to elements of memory-based bytes and string arrays under the default compilation pipeline, can cause unintended memory overwrites. Although categorized as having a low-to-medium severity level and requiring a specific combination of conditions to manifest, the defect introduces unexpected data corruption risks that developers must address by upgrading their toolchains.
The vulnerability was formally brought to light on August 14, 2026, when developer Shaheen Fazim identified and reported the anomaly through the Ethereum Foundation’s bug bounty program. According to the investigation by the Solidity development team, the issue stems from a discrepancy in how the compiler’s default evmasm pipeline handles memory writes during element deletion compared to standard assignments.
When a developer applies the delete operator to a specific element within a bytes or string array located in memory, the generated bytecode incorrectly writes 32 zero bytes—an entire 32-byte word—starting precisely at the index of the targeted element. This behavior stands in stark contrast to the equivalent explicit assignment, such as setting b[i] = 0, which correctly targets and clears a single byte without disrupting adjacent memory.
Because the erroneous 32-byte zero write begins at the index of the deleted element rather than aligning with a standard 32-byte memory word boundary, it ripples forward and clears up to 31 bytes following the target. Depending on the element’s position within the array, this unintended wipe either obliterates subsequent elements residing within the same array or spills past the array’s boundary entirely, corrupting whatever data happens to be allocated immediately afterward in the Ethereum Virtual Machine’s memory.
The development team confirmed that the affected code path is deeply embedded in the compiler’s history, predating the very first official release of Solidity. Consequently, every version of Solidity up to and including version 0.8.36 is affected by the flaw. The issue has been officially resolved in Solidity version 0.8.37, prompting an immediate recommendation for developers to update their compilation environments.
To gauge the real-world impact of the vulnerability, the security team scanned the Sourcify database, which catalogs roughly 870,000 verified smart contract compilations. The analysis searched for the specific source pattern capable of triggering the bug. Out of nearly a million verified compilations, the pattern appeared in only 17 instances, encompassing just two distinct functions. Furthermore, a deeper forensic assessment revealed that neither of those two functions was actually vulnerable in practice, as the corrupted bytes were either subsequently discarded or landed in entirely unused memory spaces. At the time of disclosure, no deployed smart contracts in the wild are known to have suffered exploitation or adverse effects from the bug.
Which Contracts Are Affected?
For a smart contract to be vulnerable to this specific code generator defect, a strict set of technical conditions must be met simultaneously. First, the contract must be compiled using the default evmasm pipeline. Contracts compiled using the alternative Intermediate Representation (IR) pipeline remain entirely unaffected, as do contracts compiled with or without the Solidity optimizer enabled, since the optimizer merely preserves the faulty semantics generated by the underlying code path.
Second, the code must apply the delete operator specifically to an element of a dynamic byte array or string residing in memory. Whole-array deletions, such as executing delete b on an entire array, utilize a completely distinct and secure code path and are not vulnerable. Furthermore, arrays located in storage use separate compilation logic and remain unaffected, while calldata arrays cannot be targeted by the delete operator at all. Additionally, arrays whose elements each occupy a full 32-byte word in memory—such as bytes1[] memory—do not suffer from the flaw because their elements are not packed; only tightly packed types like bytes and string are susceptible.
While direct application of delete to string index access is not permitted by the compiler syntax, developers frequently convert strings to bytes arrays for manipulation. Executing delete bytes(s)[i] on a string converted in memory triggers the exact same vulnerable code path, modifying the string’s underlying data in place. Conversely, fixed-byte types such as bytes32 are unaffected because indexing them creates an isolated copy of the byte rather than returning a mutable reference into the underlying memory structure.
Third, the extent of the corruption depends heavily on the memory layout produced by the compiler, including how the array was allocated and where the deleted element resides. Because verifying memory layout nuances can be complex, the engineering team advises that if the first two major conditions are met, developers should treat their contracts with caution rather than attempting to definitively rule out the layout-dependent third condition.
Technical Details

To fully understand why the vulnerability occurs, it is necessary to examine how Solidity manages memory allocation. Most data types in Ethereum memory consume full 32-byte words. Dynamic byte arrays are a notable exception; they consist of an initial 32-byte length field followed by raw data packed contiguously back-to-back without internal gaps. Solidity manages memory linearly by advancing a free memory pointer, meaning consecutive allocations sit flush against one another, separated only by alignment padding. When a write extends beyond the boundary of one allocation, it immediately overwrites the beginning of the next.
Arrays created via explicit instantiation like new bytes(n) or initialized from literal values are typically followed by up to 31 zero bytes of padding to ensure that subsequent memory allocations start cleanly on a word boundary. These are classified as padded arrays. In contrast, the current evmasm pipeline does not pad the output of functions such as bytes.concat, string.concat, and various abi.encode variants. These unpadded arrays end abruptly where the next memory allocation begins, making them inherently more susceptible to cross-allocation memory corruption.
The root cause of the bug lies in the divergence between how assignments and deletions are compiled within the evmasm pipeline. When a developer executes an assignment like b[i] = 0, the compiler correctly consults the element’s width and emits a single-byte store instruction (mstore8), ensuring that only the targeted byte is modified. However, when the developer executes delete b[i], the compiler invokes a different code path that issues a full 32-byte zero write (mstore) starting directly at the element’s memory address.
Because this 32-byte write initiates at an arbitrary byte index rather than aligning with a word boundary, it overwrites the designated element alongside up to 31 subsequent bytes. The array’s 32-byte length field, which precedes the data payload, remains untouched, meaning the array preserves its original length indicator. Consequently, any subsequent operations relying on the array’s contents—such as computing cryptographic hashes via keccak256, performing ABI encoding, or returning data to an external caller—silently process the corrupted byte sequence.
Example Demonstrating the Flaw
The practical implications of the bug can be observed in controlled scenarios where adjacent memory allocations interact. Consider a smart contract designed with functions that perform element deletions on memory byte arrays alongside adjacent data structures. When such a contract is compiled under the default evmasm pipeline in vulnerable Solidity versions, the execution yields stark deviations from expected outcomes.
In scenarios involving intra-array corruption, deleting an element near the beginning of a short, padded byte array results in a 32-byte zero write that wipes out not only the targeted index but also every subsequent byte remaining in the array. Rather than clearing a single designated element, the entire payload is zeroed out.
In scenarios involving cross-allocation corruption, where an unpadded or minimally padded array sits directly adjacent to a complex data structure such as a memory struct containing a large integer, deleting an element near the end of the array causes the 32-byte zero write to spill over into the neighboring allocation. Because integers in memory are stored with their most significant bytes first, the overflow zeroes out the leading bytes of the adjacent variable. For instance, an integer holding the maximum possible value can have its upper bytes systematically stripped away, drastically altering its numerical value and causing downstream logic failures.
Remediation and Recommended Actions
The discovery of this memory corruption vulnerability underscores the importance of rigorous testing and timely compiler updates in smart contract development. Because the bug does not trigger runtime reverts or compiler warnings, affected contracts fail silently, producing altered data states that can be difficult to trace during routine debugging.
The fix implemented in Solidity version 0.8.37 corrects the underlying code generator logic. The updated compiler ensures that the delete instruction consults the element width in the exact same manner as standard assignments. When clearing an element inside a packed byte array, the compiler now correctly emits a single-byte store operation rather than a full-word memory write, bringing the behavior of delete b[i] and b[i] = 0 into complete alignment across all compilation pipelines.
Developers maintaining codebases written in Solidity versions 0.8.36 and earlier are strongly advised to audit their source code for memory-based bytes and string element deletions and to upgrade their projects to Solidity 0.8.37 or later as part of standard security hygiene.






