com um clique
solidity-coding
// Write production-quality Solidity contracts. Trigger phrases - write contract, implement function, add feature, add error, gas optimization, event design, contract architecture, or when working in src/ directories.
// Write production-quality Solidity contracts. Trigger phrases - write contract, implement function, add feature, add error, gas optimization, event design, contract architecture, or when working in src/ directories.
Security audit and code review for Solidity smart contracts. Trigger phrases - audit, check PR, security review, pre-audit preparation, vulnerability check, or when preparing code for external audit.
Write bulloak tree specifications (.tree files) for smart contract integration tests. Trigger phrases - write a tree, create test tree, BTT spec, bulloak tree, Branching Tree Technique, or when writing integration tests for contract functions.
Verify smart contracts on Etherscan, Routescan, and Blockscout block explorers. This skill should be used when the user asks to "verify contract", "verify on etherscan", "verify on blockscout", "verify on routescan", "verify on chain scan". Handles standard verification, Etherscan V2 API, Routescan, Blockscout verification, proxy patterns, and factory-created contracts.
Write Foundry-based tests and scripts. Trigger phrases - foundry testing, write test, fuzz test, fork test, invariant test, deploy script, gas benchmark, coverage, or when working in tests/ or scripts/ directories.
Protocol domain knowledge - Lockup (vesting), Flow (streaming), Airdrops (merkle distribution). This skill provides context when implementing business logic, understanding protocol formulas, state transitions, or answering questions about how Sablier protocols work.
| name | solidity-coding |
| user-invocable | true |
| description | Write production-quality Solidity contracts. Trigger phrases - write contract, implement function, add feature, add error, gas optimization, event design, contract architecture, or when working in src/ directories. |
This skill provides expertise for writing production-quality Solidity contracts following industry best practices.
For detailed patterns and code examples, read these reference files:
| Reference | Content | When to Read |
|---|---|---|
.claude/skills/solidity-coding/references/coding-patterns.md | NatSpec, errors, modifiers, imports, section headers | Before writing any contract code |
.claude/skills/solidity-coding/references/security-practices.md | CEI, access control, EIP-7702, upgrades | When implementing state changes |
.claude/skills/solidity-coding/references/gas-optimization.md | EIP-1153, L2 patterns, Solady, storage caching | When optimizing contract efficiency |
.claude/skills/solidity-coding/references/event-design.md | Event design for The Graph and indexers | When adding events to contracts |
.claude/skills/solidity-coding/references/versioning-migration.md | Interface versioning, storage migration, deprecation | When releasing new contract versions |
.claude/skills/solidity-coding/references/sablier-conventions.md | Sablier-specific naming, patterns, and examples | When working in Sablier repos |
.claude/skills/solidity-coding/references/nft-descriptor.md | Onchain NFT metadata and SVG generation | When implementing tokenURI |
Note: Your repo's agent will provide repo-specific structure (package locations, inheritance hierarchies, etc.)
| Element | Convention | Example |
|---|---|---|
| Contract / Library | PascalCase | TokenVault |
| Interface | I + PascalCase | ITokenVault |
| Function | camelCase | withdrawableAmountOf |
| Variable | camelCase | streamId |
| Constant | SCREAMING_SNAKE | MAX_SEGMENT_COUNT |
| Private/Internal | _underscore prefix | _balances |
| Error | {Contract}_{Description} | TokenVault_Overdraw |
@inheritdoc in implementations; full docs live in interfacessafeTransfer and safeTransferFromuint40 for all timestampsuint128 for token amountssrc/
├── MainContract.sol # Entry point
├── abstracts/ # Inheritance chain (state, features, base contracts)
├── interfaces/ # Public APIs - NatSpec lives here (use @inheritdoc in impl)
├── libraries/ # Errors.sol, Helpers.sol, Math libraries
└── types/ # Structs, enums, namespace libraries
Inherit in alphabetical order:
contract TokenVault is Batch, ERC721, ITokenVault, VaultDynamic, VaultLinear { ... }
When writing a new contract or function:
@inheritdoc for interface implementationsuint40 for timestamps, uint128 for amountsContracts must stay under the 24kb bytecode limit. Verify with the optimized profile:
forge build --sizes
If a contract exceeds the limit:
public/external library functions instead of internalUse public library functions to reduce contract size (called via DELEGATECALL rather than inlined):
// Library with PUBLIC functions (not inlined, reduces contract size)
library VaultMath {
function calculateAmount(...) public pure returns (uint128) { ... }
}
library Helpers {
function validateParams(...) public view { ... }
}
// Main contract calls library functions (DELEGATECALL, not inlined)
contract TokenVault {
function _computeAmount(uint256 id) private view returns (uint128) {
return VaultMath.calculateAmount(...);
}
}
Key insight: internal library functions are inlined into the contract bytecode. public/external library
functions are called via DELEGATECALL, keeping bytecode smaller but costing slightly more gas per call.
When you encounter "Stack Too Deep" errors, use an in-memory struct to bundle local variables:
/// @dev Needed to avoid Stack Too Deep.
struct ComputeVars {
address token;
string tokenSymbol;
uint128 depositedAmount;
string json;
ITokenVault vault;
string status;
}
function compute(uint256 id) external view returns (string memory result) {
ComputeVars memory vars;
vars.vault = ITokenVault(address(this));
vars.depositedAmount = vars.vault.getDepositedAmount(id);
vars.token = address(vars.vault.getToken(id));
// ... use vars.field instead of separate local variables
}
Place *Vars structs in types/DataTypes.sol if reused, or inline in the contract if function-specific.
libraries/Errors.sol{ContractName}_{ErrorDescription}/// @notice Thrown when.../// @notice Thrown when trying to withdraw more than available.
error TokenVault_Overdraw(uint256 id, uint128 amount, uint128 withdrawableAmount);
@inheritdocusing SafeERC20 for IERC20;
// Safe transfers handle non-standard ERC20s
token.safeTransfer(to, amount);
token.safeTransferFrom(from, to, amount);
@inheritdoc InterfaceNamenotNull(id) if accessing resource state)@inheritdocnoDelegateCall, notNull(id), etc.libraries/Errors.sol with section comment/// @notice Thrown when...revert Errors.ContractName_ErrorDesc(...)types/ directory.claude/skills/solidity-coding/references/coding-patterns.md)@param for each field in struct NatSpecTest this skill with these prompts:
getStreamBalance view function to the ISablierFlow interface"Flow_InsufficientBalance error with debugging parameters"_withdraw function using storage caching"TokenVesting contract with deposit, withdraw, and claim
functions"