Solc keccak256 Optimizer Bug (2021-03) Remediation
Overview
Related Detector: Solc keccak256 Optimizer Bug (2021-03)
This is a compiler bug, not a source bug: the optimizer in Solidity before 0.8.3 could replace one keccak256(ptr, L1) with the result of an earlier keccak256(ptr, L2) when L1 and L2 rounded up to the same 32-byte word count, producing a wrong digest inside inline assembly. The remediation is not to change the contract logic but to recompile with a fixed compiler and confirm the deployed bytecode no longer carries the bug.
Recommended Fix
The condition is a property of the toolchain, so remediate at the build level.
// Affected: solc < 0.8.3 (optimizer enabled, two keccak256 over a shared memory
// pointer in inline assembly with no intervening jump/call).
// Fixed in: solc 0.8.3.
// Pin the compiler to a fixed version and recompile:
pragma solidity ^0.8.3; // or later
Steps:
- Set the compiler to 0.8.3 or later and rebuild.
- Redeploy — a contract already deployed from an affected compiler keeps the buggy bytecode; recompiling only helps future deployments.
- Verify the deployed runtime bytecode matches the output of the fixed compiler.
Common Mistakes
- Editing the assembly and assuming the source was wrong — the source is fine; the compiler mistranslated it.
- Bumping the pragma but redeploying with an old local
solcbinary, so the affected bytecode ships anyway. - Verifying flattened source on an explorer while the on-chain bytecode was produced by the affected compiler.