Skip to main content

CGM Architecture

There are currently two Chain Fusion Governance Module (CGM) archetypes, the ICP Treasury, which is deployed on Q and ICP and can hold tokens natively on ICP; and the Chain Fusion Treasury Hub, which utilizes ICP to govern assets on one or multiple foreign chains.

Each deployed instance, the CGM consists of multiple components, deployed on the chains that are involved. Depending on the archetype and individual use case, these are:

  • DAO and DAO Module Smart Contracts on the Q Blockchain
  • Backend Canisters on the Internet Computer Protocol (ICP)
  • One or multiple Treasury contracts on the foreign-chains (e.g. an EVM L2)

To better understand the components, an overview of all component functions is given below.

ICP Treasury

Contract/ CanisterNetworkExplanationSource Code
ICP Treasury ModuleQCan be used by Chain Fusion DAO to govern a treasury on ICP. Specifically for transferring native ICP or other ICRC tokens.DAO Module Smart Contract
ICP TreasuryICPReads the state on the ICP Treasury Module on Q and executes token transfers on ICP. It is configured to only work in combination with one dedicated ICP Treasury Module on Q and initialized with its address. Transfers can only be executed on ICP once for any relevant and successfully executed proposal on Q.Canister Elements

Chain Fusion Treasury Hub

Contract/ CanisterNetworkExplanationSource Code
Chain Fusion Treasury Hub ModuleQCan be used by Chain Fusion DAO to govern one or multiple treasuries on any EVM chain. Specifically, for transferring the destination-chain’s native token or ERC20 tokens.DAO Module Smart Contract
Chain Fusion Treasury HubICPReads the state on the Chain Fusion Treasury Hub Module on Q and relays a transfer transation to a dedicated treasury contract on the destination-chain. It is configured to only work in combination with one dedicated Chain Fusion Treasury Hub Module on Q and initialized with its address. However, multiple treasuries on foreign chains can be configured to be called by this canister. Therefore, this canister has a dedicated EVM address in addition to its identifier on ICP. Foreign-chain transfers can only be executed once for any relevant and successfully executed proposal on Q.Canister Elements
Foreign-Chain Treasury[Any EVM based chain]A treasury smart contract to be deployed on any foreign EVM chain. It can hold the chain’s native token, as well as other ERC20 tokens. It is configured to only allow transfers if called by the respective Chain Fusion Treasury Hub canister’s EVM address and thereby can only be used by the DAO on Q through oRicial proposals.Smart Contract

Component Functions

The following sections dive deeper into the components introduced above and explain the most important functions of each component.

DAO Module Smart Contracts

Depending on whether a DAO wants to use the ICP Treasury or the Chain Fusion Hub, a respective DAO module contract needs to be deployed on Q and added to the DAO. Since the focus of this section of the documentation lays in explaining the integration between Chain Fusion and Q, the functions crucial for achieving the respective use case are discussed in the tables below. Other internal functions (i.e. for configuring the module) can be found in the source code provided above.

ICP Treasury Module (Q DAO Side)

FunctionInputCalled byExplanation
sendICRCTokensstring (token); string (recipient); uint (amount)DAOVoting ContractProvides all relevant information for calling the ‘icrc1_transfer’ function of the provided token to be executed by the ICP Treasury canister. This function can only be called by the DAO after a successful proposal.
sendICPTokensstring (recipient); uint (amount)DAOVoting ContractAnalogous to the sendICRCTokens function described above, but the ICP token address is pre-configured, so this function can only be used to transfer the native ICP token. This function can only be called by the DAO after a successful proposal.
getICPMessageuint256 (messageId_)ICP Treasury (canister)Provides a message that was approved through a sucessfully executed DAO proposal and that contains the details of a token transfer (either ICRC or ICP) to be executed by the ICP Treasury canister.
getNextICPMessageIdnoneit dependsReturns the number of messages approved through sucessfully executed DAO proposals. This functiton is used internally by the module, but also by the Chain Fusion Treasury Hub canister when calling ‘icp_execute_last_message’
[internal functions]it dependsit dependsVarious functions used for configuring and utilizing the module by the DAO.

