agentleFS
iktok90-designiktok90-design/ai-smart-contract-auditor/skills/diamond-eip2535/SKILL.md

diamond-eip2535

Skill36 starsChanged 5 months agoMITView on GitHub

Detect Diamond (EIP-2535) bugs — facet selector collisions, init-vs-upgrade safety, storage-namespace collisions, facet selfdestruct paths, missing facet cuts. Activate on Diamond imports, DiamondCut, IDiamondLoupe, IDiamondCut, LibDiamond, facet patterns.

The file

We split this skill into the rules it gives an agent

4 rules. About 0 are common, 4 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈4

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use unique namespace strings per facet.

    line 26
  2. Distinctive:

    If multiple facets share a storage struct, modifying struct fields requires coordinated upgrades.

    line 59
  3. Distinctive:

    Use proven framework (Nick Mudge's diamond-1 or LDC) — don't roll your own.

    line 76
  4. Distinctive:

    Document the storage struct shared by facets in a separate file.

    line 81

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Diamond (EIP-2535) detection

When this applies

  • Any contract using EIP-2535 Diamond Standard
  • Custom multi-facet upgradeable systems
  • Frameworks: Nick Mudge's diamond-1, Diamond Industries' SoliState, custom diamond impls

Detection patterns

Function-selector collision (CRITICAL)

Two facets implementing the same 4-byte selector (e.g. function foo() and function bar(uint256) that hash to the same selector). Diamond routes to the last-cut facet, but during a cut, the old version may be reachable.

  • Required: precompute selector mapping at deploy + verify uniqueness; rerun at every diamond-cut.

Storage namespace collision (CRITICAL)

Two facets using the same bytes32 STORAGE_POSITION slot prefix.

library LibA { bytes32 constant POS = keccak256("auditsentry.a"); }
library LibB { bytes32 constant POS = keccak256("auditsentry.a"); }   // ← collision

Use unique namespace strings per facet.

Init-vs-upgrade confusion (HIGH)

Diamond init runs once via delegatecall to an Init contract. Re-running init after diamond-cut → can re-initialize values or run dangerous code. See [[initialization]].

diamondCut access control (CRITICAL)

function diamondCut(FacetCut[] calldata cuts, address init, bytes calldata data) external {
    // ← no owner check
}

Anyone can add/remove/replace facets.

Removing facet without removing selectors (HIGH)

Facet contract removed from blockchain (selfdestructed pre-6780, or simply deauthorized), but selectors still point to the old address → reverts.

Replacing critical infrastructure facet (CRITICAL)

A malicious facet replacement can hijack the entire diamond. Centralization risk depends on diamondCut authority.

Facet selfdestruct pre-EIP-6780 (HIGH)

Pre-Cancun: a facet calling selfdestruct deletes itself, breaking the diamond. Post-Cancun (EIP-6780): only delete-in-deploy-tx. Existing facets still risky if deployed before. See [[selfdestruct-eip6780]].

Missing IDiamondLoupe (MEDIUM)

Without Loupe, off-chain consumers can't introspect facets. Soft requirement.

Function visibility per facet (MEDIUM)

Internal functions in a facet aren't callable through the diamond (only externals are routed). Devs sometimes mistake the contracts.

Init function reentrancy (HIGH)

init delegate-call during diamond-cut can reenter. Lock during cut.

Multi-facet shared storage (HIGH)

If multiple facets share a storage struct, modifying struct fields requires coordinated upgrades. Refactoring one facet's view of the struct breaks others.

Severity rubric

PatternSeverity
diamondCut lacks owner checkCritical
Selector collision (or missed verification)Critical
Storage namespace collisionCritical
Init function callable post-deployHigh
Removing facet leaves dangling selectorsHigh
Facet selfdestruct path (pre-6780 deploy)High
Missing LoupeMedium
Internal function mis-exposedMedium

Remediation patterns

  • Use proven framework (Nick Mudge's diamond-1 or LDC) — don't roll your own.
  • Maintain off-chain selector registry; gate diamondCut with a Timelock and a CI check that runs diamondCut --dry-run.
  • Storage: per-facet namespaced via keccak256("<unique-app-name>.<facet-name>").
  • Init: callable only via LibDiamond.diamondCut, never directly.
  • Loupe: always implement for introspection.
  • Document the storage struct shared by facets in a separate file.

False-positive notes

  • Reading-only Loupe call isn't a finding.
  • A diamond with a single facet is fine; the complexity surfaces at >2 facets.

Related

  • [[storage-layout]]
  • [[delegatecall-risks]]
  • [[selfdestruct-eip6780]]
  • [[centralization-risk]]

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.