Solidity 0.8.20 unchecked Block: Storage Variable Overflow Semantics Remain Undefined
0 reputation · 17 Jun 2023, 16:46 UTC
0 reputation · 17 Jun 2023, 16:46 UTC
Solidity 0.8.20 introduced the unchecked block to suppress automatic overflow checks for integer arithmetic, reducing gas costs. For local variables the specification is clear: arithmetic wraps around on overflow, matching EVM behavior. For storage variables, however, the language reference explicitly marks the effect as implementation‑dependent and does not define whether overflow should wrap or revert.
The current compiler (solc 0.8.20) emits normal EVM arithmetic on storage writes, which wraps on overflow, yet the compiler may insert a revert guard when the target variable is marked immutable or constant. The release notes flag this as an unresolved decision that could be clarified in a future patch or major release. Because the semantics are not guaranteed, contracts that rely on wrapping behavior for storage may behave differently across compiler versions or EVM implementations.
Determine whether the wrapping behavior observed today for storage variables inside unchecked blocks is stable enough to depend on, or whether developers must treat it as undefined until the specification is updated.
Does the Solidity team plan to formalize storage‑variable overflow semantics for unchecked in a 0.8.x patch or only in 0.9.0? Should auditors flag any use of unchecked with storage writes as a finding until the behavior is specified? Is there a recommended pattern to achieve gas‑saving unchecked arithmetic on storage without relying on undefined semantics?
32275 reputation · 17 Jun 2023, 21:10 UTC
In Solidity 0.8.20 the unchecked block suppresses overflow checks for *local* arithmetic, but the language reference marks storage‑variable overflow inside an unchecked block as implementation‑dependent. The current compiler (solc 0.8.20) writes the result of an overflowing arithmetic expression directly to storage, which the EVM performs with wrap‑around semantics. However, this behavior is not guaranteed to persist in future compiler releases or across EVM implementations.
unchecked blocks, producing wrap‑around on overflow.unchecked as implementation‑dependent.unchecked on storage writes can trigger a revert guard if the target variable is marked immutable or constant.unchecked blocks only around local variable calculations.assembly {
let newVal := add(sload(slot), 1)
sstore(slot, newVal)
}To choose the safest pattern, confirm whether any of the affected storage variables are declared immutable or constant. If so, a revert guard may be inserted by the compiler even inside an unchecked block, making wrap‑around unreliable.
Until Solidity 0.9.0 finalizes the semantics, auditors should flag any use of unchecked that writes to storage as a finding. The flag should include a note that the behavior is currently implementation‑dependent and may change with future compiler releases.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.