Chain Fusion Treasury Hub Module (Q DAO Side)

FunctionInputCalled byExplanation
setDestinationChainDatastring (chain); address (treasury contract)DAOVoting ContractConfigures the DAO module to utilize the treasury contract address for a specific foreign chain as provided. It also provides the information for setting up the Chain Fusion Treasury Hub canister on ICP. The function only needs to be called once for every foreign-chain treasury during configuration. It can only be called by the DAO after a successful proposal.
sendNativeEVMaddress (recipient); unit (amount); string (chain)DAOVoting ContractProvides all relevant information for building a transaction to call the foreign-chain treasury from the Chain Fusion Treasury Hub canister and transfer the foreign-chain’s native token from the foreign-chain treasury. Hence this function takes the address of the recipient on the foreign- chain, the amount to be sent and the identifier of the destination chain used when calling ‘setDestinationChainAddress’. When defining the amount, pay attention to the native token’s decimals (18 for ETH) and add sufficient trailing zeros. This function can only be called by the DAO after a successful proposal.
sendERC20EVMAddress (token); address (recipient); unit (amount); string (chain)DAOVoting ContractProvides all relevant information for building a transaction to call the foreign-chain treasury from the Chain Fusion Treasury Hub canister and transfer a specific ERC20 token from the foreign-chain treasury. Hence this function takes the addresses of the desired token and of the recipient on the foreign-chain, the amount to be sent and the identifier of the destination chain used when calling ‘setDestinationChainAddress’. When defining the amount, pay attention to the native token’s decimals (18 for ETH) and add sufficient trailing zeros. This function can only be called by the DAO after a successful proposal.
getEVMMessageuint256 (messageId_)Chain Fusion Treasury Hub (canister)Provides a message that was approved through a sucessfully executed DAO proposal and that contains the details of a transaction to be executed by the Chain Fusion Treasury Hub canister for transferring funds from the foreign-chain treasury.
getNextEVMMessageIdnoneit dependsReturns the number of messages approved by the DAO. It is used internally by the module, but also by the Chain Fusion Treasury Hub canister when calling ‘evm_execute_last_message’
[internal functions]it dependsit dependsVarious functions used for configuring and utilizing the module by the DAO.

Backend Canisters

As mentioned above, this documentation introduces two Archetypes, the ICP Treasury and the Chain Fusion Treasury Hub . For improved readability, the tables below are structured to first discuss the functions which are unique to the respective canister. A table of functions that are implemented on both canisters is provided at the end of this section.

Unique to ICP Treasury

FunctionInputCalled ByExplanation
icp_execute_last_messagenoneanyoneRetrieves the last message that was approved by the DAO through an ICP Treasury Module Vote and executes it on ICP according to the details provided. Depending on the function called by the module and its input, the execution triggers a transfer of the defined amount of ICP tokens or another ICRC token held by the ICP Treasury canister to the recipient provided. It is also used when (re-)configuring the canister through the DAO.
icp_execute_messagenatanyoneExecutes the same type of message, but instead of retrieving the last message, it executes a dedicated message, as provided by the input parameter. This is relevant, when multiple ICP Treasury Module Vote proposals have been passed and executed simultaneously on Q, but have not yet been executed on ICP.
                                                                                                                           |

Unique to Chain Fusion Treasury Hub canister

