算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
blockchain-patterns【设计与创意】Use this skill when asked about blockchain design patterns, token standards, upgradeable contracts, oracle patterns, layer 2 scaling patterns, cross-chain communication patterns, and common blockchain architecture patterns. Covers ERC standards (20, 721, 1155, 4626, 4337), proxy patterns (UUPS, transparent, beacon), bridge patterns, state channel pat…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Catalog and guide the selection of blockchain design patterns covering token standards, contract upgradeability, scaling solutions, cross-chain communication, and protocol architecture. This skill enforces standardized pattern selection with documented trade-offs and security implications.
"blockchain pattern", "token standard", "ERC-20", "ERC-721", "ERC-1155", "ERC-4626", "ERC-4337", "ERC-2612", "ERC-3525", "ERC-3643", "ERC-4907", "ERC-5192", "permit", "upgradeable contract", "proxy pattern", "UUPS", "oracle pattern", "bridge pattern", "layer 2", "state channel", "sidechain", "MEV", "cross-chain", "blockchain design pattern", "smart contract pattern", "vault pattern", "yield-bearing vault", "semi-fungible", "soulbound", "rollup", "validium", "optimistic rollup", "zk-rollup", "IBC", "LayerZero", "light client", "AMM", "constant product", "lending pool", "compound fork", "aave fork", "flash loan", "governance token", "veToken", "vote escrow", "factory pattern", "minimal proxy", "EIP-1167", "EIP-1967", "EIP-1822", "EIP-2535", "diamond pattern", "multi-facet", "federated sidechain", "ZK-bridge", "optimistic bridge", "PBS", "MEV-Boost", "ePBS", "ERC-5218", "NFT rental", "soulbound token", "account abstraction", "ERC-6551", "TBA", "token bound account", "ERC-6909"
Pattern recommendation with:
4000 tokens
| Feature | UUPS | Transparent | Beacon | Diamond (EIP-2535) |
|---|---|---|---|---|
| Upgrade function | Implementation | Proxy | Beacon | Diamond owner |
| Gas cost per call | Low (1 SLOAD) | Medium (2 SLOAD) | Low (1 SLOAD + beacon read) | Low (1 SLOAD + facet map) |
| Deployment cost | Low (no admin) | High (admin storage) | Medium (beacon deploy) | High (facet setup) |
| Multiple implementations | No (1:1) | No (1:1) | Yes (1:N) | Yes (N:M facets) |
| Storage collision risk | Low | Low (admin at high slot) | Low | Low (diamond storage) |
| Max implementations | 1 | 1 | Unlimited | Unlimited (48 facets) |
| Recommended | Default choice | Legacy projects | Many instances (ERC-1167 clones) | Large, modular protocols |
Decide: Token Standard
├── Fungible token?
│ ├── Standard → ERC-20 + ERC-2612 (permit)
│ ├── Yield-bearing vault → ERC-4626 (share-based accounting)
│ ├── Minimal gas (no permit) → ERC-20 (Solady)
│ └── Semi-fungible → ERC-3525 (financial NFTs: invoices, bonds)
├── Non-fungible token?
│ ├── Standard → ERC-721
│ ├── Rental support → ERC-4907 (adds user/expires roles)
│ ├── Soulbound → ERC-5192 (non-transferrable)
│ ├── Token-bound account → ERC-6551 (NFT owns assets)
│ └── Fractionalized → ERC-20 wrapper (fractionalize floor prices)
├── Multi-token contract?
│ ├── Single contract → ERC-1155 (minimal deployment cost)
│ ├── Tiered access → ERC-1155 with role mapping
│ └── Dynamic supply → ERC-1155 with mint/burn hooks
└── Account abstraction?
├── Smart wallet → ERC-4337 (EntryPoint + account contract)
└── Session keys → ERC-4337 with ephemeral key module
Decide: Scaling Pattern
├── Need general smart contracts?
│ ├── YES → Rollup (Optimistic or ZK)
│ │ ├── EVM-equivalent needed?
│ │ │ ├── YES → Optimism OP Stack / Arbitrum Nitro
│ │ │ └── YES + fast finality → Scroll / Linea (ZK-EVM)
│ │ └── EVM-compatible acceptable?
│ │ └── ZKSync Era / StarkNet
│ └── NO → Check use case
│ ├── Payments only → Lightning Network / State channels
│ ├── Gaming / NFT → Validium (Immutable X)
│ └── Custom chain → App-chain (RollOps, Polygon CDK)
├── Need cross-chain interaction?
│ ├── Canonical bridge (single L1↔L2)
│ ├── IBC (multiple chains, trustless)
│ │ └── Both chains must be IBC-enabled
│ ├── External verifier (LayerZero, Wormhole)
│ │ └── Any chain pair, trust in verifier set
│ └── ZK-bridge (trustless, unilateral)
│ └── Any pair, proving cost is barrier
└── Need decentralized oracle?
├── Pull model (Chainlink): Request → Aggregation → Response
└── Push model (Pyth, Chronicle): Publisher → On-chain → Consumer
Decide: AMM Model
├── General trading (correlated assets)?
│ ├── Constant Product (x*y=k) → Uniswap v2
│ │ ├── Pros: Simple, proven, universal
│ │ ├── Cons: High slippage on large trades
│ │ └── Use: Correlated + uncorrelated pairs
│ ├── Concentrated Liquidity → Uniswap v3
│ │ ├── Pros: 4000x capital efficiency
│ │ ├── Cons: LP complexity, IL management
│ │ └── Use: Professional LPs, stable pairs
│ └── Stable Swap → Curve
│ ├── Pros: Minimal slippage for stablecoins
│ └── Cons: Only works for near-identical assets
├── Need dynamic fees?
│ ├── Maverick: Directional LP (concentrated + dynamic)
│ └── Trader Joe v2: Bin-step LP (narrow bins per fee tier)
└── Need volatility-based pools?
└── Gyroscope: Multi-dimensional invariant
Decide: Bridge Architecture
├── Same chain family (EVM↔EVM)?
│ ├── Trustless → Canonical bridge (L1↔L2)
│ │ ├── Messages: ~30 min finality
│ │ ├── Security: Inherits L1 security
│ │ └── Cost: L1 gas for validity proof
│ └── Fast → External validator (LayerZero, Axelar)
│ ├── Messages: ~1 minute
│ ├── Security: Trust in DVN/verifier set
│ └── Cost: Oracle + relayer fees
├── Heterogeneous chains (EVM↔Cosmos)?
│ ├── IBC (if Cosmos-enabled)
│ └── ZK-bridge (any pair, trustless)
└── Maximum security?
├── ZK light client bridge (trustless, unilateral)
└── Optimistic bridge (fraud proof window)
updatedAt is within acceptable window.supportsInterface break composability with other contracts.selfdestruct, the proxy loses all funds. Never use selfdestruct in upgradeable contracts.initialize function instead of constructor (callable once)block.timestamp and block.number guards against MEV timing manipulation| Standard | Category | Key Feature |
|---|---|---|
| ERC-2612 | Fungible | Gasless approve via off-chain signature (permit) |
| ERC-4626 | Vault | Standardized yield-bearing share accounting |
| ERC-3525 | Semi-fungible | Financial NFTs with slot/value model |
| ERC-3643 | Security | Permissioned transfer, compliance wrapper |
| ERC-4907 | NFT | Rental roles (user + expires) |
| ERC-5192 | NFT | Soulbound (non-transferrable) |
| ERC-5218 | NFT | NFT rental with temporal ownership |
| ERC-6551 | NFT | Token-bound account (NFT = smart wallet) |
| ERC-6909 | Multi-token | Minimal ERC-1155 alternative (gas optimized) |
| ERC-1155 | Multi-token | Single contract for infinite token types |
| ERC-4337 | Account abstraction | Smart wallet via EntryPoint |
| ERC-6900 | Account abstraction | Modular smart accounts |
| Aspect | Rollup | State Channel | Plasma | Validium |
|---|---|---|---|---|
| Throughput | 2,000-100,000 TPS | Unlimited (off-chain) | 10,000+ TPS | 10,000+ TPS |
| Finality | Minutes (ZK) / 7d (Optimistic) | Instant | Hours | Minutes |
| Data availability | On-chain | Off-chain | On-chain (compressed) | Off-chain (DAC) |
| General computation | Yes (EVM or ZK-EVM) | No (payment/state) | Limited (predicates) | Yes (EVM) |
| Capital efficiency | High | Medium | Low | High |
| User experience | Good (like L1) | Excellent (instant) | Poor (challenge period) | Good |
| Feature | Pool-based (Aave/Compound) | Peer-to-peer (Morpho) | Isolated (Euler) |
|---|---|---|---|
| Capital efficiency | High (aggregated) | Medium (order book) | Medium (per-pair) |
| Liquidation | Soft (health factor) | Hard (position level) | Soft + IRM-based |
| Risk isolation | No (pool-wide risk) | Partial (per pair) | Yes (per market) |
| Oracle dependency | Single oracle | Single oracle | Per-market oracle |
| Upgradeability | Proxy-based | Proxy-based | Diamond (EIP-2535) |
StorageSlot library to prevent storage collision across upgrades__gap arrays for future storageselfdestruct in upgradeable contracts (renders proxy unusable)updatedAt within [block.timestamp - threshold])delegatecall-compatible storage layoutsecrecover address matches owner exactly (not just non-zero)_beforeTokenTransfer hooks for composability// UUPS upgradeable proxy — OpenZeppelin style
contract UUPSProxy is ERC1967Proxy {
constructor(address _logic, bytes memory _data) ERC1967Proxy(_logic, _data) {}
}
abstract contract UUPSUpgradeable is Initializable, UUPSUpgradeable {
function _authorizeUpgrade(address newImplementation) internal virtual;
function upgradeTo(address newImplementation) external virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, new bytes(0));
}
// Storage gap for future variables
uint256[50] private __gap;
}
// Example usage
contract MyContractV1 is UUPSUpgradeable {
uint256 public value;
function initialize(uint256 _value) public initializer {
__UUPSUpgradeable_init();
value = _value;
}
function setValue(uint256 _value) external {
value = _value;
}
}
contract MyContractV2 is MyContractV1 {
function setValue(uint256 _value) external override {
require(_value > 0, "Zero not allowed");
value = _value;
}
}
contract YieldVault is ERC4626, ERC20Permit {
using SafeERC20 for IERC20;
constructor(
IERC20 _asset,
string memory _name,
string memory _symbol
) ERC4626(_asset) ERC20(_name, _symbol) ERC20Permit(_name) {
// Virtual shares defense against inflation attack
_mint(address(this), 10**6); // 1M virtual shares
_asset.safeTransferFrom(msg.sender, address(this), 10**6); // 1M virtual assets
}
// Override to add fees
function _afterDeposit(uint256 assets, uint256 shares) internal override {
// Fee: 0.1% deposit fee
uint256 fee = assets / 1000;
_asset.safeTransfer(treasury, fee);
}
// Override to add performance fee on withdraw
function _beforeWithdraw(uint256 assets, uint256 shares) internal override {
uint256 totalAssets = totalAssets();
uint256 totalSupply = totalSupply() - 10**6; // Exclude virtual shares
uint256 navPerShare = totalAssets / totalSupply;
// Performance fee: 10% of yield above NAV
if (navPerShare > highWaterMark) {
uint256 yield = (navPerShare - highWaterMark) * shares;
uint256 perfFee = yield / 10;
_asset.safeTransfer(treasury, perfFee);
highWaterMark = navPerShare;
}
}
uint256 public highWaterMark;
address public treasury;
}
contract MyOFT is OFT {
// LayerZero OFT — send tokens cross-chain
function sendCrossChain(
uint16 _dstChainId,
address _to,
uint256 _amount,
address payable _refundAddress,
bytes memory _adapterParams
) external payable {
_send(_msgSender(), _dstChainId, _to, _amount, msg.value, _adapterParams);
}
// Override to enforce rate limiting
function _debitFrom(
address _from,
uint16 _dstChainId,
bytes memory _toAddress,
uint256 _amount
) internal override returns (uint256) {
uint256 sentToday = dailyVolume[_dstChainId][block.timestamp / 86400];
require(sentToday + _amount <= dailyLimit, "Rate limit exceeded");
dailyVolume[_dstChainId][block.timestamp / 86400] = sentToday + _amount;
return super._debitFrom(_from, _dstChainId, _toAddress, _amount);
}
mapping(uint16 => mapping(uint256 => uint256)) public dailyVolume;
uint256 public dailyLimit = 100_000 * 10**18; // 100k tokens/day
}
contract ConstantProductPool {
IERC20 public token0;
IERC20 public token1;
uint256 public reserve0;
uint256 public reserve1;
function swap(uint256 amount0Out, uint256 amount1Out, address to) external {
require(amount0Out > 0 || amount1Out > 0, "No output");
require(amount0Out < reserve0 && amount1Out < reserve1, "Insufficient liquidity");
uint256 balance0Before = token0.balanceOf(address(this));
uint256 balance1Before = token1.balanceOf(address(this));
// Transfer output tokens
if (amount0Out > 0) token0.safeTransfer(to, amount0Out);
if (amount1Out > 0) token1.safeTransfer(to, amount1Out);
// Verify invariant: (r0 - a0) * (r1 - a1) >= r0 * r1
uint256 balance0After = token0.balanceOf(address(this));
uint256 balance1After = token1.balanceOf(address(this));
uint256 amount0In = balance0After - (reserve0 - amount0Out);
uint256 amount1In = balance1After - (reserve1 - amount1Out);
require(amount0In > 0 || amount1In > 0, "Insufficient input");
uint256 balance0Adjusted = balance0After * 1000 - amount0In * 3; // 0.3% fee
uint256 balance1Adjusted = balance1After * 1000 - amount1In * 3;
require(
balance0Adjusted * balance1Adjusted >= reserve0 * reserve1 * 1_000_000,
"Invariant failed"
);
(reserve0, reserve1) = (balance0After, balance1After);
emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to);
}
event Swap(address indexed sender, uint256 amount0In, uint256 amount1In,
uint256 amount0Out, uint256 amount1Out, address indexed to);
}
contract FlashLoanProvider {
IERC20 public token;
uint256 public protocolFee = 9; // 0.09% fee
function flashLoan(uint256 amount, address receiver, bytes calldata data) external {
uint256 balanceBefore = token.balanceOf(address(this));
require(balanceBefore >= amount, "Insufficient liquidity");
token.safeTransfer(receiver, amount);
// Callback to borrower
IFlashLoanReceiver(receiver).executeOperation(amount, protocolFee, data);
// Verify repayment + fee
uint256 balanceAfter = token.balanceOf(address(this));
require(balanceAfter >= balanceBefore + amount * protocolFee / 10000, "Repayment failed");
emit FlashLoan(receiver, amount, protocolFee);
}
event FlashLoan(address indexed receiver, uint256 amount, uint256 fee);
}
interface IFlashLoanReceiver {
function executeOperation(uint256 amount, uint256 fee, bytes calldata data) external;
}
contract WalletFactory {
address public immutable implementation;
event WalletCreated(address indexed wallet, address indexed owner);
constructor(address _implementation) {
implementation = _implementation;
}
function createWallet(address owner, bytes32 salt) external returns (address) {
bytes memory initData = abi.encodeWithSelector(Wallet.initialize.selector, owner);
address wallet = Clones.cloneDeterministic(implementation, salt);
// Deploy cost: ~200 gas (ERC-1167 minimal proxy)
// vs ~500k gas for full contract deployment
IProxy(wallet).initialize(initData);
emit WalletCreated(wallet, owner);
return wallet;
}
}
// ERC-1167 minimal proxy bytecode:
// 0x363d3d373d3d3d363d73{b_20 bytes address}5af43d82803e903d91602b57fd5bf3
| Pattern | Primary Attack Vector | Mitigation |
|---|---|---|
| UUPS Proxy | Initialization frontrunning | Constructor _disableInitializers() |
| Transparent Proxy | Function selector collision | Admin storage at 0xb53127684a... (EIP-1967) |
| Beacon Proxy | Beacon implementation change mid-transaction | Atomic updates with reentrancy guard |
| Diamond (EIP-2535) | Storage collision across facets | Diamond storage with unique namespace |
| ERC-4626 Vault | Inflation attack | Virtual shares + assets (OpenZeppelin fix) |
| AMM Constant Product | Sandwich attack | Slippage tolerance + TWAP oracle |
| AMM Concentrated Liquidity | Range manipulation | Tick-based pricing, immutable tick boundaries |
| Bridge (Canonical) | Reorg finality gap | Challenge window (7d Optimistic / 30min ZK) |
| Bridge (External Verifier) | Verifier collusion | Threshold signing + economic bonding |
| LayerZero | DVN compromise | Multiple DVN paths + security stack |
| State Channel | Watchtower offline | Watchtower service, challenge period |
| Flash Loan | Oracle manipulation | TWAP oracle, min-max bounds checks |
| ERC-20 Permit | Signature replay (cross-chain) | Include chain ID in domain separator |
| ERC-4337 AA | EntryPoint DoS | Per-account staking + gas limits |
blockchain-patterns → blockchain-application (for pattern implementation in code) blockchain-patterns → blockchain-security (for pattern-specific security analysis) blockchain-patterns → blockchain-core (for scaling protocol integration)