A critical memory corruption vulnerability has been officially disclosed within the Solidity code generator, impacting all historical versions of the language up to and including version 0.8.36. Discovered and reported by developer Shaheen Fazim on August 14, 2026, through the Ethereum Foundation’s bug bounty program, the defect involves how the compiler handles the deletion of individual elements within memory-based byte arrays and strings. Although the vulnerability carries a low-to-medium internal severity rating, it introduces subtle and potentially hazardous memory overwrites that smart contract developers must address.
The core issue emerges when the delete keyword is applied directly to a specific element of a bytes array—or a converted string—allocated within contract memory. Under normal operating conditions, deleting an element should clear only that single byte, perfectly mirroring the functional behavior of an explicit assignment such as b[i] = 0. However, due to a discrepancy deep within the default evmasm compilation pipeline, the generated bytecode diverges significantly. Instead of clearing a single byte via a targeted memory operation, the compiler emits a full 32-byte zero-write starting directly at the index of the targeted element.
This unintended behavior means that the delete operation clears not only the designated element but also up to 31 subsequent bytes. Depending on where the deleted element resides within the array, this excessive write can corrupt neighboring elements within the same data structure or spill past the boundary of the array entirely, overwriting whatever contiguous memory allocation follows it. Interestingly, direct assignments like b[i] = 0 remain entirely unaffected by the bug and continue to clear precisely one byte as intended.
Which Contracts Are Affected?
To determine whether a specific smart contract is exposed to this memory corruption flaw, developers must evaluate several overlapping conditions inherent to their codebase and compilation settings. First and foremost, the contract must be compiled using the default evmasm pipeline. The modern IR (Intermediate Representation) pipeline is completely unaffected by the defect, as it utilizes a uniform store implementation for both direct assignments and delete operations. Furthermore, the use of the Solidity optimizer is not required to trigger the bug; the erroneous code path is hardcoded into the raw output generated during the codegen stage.
The scope of affected types is also specific. The vulnerability exclusively targets dynamic byte arrays (bytes memory) and strings that have been explicitly or implicitly cast to bytes memory arrays for index-based deletion. Fixed-size byte arrays, such as bytesN types, are completely unaffected because indexing them yields an isolated copy of the individual byte rather than a mutable reference to underlying memory. Similarly, arrays residing in contract storage are handled through an entirely separate, secure code path, and calldata arrays do not support the delete operator at all. Arrays where each element occupies a full 32-word memory slot—such as bytes1[] memory—also remain safe because they do not rely on packed byte arrangements.
Crucially, if a smart contract never applies the delete operator to an element of a bytes or string value located in memory, it is entirely immune to the vulnerability, regardless of the compiler version used. However, because verifying whether a delete operation crosses memory boundaries often requires deep reasoning about the compiler’s internal memory layout, developers utilizing vulnerable compiler versions are strongly advised to audit their codebases thoroughly or upgrade their toolchain immediately.
Technical Details and Compiler Internals
To understand why this memory corruption occurs, it is necessary to examine how Solidity manages memory allocation and data representation. Most data types in Solidity memory consume full 32-byte words, maintaining clean alignments across execution cycles. Dynamic byte arrays (bytes) and strings represent a prominent exception to this rule. A memory-based byte array consists of a 32-byte length header followed immediately by the raw data bytes packed tightly back-to-back without internal word-alignment padding.
Solidity allocates memory sequentially by advancing a global free memory pointer. Every new allocation starts precisely where the previous one concluded, meaning that consecutive memory objects sit flush against each other, separated only by necessary word-boundary padding. Consequently, any write operation that overshoots its intended target will bleed directly into the subsequent memory allocation.
The compiler handles memory allocation padding in distinct ways depending on the origin of the data structure. Arrays created via standard allocation expressions—such as new bytes(n)—or initialized from literal strings are typically padded with up to 31 trailing zero bytes to ensure that any subsequent allocation begins cleanly on a new 32-byte word boundary. These are referred to as padded arrays. In contrast, the evmasm pipeline leaves the outputs of bytes.concat, string.concat, and all abi.encode variants entirely unpadded. For these unpadded arrays, the data ends precisely where the next memory block begins, leaving zero buffer space to absorb errant writes.

The root cause of the vulnerability lies within the specific code path invoked by the delete statement. When a developer executes delete b[i], the compiler’s evmasm code generator issues a 32-byte word-level write (mstore) starting at the memory address of the targeted element. Because the element index rarely aligns perfectly with the start of a 32-byte word boundary, the zero-write sweeps across the targeted byte and continues forward for a full 32 bytes.
Because the array’s length field is stored prior to the data payload, it remains untouched by the operation. As a result, the array retains its original length metadata, but its internal contents become heavily corrupted. Any subsequent operations relying on the array’s contents—such as hashing via keccak256, ABI encoding routines, or returning data to external callers—will process the corrupted memory, leading to silent calculation errors or unpredictable application behavior.
Corruption Inside and Beyond the Array
The consequences of this bug manifest in two distinct ways depending on the position of the deleted element relative to the array’s boundaries. When an element is deleted from the interior of an array, up to 31 subsequent elements are forcibly overwritten with zeros. Unless the array happens to consist entirely of zero bytes past the deletion point, this corruption alters the data structure instantly upon execution, requiring no complex preconditions.
When the deleted element sits near the end of a padded array, or anywhere within an unpadded array, the 32-byte zero-write can easily breach the array’s allocation boundary and spill over into whatever data structure happens to reside immediately after it in memory. For instance, if a dynamic byte array is declared right before a complex struct or a reference type, the errant write will overwrite the leading bytes of that neighboring structure.
The exact nature of this external corruption depends heavily on the alignment of the overwritten variable. Left-aligned data types lose their most significant bytes, while right-aligned types—such as integers, addresses, and memory pointers—experience corruption at the front of their storage words. Depending on the size of the overwrite, critical values can be silently truncated, transformed into zero, or altered in ways that bypass standard logic checks without triggering an immediate runtime revert.
Assessment and Remediation
Despite the potential severity of silent memory corruption, real-world exposure to this vulnerability appears remarkably constrained. An extensive automated scan conducted across the Sourcify database, encompassing approximately 870,000 verified smart contract compilations, searched specifically for the vulnerable source code pattern. The scan identified the pattern in only 17 compilations, which collectively contained just two distinct deployed functions. Furthermore, a deeper security assessment revealed that neither of those functions was actually exploitable in practice; in both cases, the corrupted bytes were either immediately discarded or written into unoccupied memory space where no active data resided.
Nevertheless, because the compiler emits no warnings and the EVM does not register a runtime exception when the corruption occurs, diagnosing such a bug can prove exceptionally difficult during standard testing cycles. The Ethereum Foundation and the Solidity core development team addressed the issue decisively by releasing Solidity version 0.8.37.
The fix modifies the evmasm code generator to ensure that the delete path consults the underlying element width in the exact same manner as the assignment path. When clearing an element inside a packed byte array, the compiler now correctly emits a single-byte store (mstore8) rather than a full-word store, bringing the behavior of delete b[i] into complete alignment with b[i] = 0 across all compilation pipelines. Developers utilizing vulnerable versions are strongly urged to update their compiler toolchains to version 0.8.37 or later to ensure complete security against memory corruption stemming from array element deletions.

