Skip to main content

Command Palette

Search for a command to run...

Understanding Ethereum Upgradability: Proxy Patterns, delegatecall & Building Production-Ready Contracts

Published
3 min read
H

I am a software engineer with a strong background in competitive programming and backend focused development.

I graduated in IT from Army Institute of Technology, Pune (2025) and currently work at NxtWave, where I build and review technical content around data structures, algorithms, and problem solving.

My recent work is focused on smart contract and protocol development using Solidity and Foundry. I enjoy building systems where correctness, security, and clear invariants matter such as token vesting, staking mechanisms, and upgradeable protocols.

Earlier, I spent several years in competitive programming (Codeforces Expert, 5★ CodeChef), which shaped how I approach problem solving, edge cases, and testing.

On this blog, I write about the design and implementation of smart contracts, testing strategies, and engineering tradeoffs I encounter while building Web3 protocols.

One of the biggest challenges in Ethereum development is this:

Smart contracts are immutable once deployed.

But real-world applications evolve. Bugs are found. Features change. This is where upgradability patterns become critical.

In this article, I’ll share what I learned while deep-diving into Ethereum upgradability, proxy patterns, and building end-to-end, production-style contracts.


Why Upgradability Is Needed

Once a smart contract is deployed:

  • The code cannot be changed

  • Any bug becomes permanent

  • Adding new features requires redeployment

For protocols handling real money, this is unacceptable. Upgradability allows:

  • Bug fixes

  • Feature additions

  • Safer long-term maintenance


Naive Upgrade Approaches (And Why They Fail)

Early ideas include:

  • Redeploying contracts and asking users to migrate

  • Using multiple versions of the same contract

Problems:

  • Bad UX

  • Loss of state

  • High operational risk

This led to more robust approaches using proxy contracts.


delegatecall: The Core Building Block

delegatecall allows a contract to:

  • Execute code from another contract

  • While preserving the caller’s storage and address

In simple terms:

  • Proxy holds the data

  • Logic contract holds the code

  • Execution happens in the proxy’s context

This is the foundation of proxy-based upgrades.


Proxy Pattern Explained

The Proxy Pattern separates:

  • Storage → Proxy contract

  • Logic → Implementation contract

Flow:

  1. User calls the proxy

  2. Proxy forwards the call using delegatecall

  3. Logic executes using proxy storage

This allows swapping the logic contract without losing state.


Storage Layout: The Hidden Danger

One of the biggest risks in upgradeable contracts is storage collision.

Key learnings:

  • Storage variables must never change order

  • New variables should only be appended

  • Incorrect layout can corrupt state permanently

Understanding this is essential for safe upgrades.


Transparent Proxy Pattern

The Transparent Proxy Pattern solves a major problem:

  • Admin functions interfering with user calls

Key ideas:

  • Admin can only call upgrade functions

  • Users can only call implementation logic

  • Clean separation of responsibilities

This is the industry standard used by OpenZeppelin.


Building & Testing Upgradeable Contracts

Beyond theory, I worked on:

  • Initializing upgradeable contracts correctly

  • Adding access control (onlyOwner)

  • Writing unit tests

  • Debugging failing test cases

  • Fixing logic using upgradability instead of redeployment

Testing plays a crucial role in avoiding costly upgrade mistakes.


End-to-End Ethereum Application

I also worked on a full ETH project involving:

  • ERC-20 token (OrcaCoin)

  • Staking contract

  • Contract testing

  • Architecture understanding

  • Reviewing the original solution for design insights

This helped bridge the gap between learning concepts and production-ready thinking.


Backend Concepts for Web3 Apps

To understand real systems, I also studied:

  • Redis

  • Pub/Sub

  • Queues

These are commonly used to:

  • Index blockchain events

  • Handle async workflows

  • Build scalable Web3 backends


Key Takeaways

  • Upgradability is essential for real-world Ethereum apps

  • delegatecall and proxy patterns power safe upgrades

  • Storage layout mistakes can be catastrophic

  • Testing is non-negotiable

  • Production Web3 requires both Solidity + backend knowledge

    my codebase for projects and reference : https://github.com/harshkumarrai