// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; /** * @title SOMA Template Factory Contract. * @author SOMA.finance. * @notice Interface of the {TemplateFactory} contract. */ interface ITemplateFactory { /** * @notice Emitted when a template version is created. * @param templateId The ID of the template added. * @param version The version of the template. * @param implementation The address of the implementation of the template. * @param sender The address of the message sender. */ event TemplateVersionCreated( bytes32 indexed templateId, uint256 indexed version, address implementation, address indexed sender ); /** * @notice Emitted when a deploy role is updated. * @param templateId The ID of the template with the updated deploy role. * @param prevRole The previous role. * @param newRole The new role. * @param sender The address of the message sender. */ event DeployRoleUpdated(bytes32 indexed templateId, bytes32 prevRole, bytes32 newRole, address indexed sender); /** * @notice Emitted when a template is enabled. * @param templateId The ID of the template. * @param sender The address of the message sender. */ event TemplateEnabled(bytes32 indexed templateId, address indexed sender); /** * @notice Emitted when a template is disabled. * @param templateId The ID of the template. * @param sender The address of the message sender. */ event TemplateDisabled(bytes32 indexed templateId, address indexed sender); /** * @notice Emitted when a template version is deprecated. * @param templateId The ID of the template. * @param version The version of the template deprecated. * @param sender The address of the message sender. */ event TemplateVersionDeprecated(bytes32 indexed templateId, uint256 indexed version, address indexed sender); /** * @notice Emitted when a template version is undeprecated. * @param templateId The ID of the template. * @param version The version of the template undeprecated. * @param sender The address of the message sender. */ event TemplateVersionUndeprecated(bytes32 indexed templateId, uint256 indexed version, address indexed sender); /** * @notice Emitted when a template is deployed. * @param instance The instance of the deployed template. * @param templateId The ID of the template. * @param version The version of the template. * @param args The abi-encoded constructor arguments. * @param functionCalls The abi-encoded function calls. * @param sender The address of the message sender. */ event TemplateDeployed( address indexed instance, bytes32 indexed templateId, uint256 version, bytes args, bytes[] functionCalls, address indexed sender ); /** * @notice Emitted when a template is cloned. * @param instance The instance of the deployed template. * @param templateId The ID of the template. * @param version The version of the template. * @param functionCalls The abi-encoded function calls. * @param sender The address of the message sender. */ event TemplateCloned( address indexed instance, bytes32 indexed templateId, uint256 version, bytes[] functionCalls, address indexed sender ); /** * @notice Emitted when a template function is called. * @param target The address of the target contract. * @param data The abi-encoded data. * @param result The abi-encoded result. * @param sender The address of the message sender. */ event FunctionCalled(address indexed target, bytes data, bytes result, address indexed sender); /** * @notice Structure of a template version. * @param exists True if the version exists, False if it does not. * @param deprecated True if the version is deprecated, False if it is not. * @param implementation The address of the version's implementation. * @param creationCode The abi-encoded creation code. * @param totalParts The total number of parts of the version. * @param partsUploaded The number of parts uploaded. * @param instances The array of instances. */ struct Version { bool deprecated; address implementation; bytes creationCode; uint256 totalParts; uint256 partsUploaded; address[] instances; } /** * @notice Structure of a template. * @param disabled Boolean value indicating if the template is enabled. * @param latestVersion The latest version of the template. * @param deployRole The deployer role of the template. * @param version The versions of the template. * @param instances The instances of the template. */ struct Template { bool disabled; bytes32 deployRole; Version[] versions; address[] instances; } /** * @notice Structure of deployment information. * @param exists Boolean value indicating if the deployment information exists. * @param templateId The id of the template. * @param version The version of the template. * @param args The abi-encoded arguments. * @param functionCalls The abi-encoded function calls. * @param cloned Boolean indicating if the deployment information is cloned. */ struct DeploymentInfo { bool exists; uint64 block; uint64 timestamp; address sender; bytes32 templateId; uint256 version; bytes args; bytes[] functionCalls; bool cloned; } /** * @notice Returns a version of a template. * @param templateId The id of the template to return the version of. * @param _version The version of the template to be returned. * @return The version of the template. */ function version(bytes32 templateId, uint256 _version) external view returns (Version memory); /** * @notice Returns the latest version of a template. * @param templateId The id of the template to return the latest version of. * @return The latest version of the template. */ function latestVersion(bytes32 templateId) external view returns (uint256); /** * @notice Returns the instances of a template. * @param templateId The id of the template to return the latest instance of. * @return The instances of the template. */ function templateInstances(bytes32 templateId) external view returns (address[] memory); /** * @notice Returns the deployment information of an instance. * @param instance The instance of the template to return deployment information of. * @return The deployment information of the template. */ function deploymentInfo(address instance) external view returns (DeploymentInfo memory); /** * @notice Returns the deploy role of a template. * @param templateId The id of the template to return the deploy role of. * @return The deploy role of the template. */ function deployRole(bytes32 templateId) external view returns (bytes32); /** * @notice Returns True if an instance has been deployed by the template factory, else returns False. * @dev Returns `true` if `instance` has been deployed by the template factory, else returns `false`. * @param instance The instance of the template to return True for, if it has been deployed by the factory, else False. * @return Boolean value indicating if the instance has been deployed by the template factory. */ function deployedByFactory(address instance) external view returns (bool); /** * @notice Uploads a new template and returns True. * @param templateId The id of the template to upload. * @param initialPart The initial part to upload. * @param totalParts The number of total parts of the template. * @param implementation The address of the implementation of the template. * @custom:emits TemplateVersionCreated * @custom:requirement `templateId` must not be equal to bytes32(0). * @custom:requirement The length of `initialPart` must be greater than zero. * @custom:requirement `totalParts` must be greater than zero. */ function uploadTemplate(bytes32 templateId, bytes memory initialPart, uint256 totalParts, address implementation) external returns (bool); /** * @notice Uploads a part of a template. * @param templateId The id of the template to upload a part to. * @param version The version of the template to upload a part to. * @param part The part to upload to the template. * @custom:requirement The length of part must be greater than zero. * @custom:requirement The version of the template must already exist. * @custom:requirement The version's number of parts uploaded must be less than the version's total number of parts. * @return Boolean value indicating if the operation was successful. */ function uploadTemplatePart(bytes32 templateId, uint256 version, bytes memory part) external returns (bool); /** * @notice Updates the deploy role of a template. * @param templateId The id of the template to update the deploy role for. * @param _deployRole The deploy role to update to. * @custom:emits DeployRoleUpdated * @custom:requirement The template's existing deploy role cannot be equal to `deployRole`. * @return Boolean value indicating if the operation was successful. */ function updateDeployRole(bytes32 templateId, bytes32 _deployRole) external returns (bool); /** * @notice Disables a template and returns True. * @dev Disables a template and returns `true`. * @param templateId The id of the template to disable. * @custom:emits TemplateDisabled * @custom:requirement The template must be enabled when the function call is made. * @return Boolean value indicating if the operation was successful. */ function disableTemplate(bytes32 templateId) external returns (bool); /** * @notice Enables a template and returns True. * @dev Enables a template and returns `true`. * @param templateId The id of the template to enable. * @custom:emits TemplateEnabled * @custom:requirement The template must be disabled when the function call is made. * @return Boolean value indicating if the operation was successful. */ function enableTemplate(bytes32 templateId) external returns (bool); /** * @notice Deprecates a version of a template. A deprecated template version cannot be deployed. * @param templateId The id of the template to deprecate the version for. * @param _version The version of the template to deprecate. * @custom:emits TemplateVersionDeprecated * @custom:requirement The version must already exist. * @custom:requirement The version must not be deprecated already. * @return Boolean value indicating if the operation was successful. */ function deprecateVersion(bytes32 templateId, uint256 _version) external returns (bool); /** * @notice Undeprecates a version of a template and returns True. * @param templateId The id of the template to undeprecate a version for. * @param _version The version of a template to undeprecate. * @custom:emits TemplateVersionUndeprecated * @custom:requirement The version must be deprecated already. * @return Boolean value indicating if the operation was successful. */ function undeprecateVersion(bytes32 templateId, uint256 _version) external returns (bool); /** * @notice Returns the Init Code Hash. * @dev Returns the keccak256 hash of `templateId`, `version` and `args`. * @param templateId The id of the template to return the init code hash of. * @param _version The version of the template to return the init code hash of. * @param args The abi-encoded constructor arguments. * @return The abi-encoded init code hash. */ function initCodeHash(bytes32 templateId, uint256 _version, bytes memory args) external view returns (bytes32); /** * @notice Overloaded predictDeployAddress function. * @dev See {ITemplateFactory-predictDeployAddress}. * @param templateId The id of the template to predict the deploy address for. * @param _version The version of the template to predict the deploy address for. * @param args The abi-encoded constructor arguments. * @param salt The unique hash ot identify the contract. */ function predictDeployAddress(bytes32 templateId, uint256 _version, bytes memory args, bytes32 salt) external view returns (address); /** * @notice Predict the clone address. * @param templateId The id of the template to predict the clone address for. * @param _version The version of the template to predict the clone address for. * @param salt The unique hash ot identify the contract. * @return The predicted clone address. */ function predictCloneAddress(bytes32 templateId, uint256 _version, bytes32 salt) external view returns (address); /** * @notice Deploys a version of a template. * @param templateId The id of the template to deploy. * @param _version The version of the template to deploy. * @param args The abi-encoded constructor arguments. * @param functionCalls The abi-encoded function calls. * @param salt The unique hash to identify the contract. * @custom:emits TemplateDeployed * @custom:requirement The version's number of parts must be equal to the version's number of parts uploaded. * @custom:requirement The length of the version's creation code must be greater than zero. * @return instance The instance of the deployed template. */ function deployTemplate( bytes32 templateId, uint256 _version, bytes memory args, bytes[] memory functionCalls, bytes32 salt ) external returns (address instance); /** * @notice Clones a version of a template. * @param templateId The id of the template to clone. * @param _version The version of the template to clone. * @param functionCalls The abi-encoded function calls. * @param salt The unique hash to identify the contract. * @custom:emits TemplateCloned * @custom:requirement The version's implementation must not equal `address(0)`. * @return instance The address of the cloned template instance. */ function cloneTemplate(bytes32 templateId, uint256 _version, bytes[] memory functionCalls, bytes32 salt) external returns (address instance); /** * @notice Calls a function on the target contract. * @param target The target address of the function call. * @param data Miscalaneous data associated with the transfer. * @custom:emits FunctionCalled * @return result The result of the function call. */ function functionCall(address target, bytes memory data) external returns (bytes memory result); }