As I understand to and data parameters used in the setupModules function, can help to execute a delegated call that makes modules setup on the Safe creation.

    /// @dev Setup function sets initial storage of contract.
    /// @param _owners List of Safe owners.
    /// @param _threshold Number of required confirmations for a Safe transaction.
    /// @param to Contract address for optional delegate call.
    /// @param data Data payload for optional delegate call.
    /// @param fallbackHandler Handler for fallback calls to this contract
    /// @param paymentToken Token that should be used for the payment (0 is ETH)
    /// @param payment Value that should be paid
    /// @param paymentReceiver Adddress that should receive the payment (or 0 if tx.origin)
    function setup(
        address[] calldata _owners,
        uint256 _threshold,
        address to,
        bytes calldata data,
        address fallbackHandler,
        address paymentToken,
        uint256 payment,
        address payable paymentReceiver
    ) external {
        // setupOwners checks if the Threshold is already set, therefore preventing that this method is called twice
        setupOwners(_owners, _threshold);
        if (fallbackHandler != address(0)) internalSetFallbackHandler(fallbackHandler);
        // As setupOwners can only be called if the contract has not been initialized we don't need a check for setupModules
        setupModules(to, data);

        if (payment > 0) {
            // To avoid running into issues with EIP-170 we reuse the handlePayment function (to avoid adjusting code of that has been verified we do not adjust the method itself)
            // baseGas = 0, gasPrice = 1 and gas = payment => amount = (payment + 0) * 1 = payment
            handlePayment(payment, 0, 1, paymentToken, paymentReceiver);
        emit SafeSetup(msg.sender, _owners, _threshold, to, fallbackHandler);

If I am correct, do you have any example of the contract, I can look after to see how to configure Module on the Safe creation stage properly? Without starting "Safe-transaction" which requires signatures of all owners

1 Answer 1


An easy way is to use the multisend contract with the setup method. As the setup method is performing a delegate call to to this can be used to perform multiple "sub" setup calls.

This can be used to deploy and setup modules. You can find the JS code to encode multiple tx for multisend here. The encoded calls would then be the data. The addresses for the multisend contract on each network can be found here.

  • do you have examples of using it not in JS but in contracts? I want to create safes with a custom factory contract that sets up all configs. (my factory to call the original safe factory) May 4, 2023 at 9:21

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.