To create an upgradeable contract I have to use multiple proxies. The contract applies to Proxy A, then Proxy A applies to Proxy B. But delegatecall doesn't work in this case.

The simplified code of my contracts:

pragma solidity ^0.4.24;

contract A {
    uint256 public value = 100;

    function mul() public {
        value *= 2;

contract B {
    uint256 public value = 200;
    address a;

    constructor(address _a) {
        a = _a;

    function delegate() public {

contract C {
    uint256 public value = 500;
    address b;

    constructor(address _b) {
        b = _b;

    function delegate() public {

delegate() function works only if it called at contract B



When, in C, you do b.delegatecall(, what happens is that:

  • the code used is that of B
  • the storage used is that of C

And B and C have the same storage layout:

  • both the uint value are located on storage slot 0.
  • with address a and address b located on storage slot 1

So now you are executing B's code with C's storage. And you ask a.delegatecall(bytes4(keccak256("mul()")));. What the underlying bytecode does is actually take C's value at storage slot 1, in effect b, and use that as a. So you are about to delegatecall on B again.

And you call mul() on B? There is no such function, so it does nothing. In fact, depending on your version of Solidity, this call would silently fail or not.

It's working as expected :)

  • Thanks, your answer is very comprehensive. I wonder if it is possible to achieve what Mikky want to do. – Mehmet Doğan Aug 15 '18 at 14:55

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.