The Gnosis Safe smart contract was written with the usage of a proxy contract in mind. Because of that there is no constructor and it is required to call an initialize function on the contract before it can be used. For this it is recommended to use the ProxyFactory or the DelegatingConstructorProxy.
After the Safe proxy is deployed it needs to be initialized. As the general proxy has no constructor it is necessary to initialize the contract using a function call.
For this the GnosisSafe.sol contract exposes the method
setup. It requires four parameters:
- owners - List of Safe owners.
- threshold - Number of required confirmations for a Safe transaction.
- to - Contract address for optional delegate call.
- data - Data payload for optional delegate call.
data it is possible to nest advanced initialization. One of the use cases would be to initialize a Safe with some default modules. This can be done using the CreateAndAddModules.sol library.
The module assumes that Proxies are used for all modules. The library will use a ProxyFactory to deploy a Proxy for each module. So when triggering the
to would be the address of the deployed libary contract and
data the call to the method
createAndAddModules. This method has two parameters:
- proxyFactory - Address of the Proxy factory used to create the Proxy for each module
- data - Modules initialization payload. This is the data for each proxy factory call concatinated.
For a complete example see the CreateAndAddModules test
Trustless deployment with ERC20 Tokens
Using the ProxyFactory or deploying a proxy requires that the user has Ether on an externally owned account. To make it possible to pay for the creation with any token or Ether the following flow is used.
- Create deployment transaction. The PayingProxy enables the payment in any ERC20 token. Once the proxy is deployed it will refund a predefined address with the funds present at the address where it was deployed.
- To make the deployed address deterministic it is necessary to use a known account and calculate the target address. To make this trustless it is recommended to use a random account that has nonce 0. This can be done by creating a random signature for the deployment transaction. From that transaction it is possible to derive the sender and the target address.
- The user needs to transfer at least the amount required for the payment to the target address.
- Once the payment is present at the target address the relay service will fund the sender with Ether required for the creation transaction.
- As soon as the sender is funded the creation transaction can be submitted.
For more details on the Safe deployment process please checkout the DappCon 2018 presentation
Trustless deployment with Create2
The described approach for trustless deployment requires 3 transactions:
- Fund calculated Safe address
- Fund address that will deploy the Proxy contract
- Deploy the Proxy contract
Using the new
create2 opcode makes it possible to use a factory without having to worry about the nonce of the factory. By using a factory it is possible to eliminate one of the transactions required by described flow. The adjusted flow would be the following:
- Fund calculated Safe address (address is based on factory address, the init code of the contract that is deployed and a salt)
- Trigger the Proxy factory
To make sure that the correct contract will be deployed the Safe configuration should be part of the init code and the salt should be generated in a way that all parties involved can verify that it was not manipulated.
For more details on the Safe deployment process with create2 please checkout the EthCC 2019 presentation