Deploy Your Root Layer Using the Root Factory

An entire Root Layer can be deployed using the Root Layer Factory in a single transaction. You can use the Root Layer Factory on the EthOS platform here (link coming soon)!

The Root Layer Factory, which is a custom Factory, allows you to clone (via the deploy function) your Root Layer, choose which Components you want to link to it and initialize them all at once.

You can assemble the Root Layer with a selection of the following Components:

  • Treasury Manager

  • Microservices Manager

  • State Manager

  • Treasury Splitter Manager

  • SubDAO Manager

  • Delegations Manager

  • Investments Manager

The Proposal Manager is the only mandatory Component; it is automatically cloned and linked to your Root Layer.

Deploy the Root Layer

As input, the deploy method of the Factory takes the deployData parameter:

function deploy(bytes memory deployData) external virtual override(IFactory, Factory) payable returns(address productAddress, bytes memory productInitResponse);

The deployData is the encoded value of the OrganizationDeployData struct, composed as follows:

struct OrganizationDeployData {
    string uri;
    bytes[] mandatoryComponentsDeployData;
    uint256[] additionalComponents;
    bytes[] additionalComponentsDeployData;
    bytes[] specialComponentsData;
    bytes specificOrganizationData;
  • string uri -> this is a uri parameter that contains the Metadata of the Organization. The Organization contract implements the DynamicMetadataCapableElement . You can set either traditional or a dynamic uri (see here to learn more).

  • bytes[] mandatoryComponentsDeployData -> this is the init data to initialize the Proposal Manager, which is the only mandatory Component of the Root Layer.

  • uint256[] additionalComponents -> this is the index of the additional Components that you want to link to the Root Layer. See below to find the Component indices.

  • bytes[] additionalComponentsDeployData -> this init data initializes the additional chosen Components. Each position in the bytes array corresponds to the position in the additionalComponents array.

  • bytes[] specialComponentsData -> this data is used to link and initialize external Components to the deployed subDAO. See below to learn more.

  • bytes specificOrganizationData -> pass this as empty. It is not used in this Factory.


This parameter can be used to link and initialize external Components to the subDAO. The parameter must be the encoded valued of:

(bytes32 key, address modelOrLocation, bool active, bytes memory deployData) = abi.decode(specialComponentData, (bytes32, address, bool, bytes));

for each element of the bytes[] specialComponentsData array.

  • bytes32 key -> it represents the user defined key of the Component.

  • address modelOrLocation -> it represents the Component address.

  • bool active -> it represents if the Component must be linked as active (true) or not (false)

  • bytes deployData -> if it's passed, it must contain encoded valued of:

    • clone -> it represents if the Component must be cloned (true) or not (false).

    • deployData -> it represents the initialization data of the Component.

So if you have a deployed and initialized Component you have to pass clone as false and deployData empty. If you have a deployed and not initialized Component you have to pass clone as false and deployData populated. If you have a not deployed and not initialized Component you have to pass clone as true and deployData populated.

Components Indices

  • Proposal Manager -> 0

  • Treasury Manager -> 1

  • Microservices Manager -> 2

  • State Manager -> 3

  • TreasurySplitter Manager -> 4

  • SubDAO Manager -> 5

  • Delegations Manager -> 6

  • Investments Manager -> 7

How to Pass the deployData

In this example, the Component indices are:

var values = ["proposalsManager", "treasuryManager", "stateManager", "treasurySplitterManager", "subDAOsManager", "delegationsManager", "microservicesManager"];

The deployData to pass is composed as follows:

// Proposal Manager init data
mandatoryComponentsDeployData[0] = abi.encode(['tuple(address[],uint256[],uint256[],address,address,address[],address[])'], [
        [], //address[] collections           
        [], //uint256[] objectIds
        [], //uint256[] weights
        utilities.voidEthereumAddress, //address creationRules
        utilities.voidEthereumAddress, //triggeringRules
        [], //address[] canTerminateAddresses
        [] //address[] validatorsAddresses

//in this example the Treasury, State Manager and TreasurySplitter Managers are linked as additional Components
var additionalComponentsDeployData = [
    //Treasury Manager init data
    //State Manager init data
    abi.encode(['tuple(string,bytes32,bytes)'], [
    //TreasurySplitter init data
    web3.eth.abi.encodeParameters(["uint256", "uint256", "bytes32[]", "uint256[]", "bytes32", "uint256", "uint256"], [0, 0, [],
        [], utilities.voidBytes32, 2, 3

var organizationDeployData = {
    uri: "",
    additionalComponents: [1, 2, 3], //in this example the Treasury, State and Treasury Splitter are linked as additional Components
    specialComponentsData: '0x';
    specificOrganizationData: '0x'

data = abi.encode(["tuple(string,bytes,bytes[],uint256[],bytes[],bytes)"], [Object.values(organizationDeployData)]);
organizationFactory.methods.deploy(data).send({from : myAddress})

Use this example pattern to create your own deployData.

Last updated