Solidity Coding | Skills Pool
Solidity Coding [AUTO-INVOKE] MUST be invoked BEFORE writing or modifying any Solidity contract (.sol files). Covers pragma version, naming conventions, project layout, OpenZeppelin library selection standards, Chainlink integration, and anti-patterns. Trigger: any task involving creating, editing, or reviewing .sol source files.
NeverSight 117 星標 2026年3月22日 Solidity Coding Standards
Language Rule
Always respond in the same language the user is using. If the user asks in Chinese, respond in Chinese. If in English, respond in English.
Coding Principles
Pragma : Use pragma solidity ^0.8.20; — keep consistent across all files in the project
Dependencies : OpenZeppelin Contracts 4.9.x, manage imports via remappings.txt
Error Handling : Prefer custom errors over require strings — saves gas and is more expressive
Define: error InsufficientBalance(uint256 available, uint256 required);
Use: if (balance < amount) revert InsufficientBalance(balance, amount);
Documentation : All public / external functions must have NatSpec ( , , )
npx skills add NeverSight/learn-skills.dev
星標 117
更新時間 2026年3月22日
職業 @notice
@param
@return
Event Indexing : Only add indexed to address type parameters — add comment if indexing other types
Special Keywords : immutable / constant / unchecked / assembly must have inline comment explaining why
Naming Conventions Element Convention Example Contract / Library PascalCase MyToken, StakingPoolInterface I + PascalCaseIMyToken, IStakingPoolState variable / Function lowerCamelCase totalSupply, claimDividendConstant / Immutable UPPER_SNAKE_CASE MAX_SUPPLY, ROUTER_ADDRESSEvent PascalCase (past tense) TokenTransferred, PoolCreatedCustom Error PascalCase InsufficientBalance, UnauthorizedFunction parameter prefix _ for setter function setFee(uint256 _fee)
Forbidden : Pinyin names, single-letter variables (except i/j/k in loops), excessive abbreviations
Code Organization Rules Situation Rule Cross-contract constants Place in src/common/Const.sol Interface definitions Place in src/interfaces/I<Name>.sol, separate from implementation Simple on-chain queries Use cast call or cast send Complex multi-step operations Use forge script Import style Use named imports: import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
Project Directory Structure src/ — Contract source code
interfaces/ — Interface definitions (I*.sol)
common/ — Shared constants, types, errors (Const.sol, Types.sol)
test/ — Test files (*.t.sol)
script/ — Deployment & interaction scripts (*.s.sol)
config/ — Network config, parameters (*.json)
deployments/ — Deployment records (latest.env)
docs/ — Documentation, changelogs
lib/ — Dependencies (managed by forge install)
Configuration Management
config/*.json — network RPC URLs, contract addresses, business parameters
deployments/latest.env — latest deployed contract addresses, must update after each deployment
foundry.toml — compiler version, optimizer settings, remappings
Important config changes must be documented in the PR description
OpenZeppelin Library Selection Standards When writing Solidity contracts, prioritize using battle-tested OpenZeppelin libraries over custom implementations. Select the appropriate library based on the scenario:
Access Control Scenario Library Import Path Single owner management Ownable@openzeppelin/contracts/access/Ownable.solOwner transfer needs safety Ownable2Step@openzeppelin/contracts/access/Ownable2Step.solMulti-role permission (admin/operator/minter) AccessControl@openzeppelin/contracts/access/AccessControl.solNeed to enumerate role members AccessControlEnumerable@openzeppelin/contracts/access/AccessControlEnumerable.solGovernance with timelock delay TimelockController@openzeppelin/contracts/governance/TimelockController.sol
Rule : Single owner → Ownable2Step; 2+ roles → AccessControl; governance/DAO → TimelockController
Security Protection Scenario Library Usage External call / token transfer ReentrancyGuardAdd nonReentrant modifier Emergency pause needed PausableAdd whenNotPaused to user-facing functions; keep admin functions unpaused ERC20 token interaction SafeERC20Use safeTransfer / safeTransferFrom / safeApprove instead of raw calls
Rule : Any contract that transfers tokens or ETH MUST use ReentrancyGuard + SafeERC20
Token Standards Scenario Library Notes Fungible token ERC20Base standard Token with burn mechanism ERC20BurnableAdds burn() and burnFrom() Token with max supply cap ERC20CappedEnforces totalSupply <= cap Gasless approval (EIP-2612) ERC20PermitSaves users approve tx gas Governance voting token ERC20VotesSnapshot-based voting power NFT ERC721Base NFT standard NFT with enumeration ERC721EnumerableSupports tokenOfOwnerByIndex queries Multi-token (FT + NFT mixed) ERC1155Game items, batch operations
Utility Libraries Scenario Library Usage Whitelist / airdrop verification MerkleProofGas-efficient Merkle tree verification Signature verification ECDSA + EIP712Off-chain sign + on-chain verify Auto-increment IDs CountersToken ID, order ID generation Batch function calls MulticallMultiple operations in one tx Address set / uint set EnumerableSetIterable sets with O(1) add/remove/contains Revenue sharing PaymentSplitterSplit ETH/token payments by shares Standardized yield vault ERC4626DeFi vault standard
Contract Upgrade Scenario Library Notes Upgradeable contract (gas efficient) UUPSUpgradeableUpgrade logic in implementation contract Upgradeable contract (admin separated) TransparentUpgradeableProxyUpgrade logic in proxy, higher gas Initializer (replace constructor) InitializableUse initializer modifier instead of constructor
Rule : New projects prefer UUPSUpgradeable; always use Initializable for upgradeable contracts
Chainlink Integration Scenario Library Notes Token price data AggregatorV3InterfaceOnly for tokens with Chainlink feed; check data.chain.link Verifiable randomness (lottery/NFT) VRFConsumerBaseV2On-chain provably fair random numbers Automated execution (cron jobs) AutomationCompatibleReplace centralized keepers Cross-chain messaging CCIPCross-chain token/message transfer
Library Selection Decision Flow Does contract handle user funds/tokens?
├── YES → Add ReentrancyGuard + SafeERC20
│ Does it need emergency stop?
│ ├── YES → Add Pausable
│ └── NO → Skip
└── NO → Skip
How many admin roles needed?
├── 1 role → Ownable2Step
├── 2+ roles → AccessControl
└── DAO/governance → TimelockController
Does contract need price data?
├── Token has Chainlink feed → AggregatorV3Interface
├── No Chainlink feed → Custom TWAP with min-liquidity check
└── No price needed → Skip
Will contract need upgrades?
├── YES → UUPSUpgradeable + Initializable
└── NO → Standard deployment (immutable)
Anti-Patterns (Do NOT)
Do NOT write custom transfer wrappers — use SafeERC20
Do NOT write custom access control modifiers — use Ownable / AccessControl
Do NOT write custom pause logic — use Pausable
Do NOT use SafeMath on Solidity >= 0.8.0 — overflow checks are built-in
Do NOT use require(token.transfer(...)) — use token.safeTransfer(...) via SafeERC20
Do NOT use tx.origin for auth — use msg.sender with Ownable / AccessControl
Foundry Quick Reference # Create new project
forge init <project-name>
# Install dependency
forge install OpenZeppelin/[email protected]
# Build contracts
forge build
# Format code
forge fmt
# Update remappings
forge remappings > remappings.txt
02
Language Rule