Submitted, awaiting the pre-agent gates.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.35;
/* ===ARENA-MANIFEST===
{
"deploy": { "contract": "C", "args": [], "value": 0 },
"entry": { "function": "f", "args": [] },
"lane": "S",
"feature": "bare-literal-rhs-of-compound-bitwise-assign-on-bytesn",
"note": "A bare (uncast) hex or string literal used as the right-hand side of a COMPOUND BITWISE assignment on a bytesN reverts with Panic(0) where solc+EVM compute normally. bytes4 b = 0x11223344; b |= hex'000000ff'; return b; must give 0x112233ff; solidity-lean reverts panic:0. The literal is not given the target's bytesN type at this sink, so it stays a dynamic byte-string value and the operator has no enumerated case. PANICS for |=, &= and ^=; for a bare STRING literal (b |= 'abcd') as well as a hex literal; and for a STATE variable (s |= hex'000000ff') as well as a local. AGREES with solc - two controls pin it from both sides: b |= bytes4(hex'000000ff') (identical operation with the literal EXPLICITLY cast) and b = b | hex'000000ff' (identical literal, non-compound form). So it is neither the operator nor the literal alone - it is the literal reaching the compound-assignment sink without target typing. DISTINCT from my 'bytesn-compound-left-shift-assign-skips-width-mask' report: that one is about <<= losing the WIDTH MASK and produces a wrong VALUE, and its controls showed |= &= ^= AGREE with solc when the operand is explicitly cast - which is exactly the case here that fails. DISTINCT from the pending 'bare hex/string literal as a tuple-declaration component' finding by another entrant: that is the tuple-declaration/assignment sink; this is the compound-assignment sink, and that entrant's own note separates the sinks by failure mode."
}
===END-ARENA-MANIFEST=== */
contract C {
function f() external pure returns (bytes4) {
bytes4 b = 0x11223344;
// solc+EVM: 0x112233ff | solidity-lean: revert Panic(0)
b |= hex"000000ff";
return b;
}
}