🔄 Contract Upgrades: Fix Bugs Without Redeploying
Learn how proxy patterns enable smart contract upgrades
Your Progress
0 / 5 completed🔄 The Immutability Problem
Smart contracts are immutable by default. Once deployed to Ethereum, the code cannot be changed. This is a feature—immutability prevents tampering and builds trust. But it's also a problem: What if you find a critical bug? What if you need to add features? Traditional software allows updates. Blockchain doesn't. Contract upgrade patterns solve this paradox.
🎮 Interactive: Upgrade Flow Visualization
Click through the 6 steps of contract upgradeability to understand how proxy patterns enable code changes while preserving state and contract addresses.
Deploy Proxy
Deploy proxy contract that holds state
🔑 Core Concepts
Stores all state (balances, data). Has fixed address that users interact with. Forwards calls to Logic contract via delegatecall.
Contains business logic (functions). Has no state. Can be replaced with new version. Also called "implementation" contract.
Special EVM opcode. Executes code from Logic contract in Proxy's context. State changes affect Proxy, not Logic. This is the magic.
Changes Proxy's pointer to new Logic contract. Only admin can call. State preserved because it lives in Proxy, not Logic.
⚠️ Why Upgradeability Matters
Poly Network hack ($611M, 2021): Exploited function bug. With upgrades, team could have patched immediately. Instead, relied on hacker returning funds.
Uniswap V1 → V2 → V3: Each required new contract deployment, fragmenting liquidity. With upgrades, could have evolved single contract.
OpenZeppelin upgrades: Discovered reentrancy patterns emerge. Upgradeable contracts can adopt new security standards (e.g., Checks-Effects-Interactions).
EVM improvements (e.g., EIP-1559, EIP-3529) enable cheaper patterns. Upgradeable contracts can adopt optimizations without redeployment.
💡 Key Insight
Contract upgradeability is a controlled compromise on immutability. Pure immutability is secure but inflexible—you can't fix bugs or add features. Traditional mutability is flexible but insecure—anyone could change code. Proxy patterns split the difference: state is immutable (stored in Proxy), logic is upgradeable (replaced via admin function). Users interact with one address forever, but functionality evolves. It's not perfect—introduces admin risk and complexity—but it's the best solution to the immutability dilemma.