Alarme de ponte de cadeia cruzada: Como o Polygon impede a abertura da Caixa de Pandora

Analise profundamente a estrutura da rede Polygon, interoperabilidade e modo de transmissão de mensagens de cadeia cruzada e, em seguida, fale sobre os incidentes de segurança das vulnerabilidades Shuanghua.

1  Quem é o Polygon?

Polygon é o plano de expansão layer2 da Ethereum, sua visão é construir a Internet blockchain da Ethereum. O Polygon fornece uma estrutura geral que permite aos desenvolvedores usar a segurança do Ethereum para criar cadeias personalizadas e focadas em aplicativos e fornece uma rede interoperável, combinando vários esquemas de expansão, como zk rollup, PoS, etc. Entre eles, Polygon PoS é o esquema de expansão de capacidade mais maduro e conhecido no Polygon atualmente. Ele usa a cadeia lateral para o processamento de transações para melhorar a velocidade da transação e economizar o consumo de gás.A estrutura da rede inclui principalmente as seguintes três camadas:

Camada etéreo:

Uma série de contratos na Internet principal do Ethereum, incluindo principalmente contratos de Staking, Checkpoint e Recompensa, são responsáveis pelas funções de gerenciamento de penhor relacionadas aos direitos e interesses PoS, incluindo: fornecer a função de penhor do token nativo MATIC, para que qualquer pessoa que penhore o token possa se juntar ao sistema como verificador; Verificar que a transição da rede Polygon é recompensada com compromisso; Punir a dupla assinatura do verificador, o tempo de inatividade do verificador e outros atos ilegais; Salva o posto de controlo.

Piso Heimdall:

A camada de nó de verificação de prova de equidade, incluindo um grupo de nós PoS Heimdall, é responsável por enviar o ponto de verificação da rede Polygon para a rede principal Ethereum e monitorar um grupo de contratos de penhor implantados no Ethereum. O processo principal é o seguinte: em primeiro lugar, selecionar uma parte dos verificadores ativos no pool de verificadores como produtores de blocos, que serão responsáveis pela criação de blocos na camada Bor e pela sua difusão; Em seguida, de acordo com o checkpoint enviado pela Bor, verifique o hash raiz Merkle e anexe uma assinatura; Finalmente, o proponente será responsável por coletar as assinaturas de todos os verificadores no ponto de verificação designado. Se o número de assinaturas atingir mais de 2/3, o ponto de verificação será enviado no Ethereum.

Camada bor:

A camada de nó de saída inclui um grupo de produtores de blocos regularmente selecionados pelo comitê de verificador na camada Heimdall. Eles são um subconjunto de verificadores responsáveis por agregar transações na cadeia lateral do polígono e gerar blocos. Essa camada publicará periodicamente pontos de verificação na camada Heimdall, onde o ponto de verificação representa um instantâneo na cadeia Bor, como mostrado na figura a seguir.

2  Interoperabilidade dos polígonos

2.1 Ponto de controlo

O mecanismo de Checkpoint é um mecanismo para sincronizar os dados da camada Bor com Ethereum. Os dados sincronizados são um ponto de verificação, isto é, um instantâneo dos dados do bloco da camada Bor incluídos em um intervalo de ponto de verificação. O código fonte é o seguinte:

  • Proposta: O proponente também é selecionado pelo verificador. Tanto o produtor do bloco quanto o proponente são subconjuntos do verificador, e suas responsabilidades dependem do seu rácio de equidade em todo o pool.

  • RootHash: Merkle Hash gerado pelo bloco Bor entre StartBlock e EndBlock.

O seguinte é o pseudo código do valor RootHash gerado pelos blocos Bor numerados de 1 a n:

Para resumir, este valor é o valor hash raiz da árvore Merkel composto pelo número do bloco, a hora do carimbo de data e hora do bloco, o valor hash raiz da árvore de transação tx hash e o valor hash raiz da árvore de recebimento recebe hash no cabeçalho do bloco Bor.

AccountRootHash: Cada ponto de verificação precisa ser enviado para o Merkle Hash das informações relevantes da conta do verificador no Ethereum O valor hash de uma única informação de conta é calculado da seguinte forma:

A maneira de gerar AccountRootHash a partir do valor hash raiz da árvore Merkle da conta é a mesma que o valor RootHash.

2. 2 StateSync

