GithubHelp home page GithubHelp logo

Comments (11)

JarenL avatar JarenL commented on June 10, 2024 1

@zeekay @yarrumretep Hey guys stumbling upon this thread a little late. I think i have the exact same question revolving how to make the CloneFactory upgradeable, specifically how to upgrade a fleet already deployed with CloneFactory. Did you guys figure out an implementation?

from clone-factory.

yarrumretep avatar yarrumretep commented on June 10, 2024

Hi Zach, yeah - that would be a whole 'nother thing. Likely, to upgrade you would need proxy local logic to run governance of the upgrade (could just be isOwner check) and set the new delegate address. This project is really focused on a clone contract that effectively copies the logic of the master contract verbatim - thus (a) keeping it super inexpensive to deploy / operate and (b) very simple and robust representation to readers / users - that this contract location will always implement the code at the destination.

You could certainly implement an upgradable contract as the target of the clones - and thus achieve group upgradability of all of the clones (with whatever governance of that you wanted to implement).

What you are proposing is possible, of course, just not within the scope of this project. Happy to discuss further if you'd like, but for now I'll close this issue.

from clone-factory.

zeekay avatar zeekay commented on June 10, 2024

Yeah, I was hoping to point the clones at an upgradeable shim that would delegate to the underlying contract with functionality I cared about. I'm looking at delegatecall -- could you provide any guidance around how to correctly calculate the outsize param?

My attempt:

function() payable {
    uint r;

    // Call contract in current context
    assembly {
        calldatacopy(mload(0x40), 0, calldatasize)
        r := delegatecall(sub(gas, 700), destinationContract, mload(0x40), calldatasize, mload(0x40), 32)
    }

    // Throw if the call failed
    if (r != 1) { throw; }

    // Pass on return value
    assembly {
        return(mload(0x40), 32)
    }
}

Do you happen to know how to infer the outsize variable? That's the size of the return data from the function being delegated to, no? Do you know if it's possible to look that up or predict it based on return signature of function?

Thanks for the project btw, absolute best approach I've seen to launching a clone contract!

from clone-factory.

nateawelch avatar nateawelch commented on June 10, 2024

@zeekay You can use the returndatasize opcode to get the size of the return data from the last delegatecall.

I think your upgradability would be fairly easily implemented by editing the shim contract assembly to have the target contract address be in storage instead of hardcoded in bytecode and have the master contract have code to update the master address. This would of course mean the shim contract would only be upgradable using the code in the master contract, and if you somehow messed up the upgradability of the new master, then you're SOL.

from clone-factory.

nateawelch avatar nateawelch commented on June 10, 2024

@yarrumretep I think we should actually consider creating a version that's upgradable in some fashion either through what I just described or some other mechanism

from clone-factory.

zeekay avatar zeekay commented on June 10, 2024

@flygoing something like this?

function() payable {
    // Require successfull delegate call 
    require(currentVersion.delegatecall(msg.data));
    assembly {
        let outsize := returndatasize 
        let outptr := mload(0x40) // Load memory
        mstore(0x40, add(outptr, outsize)) // Load up to return size
        returndatacopy(outptr, 0, outsize) // Copy last return into pointer
        return(outptr, outsize) 
    }
}

from clone-factory.

yarrumretep avatar yarrumretep commented on June 10, 2024

@zeekay - that looks about right. Unless you have other code in the contract that calls this default function, you don't have to bother with the 0x40 memory management pieces. Memory is a clean slate for each call, delegatecall, staticcall etc.

from clone-factory.

zeekay avatar zeekay commented on June 10, 2024

Perfect, thanks a lot ya'll :)

Ever available for some freelance hacking? I'd love to chat: [email protected].

from clone-factory.

yarrumretep avatar yarrumretep commented on June 10, 2024

@zeekay - @flygoing is right that you needn't have the logic for changing / governing the currentVersion variable in the proxy contract itself. It can (should) be in the master contracts where it will serve the dual purpose of making sure the master contract's state does not stomp on the currentVersion slot.

Also, do you want to upgrade each clone independently - or do you want to upgrade the whole fleet in one go?

from clone-factory.

zeekay avatar zeekay commented on June 10, 2024

Generally I want to upgrade whole fleet in one go. That's the rough architecture I came up with when I ran into your library last night :)

I kind of want to do two different clone factory contracts that I could pick and choose from:

  • One launches a clone that references the master contract (and makes upgrades simple)
  • The other would directly reference the current version contract (which would not be upgradeable but cost slightly less gas as it'd save one delegatecall).

I could see both approaches being useful.

from clone-factory.

yarrumretep avatar yarrumretep commented on June 10, 2024

@zeekay - it turns out there isn't a simple way to do an upgrade-in-one-go fleet of clones. Because every handoff to the master contract is a delegatecall, the storage of the called contract is the leaf contract's storage. Even with a double-delegation model, you still have to upgrade each leaf independently.

If you really want to upgrade the fleet in one go, the clone contract will need to call out to a separate contract to fetch the 'currentVersion' address. Adding an additional call to every call and a bit more complexity to the architecture. Does that make sense? Reach out to me on gitter if you want to chat more 'realtime'

from clone-factory.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.