omermaksutii/rugproof/diamond-eip2535

Claude Code and agent skill by omermaksutii/rugproof

Trust tier 3
  • community
  • ext:[{"type":"hook","description":"Pre/post lifecycle hooks"}]
Source check pending

Checking that the SKILL.md file is still in the repository.

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.

Install

npx vskill@latest install omermaksutii/rugproof/diamond-eip2535

Semi-extensibleMentions customization, but needs skill-specific knowledge. Read the extensible skills standard

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.

solidity
library LibA { bytes32 constant POS = keccak256("rugproof.a"); }
library LibB { bytes32 constant POS = keccak256("rugproof.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)
solidity
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]]

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
0

Not refreshed yet.

Extension points

  • hookPre/post lifecycle hooks

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/omermaksutii/rugproof/diamond-eip2535/badge)](https://verified-skill.com/skills/omermaksutii/rugproof/diamond-eip2535)

Something wrong with this skill or its page? Tell us.