internal/skills/content/solidity-guide/SKILL.md
Solidity/Ethereum guardrails, patterns, and best practices for AI-assisted development. Use when working with Solidity files (.sol), or when the user mentions Solidity/Ethereum/smart contracts. Provides gas optimization patterns, reentrancy prevention, upgradeable contract guidelines, and testing standards specific to this project's coding standards.
npx skillsauth add ar4mirez/samuel solidity-guideInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Applies to: Solidity 0.8.20+, Ethereum, EVM-compatible chains, DeFi, NFTs
immutable and constant for values that do not change after deployment.pragma solidity ^0.8.20;>=0.8.0). Pin to a minor range.tx.origin for authorization. Use msg.sender.selfdestruct in new contracts (deprecated in Dencun).ReentrancyGuard from OpenZeppelin for functions that make external calls.SafeERC20 for token transfers (handles non-standard return values).uint128, uint64, bool into single 256-bit slots.calldata instead of memory for read-only external function parameters.require strings (saves ~50 bytes per error site).unchecked blocks for arithmetic that provably cannot overflow.mapping over array for large datasets (O(1) vs O(n) lookups).AccessControl or Ownable2Step (not plain Ownable).TimelockController).@openzeppelin/contracts-upgradeable with initializer instead of constructors.uint256[50] private __gap;_disableInitializers();Prevents reentrancy by ordering operations: validate, update state, then call externally.
function withdraw(uint256 amount) external nonReentrant {
// 1. CHECKS
if (amount == 0) revert ZeroAmount();
if (balances[msg.sender] < amount) revert InsufficientBalance();
// 2. EFFECTS: update state BEFORE external calls
balances[msg.sender] -= amount;
// 3. INTERACTIONS: external calls last
(bool success, ) = msg.sender.call{value: amount}("");
if (!success) revert TransferFailed();
emit Withdrawn(msg.sender, amount);
}
Let users withdraw funds instead of pushing payments to them.
mapping(address => uint256) public pendingWithdrawals;
function claimPayment() external nonReentrant {
uint256 amount = pendingWithdrawals[msg.sender];
if (amount == 0) revert NothingToClaim();
pendingWithdrawals[msg.sender] = 0;
(bool success, ) = msg.sender.call{value: amount}("");
if (!success) revert TransferFailed();
emit PaymentClaimed(msg.sender, amount);
}
Custom errors are cheaper than require strings and support typed parameters.
error Unauthorized(address caller);
error InsufficientBalance(uint256 requested, uint256 available);
error ZeroAddress();
function transfer(address to, uint256 amount) external {
if (to == address(0)) revert ZeroAddress();
if (balances[msg.sender] < amount) {
revert InsufficientBalance(amount, balances[msg.sender]);
}
balances[msg.sender] -= amount;
balances[to] += amount;
emit Transfer(msg.sender, to, amount);
}
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
contract MyProtocol is UUPSUpgradeable, OwnableUpgradeable {
uint256 public protocolFee;
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() { _disableInitializers(); }
function initialize(address owner, uint256 fee) external initializer {
__Ownable_init(owner);
__UUPSUpgradeable_init();
protocolFee = fee;
}
function _authorizeUpgrade(address) internal override onlyOwner {}
uint256[49] private __gap;
}
nonReentrant to external-call functions. Follow CEI even with the guard. Watch for cross-function reentrancy on shared state.unchecked only when provably safe.block.timestamp, not block.number.tx.origin. Use Pausable for emergency stops.// test/Vault.t.sol
pragma solidity ^0.8.20;
import {Test} from "forge-std/Test.sol";
import {Vault} from "../src/Vault.sol";
contract VaultTest is Test {
Vault public vault;
address public alice = makeAddr("alice");
function setUp() public {
vault = new Vault();
vm.deal(alice, 10 ether);
}
function test_deposit_updates_balance() public {
vm.prank(alice);
vault.deposit{value: 1 ether}();
assertEq(vault.balances(alice), 1 ether);
}
function test_withdraw_reverts_on_insufficient_balance() public {
vm.prank(alice);
vm.expectRevert(Vault.InsufficientBalance.selector);
vault.withdraw(1 ether);
}
// Fuzz testing: forge generates random inputs automatically
function testFuzz_deposit_and_withdraw(uint96 amount) public {
vm.assume(amount > 0 && amount <= 10 ether);
vm.startPrank(alice);
vault.deposit{value: amount}();
vault.withdraw(amount);
vm.stopPrank();
assertEq(vault.balances(alice), 0);
}
}
Use npx hardhat test with Chai matchers and ethers.js for JS/TS projects.
forge build && forge test # Compile and test (Foundry)
forge test -vvvv # Verbose with stack traces
forge test --fuzz-runs 10000 # Extended fuzz testing
forge coverage # Coverage report
forge fmt # Format Solidity files
forge snapshot # Gas snapshot for benchmarking
slither . # Static analysis (Slither)
myth analyze src/Contract.sol # Symbolic execution (Mythril)
npx hardhat compile && npx hardhat test # Hardhat alternative
forge test passes, Slither reports zero high/medium findingsforge snapshot --diff)forge script --fork-url $RPC_URLdevelopment
Zig language guardrails, patterns, and best practices for AI-assisted development. Use when working with Zig files (.zig), build.zig, or when the user mentions Zig. Provides comptime patterns, allocator conventions, C interop guidelines, and testing standards specific to this project's coding standards.
tools
WordPress framework guardrails, patterns, and best practices for AI-assisted development. Use when working with WordPress projects, or when the user mentions WordPress. Provides theme development, plugin architecture, REST API, blocks, and security guidelines.
tools
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs. Use when testing web apps, automating browser interactions, or debugging frontend issues.
tools
Suite of tools for creating elaborate, multi-component web applications using modern frontend technologies (React, Tailwind CSS, shadcn/ui). Use for complex projects requiring state management, routing, or shadcn/ui components - not for simple single-file HTML/JSX pages.