2

I posed this question during superhack. Didn’t end up getting a response

Hey @Germán | Safe, Thanks for the response. It still reverts with an error when I try to create a new Safe using the SafeProxyFactory and call setup method using the initializer param. Here is my code for your reference:

     bytes4 public constant SETUP_MODULES_METHOD_ID =
        bytes4(keccak256("setupModules(address,bytes)"));
    bytes4 public constant SETUP_SAFE_METHOD_ID =
        bytes4(
            keccak256(
                "setup(address[],uint256,address,bytes,address,address,uint256,address)"
            )
        );
    function _deploySafe(address moduleAddress,uint salt) internal returns(GnosisSafeProxy){
            bytes memory setupModulesData = abi.encodeWithSelector(
                SETUP_MODULES_METHOD_ID,
                moduleAddress,
                ""
            );
    
            return i_safeProxyFactory.createProxyWithNonce(i_safeImplementation,abi.encodeWithSelector(
                    SETUP_SAFE_METHOD_ID,
                    [msg.sender],
                    1,
                    moduleAddress,
                    setupModulesData,
                    address(0),
                    address(0),
                    0,
                    address(0)
                ),salt);
        }

The question before this for context:

I am going with the factory implementation. I'm sorry this might be a dumb question. I am trying to call the setup function on my newly created safe. But I am getting an error because your deployed implementation contract from Safe Deployments (unusable Safe) https://goerli.etherscan.io/address/0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552#code has already set the threshold to 1 in the constructor and makes it not possible to call setupOwners because it reverts GS200(Threshold !=0).

Should I create my own version of this contract and deploy it as my own Singleton Safe Deployment? or am I missing something that is obvious? Here is my code for your reference:

    function deploySafe(uint salt, bytes calldata signature) public {
        address safeAddress = _deployProxy(
            i_safeImplementation,
            msg.sender,
            salt
        );
        address moduleAddress = _deployProxy(
            i_moduleImplementation,
            msg.sender,
            salt
        );

        bytes memory setupData = abi.encodeWithSelector(
            SETUP_MODULE_METHOD_ID,
            msg.sender,
            moduleAddress,
            bytes32(0)
        );

        bytes memory enableModuleData = abi.encodeWithSelector(
            ENABLE_MODULE_METHOD_ID,
            moduleAddress
        );

        safeAddress.call(
            abi.encodeWithSelector(
                SETUP_SAFE_METHOD_ID,
                [msg.sender],
                1,
                moduleAddress,
                setupData,
                address(0),
                address(0),
                0,
                address(0)
            )
        );
    }
2
  • Can you add the exact error message you are getting into your question body, as well as the transaction hash if possible?
    – Rohan Nero
    Sep 12, 2023 at 1:59
  • 1
    @RohanNero Hey thanks goerli.etherscan.io/address/… I posted on context on followup
    – Rich Wang
    Sep 12, 2023 at 15:04

1 Answer 1

-1

The contract you are interacting with is a Gnosis Safe contract, its intended purpose isn't to be directly called using its data and logic, instead it is supposed to be used as a template or master copy that proxy contracts can use. This means the logic on the contract is what it's used for, not its actual data/variables.

Quote taken from the line directly above the GnosisSafe constructor:

This constructor ensures that this contract can only be used as a master copy for Proxy contracts

Since it's intended to be used with delegatecall, you would actually be accessing your contract's threshold variable as opposed to the GnosisSafe's, which means as long as you haven't already initialized your proxy contract, the call shouldn't fail.

Depending on your preference and what you are trying to do, you may want to deploy a new proxy contract that points to the GnosisSafe as its implementation contract as intended; Or you may just want a different contract altogether from the one you are trying to use if you don't want to interact with your logic via an external delegatecall.

Also, there are many different options for existing multi-sig contracts you can use, here is a link to a list of resources for further reading.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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