library-api-design

Applies API design rules when writing or reviewing Solidity contracts in openzeppelin-contracts.

1|Updated Jul 3, 2026
One-click install
npx skills add https://github.com/urufu-labs/urufu-launchpad --skill library-api-design-urufu-labs
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: library-api-design
Source: https://github.com/urufu-labs/urufu-launchpad/tree/main/contracts/lib/openzeppelin-contracts/.claude/skills/library-api-design
Command: npx skills add https://github.com/urufu-labs/urufu-launchpad --skill library-api-design-urufu-labs

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Solidity library contracts are inherited downstream, so small API design mistakes (missing virtual, wrong calldata usage, reverts instead of no-ops) break every inheriting contract. This Skill encodes the openzeppelin-contracts API design conventions so new or modified contracts under contracts/ stay inheritable and consistent. ## Core Features & Use Cases - Override-point design: Enforces virtual on overridable functions, the _update single-override pattern, and correct super usage in extensions. - Signature conventions: Guides memory vs calldata, public vs external, and the internal/external split where public functions only capture _msgSender() and delegate. - Behavioral rules: Prefers no-ops over reverts, defines empty virtual hooks, and covers constructors, immutables, the upgrades transpiler tag, and ERC-7201 namespaced storage. - Use Case: When adding a new ERC-20 extension, use this Skill to decide which functions should be virtual, where _msgSender() belongs, and whether a state transition should return a bool instead of reverting. ## Quick Start Review this new contract under contracts/ against the library API design rules and flag any violations.

Frequently Asked Questions about library-api-design

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I design overridable functions in Solidity library contracts?▼

Mark every public and internal function virtual, except alias functions and convenience overloads that only forward to a canonical virtual form. Use public rather than external for override points, since an override of an external function cannot call super.

When should Solidity functions use memory vs calldata?▼

Use memory for strings, bytes, arrays, and structs by default, including in public functions, because calldata forces every inheritor to match. Calldata is only valid for msg.data slices, narrowly scoped internal decoding helpers, or explicit Calldata-suffixed utility variants.

What is the _update single override point pattern in OpenZeppelin contracts?▼

Make _mint, _burn, and _transfer non-virtual aliases that delegate to one virtual _update function. Extensions override only _update, call super._update first, then add side effects, keeping all state machine entry points consistent.

Should a Solidity function revert or no-op on empty input?▼

Prefer no-ops when doing nothing creates no security concern: skip vacuous inputs silently, return a bool for idempotent state transitions, and provide empty internal virtual hooks as extension points. Overrides can add requirements on top of a no-op base but cannot remove enforced ones.

When should I use ERC-7201 namespaced storage in OpenZeppelin contracts?▼

ERC-7201 is opt-in, not the default, because upgradeable variants are auto-generated by the OpenZeppelin Transpiler. Use it only when namespacing is genuinely necessary, such as Initializable.sol, and always verify the slot with SlotDerivation.erc7201Slot().