StateSync refere-se à sincronização de dados Ethereum para a cadeia Polygon Matic, que é dividida principalmente nas seguintes etapas:

  • Primeiro, o contrato no Ethereum acionará StateSender A função syncState () no sol sincroniza o estado

  • A função syncState() emitirá um evento, da seguinte forma:

  • Todos os verificadores da camada Heimdall receberão o evento, e um deles empacotará a transação no bloco heimdall e a adicionará à lista de sincronização de status pendente;

  • O nó bor layer obterá a lista acima para ser sincronizada através da API e submetê-la ao contrato bor layer para processamento adicional da lógica de negócios.

2.3 Ponte de polígonos

O Polygon Bridge implementa um canal de cadeia cruzada bidirecional entre o Polygon e o Ethereum, permitindo que os usuários transfiram tokens entre duas plataformas de cadeia diferentes com mais facilidade, sem ameaças de terceiros e restrições de liquidez do mercado. Existem dois tipos de Polygon Bridge: PoS e Plasma. A transferência de ativos entre Polygon e Ethereum tem as seguintes semelhanças:

1) Primeiro, você precisa mapear o token no Ethereum para Polygon, como mostrado na figura a seguir:

2) Peg bidirecional também é adotado, a saber

  • a: Os ativos de tokens transferidos do Ethereum serão bloqueados no Ethereum primeiro, e o mesmo número de tokens mapeados será lançado no Polygon;

  • b: Para extrair ativos de token para Ethereum, você precisa gravar esses tokens de mapeamento no Polygon primeiro e, em seguida, desbloquear os ativos bloqueados no Ethereum;

A figura a seguir mostra a comparação entre PoS Bridge e Plasma Bridge:

Pode ser visto a partir da figura acima que, em termos de segurança, o PoS Bridge depende da segurança do conjunto de verificadores externos, enquanto o Plasma depende da segurança da cadeia principal do Ethereum. Ao mesmo tempo, quando os usuários transferem ativos de cadeia cruzada (como transferir tokens do Polygon para Ethereum), o PoS só precisa de um intervalo de ponto de verificação, cerca de 20 minutos a 3 horas; O Plasma precisa de um período de disputa e desafio de 7 dias. Ao mesmo tempo, o PoS suporta mais tokens padrão, enquanto o Plasma suporta apenas três tipos, incluindo ETH, ERC20 e ERC721.

3  Cross chain messaging PoS Bridge

A Ponte PoS inclui principalmente duas funções: Depósito e Levantamentos.Depósito refere-se à transferência de ativos dos usuários no Ethereum para o Polygon, e Retiradas refere-se à extração de ativos do Polygon para o Ethereum.

Depósito

A seguir está um exemplo de como Alice usa o PoS Bridge para enviar ativos de token de sua conta Ethereum para sua conta Polygon:

1. Se os ativos de token que você deseja transferir são ERC20, ERC721 e ERC1155, você precisa primeiro autorizar os tokens que deseja transferir através da função de aprovação. Como mostrado abaixo: autorize o número correspondente de tokens ao contrato erc20Predicate chamando o método de aprovação no contrato de token no Ethereum.

A função de aprovação tem dois parâmetros:

  • Gastador: o endereço de destino onde o usuário está autorizado a gastar tokens

  • Quantidade: O número de tokens que podem ser gastos

2. Depois que a transação de autorização acima é confirmada, o usuário bloqueia o token no contrato erc20Predicate no Ethereum chamando o método depositFor() do contrato RootChainManager. Aqui, se o tipo de ativo transferido for ETH, o depositEtherFor() é chamado. Os pormenores são os seguintes:

A função depositFor tem três parâmetros:

  • Usuário: o endereço do usuário para receber o token de depósito no Polygon

  • RootToken: o endereço de token na cadeia principal do Ethereum

  • DepósitoData: o número de tokens codificados pela ABI

O seguinte é o código específico da função depositFor no contrato RootChainManager:

De acordo com a análise do código fonte, esta função primeiro obtém o endereço do contrato de predicado correspondente ao token e, em seguida, chama sua função lockTokens() para bloquear o token no contrato. Finalmente_ StateSender irá chamar syncState () para sincronizar o estado. Esta função só pode ser chamada pelo remetente de estado definido pelo administrador.

3,StateSender. A função syncState() no sol enviará o evento StateSynchronized, especificamente:

O primeiro parâmetro é o índice de número de série do log, o segundo parâmetro é usado para verificar se o chamador é um endereço de contrato legal registrado e o terceiro parâmetro são os dados a serem sincronizados. A transação é adicionada ao bloco Heimdall e à lista de sincronização de status pendente.

