Skip to content

AMT coverage: g2-clone-tail - #98

Merged
thedavidmeister merged 1 commit into
mainfrom
2026-09-19-amt-g2-clone-tail
Sep 20, 2026
Merged

thedavidmeister merged 1 commit into
mainfrom
2026-09-19-amt-g2-clone-tail

Conversation

@thedavidmeister

@thedavidmeister thedavidmeister commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

Adversarial + mutation campaign, group g2-clone-tail, scanned at 5a633508643e345fc72c11133f782214f60db9b5. Test-only. Tests 68 → 75.

Behaviour ledger

Verdicts come from mutation-probe (greedy fail-pattern, proof (\d+) tests passed, 0 no-run, 0 harness errors). Pass 1 ran on the untouched suite. Passes 2 and 3 ran on this branch.

checkImplementationCode

  • A01–A15 (zero code; 0xef compare/constant/boundaries; extcodecopy offsets; byte index): KILLED_PREEXISTING.
  • A03 (< 2), A08 (>= 0xef): before this PR only the fuzz testCheckImplementationCodeEtched killed them, so the kill depended on the seed. testCheckImplementationCodeSingleByte now kills them deterministically. A09 is also killed by it.
  • New testCheckImplementationCodeSingleByteEf: a lone 0xef reverts DelegatedImplementation.

cloneAndInitialize

  • B01–B07, B09–B22, B24–B36, B39–B51, B53: KILLED_PREEXISTING. These cover guard order, occupancy, CREATE2, CloneDeploymentFailed, NewClone fields and ordering, the initialize call, bubbling and the return check.
  • B08 (occupancy > 1): EQUIVALENT. The only code a CREATE2 clone address can hold is the 45-byte EIP-1167 runtime.
  • B23 (NewClone carries predicted) and B52 (return predicted): EQUIVALENT. child == predicted whenever CREATE2 succeeded.
  • B37 (bubble > 1) and B38 (bubble > 4): SURVIVED → KILLED_NEW by testInitializeRevertsWithSubWordDataBubblesVerbatim (1, 4 and 31 bytes) and the fuzz testInitializeRevertsWithDataBubblesVerbatim.
  • B55 (a 1–31 byte return is decoded rather than rejected): KILLED_NEW by testInitializeReturnsSubWordRevertsInitializationFailed.
  • B58 (guard reduced to a zero-code check): KILLED_NEW by testDelegatedImplementationRevertsDelegatedImplementation, which exercises both entry points.
  • B60 (sentinel check before bubble): KILLED_PREEXISTING by testCloneDeterministicInitializeRevertBubbles. The new tests kill it too.
  • B61 (occupancy also rejects a funded address): KILLED_NEW by testPrefundedCloneAddressDeploys. A predicted address that holds ETH but no code deploys, and the clone keeps the ETH.
  • B62 (occupancy by codehash): KILLED_PREEXISTING by testCloneDeterministicNonceOnlyCollisionReverts. The new tests kill it too.
  • B63_LINE

ICLONEABLE_V2_SUCCESS

  • C01 (string changed): KILLED_PREEXISTING. TestCloneable returns the spec literal, not the constant.

QA

  • Discriminating tests: testCheckImplementationCodeSingleByte, testCheckImplementationCodeSingleByteEf, testInitializeRevertsWithSubWordDataBubblesVerbatim, testInitializeRevertsWithDataBubblesVerbatim, testInitializeReturnsSubWordRevertsInitializationFailed, testDelegatedImplementationRevertsDelegatedImplementation, testPrefundedCloneAddressDeploys. This PR is test-only and the base behaviour is correct, so each test passes on base and fails under its mutant (mutation-probe pass 2: 10/10 killed). The full suite on the branch is 75 passed, 0 failed, and forge fmt --check is clean.
  • Mutations applied: code.length == 0 → < 2 (A03) → SingleByte; == 0xef → >= 0xef / <= 0xef (A08/A09) → SingleByte; returnData.length > 0 → > 1 / > 4 (B37/B38) → SubWordDataBubblesVerbatim, DataBubblesVerbatim; length != 32 → == 0 || > 32 (B55) → ReturnsSubWord; the guard call → a zero-code check only (B58) → DelegatedImplementation; occupancy || predicted.balance != 0 (B61) → PrefundedCloneAddressDeploys.
  • Oracle: the NatSpec on LibICloneableFactoryV4 errors and cloneAndInitialize, and ICloneableFactoryV3.cloneDeterministic: a revert with data bubbles verbatim; anything but the 32-byte sentinel is InitializationFailed; 0xef-leading code is DelegatedImplementation (checkImplementationCode admits an EIP-7702 delegated EOA, whose code the account holder can repoint or revoke after clones exist #73); CloneAddressOccupied is about code only. Expected values are literal bytes and typed selectors, not recomputed from the implementation.
  • Category check: the g2 brief scopes checkImplementationCode, the whole cloneAndInitialize tail, and ICLONEABLE_V2_SUCCESS. The ledger above covers all three.
  • Re-survey: considered and not probed as equivalent:
    • swapping the zero-code and 0xef checks (empty code copies as 0);
    • extcodecopy of 32 bytes (byte 0 unchanged);
    • !success || in the return check (a revert with data has already bubbled; a revert with empty data fails the length check);
    • calling initialize on predicted instead of child.
  • Adversarial finding filed: Open-salt NatSpec says the deployer keeps exactly one lever (timing), but the gas forwarded to initialize is a second: a front-runner can pin a degraded init state at the pinned address #95

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Tests
    • Expanded coverage for implementation validation, including single-byte implementation code and delegated implementations.
    • Verified initialization errors and revert data are surfaced correctly.
    • Added checks ensuring invalid initialization return lengths are rejected.
    • Confirmed prefunded predicted clone addresses deploy successfully while retaining their ETH balances.

…d prefunded addresses

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@thedavidmeister thedavidmeister self-assigned this Sep 19, 2026
@coderabbitai

coderabbitai Bot commented Sep 19, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 97f18e74-a48c-4ccf-9406-6f8cc0fc43e2

📥 Commits

Reviewing files that changed from the base of the PR and between 5a63350 and cafc597.

📒 Files selected for processing (2)
  • test/src/lib/LibICloneableFactoryV4.checkImplementationCode.t.sol
  • test/src/lib/LibICloneableFactoryV4.cloneAndInitialize.t.sol

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


Walkthrough

The PR extends LibICloneableFactoryV4 tests for implementation-code guards, initialization return handling, revert-data bubbling, delegated implementations, and prefunded predicted clone addresses.

Changes

Clone validation

Layer / File(s) Summary
Implementation guards
test/src/lib/LibICloneableFactoryV4.checkImplementationCode.t.sol, test/src/lib/LibICloneableFactoryV4.cloneAndInitialize.t.sol
Tests verify accepted single-byte implementation code and DelegatedImplementation reverts for 0xef and EIP-7702 delegation implementations.
Initialization results and revert data
test/src/lib/LibICloneableFactoryV4.cloneAndInitialize.t.sol
Tests verify verbatim bubbling of nonempty revert data and InitializationFailed for 1–31-byte initialization returns.
Prefunded predicted deployment
test/src/lib/LibICloneableFactoryV4.cloneAndInitialize.t.sol
Tests verify that both clone entry points deploy at prefunded predicted addresses and preserve their balances.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Other

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the AMT coverage campaign and the specific g2-clone-tail target covered by the test changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant