A critical logic flaw residing deep within the Solidity code generator has been officially patched following a responsible disclosure by security researcher Shaheen Fazim. Submitted on August 14, 2026, via the Ethereum Foundation’s bug bounty program, the vulnerability exposes a dangerous discrepancy in how the compiler handles the delete operator when applied to individual elements of memory-based byte arrays and strings. Under specific conditions, executing a deletion on a single element triggers a full 32-byte zero write rather than clearing only the targeted byte, causing unintended memory corruption that can ripple across adjacent variables and data structures.
The discovery has prompted the Solidity development team to release version 0.8.37, which fixes the underlying code generation path. While the vulnerability affects all previous iterations of the language up to and including version 0.8.36—with code paths predating the very first official release of Solidity—an extensive historical scan of verified smart contract compilations suggests that real-world exploitation is exceedingly rare. Nevertheless, given the silent and potentially insidious nature of the bug, developers have been strongly urged to upgrade their toolchains and review their memory handling logic.
Understanding the Core Defect: How delete Overwrites Memory
To comprehend the mechanics of the vulnerability, one must examine how Solidity structures dynamic byte arrays and strings within temporary EVM memory. Unlike most data types in Solidity, which neatly occupy full 32-byte words, bytes and string types in memory are packed back-to-back without internal gaps. They consist exclusively of an initial 32-byte length field followed immediately by the raw byte data.
When a developer wishes to reset an element within a standard array or variable, expectations dictate that applying the delete operator to an index—such as delete b[i]—should function identically to a direct assignment like b[i] = 0. Under normal circumstances, assigning zero to a byte array element correctly executes a single-byte store operation, known in EVM assembly as mstore8, ensuring that only the specific byte at index i is modified.
However, the legacy and default evmasm compilation pipeline suffered from a critical divergence in the code generation stage. While direct assignments correctly resolved to a single-byte store, the code path responsible for handling the delete operator on packed memory array elements inadvertently fell back to emitting a full 32-byte word store (mstore). Because this write operation initiates directly at the memory address of the targeted element rather than aligning to a standard 32-byte word boundary, it spills far beyond its intended target. Instead of clearing a single byte, the generated bytecode blankets the subsequent 31 bytes with zeroes, obliterating everything in its path.
Crucially, the dynamic array’s length field remains entirely untouched during this process. Because the length parameter is stored before the data array and is never decremented or altered by the delete instruction, the array retains its original dimensions. Any subsequent operations that rely on the array’s contents—such as hashing via keccak256, ABI encoding routines, or returning data to external callers—will read the corrupted, zeroed-out bytes silently, without triggering any runtime exceptions, revert states, or compiler warnings.
Scope of Impact: Pipelines, Pipelines Settings, and Memory Layouts
The vulnerability is strictly confined to the default evmasm compilation pipeline. Contracts compiled using the newer IR (Intermediate Representation) pipeline are completely unaffected, as the IR backend correctly routes element deletions through the proper single-byte store instructions. Furthermore, the activation or deactivation of the Solidity optimizer has no bearing on the bug; the optimizer merely preserves the faulty semantics emitted by the core code generator.
The defect impacts any version of Solidity up to 0.8.36, meaning the vulnerability has persisted across the entire lifecycle of the language. However, manifesting the bug requires a precise confluence of conditions. A smart contract is only vulnerable if it actively applies the delete operator to an element of a memory-based bytes or string array. Entire array deletions, such as calling delete b on the array as a whole, follow a completely separate and secure code path. Similarly, byte arrays residing in persistent storage (storage) are handled entirely differently and remain immune, while calldata arrays do not support element deletion at all.
Data types whose elements occupy full 32-byte words—such as standard bytes1[] memory arrays—are also unaffected because their elements are already aligned to full word boundaries. The risk is strictly limited to packed memory types, including bytes, string values treated through explicit conversions like bytes(s), and situations where developers manipulate dynamic character arrays in temporary memory.
Depending on where the deleted element sits within the array and how that array was allocated by the compiler, the trailing zero-write can manifest in two distinct ways: corruption contained entirely within the array, or corruption bleeding past the array boundary into adjacent memory allocations.
Internal Array Corruption Versus Out-of-Bounds Overwrites
When an element is deleted near the beginning or middle of a memory byte array, the 32-byte zero write stays entirely within the boundaries of the array’s allocated memory space. Every subsequent element following the deleted index—up to a maximum of 31 elements—is forcefully cleared and overwritten with zeroes. Unless the array happens to consist entirely of zero bytes past the deletion point, this corruption immediately alters the runtime data structure, altering application logic without throwing errors.

