
Memory Byte Array Element Delete Clears Whole Word Bug
The Solidity team disclosed a code-generator bug (reported by Shaheen Fazim via the Ethereum Foundation bug bounty program) where `delete b[i]` on a bytes/string element located in memory incorrectly writes a full 32-byte zero word instead of a single byte, corrupting up to 31 subsequent bytes — either later elements of the same array or, for elements near the array's end, adjacent memory allocations like other variables. The bug affects only the default evmasm pipeline (not the IR pipeline via --via-ir) in all versions up to and including 0.8.36, is fixed in 0.8.37, and the equivalent assignment `b[i] = 0` is unaffected and serves as a workaround. A Sourcify scan of ~870,000 verified compilations found the triggering pattern in only two functions, neither actually exploitable in practice.
What it is
A Solidity code-generator bug: delete b[i] on an element of a bytes or string value in memory emits a full 32-byte zero write instead of a single-byte store, zeroing up to 31 bytes past the target. The summary has the disclosure, version boundary (all versions ≤0.8.36, fixed in 0.8.37), evmasm-only scope, and the b[i] = 0 workaround. What follows is the affected-surface detail the summary omits — the distinctions that decide whether your code is affected.
What is and isn't affected
- Only element deletes.
delete bon the whole array takes a different, correct path.delete b[i]on a single element is the bug. - Memory only. Storage byte arrays use a separate correct path;
deletecan't apply to calldata. stringis affected via conversion.delete s[i]doesn't compile, butdelete bytes(s)[i]does — and becausebytes(s)is not a copy, it corrupts the string in place.- Not affected:
bytes1[] memory(elements each occupy a full word), andbytesNNvalue types (indexing yields a copy, not a reference). - Optimizer and target EVM version are irrelevant — the defect is in emitted codegen, which the optimizer preserves.
The array's length field is never touched, so the array keeps its length and any downstream keccak256, ABI encoding, or plain return uses the corrupted bytes silently — no warning, no revert.
How far the write reaches (padded vs. unpadded)
This governs whether corruption stays inside the array or hits adjacent allocations:
- Padded arrays (
new bytes(n), literals): trailing padding absorbs part of the write. Lengths 1, 33, 65, … get a full 31 bytes of padding (no element delete escapes); lengths that are multiples of 32 have no padding (last 31 elements reach past the array). - Unpadded arrays — results of
bytes.concat,string.concat, and theabi.encode*family (abi.encode,abi.encodePacked,abi.encodeWithSelector,abi.encodeWithSignature,abi.encodeCall): data ends exactly where the next allocation begins, so deleting any of the last 31 elements reaches the next allocation regardless of length. For arrays ≤31 bytes, that includes index 0. Note the page warns this padding behavior is an unspecified implementation detail that may change — don't rely on it either way.
When the write escapes, it clears the leading bytes of the next allocation: for right-aligned values (integers, addresses, pointers, the length field of a dynamic array) a ≤12-byte write leaves an address intact while a 31-byte write clears everything above 255.
What to do
- Upgrade to 0.8.37+ before deploying anything compiled with the default evmasm pipeline.
- Grep sources — including libraries and dependencies — for
deleteapplied to a memorybyteselement or abytes(s)[i]on a string. - Interim workaround on older compilers: replace
delete b[i]withb[i] = 0.
Caveats
Corruption inside the array (the common case) is likely caught by any test that exercises the path and checks the array. The Sourcify scan's two matching functions were both non-exploitable — one bounds an array length that never grows into the overwritten bytes, the other writes into unused memory — so treat this as latent-risk hygiene, not an active in-the-wild exploit.
Organisations named here
- Ethereum Foundation bug bounty program
- Shaheen Fazim
Technologies named here
- Solidity compiler
- Sourcify database
- Solidity
- Ethereum
- Sourcify
Techniques named here
- Memory byte-array element delete triggers full-word store
Related in Blockchain

THORChain Exploit Report #2 — GG20 root-cause disclosure

Black Thursday revisited: MakerDAO keeper exploited for $500K
.jpg)