Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Solady Erc20 Permit2 Assumptions

ASecurity

Detect unsafe assumptions about Solady's gas-optimized ERC20/ERC2612 permit and DN404 metadata. Solady's ERC20 uses custom storage slots, returns bools via assembly, exposes a virtual `_constantNameHash`/`_versionHash` for permit domain separation, and its DN404 mirror splits ERC20/ERC721 logic — integrators that assume OZ-style behavior, revert strings, or that `name()`/`decimals()` are always present can misbehave. Activate on solady/tokens imports, ERC2612 permit flows, DN404, or off-chain...

36 stars
0 votes
0 copies
0 views
Added 10/4/2026
blockchain

Security Analysis

A100/100

Scanned 10/4/2026

$npx -y skills add iktok90-design/ai-smart-contract-auditor --skill solady-erc20-permit2-assumptions --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Solady Erc20 Permit2 Assumptions?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Solady Erc20 Permit2 Assumptions
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/iktok90-design-solady-erc20-permit2-assumptions/badge)](https://www.skillsdirectory.com/skills/iktok90-design-solady-erc20-permit2-assumptions)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: solady-erc20-permit2-assumptions
description: Detect unsafe assumptions about Solady's gas-optimized ERC20/ERC2612 permit and DN404 metadata. Solady's ERC20 uses custom storage slots, returns bools via assembly, exposes a virtual `_constantNameHash`/`_versionHash` for permit domain separation, and its DN404 mirror splits ERC20/ERC721 logic — integrators that assume OZ-style behavior, revert strings, or that `name()`/`decimals()` are always present can misbehave. Activate on solady/tokens imports, ERC2612 permit flows, DN404, or off-chain code parsing Solady revert reasons.
---

# Solady ERC20 / permit / DN404 assumption detection

## When this applies

Trigger on any of:

- `import {ERC20} from "solady/tokens/ERC20.sol";` or `ERC2612`, `DN404`, `DN404Mirror`, `ERC4626` from solady
- Integrations calling `permit(...)` and assuming a fixed EIP-712 domain / version string
- Code relying on Solady's revert *reasons* (Solady reverts with custom errors / 4-byte selectors, not strings)
- DN404 tokens treated as plain ERC20 (the NFT mirror has separate transfer semantics)
- Off-chain indexers decoding events / revert data assuming OZ layout
- Overriding `name()`, `symbol()`, `_constantNameHash`, `_versionHash`, or `_domainNameAndVersion`

## Detection patterns

### Hardcoded permit domain separator (MEDIUM)
```solidity
bytes32 DOMAIN = keccak256(abi.encode(
    TYPE_HASH, keccak256("MyToken"), keccak256("1"), block.chainid, token
));
// ← assumes version "1"; Solady ERC2612 default version is "1" but DN404/overrides may differ
```
Solady derives the domain via `_domainNameAndVersion()` (default version `"1"`). If the token overrides `_versionHash` or `name()`, a hand-rolled separator mismatches and every `permit` reverts `InvalidPermit`.
**Signal:** off-chain or on-chain code reconstructs the EIP-712 domain instead of reading `DOMAIN_SEPARATOR()` from the token.

### Relying on revert strings (MEDIUM)
```solidity
try token.transferFrom(a, b, amt) returns (bool) {}
catch Error(string memory reason) {           // ← Solady reverts with custom errors,
    if (keccak256(bytes(reason)) == ...) {}    //    NOT Error(string); this branch never hits
}
```
Solady reverts `InsufficientBalance()` / `InsufficientAllowance()` (4-byte). `catch Error(string)` won't match; only `catch (bytes memory)` / `catch` will.
**Signal:** `catch Error(string)` or string comparison used to branch on a Solady token failure.

### DN404 treated as vanilla ERC20 (MEDIUM)
```solidity
dn404Token.transfer(to, amt);   // also mints/burns NFTs in the mirror; gas + reentrancy surface
```
DN404 fractionalizes an NFT collection; an ERC20 transfer can mint/burn mirror NFTs and invoke `onERC721Received`-style hooks. Treating it as inert ERC20 ignores added gas and a callback surface.
**Signal:** DN404 token integrated through a path that assumes ERC20 transfers have no side effects / no callbacks.

### Assuming metadata always present (LOW-MEDIUM)
```solidity
uint8 d = IERC20(token).decimals();   // Solady ERC20 leaves name/symbol/decimals virtual
```
Solady's base ERC20 leaves `name()`/`symbol()` as `virtual` returning empty unless overridden; a minimal token may omit them.
**Signal:** unguarded `decimals()`/`name()` read on a Solady-derived token.

## Severity rubric

| Pattern | Severity | Notes |
|---|---|---|
| Hand-rolled permit domain mismatching token → permits brick | **Medium** | Liveness, not loss; per-token |
| Revert-string branching never executes | **Medium** | Silent wrong control flow |
| DN404 used as plain ERC20 (callback / gas surprise) | **Medium** | Reentrancy/gas surface, see [[reentrancy]] |
| Unguarded metadata read | **Low** | Reverts or returns empty |

## Remediation patterns

1. **Read `DOMAIN_SEPARATOR()`** off the token instead of reconstructing it; never hardcode the version string.
2. **Catch `bytes`, not `Error(string)`** — match Solady custom-error selectors or use a generic `catch`.
3. **Detect DN404** (e.g. via `DN404Mirror` linkage / interface) and route it through NFT-aware logic; budget gas and treat transfers as callback-bearing.
4. **Guard metadata** with try/catch defaulting decimals to 18.

## False-positive notes

- Reading `DOMAIN_SEPARATOR()` directly (not reconstructing it) is correct — no finding.
- A non-DN404 Solady ERC20 with metadata overridden is a normal token — only flag missing overrides.
- Generic `catch {}` already handles custom errors — downgrade.

## Related

- [[signature-malleability]] — permit signature handling
- [[token-compatibility]] — non-standard return / metadata
- [[reentrancy]] — DN404 mirror callbacks

Attribution

iktok90-designiktok90-design
View sourceSee grades on GitHubMore from iktok90-design →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Nft Standards

Implement NFT standards (ERC-721, ERC-1155) with proper metadata handling, minting strategies, and marketplace integration. Use when creating NFT contracts, building NFT marketplaces, or implementing digital asset systems.

458250 votes

Nft Standards

Implement NFT standards (ERC-721, ERC-1155) with proper metadata handling, minting strategies, and marketplace integration. Use when creating NFT contracts, building NFT marketplaces, or implementing digital asset systems.

401990 votes

vyper-compiler

Vyper smart contract compiler internals. Use when working on the Vyper compiler codebase — compilation pipeline, Venom IR, semantic analysis, code generation, testing, or contributing. Triggers on vyper compiler development, Venom passes, AST/semantics changes, codegen work, or test writing.

51840 votes

Flash Loan Simulator

Simulate flash loan arbitrage strategies and profitability across DeFi protocols. Use when performing crypto analysis. Trigger with phrases like "analyze crypto", "check blockchain", or "monitor market".

27190 votes

On Chain Analytics

Perform on-chain analysis including whale tracking, token flows, and network activity. Use when performing crypto analysis. Trigger with phrases like "analyze crypto", "check blockchain", or "monitor market".

27190 votes
View all in blockchain →