4. Depois que o nó bor na cadeia Polygon Matic obtiver o evento StateSynchronized na lista de sincronização de estado através da API, o contrato ChildChainManager na cadeia chamará a função onStateReceive(), que é usada para receber os dados de sincronização carregados do Ethereum, e executará a próxima etapa de acordo com o tipo de lógica de negócios do mesmo estado:

Dados: inclui syncType do tipo bytes32 e syncData do tipo bytes. Entre eles, syncType representa o tipo de negócio, incluindo depósito e mapeamento de tokens; Quando syncType está mapeando, syncData é o endereço rootToken codificado, o endereço childToken e o tipo bytes32 tokenType; Quando syncType é depósito, syncData é o endereço de usuário codificado, endereço rootToken e depositData do tipo bytes. O depositData em REC20 é a quantidade, e ERC721 refere-se ao tokenId.

5. Porque este é o negócio do Depósito, o_ A função syncDepósito (). Esta função irá primeiro decodificar syncData no formato correspondente para obter o rootToken correspondente, endereço de usuário e depositData. Em seguida, verifique se o rootToken tem um token de mapeamento correspondente, childToken, no polígono. Se sim, chame a função deposit() do childToken.

6. Aqui tomamos o contrato de token do ERC20 como um exemplo para introduzir como descartar o contrato de token de mapeamento. Esta função transfere o número de tokens correspondentes ao mint para a conta de usuário.

Esta função tem dois parâmetros:

  • Usuário: o endereço do usuário que está depositando

  • DepósitoData: montante codificado com ABI

Retiradas

O seguinte é um exemplo de como Alice usa PoS Bridge para retirar os fundos depositados em sua conta Polygon para a conta Ethereum:

1. Quando os usuários retiram, eles precisam primeiro queimar o número correspondente de tokens mapeados na cadeia Polígono chamando a função Retirar () que mapeia o contrato de token.

Retirar contém apenas um parâmetro: o número de tokens a serem gravados. A função de retirada () no contrato de token correspondente é a seguinte:

2. A transação acima será incluída no ponto de verificação após cerca de 20 minutos a 3 horas, e a pessoa verificada irá enviá-la para Ethereum.

3. Uma vez que a transação é adicionada ao checkpoint e submetida ao Ethereum, a função exit () do contrato RootChainManager no Ethereum será chamada. Esta função confirmará a validade da transação de retirada no Polygon verificando o conteúdo do checkpoint enviado e acionará o contrato Predicate correspondente para desbloquear o token depositado pelo usuário.

Entre eles, Prova passada para a função prova que inputData inclui os seguintes dados:

  • HeaderNumber: header of checkpoint block containing withdraw transaction

  • BlockProof: prove que o cabeçalho do bloco na sub-cadeia é o nó da folha da raiz merkle enviada

  • BlockNumber: o número do bloco que contém a transação de retirada na sub-cadeia

  • BlockTime: block timestamp of withdraw transaction

  • TxRoot: valor raiz da árvore de transacções de bloco

  • ReceiptRoot: valor raiz da árvore de recibos de bloco

  • Recepção: recepção da operação de retirada

  • ReceiptProof: Certificado Merck de recebimento de transação de retirada

  • BranchMask: o caminho de recebimento de 32 bits na árvore de recebimento

  • ReceiptLogIndex: o índice de log lido a partir da árvore de recebimento

O seguinte é a lógica central da função, que inclui principalmente três partes: a primeira parte é verificar a validade do recibo de transação de retirada, a segunda parte é verificar se o ponto de verificação contém o bloco de transação, e a terceira parte é chamar a função exitTokens() no contrato de predicado para enviar o token bloqueado para o usuário.

4. Tome o contrato ERC20Predicate como exemplo, ou seja, depois de decodificar o número de tokens para o receptor, remetente e remetente do log, o número dado de tokens será enviado ao usuário.

De acordo com a análise de código fonte do processo de mensagens de cadeia cruzada da PoS Bridge, as chamadas de função de todo o processo só podem ser chamadas pela função designada pelo verificador, de modo que a segurança de cadeia cruzada é garantida apenas pelo PoS (notário).

4  Mensagens em cadeia cruzada - Ponte do Plasma

O Plasma Bridge também inclui duas funções: Depósito e Levantamentos. O processo específico é mostrado na figura a seguir:

Polygon Plasma é ligeiramente diferente da implementação MVP Bitcoin Plasma introduzida no primeiro artigo da nossa série de pontes de cadeia cruzada, que usa principalmente o Plasma MoreVP baseado no modelo de conta. Comparado com o Plasma, este algoritmo é melhorado principalmente na parte de retirada.

