solidity-gas-optimization

安装量: 87
排名: #9152

安装

npx skills add https://github.com/pseudoyu/agent-skills --skill solidity-gas-optimization

Solidity Gas Optimization Overview

Comprehensive gas optimization guide for Solidity smart contracts, containing 80+ techniques across 8 categories. Based on the RareSkills Book of Gas Optimization. Rules are prioritized by impact and safety.

When to Apply

Reference these guidelines when:

Writing new Solidity smart contracts Reviewing or auditing existing contracts Optimizing gas costs for deployment or execution Refactoring contract storage layouts Implementing cross-contract interactions Choosing between design patterns (ERC721 vs ERC1155, etc.) Priority-Ordered Categories Priority Category Impact Risk 1 Storage Optimization CRITICAL LOW 2 Deployment Optimization HIGH LOW 3 Calldata Optimization HIGH LOW 4 Design Patterns HIGH MEDIUM 5 Cross-Contract Calls MEDIUM-HIGH MEDIUM 6 Compiler Optimizations MEDIUM LOW 7 Assembly Tricks MEDIUM HIGH 8 Dangerous Techniques LOW CRITICAL Quick Reference Critical: Storage Optimization (Apply First)

Zero-to-One Writes:

Avoid zero-to-one storage writes (costs 22,100 gas) Use 1/2 instead of 0/1 for boolean-like values Keep minimum balances in ERC20 contracts

Variable Packing:

// Bad: 3 slots struct Unpacked { uint64 time; // slot 1 uint256 amount; // slot 2 address user; // slot 3 }

// Good: 2 slots struct Packed { uint64 time; // slot 1 (with address) address user; // slot 1 uint256 amount; // slot 2 }

Caching:

// Bad: reads storage twice function increment() public { require(count < 10); count = count + 1; }

// Good: reads storage once function increment() public { uint256 _count = count; require(_count < 10); count = _count + 1; }

Constants & Immutables:

uint256 constant MAX = 100; // No storage slot address immutable owner; // Set in constructor, no storage

High: Deployment Optimization

Custom Errors:

// Bad: ~64+ bytes require(amount <= limit, "Amount exceeds limit");

// Good: ~4 bytes error ExceedsLimit(); if (amount > limit) revert ExceedsLimit();

Payable Constructors:

// Saves ~200 gas on deployment constructor() payable {}

Clone Patterns:

Use EIP-1167 minimal proxies for repeated deployments Use UUPS over Transparent Proxy for upgradeable contracts High: Calldata Optimization

Calldata vs Memory:

// Bad: copies to memory function process(bytes memory data) external {}

// Good: reads directly from calldata function process(bytes calldata data) external {}

Avoid Signed Integers:

Small negative numbers are expensive (e.g., -1 = 0xffff...) Use unsigned integers in function parameters High: Design Patterns

Token Standards:

Prefer ERC1155 over ERC721 for NFTs (no balanceOf overhead) Consider consolidating multiple ERC20s into one ERC1155

Signature vs Merkle:

Prefer ECDSA signatures over Merkle trees for allowlists Implement ERC20Permit for approve + transfer in one tx

Alternative Libraries:

Consider Solmate/Solady over OpenZeppelin for gas efficiency Medium-High: Cross-Contract Calls

Reduce Interactions:

Use ERC1363 transferAndCall instead of approve + transferFrom Implement multicall for batching operations Cache external call results (e.g., Chainlink oracles)

Access Lists:

Use ERC2930 access list transactions to pre-warm storage Medium: Compiler Optimizations

Loop Patterns:

// Good: unchecked increment, cached length uint256 len = arr.length; for (uint256 i; i < len; ) { // logic unchecked { ++i; } }

Named Returns:

// More efficient bytecode function calc(uint256 x) pure returns (uint256 result) { result = x * 2; }

Bitshifting:

// Cheaper: 3 gas x << 1 // x * 2 x >> 2 // x / 4

// Expensive: 5 gas x * 2 x / 4

Short-Circuit Booleans:

Place likely-to-fail conditions first in && Place likely-to-succeed conditions first in || Medium: Assembly (Use Carefully)

Efficient Checks:

// Check address(0) with assembly assembly { if iszero(caller()) { revert(0, 0) } }

// Even/odd check x & 1 // instead of x % 2

Memory Reuse:

Reuse scratch space (0x00-0x40) for small operations Avoid memory expansion in loops Avoid: Dangerous Techniques

These are unsafe for production:

Making all functions payable Ignoring send() return values Using gasleft() for branching Manipulating block.number in tests Outdated Patterns

These no longer apply in modern Solidity:

"external is cheaper than public" - No longer true "!= 0 is cheaper than > 0" - Changed around 0.8.12 References

Full documentation with code examples:

references/solidity-gas-guidelines.md - Complete guide references/rules/ - Individual patterns by category

To look up specific patterns:

grep -l "storage" references/rules/ grep -l "assembly" references/rules/ grep -l "struct" references/rules/

Rule Categories in references/rules/ storage- - Storage optimization patterns deploy- - Deployment gas savings calldata- - Calldata optimization design- - Design pattern choices crosscall- - Cross-contract call optimization compiler- - Compiler optimization patterns assembly-* - Low-level assembly tricks Key Principles Always Benchmark - Compiler behavior varies by context and version Balance Readability - Not all optimizations are worth code complexity Test Both Approaches - Counterintuitive optimizations sometimes increase costs Consider --via-ir - Modern compiler option may obsolete some tricks Use Alternative Libraries - Solmate/Solady often beat OpenZeppelin on gas

返回排行榜