Proposta Cross-Chain treasury management
Este guia explica o processo de criação e execução de uma proposta de governança cross-chain para criar tokens W tanto para as tesourarias da Optimism quanto da Arbitrum. Neste tutorial, abordaremos como criar uma proposta na cadeia central (Ethereum Mainnet), coletar votos das cadeias secundárias (Optimism e Arbitrum), agregar os votos e executar a proposta.
Criar uma Proposta
O primeiro passo é criar a proposta na cadeia central, que neste caso é a Ethereum Mainnet. A proposta conterá instruções para criar 10 tokens W para a tesouraria da Optimism e 15 ETH para a tesouraria da Arbitrum.
No trecho de código a seguir, inicializamos a proposta com duas transações, cada uma direcionando o contrato Message Dispatcher do Hub. Essas transações irão relatar as ações de governança para as respectivas cadeias secundárias via Wormhole.
Ações principais:
Definir os alvos da proposta (duas transações para o Message Dispatcher).
Definir os valores de cada transação (neste caso, ambos são 0, pois não estamos transferindo ETH nativo).
Codificar o calldata para criar 10 tokens W na Optimism e enviar 15 ETH para a Arbitrum.
Finalmente, submeter a proposta ao contrato HubGovernor.
HubGovernor governor = HubGovernor(GOVERNOR_ADDRESS);
// Preparar os detalhes da proposta
address;
targets[0] = HUB_MESSAGE_DISPATCHER_ADDRESS;
targets[1] = HUB_MESSAGE_DISPATCHER_ADDRESS;
uint256;
values[0] = 0;
values[1] = 0;
bytes;
// Preparar mensagem para Optimism para criar 10 tokens W
calldatas[0] = abi.encodeWithSignature(
"dispatch(bytes)",
abi.encode(
OPTIMISM_WORMHOLE_CHAIN_ID,
[OPTIMISM_WORMHOLE_TREASURY_ADDRESS],
[uint256(10 ether)],
[hex"0x40c10f19000000000000000000000000b0ffa8000886e57f86dd5264b9582b2Ad87b2b910000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000"]
)
);
// Preparar mensagem para Arbitrum para receber 15 ETH
calldatas[1] = abi.encodeWithSignature(
"dispatch(bytes)",
abi.encode(
ARBITRUM_WORMHOLE_CHAIN_ID,
[ARBITRUM_WORMHOLE_TREASURY_ADDRESS],
[uint256(15 ether)],
[hex"0x40c10f19000000000000000000000000b0ffa8000886e57f86dd5264b9582b2ad87b2b910000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000"]
)
);
string memory description = "Criar 10 W para a tesouraria da Optimism e 15 W para a tesouraria da Arbitrum via Wormhole";
// Criar a proposta
uint256 proposalId = governor.propose(
targets, values, calldatas, description
);
Esse código define as transações necessárias para enviar tokens para as tesourarias da Optimism e Arbitrum, utilizando o Wormhole para garantir a transferência cross-chain. A proposta é então submetida ao contrato HubGovernor para avaliação e execução.
Parâmetros
GOVERNOR_ADDRESS address
O endereço do contrato HubGovernor na Ethereum Mainnet.
targets address[]
Um array que especifica os endereços que irão receber as ações da proposta. Aqui, ambos estão configurados para o HUB_MESSAGE_DISPATCHER_ADDRESS.
values uint256[]
Um array contendo o valor de cada transação (em Wei). Neste caso, ambos estão configurados para zero, pois nenhum ETH está sendo transferido.
calldatas bytes[]
O calldata da proposta. Estes são contratos codificados contendo instruções de despacho cross-chain para a criação de tokens e envio de ETH. O calldata especifica a criação de 10 tokens W para a tesouraria da Optimism e o envio de 15 ETH para a tesouraria da Arbitrum.
description string
Uma descrição da proposta, destacando a intenção de criar tokens para a Optimism e enviar ETH para a Arbitrum.
Retorno
proposalId
uint256
The ID of the newly created proposal on the hub chain.
Votação na Proposta via Spoke
Após a criação da proposta na cadeia central (hub), as partes interessadas podem votar nas cadeias secundárias (spoke). Este trecho demonstra como conectar-se a uma cadeia spoke e registrar um voto para a proposta. O poder de voto (peso) é calculado com base nas participações de tokens de cada parte interessada na cadeia spoke.
Ações principais:
Conectar-se ao contrato SpokeVoteAggregator na cadeia spoke. Esse contrato agrega os votos das cadeias secundárias e os retransmite para a cadeia central.
Registrar um voto em apoio à proposta.
// Conectar-se ao contrato SpokeVoteAggregator da cadeia desejada
SpokeVoteAggregator voteAggregator = SpokeVoteAggregator(VOTE_AGGREGATOR_ADDRESS);
// Registrar um voto
uint8 support = 1; // 1 para apoiar, 0 para se opor
uint256 weight = voteAggregator.castVote(proposalId, support);
Parâmetros
VOTE_AGGREGATOR_ADDRESS
address: O endereço do contratoSpokeVoteAggregato
r na cadeia spoke (Optimism ou Arbitrum).proposalId
support uint8: O voto sendo registrado (1 para apoiar a proposta, 0 para se opor).
Retornos weight uint256: O peso do voto, determinado pelas holdings de tokens do votante na cadeia spoke.
Agregação de Votos
No processo de fundo, os votos emitidos nas cadeias spoke são agregados e enviados de volta para a cadeia hub para a contagem final. Isso é normalmente gerido off-chain por um serviço "crank turner", que consulta periodicamente o status dos votos e atualiza a cadeia hub.
Ações principais:
Agregar votos de diferentes cadeias e enviá-los para a cadeia hub para a contagem.
// Agregar votos enviados para o Hub (isso geralmente seria feito por um "crank turner" off-chain)
hubVotePool.crossChainVote(queryResponseRaw, signatures);
Parâmetros
queryResponseRaw (bytes)
: Os dados brutos dos votos das cadeias spoke.signatures (bytes)
: Assinaturas criptográficas que verificam a validade dos votos das cadeias spoke.
Executar Proposta e Enviar Mensagens Cross-Chain
Após a proposta ser aprovada e os votos contados, o próximo passo é executar a proposta. O contrato HubGovernor enviará as mensagens cross-chain para as cadeias spoke, onde os respectivos tesouros receberão os tokens.
Ações principais:
Executar a proposta após o término do perÃodo de votação e aprovação da proposta.
A função execute finaliza a execução da proposta ao enviar as ações de governança cross-chain. O descriptionHash garante que a proposta executada corresponda àquela que foi votada.
HubGovernor governor = HubGovernor(GOVERNOR_ADDRESS);
// Execução padrão com timelock
governor.execute(targets, values, calldatas, descriptionHash);
Parâmetros
governor HubGovernor A instância do contrato HubGovernor.
targets address[] Um array contendo os endereços de destino para as transações da proposta (neste caso, o HUB_MESSAGE_DISPATCHER_ADDRESS para ambos).
values uint256[] Um array de valores (em Wei) associados a cada transação (ambos são zero neste caso).
calldatas bytes[] Os dados da transação codificados para enviar as ações de governança (por exemplo, minting de tokens e transferência de ETH).
descriptionHash bytes32 Um hash da descrição da proposta, usado para verificar a proposta antes da execução.
Retornos
Não há retorno direto, mas a execução dessa função finaliza as ações de governança cross-chain, enviando as mensagens codificadas via Wormhole para as cadeias spoke.
Uma vez que a proposta seja executada, as mensagens codificadas serão enviadas via Wormhole para as cadeias spoke, onde os tesouros do Optimism e do Arbitrum receberão seus respectivos fundos.
Last updated