Some DApps needs one, and only one, instance of an contract, which have the same address on any chain.
A permissionless factory for deploy of keyless deterministic contracts addresses based on its bytecode.
## Abstract
Some contracts are designed to be Singletons which have the same address no matter what chain they are, which means that should exist one instance for all, such as [EIP-1820] and [EIP-2429]. These contracts are usually deployed using a method known as [Nick]'s method, so anyone can deploy those contracts on any chain and they have a deterministic address.
This standard proposes the creation of a CREATE2 factory using this method, so other projects requiring this feature can use this factory in any chain with the same setup, even in development chains.
## Motivation
Code reuse, using the factory becomes easier to deploy singletons.
> The `r` and `s` values, made of starting `2470`, are obviously a human determined value, instead of a real signature.
3. We recover the sender of this transaction, i.e., the single-use deployment account.
> Thus we obtain an account that can broadcast that transaction, but we also have the warranty that nobody knows the private key of that account.
4. Send exactly 0.0247 ether to this single-use deployment account.
5. Broadcast the deployment transaction.
> Note: 247000 is the double of gas needed to deploy the smart contract, this ensures that future changes in OPCODE pricing are unlikely to cause this deploy transction to fail out of gas. A left over will sit in the address of about 0.01 ETH will be forever locked in the single use address.
The resulting transaction hash is `0x803351deb6d745e91545a6a3e1c0ea3e9a6a02a1a4193b70edfcd2f40f71a01c`.
This operation can be done on any chain, guaranteeing that the contract address is always the same and nobody can use that address with a different contract.
The contract has the address above for every chain on which it is deployed.
### ABI for SingletonFactory:
```json
[
{
"constant": false,
"inputs": [
{
"internalType": "bytes",
"name": "_initCode",
"type": "bytes"
},
{
"internalType": "bytes32",
"name": "_salt",
"type": "bytes32"
}
],
"name": "deploy",
"outputs": [
{
"internalType": "address payable",
"name": "createdContract",
"type": "address"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
]
```
## Rationale
SingletonFactory does not allow sending value on create2, this was done to prevent different results on the created object.
SingletonFactory allows user defined salt to facilitate the creation of vanity addresses for other projects. If vanity address is not necessary, salt `bytes(0)` should be used.
Contracts that are constructed by the SingletonFactory MUST not use `msg.sender` in their constructor, all variables must came through initialization data. This is intentional, as if allowing a callback after creation to aid initialization state would lead to contracts with same address (but different chains) to have the same address but different initial state.
The resulting address can be calculated in chain by any contract using this formula: `address(keccak256(bytes1(0xff), 0xce0042B868300000d44A59004Da54A005ffdcf9f, _salt, keccak256(_code)) << 96)` or in javascript using https://github.com/ethereumjs/ethereumjs-util/blob/master/docs/README.md#const-generateaddress2.
## Backwards Compatibility
Does not apply as there are no past versions of Singleton Factory being used.
## Test Cases
TBD
## Implementation
https://github.com/3esmit/ERC2470
## Security Considerations
Some contracts can possibly not support being deployed on any chain, or require a different address per chain, that can be safely done by using comparison in [EIP-1344] in constructor.
Account contracts are singletons in the point of view of each user, when wallets want to signal what chain id is intended, [EIP-1191] should be used.
Contracts deployed on factory must not use `msg.sender` in constructor, instead use constructor parameters, otherwise the factory would end up being the controller/only owner of those.
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).