Blockchain Patterns
Purpose
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.
Agent Protocol
Trigger
"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"
Input Context
- Requirement type (token/upgrade/oracle/bridge/scaling)
- Target platform (EVM/Solana/Cosmos)
- Security requirements (trust assumptions, upgradeability need)
- Performance requirements (throughput, latency, cost budget)
- Existing infrastructure (current contracts, bridges, oracles in use)
Output Artifact
Pattern recommendation with:
- Selected pattern with justification against alternatives
- Architecture diagram showing component interactions
- Implementation approach with key contract/system interfaces
- Security analysis with known attacks and mitigations
- Integration guide for existing systems
Response Format
- Pattern category (token/upgrade/oracle/bridge/scaling)
- Problem statement + when to use
- Implementation approach with trade-offs
- Security considerations and known pitfalls
- Code example or reference to canonical implementation
Completion Criteria
- Pattern selection is justified against at least 2 alternatives with comparison table
- Implementation approach covers storage layout for upgradeable patterns, trust assumptions for bridge patterns
- Security analysis identifies 3+ attack vectors with mitigations
- Integration guide covers dependencies, initialization order, and compatibility considerations
- Code example follows established conventions (OpenZeppelin, Solady for EVM)
Max Response Length
4000 tokens
Workflow
Phase 1: Pattern Identification
- Identify the architectural problem category (tokenization, upgradeability, scaling, cross-chain, oracle integration)
- Gather requirements: security level, upgrade frequency, throughput needs, cost constraints
- Survey available patterns with similar use cases in production
- Select primary pattern and fallback alternatives
Phase 2: Architecture Design
- Design component architecture: which contracts/modules implement which concerns
- Define storage layout with upgradeability considerations (unstructured storage for proxies)
- Specify interfaces following established standards (ERC, IBC, ULN)
- Design initialization sequence with proper access controls
Phase 3: Implementation Strategy
- Select reference implementation (OpenZeppelin, Solady, or protocol-specific)
- Implement core pattern with standardized interfaces
- Add security controls: pause mechanism, rate limits, access control
- Implement extension interfaces for future compatibility
Phase 4: Integration and Testing
- Test pattern with all standard interfaces (ERC-165 support)
- Fork-test against mainnet state (simulate real-world interactions)
- Audit pattern interactions (composability risks, circular dependencies)
- Deploy with proper initialization and ownership transfer
Architecture / Decision Trees
Proxy Pattern Comparison
| 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 |
Token Standard Selection Decision Tree
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
Scaling Pattern Decision Tree
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
AMM Pattern Selection
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
Cross-Chain Bridge Architecture
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)
Common Pitfalls
- Storage collision in proxy upgrades: Adding new variables before existing ones shifts storage slots. Use unstructured storage (EIP-1967) and never change variable order.
- Initialization frontrunning: Uninitialized proxy implementations can be frontrun. Use constructor + disableInitializers() pattern.
- Bridge trust mirroring: Using the same signers for bridge and protocol governance creates a single point of compromise.
- Insufficient oracle staleness: Not checking oracle timestamp allows stale price consumption. Always verify
updatedAt is within acceptable window.
- Calldata not compressed for L2: Posting uncompressed transaction data to L1 increases rollup costs 10x+. Implement state diff compression.
- Missing ERC-165 interface support: Contracts that don't implement
supportsInterface break composability with other contracts.
- Reentrancy in cross-chain callbacks: Cross-chain message execution reenters the calling contract. Use reentrancy guards on all message handlers.
- Beacon pattern update delay: Beacon proxy updates affect ALL implementation contracts atomically—coordinate upgrades carefully.
- EIP-1967 storage slot collision: Using wrong storage slot for proxy admin or implementation UUID breaks proxy detection tools.
- MEV extraction in AMM patterns: Unprotected AMM functions enable sandwich attacks. Implement slippage protection and commit-reveal.
- ERC-4626 inflation attack: Early depositors can manipulate share price, stealing from later depositors. Use virtual shares + assets as defense.
- ERC-2612 permit replay: Without nonce or deadline checking, valid permits can be replayed. Always include nonce and validate deadline.
- Cross-chain message timeout: Messages stuck in bridge without timeout handling lock user funds forever. Implement cancelation with timeout.
- Selfdestruct in proxy implementation: If the implementation has
selfdestruct, the proxy loses all funds. Never use selfdestruct in upgradeable contracts.
- Diamond storage collision: Multiple facets using the same storage namespace cause data corruption. Use diamond storage pattern with unique namespace.
Best Practices
Token Contract Patterns
- Use ERC-20 for fungible tokens with ERC-2612 (permit) for gasless approvals
- Use ERC-721 for NFTs with ERC-4907 (rental) for lending market compatibility
- Use ERC-1155 for multi-token contracts (games, metaverse)
- Use ERC-4626 for yield-bearing vaults (standardized share accounting)
- Use ERC-4337 for account abstraction (wallet contract + EntryPoint)
- Use ERC-6551 for token-bound accounts (NFT owns other tokens)
- Use ERC-6909 for minimal multi-token (gas-optimized multi-token)
Upgradeable Contract Patterns
- Default to UUPS proxy pattern for new projects
- Use transparent proxy only for contracts with many upgrade functions
- Use beacon pattern for ERC-1167 minimal proxy families
- Use diamond (EIP-2535) for large, modular protocols with many functions
- Always use
initialize function instead of constructor (callable once)
- Store implementation address in EIP-1967 storage slot for compatibility
Bridge Patterns
- Use canonical bridge for simple L1↔L2 asset transfer
- Use IBC for multi-chain trustless message passing (Cosmos ecosystem)
- Use LayerZero for flexible cross-chain messaging with configurable security
- Implement rate limiting and tiered withdrawal for high-value bridges
- Use ZK-bridge for maximum trust minimization at higher cost
- Always include timeout + cancelation for pending cross-chain messages
DeFi Protocol Patterns
- AMM: Constant product (Uniswap v2) for simplicity, concentrated liquidity (v3) for efficiency
- Lending: Pool-based (Aave/Compound) for capital efficiency, peer-to-peer for niche assets
- Governance: Token-weighted for simplicity, quadratic for fairness, veToken for alignment
- Oracle: Push (Pyth, Chronicle) for high-frequency, Chainlink pull for general purpose
MEV-Aware Design
- Include slippage tolerance in all AMM interactions
- Use commit-reveal schemes for order submission
- Implement private mempool integration (Flashbots Protect)
- Batch auctions for large trades (CowSwap model)
- Oracle extraction protection: use TWAP not spot price for liquidations
- Use
block.timestamp and block.number guards against MEV timing manipulation
Advanced Token Standards Reference
| 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 |
Compared With
| 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 |
DeFi Lending Pool Pattern Comparison
| 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) |
Operations & Maintenance
Upgrade Management
- Multi-sig + timelock governance for all upgradeable contract admin keys
- Test upgrades on testnet with exact bytecode before mainnet
- Maintain implementation contract verified on block explorer
- Document storage layout changes in each upgrade
- Use
StorageSlot library to prevent storage collision across upgrades
- Maintain upgrade history with
__gap arrays for future storage
Bridge Operations
- Monitor relayer uptime and gas economics
- Track pending cross-chain messages for timeout expiry
- Maintain emergency pause capabilities for bridge contracts
- Regular security reviews of verifier set composition
- Track total value secured (TVS) per bridge route
- Monitor for anomalous message patterns (potential bridge attacks)
DeFi Protocol Operations
- Monitor oracle price deviation and staleness daily
- Track liquidity depth changes across all AMM pools
- Verify liquidation health factors are in expected ranges
- Run daily invariant checks (supply = borrow + reserves)
- Gas optimization review every quarter (reduce costs for users)
MEV Monitoring
- Detect sandwich attacks on AMM pools (frontrun + backrun same tx)
- Track validator proposer boost usage for block reorgs
- Monitor private mempool (Flashbots) usage and censored transactions
- Report MEV extracted per block from the protocol
- Implement MEV tax or redistribution when applicable
Rules
- Default to UUPS proxy for upgradeable contracts—transparent only for upgrade-function-heavy contracts
- Always use EIP-1967 storage slots for proxy implementation and admin addresses
- Never use
selfdestruct in upgradeable contracts (renders proxy unusable)
- Always check oracle staleness (
updatedAt within [block.timestamp - threshold])
- Implement pull-over-push for all payment distribution patterns
- Use checks-effects-interactions in ALL contract functions, not just token transfers
- Cross-chain bridge contracts must have emergency pause and rate limiting
- Beacon proxy implementations must use
delegatecall-compatible storage layouts
- ERC-165 interface detection is mandatory for all composable contracts
- Reentrancy guards on all message execution handlers in cross-chain contracts
- EIP-2612 permit must check
ecrecover address matches owner exactly (not just non-zero)
- Rollup batch submissions must include data availability commitment for state reconstruction
- Optimistic bridges require minimum 30-minute challenge window for standard, 7 days for high-value
- All oracle price feeds must be redundant (minimum 3 independent sources)
- State channel designs must include watchtower service for offline user protection
- Proposer-builder separation (PBS) patterns require MEV-Boost or ePBS integration
- ERC-4626 vaults must implement virtual shares to prevent inflation attacks
- Cross-chain message timeout must be at least 2x the optimistic finality window
- AMM pools must have minimum liquidity threshold to prevent manipulation
- Lending pool oracles must use TWAP (not spot) for liquidation triggers
- Diamond facets must use unique namespace for each storage layout
- Beacon upgrades must be coordinated across all active proxies atomically
- NFT market contracts must implement EIP-2981 (royalty standard) for creator fees
- Off-chain oracles must not be the sole price source for liquidation-level decisions
- Token contracts must implement
_beforeTokenTransfer hooks for composability
Implementation Examples
UUPS Proxy Pattern (Solidity)
// 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;
}
}
ERC-4626 Yield-Bearing Vault (Solidity)
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;
}
Cross-Chain Message Pattern (LayerZero OFT)
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
}
AMM Constant Product Pool (Minimal)
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);
}
Flash Loan Pattern (Minimal)
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;
}
Factory + Minimal Proxy Pattern (ERC-1167)
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
Security Analysis Per Pattern
| 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 |
Performance Considerations
- UUPS vs. Beacon: UUPS costs ~200 gas more per call than beacon, but avoids an external read
- ERC-1155 batch transfers: 80% cheaper than individual ERC-721 transfers for 5+ items
- Calldata vs. blob cost: EIP-4844 blobs reduce L2 data availability cost from ~16 gas/byte to ~1-2 gas/byte
- Merkle proof verification: O(log n) gas for inclusion proof; optimize with sorted merkle trees
- Oracle update frequency: Push-based oracles (Pyth) update every ~400ms vs pull-based (Chainlink) ~20 min
- Concentrated liquidity: 2000x capital efficiency vs constant product at 1% fee tier
- ERC-1167 minimal proxy: ~200 gas to deploy vs ~500,000 for full contract
- Beacon proxy: ~100 gas overhead per call vs ~200 for transparent proxy
- Diamond proxy: ~250 gas overhead per call (facet map lookup + delegatecall)
- EIP-2535 diamond storage: No collision risk, but ~5000 gas per namespace registration
References
- references/advanced-token-standards.md — Advanced Token Standards
- references/blockchain-patterns-advanced.md — Blockchain Patterns Advanced Topics
- references/blockchain-patterns-fundamentals.md — Blockchain Patterns Fundamentals
- references/cross-chain-communication-patterns.md — Cross-Chain Communication Patterns
- references/erc-4626-vault.md — ERC-4626 Yield-Bearing Vault Standard
- references/layer2-scaling-patterns.md — Layer-2 Scaling Patterns
- references/mev-and-order-flow.md — MEV & Order Flow Patterns
- references/oracle-and-bridge-patterns.md — Oracle & Bridge Patterns
- references/token-standards.md — Token Standards & Contracts
- references/upgradeable-contracts.md — Upgradeable Contract Patterns
Handoff
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)
1---2name: blockchain-patterns3description: 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 patterns, sidechain patterns, and MEV-aware design. Do NOT use for: specific language implementation (use blockchain-application), core protocol design (use blockchain-core), or web3 integration (use blockchain-web3).4license: MIT5---67# Blockchain Patterns89## Purpose10Catalog 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.1112## Agent Protocol1314### Trigger15"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"1617### Input Context18- Requirement type (token/upgrade/oracle/bridge/scaling)19- Target platform (EVM/Solana/Cosmos)20- Security requirements (trust assumptions, upgradeability need)21- Performance requirements (throughput, latency, cost budget)22- Existing infrastructure (current contracts, bridges, oracles in use)2324### Output Artifact25Pattern recommendation with:26- Selected pattern with justification against alternatives27- Architecture diagram showing component interactions28- Implementation approach with key contract/system interfaces29- Security analysis with known attacks and mitigations30- Integration guide for existing systems3132### Response Format331. Pattern category (token/upgrade/oracle/bridge/scaling)342. Problem statement + when to use353. Implementation approach with trade-offs364. Security considerations and known pitfalls375. Code example or reference to canonical implementation3839### Completion Criteria40- Pattern selection is justified against at least 2 alternatives with comparison table41- Implementation approach covers storage layout for upgradeable patterns, trust assumptions for bridge patterns42- Security analysis identifies 3+ attack vectors with mitigations43- Integration guide covers dependencies, initialization order, and compatibility considerations44- Code example follows established conventions (OpenZeppelin, Solady for EVM)4546### Max Response Length474000 tokens4849## Workflow5051### Phase 1: Pattern Identification521. Identify the architectural problem category (tokenization, upgradeability, scaling, cross-chain, oracle integration)532. Gather requirements: security level, upgrade frequency, throughput needs, cost constraints543. Survey available patterns with similar use cases in production554. Select primary pattern and fallback alternatives5657### Phase 2: Architecture Design585. Design component architecture: which contracts/modules implement which concerns596. Define storage layout with upgradeability considerations (unstructured storage for proxies)607. Specify interfaces following established standards (ERC, IBC, ULN)618. Design initialization sequence with proper access controls6263### Phase 3: Implementation Strategy649. Select reference implementation (OpenZeppelin, Solady, or protocol-specific)6510. Implement core pattern with standardized interfaces6611. Add security controls: pause mechanism, rate limits, access control6712. Implement extension interfaces for future compatibility6869### Phase 4: Integration and Testing7013. Test pattern with all standard interfaces (ERC-165 support)7114. Fork-test against mainnet state (simulate real-world interactions)7215. Audit pattern interactions (composability risks, circular dependencies)7316. Deploy with proper initialization and ownership transfer7475## Architecture / Decision Trees7677### Proxy Pattern Comparison7879| Feature | UUPS | Transparent | Beacon | Diamond (EIP-2535) |80|---|---|---|---|---|81| Upgrade function | Implementation | Proxy | Beacon | Diamond owner |82| Gas cost per call | Low (1 SLOAD) | Medium (2 SLOAD) | Low (1 SLOAD + beacon read) | Low (1 SLOAD + facet map) |83| Deployment cost | Low (no admin) | High (admin storage) | Medium (beacon deploy) | High (facet setup) |84| Multiple implementations | No (1:1) | No (1:1) | Yes (1:N) | Yes (N:M facets) |85| Storage collision risk | Low | Low (admin at high slot) | Low | Low (diamond storage) |86| Max implementations | 1 | 1 | Unlimited | Unlimited (48 facets) |87| Recommended | Default choice | Legacy projects | Many instances (ERC-1167 clones) | Large, modular protocols |8889### Token Standard Selection Decision Tree9091```92Decide: Token Standard93├── Fungible token?94│ ├── Standard → ERC-20 + ERC-2612 (permit)95│ ├── Yield-bearing vault → ERC-4626 (share-based accounting)96│ ├── Minimal gas (no permit) → ERC-20 (Solady)97│ └── Semi-fungible → ERC-3525 (financial NFTs: invoices, bonds)98├── Non-fungible token?99│ ├── Standard → ERC-721100│ ├── Rental support → ERC-4907 (adds user/expires roles)101│ ├── Soulbound → ERC-5192 (non-transferrable)102│ ├── Token-bound account → ERC-6551 (NFT owns assets)103│ └── Fractionalized → ERC-20 wrapper (fractionalize floor prices)104├── Multi-token contract?105│ ├── Single contract → ERC-1155 (minimal deployment cost)106│ ├── Tiered access → ERC-1155 with role mapping107│ └── Dynamic supply → ERC-1155 with mint/burn hooks108└── Account abstraction?109 ├── Smart wallet → ERC-4337 (EntryPoint + account contract)110 └── Session keys → ERC-4337 with ephemeral key module111```112113### Scaling Pattern Decision Tree114115```116Decide: Scaling Pattern117├── Need general smart contracts?118│ ├── YES → Rollup (Optimistic or ZK)119│ │ ├── EVM-equivalent needed?120│ │ │ ├── YES → Optimism OP Stack / Arbitrum Nitro121│ │ │ └── YES + fast finality → Scroll / Linea (ZK-EVM)122│ │ └── EVM-compatible acceptable?123│ │ └── ZKSync Era / StarkNet124│ └── NO → Check use case125│ ├── Payments only → Lightning Network / State channels126│ ├── Gaming / NFT → Validium (Immutable X)127│ └── Custom chain → App-chain (RollOps, Polygon CDK)128├── Need cross-chain interaction?129│ ├── Canonical bridge (single L1↔L2)130│ ├── IBC (multiple chains, trustless)131│ │ └── Both chains must be IBC-enabled132│ ├── External verifier (LayerZero, Wormhole)133│ │ └── Any chain pair, trust in verifier set134│ └── ZK-bridge (trustless, unilateral)135│ └── Any pair, proving cost is barrier136└── Need decentralized oracle?137 ├── Pull model (Chainlink): Request → Aggregation → Response138 └── Push model (Pyth, Chronicle): Publisher → On-chain → Consumer139```140141### AMM Pattern Selection142143```144Decide: AMM Model145├── General trading (correlated assets)?146│ ├── Constant Product (x*y=k) → Uniswap v2147│ │ ├── Pros: Simple, proven, universal148│ │ ├── Cons: High slippage on large trades149│ │ └── Use: Correlated + uncorrelated pairs150│ ├── Concentrated Liquidity → Uniswap v3151│ │ ├── Pros: 4000x capital efficiency152│ │ ├── Cons: LP complexity, IL management153│ │ └── Use: Professional LPs, stable pairs154│ └── Stable Swap → Curve155│ ├── Pros: Minimal slippage for stablecoins156│ └── Cons: Only works for near-identical assets157├── Need dynamic fees?158│ ├── Maverick: Directional LP (concentrated + dynamic)159│ └── Trader Joe v2: Bin-step LP (narrow bins per fee tier)160└── Need volatility-based pools?161 └── Gyroscope: Multi-dimensional invariant162```163164### Cross-Chain Bridge Architecture165166```167Decide: Bridge Architecture168├── Same chain family (EVM↔EVM)?169│ ├── Trustless → Canonical bridge (L1↔L2)170│ │ ├── Messages: ~30 min finality171│ │ ├── Security: Inherits L1 security172│ │ └── Cost: L1 gas for validity proof173│ └── Fast → External validator (LayerZero, Axelar)174│ ├── Messages: ~1 minute175│ ├── Security: Trust in DVN/verifier set176│ └── Cost: Oracle + relayer fees177├── Heterogeneous chains (EVM↔Cosmos)?178│ ├── IBC (if Cosmos-enabled)179│ └── ZK-bridge (any pair, trustless)180└── Maximum security?181 ├── ZK light client bridge (trustless, unilateral)182 └── Optimistic bridge (fraud proof window)183```184185## Common Pitfalls1861871. **Storage collision in proxy upgrades**: Adding new variables before existing ones shifts storage slots. Use unstructured storage (EIP-1967) and never change variable order.1882. **Initialization frontrunning**: Uninitialized proxy implementations can be frontrun. Use constructor + disableInitializers() pattern.1893. **Bridge trust mirroring**: Using the same signers for bridge and protocol governance creates a single point of compromise.1904. **Insufficient oracle staleness**: Not checking oracle timestamp allows stale price consumption. Always verify `updatedAt` is within acceptable window.1915. **Calldata not compressed for L2**: Posting uncompressed transaction data to L1 increases rollup costs 10x+. Implement state diff compression.1926. **Missing ERC-165 interface support**: Contracts that don't implement `supportsInterface` break composability with other contracts.1937. **Reentrancy in cross-chain callbacks**: Cross-chain message execution reenters the calling contract. Use reentrancy guards on all message handlers.1948. **Beacon pattern update delay**: Beacon proxy updates affect ALL implementation contracts atomically—coordinate upgrades carefully.1959. **EIP-1967 storage slot collision**: Using wrong storage slot for proxy admin or implementation UUID breaks proxy detection tools.19610. **MEV extraction in AMM patterns**: Unprotected AMM functions enable sandwich attacks. Implement slippage protection and commit-reveal.19711. **ERC-4626 inflation attack**: Early depositors can manipulate share price, stealing from later depositors. Use virtual shares + assets as defense.19812. **ERC-2612 permit replay**: Without nonce or deadline checking, valid permits can be replayed. Always include nonce and validate deadline.19913. **Cross-chain message timeout**: Messages stuck in bridge without timeout handling lock user funds forever. Implement cancelation with timeout.20014. **Selfdestruct in proxy implementation**: If the implementation has `selfdestruct`, the proxy loses all funds. Never use selfdestruct in upgradeable contracts.20115. **Diamond storage collision**: Multiple facets using the same storage namespace cause data corruption. Use diamond storage pattern with unique namespace.202203## Best Practices204205### Token Contract Patterns206- Use ERC-20 for fungible tokens with ERC-2612 (permit) for gasless approvals207- Use ERC-721 for NFTs with ERC-4907 (rental) for lending market compatibility208- Use ERC-1155 for multi-token contracts (games, metaverse)209- Use ERC-4626 for yield-bearing vaults (standardized share accounting)210- Use ERC-4337 for account abstraction (wallet contract + EntryPoint)211- Use ERC-6551 for token-bound accounts (NFT owns other tokens)212- Use ERC-6909 for minimal multi-token (gas-optimized multi-token)213214### Upgradeable Contract Patterns215- Default to UUPS proxy pattern for new projects216- Use transparent proxy only for contracts with many upgrade functions217- Use beacon pattern for ERC-1167 minimal proxy families218- Use diamond (EIP-2535) for large, modular protocols with many functions219- Always use `initialize` function instead of constructor (callable once)220- Store implementation address in EIP-1967 storage slot for compatibility221222### Bridge Patterns223- Use canonical bridge for simple L1↔L2 asset transfer224- Use IBC for multi-chain trustless message passing (Cosmos ecosystem)225- Use LayerZero for flexible cross-chain messaging with configurable security226- Implement rate limiting and tiered withdrawal for high-value bridges227- Use ZK-bridge for maximum trust minimization at higher cost228- Always include timeout + cancelation for pending cross-chain messages229230### DeFi Protocol Patterns231- AMM: Constant product (Uniswap v2) for simplicity, concentrated liquidity (v3) for efficiency232- Lending: Pool-based (Aave/Compound) for capital efficiency, peer-to-peer for niche assets233- Governance: Token-weighted for simplicity, quadratic for fairness, veToken for alignment234- Oracle: Push (Pyth, Chronicle) for high-frequency, Chainlink pull for general purpose235236### MEV-Aware Design237- Include slippage tolerance in all AMM interactions238- Use commit-reveal schemes for order submission239- Implement private mempool integration (Flashbots Protect)240- Batch auctions for large trades (CowSwap model)241- Oracle extraction protection: use TWAP not spot price for liquidations242- Use `block.timestamp` and `block.number` guards against MEV timing manipulation243244## Advanced Token Standards Reference245246| Standard | Category | Key Feature |247|---|---|---|248| ERC-2612 | Fungible | Gasless approve via off-chain signature (permit) |249| ERC-4626 | Vault | Standardized yield-bearing share accounting |250| ERC-3525 | Semi-fungible | Financial NFTs with slot/value model |251| ERC-3643 | Security | Permissioned transfer, compliance wrapper |252| ERC-4907 | NFT | Rental roles (user + expires) |253| ERC-5192 | NFT | Soulbound (non-transferrable) |254| ERC-5218 | NFT | NFT rental with temporal ownership |255| ERC-6551 | NFT | Token-bound account (NFT = smart wallet) |256| ERC-6909 | Multi-token | Minimal ERC-1155 alternative (gas optimized) |257| ERC-1155 | Multi-token | Single contract for infinite token types |258| ERC-4337 | Account abstraction | Smart wallet via EntryPoint |259| ERC-6900 | Account abstraction | Modular smart accounts |260261## Compared With262263| Aspect | Rollup | State Channel | Plasma | Validium |264|---|---|---|---|---|265| Throughput | 2,000-100,000 TPS | Unlimited (off-chain) | 10,000+ TPS | 10,000+ TPS |266| Finality | Minutes (ZK) / 7d (Optimistic) | Instant | Hours | Minutes |267| Data availability | On-chain | Off-chain | On-chain (compressed) | Off-chain (DAC) |268| General computation | Yes (EVM or ZK-EVM) | No (payment/state) | Limited (predicates) | Yes (EVM) |269| Capital efficiency | High | Medium | Low | High |270| User experience | Good (like L1) | Excellent (instant) | Poor (challenge period) | Good |271272## DeFi Lending Pool Pattern Comparison273274| Feature | Pool-based (Aave/Compound) | Peer-to-peer (Morpho) | Isolated (Euler) |275|---|---|---|---|276| Capital efficiency | High (aggregated) | Medium (order book) | Medium (per-pair) |277| Liquidation | Soft (health factor) | Hard (position level) | Soft + IRM-based |278| Risk isolation | No (pool-wide risk) | Partial (per pair) | Yes (per market) |279| Oracle dependency | Single oracle | Single oracle | Per-market oracle |280| Upgradeability | Proxy-based | Proxy-based | Diamond (EIP-2535) |281282## Operations & Maintenance283284### Upgrade Management285- Multi-sig + timelock governance for all upgradeable contract admin keys286- Test upgrades on testnet with exact bytecode before mainnet287- Maintain implementation contract verified on block explorer288- Document storage layout changes in each upgrade289- Use `StorageSlot` library to prevent storage collision across upgrades290- Maintain upgrade history with `__gap` arrays for future storage291292### Bridge Operations293- Monitor relayer uptime and gas economics294- Track pending cross-chain messages for timeout expiry295- Maintain emergency pause capabilities for bridge contracts296- Regular security reviews of verifier set composition297- Track total value secured (TVS) per bridge route298- Monitor for anomalous message patterns (potential bridge attacks)299300### DeFi Protocol Operations301- Monitor oracle price deviation and staleness daily302- Track liquidity depth changes across all AMM pools303- Verify liquidation health factors are in expected ranges304- Run daily invariant checks (supply = borrow + reserves)305- Gas optimization review every quarter (reduce costs for users)306307### MEV Monitoring308- Detect sandwich attacks on AMM pools (frontrun + backrun same tx)309- Track validator proposer boost usage for block reorgs310- Monitor private mempool (Flashbots) usage and censored transactions311- Report MEV extracted per block from the protocol312- Implement MEV tax or redistribution when applicable313314## Rules3153161. Default to UUPS proxy for upgradeable contracts—transparent only for upgrade-function-heavy contracts3172. Always use EIP-1967 storage slots for proxy implementation and admin addresses3183. Never use `selfdestruct` in upgradeable contracts (renders proxy unusable)3194. Always check oracle staleness (`updatedAt` within [block.timestamp - threshold])3205. Implement pull-over-push for all payment distribution patterns3216. Use checks-effects-interactions in ALL contract functions, not just token transfers3227. Cross-chain bridge contracts must have emergency pause and rate limiting3238. Beacon proxy implementations must use `delegatecall`-compatible storage layouts3249. ERC-165 interface detection is mandatory for all composable contracts32510. Reentrancy guards on all message execution handlers in cross-chain contracts32611. EIP-2612 permit must check `ecrecover` address matches `owner` exactly (not just non-zero)32712. Rollup batch submissions must include data availability commitment for state reconstruction32813. Optimistic bridges require minimum 30-minute challenge window for standard, 7 days for high-value32914. All oracle price feeds must be redundant (minimum 3 independent sources)33015. State channel designs must include watchtower service for offline user protection33116. Proposer-builder separation (PBS) patterns require MEV-Boost or ePBS integration33217. ERC-4626 vaults must implement virtual shares to prevent inflation attacks33318. Cross-chain message timeout must be at least 2x the optimistic finality window33419. AMM pools must have minimum liquidity threshold to prevent manipulation33520. Lending pool oracles must use TWAP (not spot) for liquidation triggers33621. Diamond facets must use unique namespace for each storage layout33722. Beacon upgrades must be coordinated across all active proxies atomically33823. NFT market contracts must implement EIP-2981 (royalty standard) for creator fees33924. Off-chain oracles must not be the sole price source for liquidation-level decisions34025. Token contracts must implement `_beforeTokenTransfer` hooks for composability341342## Implementation Examples343344### UUPS Proxy Pattern (Solidity)345```solidity346// UUPS upgradeable proxy — OpenZeppelin style347contract UUPSProxy is ERC1967Proxy {348 constructor(address _logic, bytes memory _data) ERC1967Proxy(_logic, _data) {}349}350351abstract contract UUPSUpgradeable is Initializable, UUPSUpgradeable {352 function _authorizeUpgrade(address newImplementation) internal virtual;353354 function upgradeTo(address newImplementation) external virtual onlyProxy {355 _authorizeUpgrade(newImplementation);356 _upgradeToAndCallUUPS(newImplementation, new bytes(0));357 }358359 // Storage gap for future variables360 uint256[50] private __gap;361}362363// Example usage364contract MyContractV1 is UUPSUpgradeable {365 uint256 public value;366367 function initialize(uint256 _value) public initializer {368 __UUPSUpgradeable_init();369 value = _value;370 }371372 function setValue(uint256 _value) external {373 value = _value;374 }375}376377contract MyContractV2 is MyContractV1 {378 function setValue(uint256 _value) external override {379 require(_value > 0, "Zero not allowed");380 value = _value;381 }382}383```384385### ERC-4626 Yield-Bearing Vault (Solidity)386```solidity387contract YieldVault is ERC4626, ERC20Permit {388 using SafeERC20 for IERC20;389390 constructor(391 IERC20 _asset,392 string memory _name,393 string memory _symbol394 ) ERC4626(_asset) ERC20(_name, _symbol) ERC20Permit(_name) {395 // Virtual shares defense against inflation attack396 _mint(address(this), 10**6); // 1M virtual shares397 _asset.safeTransferFrom(msg.sender, address(this), 10**6); // 1M virtual assets398 }399400 // Override to add fees401 function _afterDeposit(uint256 assets, uint256 shares) internal override {402 // Fee: 0.1% deposit fee403 uint256 fee = assets / 1000;404 _asset.safeTransfer(treasury, fee);405 }406407 // Override to add performance fee on withdraw408 function _beforeWithdraw(uint256 assets, uint256 shares) internal override {409 uint256 totalAssets = totalAssets();410 uint256 totalSupply = totalSupply() - 10**6; // Exclude virtual shares411 uint256 navPerShare = totalAssets / totalSupply;412 // Performance fee: 10% of yield above NAV413 if (navPerShare > highWaterMark) {414 uint256 yield = (navPerShare - highWaterMark) * shares;415 uint256 perfFee = yield / 10;416 _asset.safeTransfer(treasury, perfFee);417 highWaterMark = navPerShare;418 }419 }420421 uint256 public highWaterMark;422 address public treasury;423}424```425426### Cross-Chain Message Pattern (LayerZero OFT)427```solidity428contract MyOFT is OFT {429 // LayerZero OFT — send tokens cross-chain430 function sendCrossChain(431 uint16 _dstChainId,432 address _to,433 uint256 _amount,434 address payable _refundAddress,435 bytes memory _adapterParams436 ) external payable {437 _send(_msgSender(), _dstChainId, _to, _amount, msg.value, _adapterParams);438 }439440 // Override to enforce rate limiting441 function _debitFrom(442 address _from,443 uint16 _dstChainId,444 bytes memory _toAddress,445 uint256 _amount446 ) internal override returns (uint256) {447 uint256 sentToday = dailyVolume[_dstChainId][block.timestamp / 86400];448 require(sentToday + _amount <= dailyLimit, "Rate limit exceeded");449 dailyVolume[_dstChainId][block.timestamp / 86400] = sentToday + _amount;450 return super._debitFrom(_from, _dstChainId, _toAddress, _amount);451 }452453 mapping(uint16 => mapping(uint256 => uint256)) public dailyVolume;454 uint256 public dailyLimit = 100_000 * 10**18; // 100k tokens/day455}456```457458### AMM Constant Product Pool (Minimal)459```solidity460contract ConstantProductPool {461 IERC20 public token0;462 IERC20 public token1;463 uint256 public reserve0;464 uint256 public reserve1;465466 function swap(uint256 amount0Out, uint256 amount1Out, address to) external {467 require(amount0Out > 0 || amount1Out > 0, "No output");468 require(amount0Out < reserve0 && amount1Out < reserve1, "Insufficient liquidity");469470 uint256 balance0Before = token0.balanceOf(address(this));471 uint256 balance1Before = token1.balanceOf(address(this));472473 // Transfer output tokens474 if (amount0Out > 0) token0.safeTransfer(to, amount0Out);475 if (amount1Out > 0) token1.safeTransfer(to, amount1Out);476477 // Verify invariant: (r0 - a0) * (r1 - a1) >= r0 * r1478 uint256 balance0After = token0.balanceOf(address(this));479 uint256 balance1After = token1.balanceOf(address(this));480481 uint256 amount0In = balance0After - (reserve0 - amount0Out);482 uint256 amount1In = balance1After - (reserve1 - amount1Out);483484 require(amount0In > 0 || amount1In > 0, "Insufficient input");485486 uint256 balance0Adjusted = balance0After * 1000 - amount0In * 3; // 0.3% fee487 uint256 balance1Adjusted = balance1After * 1000 - amount1In * 3;488489 require(490 balance0Adjusted * balance1Adjusted >= reserve0 * reserve1 * 1_000_000,491 "Invariant failed"492 );493494 (reserve0, reserve1) = (balance0After, balance1After);495496 emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to);497 }498499 event Swap(address indexed sender, uint256 amount0In, uint256 amount1In,500 uint256 amount0Out, uint256 amount1Out, address indexed to);501}502```503504### Flash Loan Pattern (Minimal)505```solidity506contract FlashLoanProvider {507 IERC20 public token;508 uint256 public protocolFee = 9; // 0.09% fee509510 function flashLoan(uint256 amount, address receiver, bytes calldata data) external {511 uint256 balanceBefore = token.balanceOf(address(this));512 require(balanceBefore >= amount, "Insufficient liquidity");513514 token.safeTransfer(receiver, amount);515516 // Callback to borrower517 IFlashLoanReceiver(receiver).executeOperation(amount, protocolFee, data);518519 // Verify repayment + fee520 uint256 balanceAfter = token.balanceOf(address(this));521 require(balanceAfter >= balanceBefore + amount * protocolFee / 10000, "Repayment failed");522523 emit FlashLoan(receiver, amount, protocolFee);524 }525526 event FlashLoan(address indexed receiver, uint256 amount, uint256 fee);527}528529interface IFlashLoanReceiver {530 function executeOperation(uint256 amount, uint256 fee, bytes calldata data) external;531}532```533534### Factory + Minimal Proxy Pattern (ERC-1167)535```solidity536contract WalletFactory {537 address public immutable implementation;538539 event WalletCreated(address indexed wallet, address indexed owner);540541 constructor(address _implementation) {542 implementation = _implementation;543 }544545 function createWallet(address owner, bytes32 salt) external returns (address) {546 bytes memory initData = abi.encodeWithSelector(Wallet.initialize.selector, owner);547548 address wallet = Clones.cloneDeterministic(implementation, salt);549 // Deploy cost: ~200 gas (ERC-1167 minimal proxy)550 // vs ~500k gas for full contract deployment551552 IProxy(wallet).initialize(initData);553 emit WalletCreated(wallet, owner);554 return wallet;555 }556}557558// ERC-1167 minimal proxy bytecode:559// 0x363d3d373d3d3d363d73{b_20 bytes address}5af43d82803e903d91602b57fd5bf3560```561562## Security Analysis Per Pattern563564| Pattern | Primary Attack Vector | Mitigation |565|---------|----------------------|------------|566| UUPS Proxy | Initialization frontrunning | Constructor `_disableInitializers()` |567| Transparent Proxy | Function selector collision | Admin storage at `0xb53127684a...` (EIP-1967) |568| Beacon Proxy | Beacon implementation change mid-transaction | Atomic updates with reentrancy guard |569| Diamond (EIP-2535) | Storage collision across facets | Diamond storage with unique namespace |570| ERC-4626 Vault | Inflation attack | Virtual shares + assets (OpenZeppelin fix) |571| AMM Constant Product | Sandwich attack | Slippage tolerance + TWAP oracle |572| AMM Concentrated Liquidity | Range manipulation | Tick-based pricing, immutable tick boundaries |573| Bridge (Canonical) | Reorg finality gap | Challenge window (7d Optimistic / 30min ZK) |574| Bridge (External Verifier) | Verifier collusion | Threshold signing + economic bonding |575| LayerZero | DVN compromise | Multiple DVN paths + security stack |576| State Channel | Watchtower offline | Watchtower service, challenge period |577| Flash Loan | Oracle manipulation | TWAP oracle, min-max bounds checks |578| ERC-20 Permit | Signature replay (cross-chain) | Include chain ID in domain separator |579| ERC-4337 AA | EntryPoint DoS | Per-account staking + gas limits |580581## Performance Considerations582583- **UUPS vs. Beacon**: UUPS costs ~200 gas more per call than beacon, but avoids an external read584- **ERC-1155 batch transfers**: 80% cheaper than individual ERC-721 transfers for 5+ items585- **Calldata vs. blob cost**: EIP-4844 blobs reduce L2 data availability cost from ~16 gas/byte to ~1-2 gas/byte586- **Merkle proof verification**: O(log n) gas for inclusion proof; optimize with sorted merkle trees587- **Oracle update frequency**: Push-based oracles (Pyth) update every ~400ms vs pull-based (Chainlink) ~20 min588- **Concentrated liquidity**: 2000x capital efficiency vs constant product at 1% fee tier589- **ERC-1167 minimal proxy**: ~200 gas to deploy vs ~500,000 for full contract590- **Beacon proxy**: ~100 gas overhead per call vs ~200 for transparent proxy591- **Diamond proxy**: ~250 gas overhead per call (facet map lookup + delegatecall)592- **EIP-2535 diamond storage**: No collision risk, but ~5000 gas per namespace registration593594## References595- references/advanced-token-standards.md — Advanced Token Standards596- references/blockchain-patterns-advanced.md — Blockchain Patterns Advanced Topics597- references/blockchain-patterns-fundamentals.md — Blockchain Patterns Fundamentals598- references/cross-chain-communication-patterns.md — Cross-Chain Communication Patterns599- references/erc-4626-vault.md — ERC-4626 Yield-Bearing Vault Standard600- references/layer2-scaling-patterns.md — Layer-2 Scaling Patterns601- references/mev-and-order-flow.md — MEV & Order Flow Patterns602- references/oracle-and-bridge-patterns.md — Oracle & Bridge Patterns603- references/token-standards.md — Token Standards & Contracts604- references/upgradeable-contracts.md — Upgradeable Contract Patterns605606## Handoff607blockchain-patterns → blockchain-application (for pattern implementation in code)608blockchain-patterns → blockchain-security (for pattern-specific security analysis)609blockchain-patterns → blockchain-core (for scaling protocol integration)