Please bear with me here, I have been trying to figure it out myself but couldn't. I am trying to learn upgradeability with a Proxy pattern .https://blog.gnosis.pm/solidity-delegateproxy-contracts-e09957d0f201 .

We can test this setup by constructing a full Kombucha instance (which takes no arguments now), constructing a KombuchaProxy instance with the address of the full Kombucha instance’s address as the first argument.

When I checked Kombucha instance variables they are still at default value but they should have the values given to Kombucha proxy while instantiating its instance because KombuchaProxy and Kombucha both have inherited KombuchaData.

pragma solidity ^0.6.0;

contract ProxyData {
    address public proxied;

contract Proxy is ProxyData {
    constructor(address _proxied) public {
        proxied = _proxied;

    receive () payable external {}

    fallback () external payable {
        address addr = proxied;
        assembly {
            let freememstart := mload(0x40)
            calldatacopy(freememstart, 0, calldatasize())
            let success := delegatecall(not(0), addr, freememstart, calldatasize(), freememstart, 32)
            switch success
            case 0 { revert(freememstart, 32) }
            default { return(freememstart, 32) }

contract KombuchaData is ProxyData {
    event FilledKombucha(uint amountAdded, uint newFillAmount);
    event DrankKombucha(uint amountDrank, uint newFillAmount);

    uint public fillAmount;
    uint public capacity;
    string public flavor;

contract KombuchaProxy is Proxy, KombuchaData {
    constructor (address proxied, string memory _flavor, uint _fillAmount, uint _capacity)
        // the body is identical to our original constructor!
        require(_fillAmount <= _capacity && _capacity > 0);
        flavor = _flavor;
        fillAmount = _fillAmount;
        capacity = _capacity;

contract Kombucha is KombuchaData{

    function fill(uint amountToAdd) public {
        uint newAmount = fillAmount + amountToAdd;
        require(newAmount > fillAmount && newAmount <= capacity);
        fillAmount = newAmount;
        emit FilledKombucha(amountToAdd, newAmount);
    function drink(uint amountToDrink) public {
        uint newAmount = fillAmount - amountToDrink;
        require(newAmount < fillAmount);
        fillAmount = newAmount;
        emit DrankKombucha(amountToDrink, newAmount);
        // this mess of hashes just here to pad out the bytecode
  • How did you instance the contracts? How do you query them? – Ismael Mar 28 '20 at 13:32
  • First, Kombucha was compiled and deployed and then using its address and other args like flavour, fillamount, capacity KombhuchaProxy was deployed. – GraphicalDot Mar 28 '20 at 13:48
  • Please show the code used for deployment and testing. Your contracts appear to be fine. – Ismael Mar 29 '20 at 2:20
  • I connected metamask with remix to deploy them on Rinkyby Test Netwrok. Kombucha is present at 0x82aE891Cd0A8A5b96652b82784B1B4483Ac44c6B. KombuchaProxy is present at 0x5BBa28b0ad780250dE62Bd88b9F4F647073cbA47. – GraphicalDot Mar 29 '20 at 18:07

I tried the deployed contracts and they work as expected.

KombuchaProxy shouldn't update Kombucha contract. It updates its own storage.

The whole idea of a proxy is that it contains the data and point to another contract that has the code.

To test this in Remix I instantiated Kombucha contract at KombuchaProxy address. Now you can execute Kombucha functions fill and drink. The chnages will be in KombuchaProxy contract storage.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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