Upgradable smartcontracts ,Proxy Contract & Delegate Call

Introduction to Upgradable smartcontracts

In this Article we will discuss on below

1) Why we upgrade smart contracts,

2) How to upgrade smart contracts, and

3) What issues to consider when you’re doing

Why do we need to upgrade smart contracts?

  1. To alter a smart contract to fix a bug they found,

  2. To add additional features, or simply to change the rules enforced by it.

  3. To optimize the code for more efficient use of Ethereum gas

Think of a traditional contract between two parties: if they both agreed to change it, they would be able to do

How to upgrade smart contracts?

Upgrading a smart contract does not mean we modify the code of a smart contract that is deployed—it means we swap one smart contract out for another. We accomplish this so that, in most circumstances, the end user's interaction with the dApp is unaffected.

What would be required if a contract had a bug:

  1. Deploy a new version of a contract

  2. Manually migrate from the old to the new smart contract (very expensive)

  3. Parameterised updates, Update all contracts that interacted with the old contract to use the address of the new one

We have contract upgrades already incorporated into our plugins to save you from having to go through this hassle. This gives us the flexibility to alter the contract code while keeping the state, balance, and address the same.

  1. Proxy contracts: It will use delegate call which is a low-level function similar to call

you can swap out other smart contracts in the system and simply update the proxy smart contract with the correct address of the newly deployed smart contract. End users of the dApp interact with the proxy directly, and with the other smart contracts only indirectly, via the proxy.

Delegate call is a method in Solidity used to call a function in a target contract from an original contract.

How does Uniswap upgrade its smart contract given that smart contract are immutable once deployed?

UNISWAP uses this proxy contracts - community driven upgrade to a blockchain project.

The basic idea is using a proxy for upgrades. The first contract is a simple wrapper or "proxy" which users interact with directly and is in charge of forwarding transactions to and from the second contract, which contains the logic. The key concept to understand is that the logic contract can be replaced while the proxy or the access point is never changed. Both contracts are still immutable in the sense that their code cannot be changed, but the logic contract can simply be swapped by another contract. The wrapper can thus point to a different logic implementation and in doing so, the software is "upgraded".

Being a smart contract, a proxy has its own Ethereum contract address that is “stable” (i.e. unchanging). So you can swap out other smart contracts in the system and simply update the proxy smart contract with the correct address of the newly deployed smart contract. End users of the app interact with the proxy directly, and with the other smart contracts only indirectly, via the proxy.

Proxy Pattern is achieved through the following two pieces

  1. The proxy smart contract

  2. The execution contract, also called the logic contract or the implementation contract.

Image showing end user, proxy contract, and logic contract.



User ---- tx ---> Proxy ----------> Implementation_v0
                     |
                      ------------> Implementation_v1
                     |
                      ------------> Implementation_v2

The proxy contract uses storage variables to keep track of the addresses of other smart contracts that make up the dApp. This is how it can redirect transactions and call the relevant smart contract.

DELEGATE CALL

How proxy contract pass the message calls to the correct contract. The proxy contract doesn’t just do a regular function call to the logic contract; it uses something called a delegate call.

What happens when the target contract is called from the original contract using the delegatecall() method is that It executes the function using the context of the original or calling contract.

If the logic contract’s code changes storage variables, those changes are reflected in the proxy contract’s storage variables—i.e. in the proxy contract’s state.

In Ethereum, a function can be represented as 4 + 32*N bytes where 4 bytes are for the function selector and the 32*N bytes are for function arguments.

Function selector : we hash the function's name along with the type of its arguments without the empty space and then take its first 4 bytes

eg : putValue(uint)

Function Argument: is created when you convert each argument into a 32 bytes hex string and then concatenate them

what is a delegate method in solidity ?

A solidity method used to call a function in a target contract from original contract

Where is delegate call method heavily used? proxy (upgradeable) contracts

.delegatecall() is heavily used within proxy (upgradeable) contracts. Since smart contracts are not upgradeable by default, the way to make them upgradeable is typically by having one storage contract which does not change, which contains an address for an implementation contract. If you wanted to update your contract code, you change the address of the implementation contract to something new. The storage contract makes all calls using .delegatecall() which allows to run different versions of the code while maintaining the same persisted storage over time, no matter how many implementation contracts you change. Therefore, the logic can change, but the data is never fragmented

How to prevent attacks on contracts which are using delegatecall?

Use stateless library contracts which means that the contracts to which you delegate the call should only be used for execution of logic and should not maintain state. This way, it is not possible for functions in the library to modify the state of the calling contract.

Did you find this article valuable?

Support Ashok V by becoming a sponsor. Any amount is appreciated!