Como a transmissão de token do ERC20 e ERC721 é realizada através de um log de eventos semelhante ao Bitcoin UTXO, vamos primeiro introduzir este evento:

  • Entrada 1: saldo da conta do remetente antes da transferência

  • Entrada 2: saldo da conta do destinatário antes da transferência

  • Resultado1: saldo da conta do remetente após a transferência

  • Resultado2: saldo da conta do destinatário após a transferência

Em segundo lugar, uma vez que os blocos MVP Plasma originais são gerados por um único operador ou alguns produtores de blocos, existem dois cenários de ataque no Polygon:

Os operadores fazem o mal.

Artigo anterior(《Revisão de segurança de pontes de cadeia cruzada: Que inspiração nos dá o roubo descentralizado Nomad?()É mencionado que quando a transação de um usuário é empacotada como um bloco Plasma pelo Operador, há um problema da indisponibilidade dos dados fora da cadeia. Portanto, se o usuário sair de uma transação mais antiga durante uma transação de saída, o operador pode usar sua transação mais recente para desafiar o usuário, e o desafio terá sucesso. Ao mesmo tempo, uma vez que o mecanismo de ponto de verificação PoS é usado no Plasma, se o operador colidir com o verificador para fazer o mal, ele pode até forjar algumas transições de estado e submetê-las ao Ethereum.

Os usuários fazem o mal:

Depois que o usuário inicia uma transação de saída, ele/ela continua a gastar tokens no Polygon, semelhante às flores duplas de cadeia cruzada.

Resumindo, o algoritmo Plasma MoreVp da Polygon usa outro algoritmo para calcular a prioridade de saída, ou seja, a saída da transação mais recente. Este método usa um evento LogTransfer semelhante ao UTXO. Desde que as transações legítimas do usuário usem a entrada correta1 e a entrada correta2, mesmo que algumas transações maliciosas do Operador sejam empacotadas antes da transação do usuário, a transação do usuário pode ser processada corretamente porque ela só vem da entrada válida. Os pseudocódigos relevantes são os seguintes:

Depósito

O seguinte é um exemplo de como Alice usa o Plasma Bridge para enviar ativos de token de sua conta Ethereum para sua conta Polygon:

1. Primeiro, o usuário também precisa autorizar os ativos do token a serem transferidos para o depositManager do contrato do Polygon na cadeia principal (Ethereum) através da função de aprovação.

2. Após a transação de autorização é confirmada, o usuário chama erc20token A função deposit() aciona a função depositERC20ForUser() do contrato depositManager e armazena os ativos de token ERC20 do usuário.

3. Quando a rede principal Ethereum confirmar a transação de depósito, ela criará um bloco contendo apenas essa transação e enviá-la para o contrato childChain na rede Polygon usando o mecanismo de sincronização de estado. Minte a mesma quantidade de moeda mapeada e deposite-a na conta do usuário no Polygon.

Nota: De acordo com a análise do código fonte do contrato childChain, o Plasma suporta apenas três tipos, incluindo ETH, ERC20 e ERC721.

Retirar

Quando os usuários quiserem usar o Plasma bridge para extrair ativos do Polygon para Ethereum, eles passarão pelas seguintes etapas:

1. O usuário pode queimar os ativos de token mapeados na cadeia Polygon chamando a função Retirar () de moedas mapeadas no Polygon:

Você também pode chamar a implementação da interface withdraStart() do Plasma Client no Polygon.

2. Os usuários podem chamar a função startExitWithBurntTokens() no contrato ERC20Predicate, que primeiro chama o RetirarManager VerifyInclusion() verifica se o ponto de verificação contém a transação de retirada e o recibo correspondente. O código é o seguinte:

Depois que a verificação for passada, o RetirarManager será chamado AddExitToQueue() insere-os na fila de mensagens por prioridade:

Finalmente, addExitToQueue() chama_ AddExitToQueue() lança um NFT como um voucher de reembolso:

3. Período de desafio de 7 dias para os usuários

4. Após o período de desafio ser concluído, você pode ligar para o RetirarManager A função processExits() envia tokens para o usuário.

Esta função é dividida principalmente em duas etapas: primeiro, confirme se a transação de retirada na fila de mensagens passou o período de desafio de 7 dias. Se ela passou o período de desafio, remova a transação da fila:

Em seguida, julgue se o voucher de reembolso NFT foi excluído durante o período de contestação. Se não, destrua o NFT e devolva o ativo correspondente ao usuário:

5  Vulnerabilidade de Dupla Flor da Ponte Plasma de Polígono

Em 5 de outubro de 2021, Gerhard Wagner, o chapéu branco, apresentou uma vulnerabilidade de Polígono, o que pode levar a um ataque de flor dupla, envolvendo um valor de 850 milhões de dólares. Portanto, o chapéu branco recebeu uma recompensa oficial de vulnerabilidade de Polígono de 2000000 dólares.

Na introdução do Plasma Bridge acima, sabemos que um processo completo de transação de Retirada é:

  1. O usuário inicia uma transação de Retirada no Polygon, que gravará o token do usuário no Polygon;

  2. Após um intervalo de checkpoint (cerca de 30 minutos), aguarde que a transação de retirada seja incluída no checkpoint;

  3. Neste momento, o usuário chama startExitWithBurntTokens() no contrato ERC20PredicateBurnOnly para verificar se o checkpoint contém uma transação de gravação;

  4. Se a verificação for aprovada, um voucher de reembolso NFT será falsificado e enviado ao usuário

  5. O usuário espera por um período de desafio de 7 dias

  6. Gestor de Retiradas de Chamadas ProcessExits() destrói o NFT e devolve ao usuário

Nota: Para evitar a repetição da transação (ataque de flor dupla), a Polygon usa NFT como voucher de reembolso para identificar exclusivamente uma transação de Retirada. No entanto, devido à falha de geração de ID do NFT, os invasores podem construir parâmetros para gerar vários NFTs com IDs diferentes usando a mesma transação de Retirada válida e, em seguida, usar esses NFTs para transações de reembolso, realizando assim "ataque de flor dupla".

Como gerar NFT é descrito em detalhes abaixo:

1. A partir da análise de código fonte acima, addExitToQueue() irá chamar_ AddExitToQueue () transmitindo um NFT:

Pode ser visto a partir da análise de transferência de parâmetros que exitid=priority, então o ID do NFT é gerado mudando a prioridade de idade deixada um bit na Plasma Bridge.

2. De acordo com a análise de código fonte acima, a idade é o RetirarManager O valor de retorno da função verifyInclusion (). Esta função irá verificar primeiro a validade da transacção de retirada. Se a verificação for passada, será gerada a idade correspondente. Na lógica de verificação, o valor branchMaskBytes decodificado a partir dos dados do parâmetro controlável é usado:

Este valor também é usado ao gerar idade:

3. MerklePatriciaProof que rastreia chamadas na lógica de validação de transação A função verify () é encontrada para call_ GetNibbleArray () transcode branchMaskBytes:

4. Continue a acompanhar a função de decodificação. A função descarta alguns valores ao transcodificar branchMaskBytes. Esta forma de perder valores fará com que diferentes valores sejam transcodificados para obter o mesmo valor de decodificação. Especificamente, se o primeiro bit hexadecimal (meio byte) do valor codificado hp de entrada b for 1 ou 3, o segundo bit hexadecimal será analisado. Caso contrário, o primeiro byte é ignorado.

Se um invasor constrói um parâmetro branchMaskBytes para que o primeiro bit hexadecimal não seja igual a 1 e 3, há 14 * 16=224 maneiras de obter o mesmo valor transcodificado.

O processo de ataque específico é o seguinte:

  • Depósitoe uma grande quantidade de ETH/tokens no Polygon via Polygon Plasma

  • Inicie uma transação de retirada no Polygon e aguarde um período de desafio de 7 dias

  • Modifique o primeiro byte do parâmetro branchMaskBytes na transação de retirada (a mesma transação válida pode ser reenviada por até 223 vezes) e inicie a transação Retirar repetidamente

Resumindo, essa vulnerabilidade se deve principalmente a um problema no desenho do algoritmo ID do NFT que gera o voucher de reembolso para evitar repetição, o que leva a diferentes NFTs gerados a partir da mesma transação de reembolso, resultando em um ataque de flor dupla. Foi provado que o primeiro byte da máscara de ramificação codificada deve ser sempre 0x00. A correção é verificar se o primeiro byte da máscara de ramificação codificada é 0x00 e não tratá-lo como uma máscara incorreta.

Título Original: Research on Safety of Chain Bridge (III) | Polygon Warrior Polygon Safety Dialysis, How to Prevent the Opening of Pandora's Box

Escrito por: Chengdu Lian'an

Fonte: Foresight News