pcaversaccio / create2deployer

Helper smart contract to make easier and safer usage of the `CREATE2` EVM opcode.
MIT License
286 stars 42 forks source link

create2 factory with initial call #81

Closed noyyyy closed 2 years ago

noyyyy commented 2 years ago

I suggest a new factory contract that can pass initial call bytes, like

    function deployWithInitCall(
        uint256 value,
        bytes32 salt,
        bytes memory code,
        bytes memory initCall
    ) public whenNotPaused {
        Create2.deploy(value, salt, code);

        if (_initCall.length > 0) {
            (bool success, bytes memory reason) = addr.call(_initCall);
            require(success, string(reason));
        }
    }

more can be seen here. https://github.com/wighawag/hardhat-deploy/issues/383

pcaversaccio commented 2 years ago

I see where you are coming from but this can be solved within the contract itself rather by changing the create2deployer contract. The only purpose of the create2deployer is to execute CREATE2 deployments and not to conduct further actions. Whatever you want to do can be achieved via constructor arguments. So for the owner<>msg.sender problem you can for instance do the following:

contract mainContract is Ownable {
    constructor(address owner) {
        _transferOwnership(owner);
    }
    ...
}

This will lead to 2 events emitted during the contract creation transaction (the first owner will be transferred to msg.sender and the second thereafter to the set address in the main constructor). The reason why this can be done is due to the linearization pattern of multiple inheritance in Solidity (see here).

For the AccessControl control case it would look like this:

contract mainContract is AccessControl {
    constructor(address admin) {
        _grantRole(DEFAULT_ADMIN_ROLE, admin);
    }
    ...
}
noyyyy commented 2 years ago

Thanks for your comment!