0
0
Blockchain / Solidityprogramming~20 mins

Proxy pattern (upgradeable contracts) in Blockchain / Solidity - Practice Problems & Coding Challenges

Choose your learning style9 modes available
Challenge - 5 Problems
🎖️
Proxy Pattern Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
Predict Output
intermediate
2:00remaining
Output of a simple proxy delegatecall

Consider a proxy contract that delegates calls to an implementation contract. What will be the output of the following Solidity code snippet when calling getValue() through the proxy?

Blockchain / Solidity
pragma solidity ^0.8.0;

contract Implementation {
    uint public value;
    function setValue(uint _value) public {
        value = _value;
    }
    function getValue() public view returns (uint) {
        return value;
    }
}

contract Proxy {
    uint public value;
    address public implementation;

    constructor(address _impl) {
        implementation = _impl;
    }

    fallback() external payable {
        (bool success, ) = implementation.delegatecall(msg.data);
        require(success);
    }
}
AReturns the value stored in Implementation contract's storage
BReverts with an error
C0
DReturns a random number
Attempts:
2 left
💡 Hint

Remember that delegatecall runs code in the context of the calling contract's storage.

🧠 Conceptual
intermediate
1:30remaining
Storage collision in proxy pattern

Why is it important to carefully manage storage layout in upgradeable proxy contracts?

ABecause storage variables in the implementation contract are copied to the proxy on deployment
BBecause storage variables in the proxy and implementation share the same storage slots during delegatecall
CBecause the proxy contract cannot have any storage variables
DBecause storage variables in the implementation contract are ignored during delegatecall
Attempts:
2 left
💡 Hint

Think about how delegatecall works with storage.

🔧 Debug
advanced
2:30remaining
Identify the bug causing upgrade failure

The following proxy upgrade code fails to preserve state after upgrading the implementation. What is the main cause?

Blockchain / Solidity
pragma solidity ^0.8.0;

contract ImplementationV1 {
    uint public count;
    function increment() public {
        count += 1;
    }
}

contract ImplementationV2 {
    uint public count;
    uint public newVar;
    function increment() public {
        count += 1;
    }
    function setNewVar(uint _val) public {
        newVar = _val;
    }
}

contract Proxy {
    uint public count;
    address public implementation;

    constructor(address _impl) {
        implementation = _impl;
    }

    fallback() external payable {
        (bool success, ) = implementation.delegatecall(msg.data);
        require(success);
    }

    function upgrade(address _newImpl) public {
        implementation = _newImpl;
    }
}
AImplementationV2 added a new storage variable breaking storage layout compatibility
BUpgrade function does not call initialize on new implementation
CProxy contract does not have a fallback function
DDelegatecall is used instead of call
Attempts:
2 left
💡 Hint

Check storage variables order and count in proxy and implementations.

📝 Syntax
advanced
1:30remaining
Identify the syntax error in proxy fallback

Which option correctly implements a fallback function in Solidity 0.8+ for a proxy contract that forwards calls using delegatecall?

Afallback() external payable { (bool success, ) = implementation.delegatecall(msg.data); require(success); }
Bfunction fallback() external { (bool success, ) = implementation.delegatecall(msg.data); require(success); }
Cfallback() public { (bool success, ) = implementation.call(msg.data); require(success); }
Dfunction fallback() external payable { (bool success, ) = implementation.delegatecall(msg.data); require(success); }
Attempts:
2 left
💡 Hint

Recall the correct syntax for fallback functions in Solidity 0.8+.

🚀 Application
expert
3:00remaining
Calculate number of storage slots used by proxy and implementation

A proxy contract has 2 storage variables: address implementation and uint256 owner. The implementation contract has 3 storage variables: uint256 count, bool active, and uint256 data. How many storage slots does the proxy contract use after upgrade if the implementation is called via delegatecall?

ACannot determine without more info
B3 storage slots
C2 storage slots
D5 storage slots
Attempts:
2 left
💡 Hint

Remember that delegatecall uses the proxy's storage layout, so all variables must fit in proxy storage.