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
| improve this question | | | | |
  • How did you instance the contracts? How do you query them? – Ismael Mar 28 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 at 13:48
  • Please show the code used for deployment and testing. Your contracts appear to be fine. – Ismael Mar 29 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 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.

| improve this answer | | | | |

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.