Unit
src/lib/LibExtrospectBytecode.sol — checkNoSolidityCBORMetadata.
Intent oracle
NatSpec's stated purpose: "…as a defense against the metamorphic metadata attack" — i.e. against an address whose code can change.
Violated property
The gate answers "safe" about an address that has no code today: an EOA, a self-destructed account, or an undeployed CREATE2 slot an attacker controls. That is precisely the case the metamorphic threat model is about, and it is the one input for which "no metadata present" carries no information at all.
Contrast the sibling: checkCBORTrimmedBytecodeHash reverts MetadataNotTrimmed on an empty account. The two account-taking checks answer the empty case in opposite directions and neither NatSpec mentions it.
Verified repro
repro-tests/TriageBytecode.t.sol :: testT7_CodelessPassesNoMetadata — PASSES at 28017b6:
assertEq(address(0x1234).code.length, 0);
LibExtrospectBytecode.checkNoSolidityCBORMetadata(address(0x1234)); // returns cleanly
Triage
Severity: medium-high by value-at-risk; low by depth. This is an intent question, not a coding error: test/src/lib/LibExtrospectBytecode.checkNoSolidityCBORMetadata.t.sol::testCheckNoMetadataEmptyAccount asserts the pass as intended, so the suite entrenches it. The ruling needed is whether an empty account should revert, or whether the caller's code.length != 0 obligation should be stated. Same shape as the separate checkNotMetamorphic(hex"") issue.
Provenance
Adversarial mutation-test campaign on rainlanguage/rain.extrospection @ 28017b6, triage pass.
Repros in this issue were re-executed by the triage agent against a fresh clone at 28017b6
(nix develop -c forge test, baseline 304 passed / 0 failed) unless the issue says otherwise.
Triage repro sources: /home/gildlab/artifacts/2026-08-18-extrospection-amt/triage/repro-tests/
(TriageBytecode.t.sol, TriageProxy.t.sol, TriageEtch.t.sol) — drop into test/triage/ of a
clone at 28017b6 and run nix develop -c forge test --match-path 'test/triage/*'.
Unit
src/lib/LibExtrospectBytecode.sol—checkNoSolidityCBORMetadata.Intent oracle
NatSpec's stated purpose: "…as a defense against the metamorphic metadata attack" — i.e. against an address whose code can change.
Violated property
The gate answers "safe" about an address that has no code today: an EOA, a self-destructed account, or an undeployed CREATE2 slot an attacker controls. That is precisely the case the metamorphic threat model is about, and it is the one input for which "no metadata present" carries no information at all.
Contrast the sibling:
checkCBORTrimmedBytecodeHashrevertsMetadataNotTrimmedon an empty account. The two account-taking checks answer the empty case in opposite directions and neither NatSpec mentions it.Verified repro
repro-tests/TriageBytecode.t.sol :: testT7_CodelessPassesNoMetadata— PASSES at28017b6:Triage
Severity: medium-high by value-at-risk; low by depth. This is an intent question, not a coding error:
test/src/lib/LibExtrospectBytecode.checkNoSolidityCBORMetadata.t.sol::testCheckNoMetadataEmptyAccountasserts the pass as intended, so the suite entrenches it. The ruling needed is whether an empty account should revert, or whether the caller'scode.length != 0obligation should be stated. Same shape as the separatecheckNotMetamorphic(hex"")issue.Provenance
Adversarial mutation-test campaign on
rainlanguage/rain.extrospection@28017b6, triage pass.Repros in this issue were re-executed by the triage agent against a fresh clone at
28017b6(
nix develop -c forge test, baseline 304 passed / 0 failed) unless the issue says otherwise.Triage repro sources:
/home/gildlab/artifacts/2026-08-18-extrospection-amt/triage/repro-tests/(
TriageBytecode.t.sol,TriageProxy.t.sol,TriageEtch.t.sol) — drop intotest/triage/of aclone at
28017b6and runnix develop -c forge test --match-path 'test/triage/*'.