How is the mapping of storage done in upgradeable contracts?

I was going through proxy-delegate pattern for upgradeability of smart contracts. This gave a nice explanation: https://fravoll.github.io/solidity-patterns/proxy_delegate.html . While I was able to know how proxy acts as a storage layer and delegate as a logic layer, I was still unable to wrap my head around how the storage in proxy is mapped to the logic and variables in implementation contract…

On upgrading a contract, I got it that the implementation address is only changed, hence it is easy for proxy to point from one address to another…

But what about proxy’s storage?
If a new state variable is to be added to the implementation contract, since the storage of the proxy is used, is that new variable not added to proxy too? (and I know this doesn’t happen… so what is actually happening…?)
And there’s the rule that upon changing the pattern of variables in implementation, the storage pattern in proxy will get disrupted…
Why does that happen?

Can you explain to me about the deal with storage and mappings and delegatecalls in upgradeable contracts?
I’ve looked at various places, still cannot find a nice enough clear explanation!

2 Likes

Hi @asmeedhungana,

The proxy holds the state, while the logic contract provides the code.

If you upgrade to a new logic contract and that logic contract adds a new state variable, when you modify that state variable, the state is stored on the proxy.

The logic contract declares the type and order of the state variables that are stored on the proxy. If during an upgrade you change the type or order, then you will access the variables as per the updated logic contract but the values stored on the proxy will be in the type and order as per the previous logic contract.


The following documentation could help with your understanding:

Please ask all the questions that you need.

2 Likes

Thank you so much @abcoathup
I’ve been through the docs that you’ve provided as well as many resources about proxy-delegate system over the internet… However, I was still confused as to what is really stored in the proxy! Is it an arbitrary storage holder? on delegatecall, the storage of the proxy is used, right? its balance is used and the function caller will be the msg.sender of the external caller on the proxy…
i was just curious when I read that the contract is divided into logic and state…
so that made me question how the state is separated in the proxy contract…?
it isn’t done by name of the state variables, is it?
because upon changing the names of the variables in the implementation contract, the overall executions are never affected as long as their patterns or types are changed or deleted…

2 Likes

Hi @asmeedhungana,

I'm sorry that you are still confused, I will work on my explanation.
Please keep asking all the questions that you need.

A very important thing to note is that the code makes use of the EVM’s delegatecall opcode which executes the callee’s code in the context of the caller’s state. That is, the logic contract controls the proxy’s state and the logic contract’s state is meaningless. Thus, the proxy doesn’t only forward transactions to and from the logic contract, but also represents the pair’s state. The state is in the proxy and the logic is in the particular implementation that the proxy points to.

The state variables are declared in the logic contract and are stored in the proxy contract.

The only exception is that the proxy contract also has the address of the logic (implementation) contract. See Unstructured Storage Proxies.

2 Likes

Thank you so much! I think I’m getting it now! :heart:

1 Like

Great to hear. Please ask all the questions that you need.

1 Like

A post was split to a new topic: What is the ProxyAdmin?

A post was split to a new topic: Are the logic contracts state variables initialized and stored in the proxy contract’s context?