Skip to content

Latest commit

 

History

History

governance

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

MultiversX Governance Smart Contract

This contract is used to manage cross-chain governance proposals. It is built on top of the CGP (Cross-chain Gateway Protocol).

It is based on the Axelar Service Governance Solidity implementation available at the time of writing: (v6.0.4)

For a general design of the contract check this document: https://github.com/axelarnetwork/axelar-gmp-sdk-solidity/blob/main/contracts/governance/DESIGN.md

You can also check here to see how it broadly works: https://bright-ambert-2bd.notion.site/Axelar-Gateway-Governance-EXTERNAL-3242da44ef7a4b87a3e0da0b7737ff3f

Deployment of Governance contract & general information

This contract will be used instead of a multisig to manage the Gateway contract.

  • Governance contract will be owner of Gateway contract and itself (similar to multisig)
  • upgrading of Gateway will be done through this contract
  • it is based on Axelar General Message Passing, Axelar Validators need to first approve an execute call for this contract which comes from a trusted Governance Chain (the Axelar Network chain)
  • after a proposal is approved, there is at least a minimum time delay so validators can action and cancel the proposal if something is not right
  • after the time delay has passed, anyone can call the executeProposal with the appropriate arguments to actually execute the proposal

Important endpoints

The most used endpoints are:

  • executeProposal (target, call_data, native_value) - can be called by anyone (most likely a Relayer) to execute a proposal after it was approved
  • executeOperatorProposal (target, call_data, native_value) - can be called by an operator (most likely a Multisig contract) to execute operator proposals, which can be executed without timelock
  • execute (source_chain, message_id, source_address, payload) - can be called only cross-chain from the source chain and source contract configured on deployment

These endpoints look like this:

#[payable("*")]
#[endpoint(executeProposal)]
fn execute_proposal(
    &self,
    target: ManagedAddress,
    call_data: ManagedBuffer,
    native_value: BigUint,
);
#[payable("*")]
#[endpoint(executeOperatorProposal)]
fn execute_operator_proposal(
    &self,
    target: ManagedAddress,
    call_data: ManagedBuffer,
    native_value: BigUint,
);

Where call_data is of type DecodedCallData as top encoded bytes:

#[derive(TypeAbi, TopDecode)]
pub struct DecodedCallData<M: ManagedTypeApi> {
    pub endpoint_name: ManagedBuffer<M>,
    pub arguments: ManagedVec<M, ManagedBuffer<M>>,
    pub min_gas_limit: u64,
}

This contains all the information needed to Async call the target contract on MultiversX.

The execute endpoint looks like this:

#[endpoint]
fn execute(
    &self,
    source_chain: ManagedBuffer,
    message_id: ManagedBuffer,
    source_address: ManagedBuffer,
    payload: ManagedBuffer,
);

Where payload is of type ExecutePayload as top encoded bytes:

#[derive(TypeAbi, TopDecode)]
pub struct ExecutePayload<M: ManagedTypeApi> {
    pub command: GovernanceCommand,
    pub target: ManagedAddress<M>,
    pub call_data: ManagedBuffer<M>,
    pub native_value: BigUint<M>,
    pub eta: u64,
}

And GovernanceCommand is an enum currently with 2 types of commands supported:

#[derive(TypeAbi, TopDecode, NestedDecode)]
pub enum ServiceGovernanceCommand {
    ScheduleTimeLockProposal,
    CancelTimeLockProposal,
    ApproveOperatorProposal,
    CancelOperatorApproval,
}