FunctionInputCalled ByExplanation
evm_execute_last_messagenoneanyoneRetrieves the last message that was approved by the DAO through a Chain Fusion Treasury Hub Module Vote and executes it on the foreign-chain according to the details provided. Depending on the function called by the module and its input, the execution triggers the foreign-chain treasury to transfer of the defined amount of native tokens or of the defined ERC20 token held by the foreign-chain treasury to the recipient provided. t is also used when (re-)configuring the canister through the DAO.
evm_execute_messagenatanyoneExecutes the same type of message as above, but instead of retrieving the last message, it executes a dedicated message, as provided by the input parameter. This is relevant, when multiple Chain Fusion Treasury Hub Module Vote proposals have been passed and executed simultaneously.
eth_addressnoneanyoneReturns the canister’s EVM address. It is used to call the transfer function on the foreign-chain treasury. The user needs to know this address to set up the foreign-chain treasury and to fund it with gas tokens for transaction fees on the foreign-chain.
sync_foreign_chain_dataText (chain)anyoneConfigures the canister to add a foreign-chain treasury, as identified by the chain name provided. New treasuries can only be added after a sucessful proposal in the DAO, which calls ‘setDestinationChainData’ on Q. In the DAO proposal, the corresponding RPC of the foreign-chain and the address of the treasury contract are provided.
get_foreign_chain_id_datatextanyoneReturns the numeric chainID linked to a specific chain name as set when calling ‘set_foreign_chain_data'.
get_foreign_rpc_datatextanyoneReturns the RPC URL linked to a specific chain name as set when calling ‘set_foreign_chain_data'.
is_evm_message_executednatanyoneUtility function that is used to check if a message with a specific ID has already been executed.

Common functions for both canisters

  • [!] Note: the functions callable by the 'canister owner' are available to set up the canister. Ownership should be revoked after setup.
FunctionInputCalled ByExplanation
get_canister_rpcsnoneanyoneReturns a list of the RPCs used to verify messages from the DAO module to the respective canister.
remove_existing_rpctextonly canister ownerAllows removing individual RPCs.
get_current_module_addressnoneanyoneReturns the address of the DAO Module on Q that the respective canister is configured with.
get_canister_ownersnoneanyoneReturns a list of principals which are privileged to configure the canister.
add_new_ownerprincipalonly canister ownerAllows adding new principals, privileged to configure the canister (to be revoked after configuration phase).
remove_existing_ownerprincipalonly canister ownerAllows removing principals from being privileged to configure the canister.
get_account_identifier_from_principalprincipalanyoneUtility function which returns the account identifier to a given principal.
get_canister_principalnoneanyoneUtility function which returns the canisters principal identifier.
get_canister_identifiernoneanyoneUtility function which returns the canisters identifier.
update_current_module_addressnoneanyoneUpdates the address of which DAO module can control the canister. This enables a migration of the Treasury or Hub from one DAO module to another, or even to a completely new DAO. This function can only be sucessfully after a successful DAO Proposal on the existing DAO module (Calling the setDestinationChainData funciton on Q)

Treasury contracts on the foreign-chains

The contract on the foreign chain is configured to only handle and execute the transactions provided by the DAO through the Chain Fusion Treasury Hub. In the Treasury case, this is limited to the transfer of funds, either in the foreign-chain's native token, or ERC-20 tokens.

Other user Facing DAO Functions of (on Q)

Besides the components unique to the CGM, this documentation would be incomplete without addressing the role of a DAO's system smart contracts. Below is a selected list of functions which are called directly by the end-user (DAO member) when using the CGM through their DAO:

FunctionInputExplanationApplicable Smart Contract
approveaddress (_spender); uint256 (_value)Approve a transfer of DAO Tokens to the DAO Vault.DAO Token
depositERC20/ [or depositNFT]address (tokenAddress_); uint256 (amount_)/ [or uint256 tokenId_]Transfer DAO Tokens to the DAO Vault. This gives the voting power within the DAO to the user and allows them to create and vote on proposals.DAO Vault
createProposalstring (situation_), string (remark_), bytes (callData_)In this case this will be creating an "ICP Treasury Module Voting" or “Chain Fusion Treasury Hub Module Voting “(situation_), with a description for DAO Members to understand the proposal (remark_) and the necessary call data to call the respective transfer function with the correct input (callData_). The call data contains the information which function to call, and the input parameters like token identifier, recipient address and the amount to transfer.DAOVoting Contract
voteFor (or voteAgainst)uint256 (_proposalId)Vote on a specific proposal. In this case the ICP Treasury Module Voting or Chain Fusion Treasury Hub Module Voting.DAOVoting Contract
executeProposaluint256 (_proposalId)Execute the Proposal (if successful) and call the ICP Treasury Module or Chain Fusion Treasury Hub Module (via the Voting Contract).DAOVoting Contract