More hazardous, however, is when the deletion targets one of the final 31 elements of an array. Solidity allocates memory sequentially by advancing a free memory pointer, meaning consecutive variable declarations sit flush against each other. When an array sits near the end of an allocation block, a 32-byte zero-write triggered by a trailing element deletion can spill past the array’s allocated boundary and overwrite whatever data happens to reside immediately afterward in memory.
The extent of this overflow depends heavily on whether the array is padded or unpadded. Standard arrays created via explicit memory instantiations or literals typically include up to 31 bytes of trailing zero padding to ensure that subsequent memory allocations begin cleanly on a 32-byte word boundary. This padding can absorb a portion of the runaway write. For instance, an array of length 40 features 24 bytes of padding, meaning that deleting only the last seven elements will manage to breach the allocation boundary, extending into subsequent memory by at most seven bytes.
Conversely, unpadded arrays—such as those generated by built-in utilities like bytes.concat, string.concat, and the entire suite of abi.encode functions—terminate precisely where the next allocation begins, with zero padding bytes. For these unpadded structures, deleting any of the final 31 elements will invariably bleed into whatever variable, struct, or pointer was declared next in the function scope.
The consequences of overwriting adjacent memory depend entirely on the data type residing there. Left-aligned types, such as fixed-size bytesN variables, will have their most significant bytes wiped clean. Right-aligned primitives, including unsigned integers, addresses, and memory pointers, store their most significant bytes at the end of the word space. Consequently, a multi-byte zero overflow can drastically alter numerical values, transforming maximum integer boundaries into trivial numbers or neutralizing crucial access control addresses by zeroing out their leading bytes.
Practical Demonstration and Real-World Assessment
To illustrate the severity of the flaw, security analysts constructed a reference contract highlighting both internal and external memory corruption scenarios. In a function designed to clear an individual element of a short five-byte memory array, executing a deletion at the zeroth index inadvertently wiped out the subsequent four bytes, transforming the intended data state into a completely zeroed-out sequence.
In a second scenario involving a 32-byte unpadded array declared directly adjacent to a tightly packed memory struct containing a maximum-value 256-bit unsigned integer, deleting the final array element caused a 31-byte zero-write to flood the adjacent memory variable. Rather than returning the expected maximum uint256 value, the function returned a numerical value of 255 because the leading 31 bytes of the integer had been silently erased by the compiler’s faulty deletion logic. Substituting these deletions with standard assignments successfully avoided the corruption, confirming that the bug was strictly an artifact of the compiler’s code generation pathways.
Despite the profound technical implications of the bug, empirical investigations suggest that the practical risk to deployed decentralized applications is remarkably low. Following the disclosure, the Ethereum Foundation and security researchers conducted an automated scan of the Sourcify database, analyzing approximately 870,000 verified smart contract compilations to detect the specific source code pattern capable of triggering the defect.
The scanning initiative identified the vulnerable pattern in a mere 17 compilations, encompassing only two distinct deployed functions across the entire verified corpus. Further auditing of those two functions revealed that neither was actually susceptible to malicious exploitation or functional failure. In both instances, the bytes cleared within the array were subsequently discarded or overwritten during routine execution, while memory allocations residing beyond the arrays were either structurally protected or located in entirely unused memory space. Furthermore, developers have confirmed that no known production contracts or deployed protocols have suffered from exploits related to this memory corruption flaw.
The Fix and Recommended Actions
The resolution implemented in Solidity version 0.8.37 directly addresses the root cause of the vulnerability by aligning the code generation pathways for both assignment and deletion operations. The compiler’s delete route has been updated to query the exact element width of the target data structure. When processing packed byte arrays and strings, the compiler now correctly emits a single-byte store (mstore8) instead of an indiscriminate full-word write, ensuring that delete b[i] and b[i] = 0 share identical and correct semantics across both the evmasm and IR compilation pipelines.
As part of recommended security hygiene, developers utilizing the Solidity compiler are urged to immediately update their development environments, continuous integration pipelines, and compilation toolchains to version 0.8.37 or later. Project maintainers should review their codebase for any instances where the delete operator is applied to individual indices of memory-resident byte arrays or strings, particularly when those arrays interact closely with adjacent memory variables, structs, or inline assembly blocks.
The Ethereum Foundation and the Solidity core team expressed their gratitude to security researcher Shaheen Fazim for identifying the vulnerability, providing a functional reproduction script, and reporting the issue through the official bug bounty program, ensuring that the flaw was neutralized before widespread exploitation could occur in the broader decentralized finance ecosystem.






