Skip to content

Commit

Permalink
feat: create LSP23MultiChainDeployment (#649)
Browse files Browse the repository at this point in the history
* feat: create LSP23MultiChainDeployment

* refactor: improve LSP23 readability (#650)

* refactor: improve LSP23 readability

* tests: create helper to calculate deployed addresses

* tests: add test for lsp23

* refactor: add suggested changes & surther simplify

* refactor: remove event split, restore the initial events.

* refactor: fix generation of salt

* refactor: make salt generation functions virtual

* chore: fix typo

* refactor: move `emit` before external call to `IPostDeploymentModule`

* chore: add suggested changes

* docs: improve Natspec as suggetsed

* docs: fix Natspec typo

* chore: remove unrelated file

---------

Co-authored-by: maxvia87 <maximeviard@hotmail.fr>

---------

Co-authored-by: b00ste.lyx <62855857+b00ste@users.noreply.github.com>
Co-authored-by: Jean Cvllr <31145285+CJ42@users.noreply.github.com>
  • Loading branch information
3 people authored Aug 4, 2023
1 parent e0c7922 commit 01fd820
Show file tree
Hide file tree
Showing 7 changed files with 856 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

interface IOwnerControlledContractDeployer {
event DeployedContracts(
address indexed controlledContract,
address indexed ownerContract,
ControlledContractDeployment controlledContractDeployment,
OwnerContractDeployment ownerContractDeployment,
address postDeploymentModule,
bytes postDeploymentModuleCalldata
);

event DeployedERC1167Proxies(
address indexed controlledContract,
address indexed ownerContract,
ControlledContractDeploymentInit controlledContractDeploymentInit,
OwnerContractDeploymentInit ownerContractDeploymentInit,
address postDeploymentModule,
bytes postDeploymentModuleCalldata
);

/**
* @param salt A unique value used to ensure each created proxies are unique. (Can be used to deploy the contract at a desired address.)
* @param fundingAmount The value to be sent with the deployment transaction.
* @param creationBytecode The bytecode of the contract with the constructor params.
*/
struct ControlledContractDeployment {
bytes32 salt;
uint256 fundingAmount;
bytes creationBytecode;
}

/**
* @param fundingAmount The value to be sent with the deployment transaction.
* @param creationBytecode The constructor + runtime bytecode (without the controlled contract's address as param)
* @param addControlledContractAddress If set to `true`, this will append the controlled contract's address + the `extraConstructorParams` to the `creationBytecode`.
* @param extraConstructorParams Params to be appended to the `creationBytecode` (after the controlled contract address) if `addControlledContractAddress` is set to `true`.
*/
struct OwnerContractDeployment {
uint256 fundingAmount;
bytes creationBytecode;
bool addControlledContractAddress;
bytes extraConstructorParams;
}

/**
* @param salt A unique value used to ensure each created proxies are unique. (Can be used to deploy the contract at a desired address.)
* @param fundingAmount The value to be sent with the deployment transaction.
* @param implementationContract The address of the contract that will be used as a base contract for the proxy.
* @param initializationCalldata The calldata used to initialise the contract. (initialization should be similar to a constructor in a normal contract.)
*/
struct ControlledContractDeploymentInit {
bytes32 salt;
uint256 fundingAmount;
address implementationContract;
bytes initializationCalldata;
}

/**
* @param fundingAmount The value to be sent with the deployment transaction.
* @param implementationContract The address of the contract that will be used as a base contract for the proxy.
* @param initializationCalldata The first part of the initialisation calldata, everything before the controlled contract address.
* @param addControlledContractAddress If set to `true`, this will append the controlled contract's address + the `extraInitializationParams` to the `initializationCalldata`.
* @param extraInitializationParams Params to be appended to the `initializationCalldata` (after the controlled contract address) if `addControlledContractAddress` is set to `true`
*/
struct OwnerContractDeploymentInit {
uint256 fundingAmount;
address implementationContract;
bytes initializationCalldata;
bool addControlledContractAddress;
bytes extraInitializationParams;
}

/**
* @dev Deploys a contract and its owner contract.
* @notice Contracts deployed. Contract Address: `controlledContractAddress`. Owner Contract Address: `ownerContractAddress`
*
* @param controlledContractDeployment Contains the needed parameter to deploy a contract. (`salt`, `fundingAmount`, `creationBytecode`)
* @param ownerContractDeployment Contains the needed parameter to deploy the owner contract. (`fundingAmount`, `creationBytecode`, `addControlledContractAddress`, `extraConstructorParams`)
* @param postDeploymentModule The module to be executed after deployment
* @param postDeploymentModuleCalldata The data to be passed to the post deployment module
*
* @return controlledContractAddress The address of the deployed controlled contract.
* @return ownerContractAddress The address of the deployed owner contract.
*/
function deployContracts(
ControlledContractDeployment calldata controlledContractDeployment,
OwnerContractDeployment calldata ownerContractDeployment,
address postDeploymentModule,
bytes calldata postDeploymentModuleCalldata
)
external
payable
returns (
address controlledContractAddress,
address ownerContractAddress
);

/**
* @dev Deploys proxies of a contract and its owner contract
* @notice Contract proxies deployed. Contract Proxy Address: `controlledContractAddress`. Owner Contract Proxy Address: `ownerContractAddress`
*
* @param controlledContractDeploymentInit Contains the needed parameter to deploy a proxy contract. (`salt`, `fundingAmount`, `implementationContract`, `initializationCalldata`)
* @param ownerContractDeploymentInit Contains the needed parameter to deploy the owner proxy contract. (`fundingAmount`, `implementationContract`, `addControlledContractAddress`, `initializationCalldata`, `extraInitializationParams`)
* @param postDeploymentModule The module to be executed after deployment.
* @param postDeploymentModuleCalldata The data to be passed to the post deployment module.
*
* @return controlledContractAddress The address of the deployed controlled contract proxy
* @return ownerContractAddress The address of the deployed owner contract proxy
*/
function deployERC1167Proxies(
ControlledContractDeploymentInit
calldata controlledContractDeploymentInit,
OwnerContractDeploymentInit calldata ownerContractDeploymentInit,
address postDeploymentModule,
bytes calldata postDeploymentModuleCalldata
)
external
payable
returns (
address controlledContractAddress,
address ownerContractAddress
);

/**
* @dev Computes the addresses of the controlled and owner contracts to be created
*
* @param controlledContractDeployment Contains the needed parameter to deploy a contract. (`salt`, `fundingAmount`, `creationBytecode`)
* @param ownerContractDeployment Contains the needed parameter to deploy the owner contract. (`fundingAmount`, `creationBytecode`, `addControlledContractAddress`, `extraConstructorParams`)
* @param postDeploymentModule The module to be executed after deployment
* @param postDeploymentModuleCalldata The data to be passed to the post deployment module
*
* @return controlledContractAddress The address of the deployed controlled contract.
* @return ownerContractAddress The address of the deployed owner contract.
*/
function computeAddresses(
ControlledContractDeployment calldata controlledContractDeployment,
OwnerContractDeployment calldata ownerContractDeployment,
address postDeploymentModule,
bytes calldata postDeploymentModuleCalldata
)
external
view
returns (
address controlledContractAddress,
address ownerContractAddress
);

/**
* @dev Computes the addresses of the controlled and owner contract proxies to be created.
*
* @param controlledContractDeploymentInit Contains the needed parameter to deploy a proxy contract. (`salt`, `fundingAmount`, `implementationContract`, `initializationCalldata`)
* @param ownerContractDeploymentInit Contains the needed parameter to deploy the owner proxy contract. (`fundingAmount`, `implementationContract`, `addControlledContractAddress`, `initializationCalldata`, `extraInitializationParams`)
* @param postDeploymentModule The module to be executed after deployment.
* @param postDeploymentModuleCalldata The data to be passed to the post deployment module.
*
* @return controlledContractAddress The address of the deployed controlled contract proxy
* @return ownerContractAddress The address of the deployed owner contract proxy
*/
function computeERC1167Addresses(
ControlledContractDeploymentInit
calldata controlledContractDeploymentInit,
OwnerContractDeploymentInit calldata ownerContractDeploymentInit,
address postDeploymentModule,
bytes calldata postDeploymentModuleCalldata
)
external
view
returns (
address controlledContractAddress,
address ownerContractAddress
);
}
10 changes: 10 additions & 0 deletions contracts/LSP23MultiChainDeployment/IPostDeploymentModule.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

interface IPostDeploymentModule {
function executePostDeployment(
address ownerControlledContract,
address ownerContract,
bytes calldata calldataToPostDeploymentModule
) external;
}
24 changes: 24 additions & 0 deletions contracts/LSP23MultiChainDeployment/LSP23Errors.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/**
* @dev Reverts when the `msg.value` sent is not equal to the sum of value used for the deployment of the contract & its owner contract.
* @notice Invalid value sent.
*/
error InvalidValueSum();

/**
* @dev Reverts when the deployment & intialisation of the contract has failed.
* @notice Failed to deploy & initialise the Controlled Contract Proxy. Error: `errorData`.
*
* @param errorData Potentially information about why the deployment & intialisation have failed.
*/
error ControlledContractProxyInitFailureError(bytes errorData);

/**
* @dev Reverts when the deployment & intialisation of the owner contract has failed.
* @notice Failed to deploy & initialise the Owner Contract Proxy. Error: `errorData`.
*
* @param errorData Potentially information about why the deployment & intialisation have failed.
*/
error OwnerContractProxyInitFailureError(bytes errorData);
Loading

0 comments on commit 01fd820

Please sign in to comment.