7 de janeiro de 2022
Introdução
UMA é uma plataforma que permite aos usuários celebrar contratos financeiros com confiança minimizada no blockchain Ethereum. Nós auditamos anteriormente o oráculo descentralizado, um modelo específico de contrato financeiro, algumas solicitações pull ad hoc, o modelo multipartidário perpétuo, várias solicitações pull incrementais em um envolvimento mais longo e a ponte segurada.
Nesta auditoria, revisamos uma nova proposta de contrato de governança, um mecanismo para estender o ecossistema UMA em múltiplas cadeias, um mecanismo para distribuir recompensas aos detentores de tokens ERC721 de acordo com uma especificação fora da cadeia e uma atualização da ponte segurada para apoiar WETH na cadeia do Otimismo.
O commit auditado é 0c4cea3c3d5e48da6f8984b8ba3afdfea4ce47cc
e o escopo inclui os seguintes contratos:
oracle/implementation/Proposer.sol
cross-chain-oracle/*
(excluindo contratos de teste e Polygon)financial-templates/optimistic-rewarder/*
(excluindo contratos de teste)
Também revisamos as alterações nos arquivos de solidez em Solicitação pull 3611.
Todo código externo e dependências de contrato foram assumidas para funcionar conforme documentado.
Visão geral do sistema
A corrente Governance
O contrato permite que a Risk Labs Foundation proponha novas ações de governança que possam ser ratificadas pelos detentores do token UMA. O novo Proposer
O contrato pretende assumir o papel de proponente, permitindo que qualquer pessoa faça novas propostas, desde que forneça um vínculo que será sacrificado caso a proposta fracasse. Não há incentivo específico para apresentação de propostas. A intenção é garantir que apenas serão propostas as acções que têm grande probabilidade de serem aceites.
O novo mecanismo cross-chain permite que a proposta de governança seja passada da rede principal Ethereum para as cadeias Optimism e Arbitrum. Desta forma, o mecanismo de governança UMA na camada 1 pode ser usado para governar contratos UMA nas cadeias de camada 2 suportadas. O mecanismo também permite que solicitações de preços e resoluções sejam encaminhadas entre as camadas, de modo que os Oráculos Otimistas nas cadeias da camada 2 possam ser protegidos pelo Mecanismo de Verificação de Dados da rede principal da mesma forma que o Oráculo Otimista da camada 1 é protegido pelo DVM.
É importante notar que essas mensagens são enviadas utilizando a mecânica de ponte nativa, o que significa que são limitadas pelas características das cadeias relevantes da camada 2. Em particular, as mensagens da camada 2 para a camada 1 podem levar uma semana ou mais para transitar pela ponte. Além disso, o mecanismo de governança UMA suporta propostas que incluem múltiplas transações ordenadas, mas isto apenas restringe a ordem em que podem ser adicionadas à ponte. É possível que algumas dessas transações sejam executadas em uma ordem diferente, ou nem sejam executadas, na camada 2.
O contrato do Optimistic Rewarder simplesmente emite tokens ERC721 para qualquer pessoa que os solicite. Também permite que qualquer pessoa associe dados arbitrários a qualquer token e deposite vários tokens ERC20 para serem distribuídos como recompensas. A interpretação dos dados arbitrários e a distribuição esperada de recompensas entre os detentores de tokens são determinadas usando um procedimento fora da cadeia não especificado. Qualquer um pode alegar que um token ERC721 específico deve um conjunto de recompensas se estiver disposto a depositar um título. O mecanismo padrão da Optimistic Oracle é usado para permitir que outra pessoa conteste a reivindicação, que será resolvida pelo DVM. As reivindicações que não são contestadas a tempo são consideradas válidas e o contrato distribui as recompensas de acordo. A única restrição (para simplificar a contabilidade) é que o token Oracle Bond não pode ser usado como token de recompensa.
Por último, PR3611 modifica o mecanismo de ponte segurada para evitar o envio de WETH através da ponte de token Optimism, que não é suportada. Em vez disso, qualquer L2 WETH depositado na caixa de depósito do Optimism é desembrulhado para L2 ETH antes de transitar pela ponte. Na camada 1, o ETH é convertido em WETH antes de ser encaminhado para o pool de pontes WETH.
Gravidade crítica
[C01] Não é possível contestar recompensa inválida
Ao contestar um pedido de recompensa, o OptimisticRewardBase
contrato primeiro aciona uma proposta na SkinnyOptimisticOracle
e depois contesta essa proposta. No entanto, a proposta define o tempo de expiração como uma compensação do tempo atual (disputa), enquanto a disputa especifica a expiração como uma compensação a partir do momento da solicitação de recompensa original. Na maioria dos casos, esta discrepância impedirá que o oráculo identifique a proposta a ser contestada, o que significa que disputas válidas não serão processadas e solicitações de recompensa inválidas serão aceitas.
Considere atualizar a invocação de disputa para especificar corretamente a proposta a ser contestada.
Update: Corrigido a partir do commit 9e15557
in PR3690.
[C02] Resolver propostas repetidamente
A resolveProposal
função do Proposer
contract simplesmente valida que o oráculo resolveu, mas não verifica se o título foi distribuído. Isso significa que a mesma proposta pode ser resolvida várias vezes, resultando em pagamentos duplicados de títulos. Considere sinalizar ou excluir propostas existentes quando elas forem resolvidas.
Update: Corrigido a partir do commit b152718
in PR3689.
Alta gravidade
Nenhum.
Gravidade média
[M01] Parâmetros de evento incorretos
A OptimisticRewarderBase
contrato define um Requested
evento que é emitido pelo requestRedemption
funcionar quando um resgate é solicitado. Este evento é definido para emitir o prazo de vencimento do resgate como seu último parâmetro. No entanto, quando o evento é emitido, seu último parâmetro está configurado incorretamente para o hora atual.
Da mesma forma, o Redeemed
evento lê o tempo de expiração após a exclusão do registro, portanto, será definido incorretamente como zero.
Dado que este evento pode ser usado para desencadear cálculos fora da cadeia, considere atualizar o valor emitido de forma adequada.
Update: Corrigido a partir do commit f04eef9
in PR3694.
Baixa gravidade
[L01] Falta de emissão de evento após disputa de resgate
A OptimisticRewarderBase
contrato define um Disputed
evento que se destina a ser acionado se um resgate for contestado. No entanto, este evento não é emitido dentro ou fora do OptimisticRewarderBase
contrato.
Considere emitir o evento depois que alterações sensíveis ocorrerem no dispute
função, para facilitar o rastreamento e notificar os clientes fora da rede após a atividade dos contratos.
Update: Corrigido a partir do commit c275e92
in PR3695.
[L02] Guarda de reentrada inconsistente
A Optimism_ParentMessenger
e Arbitrum_ParentMessenger
contratos aplicam inconsistentemente o nonReentrant
modificador. Considere incluí-lo em todas as funções públicas.
Update: Corrigido a partir do commit 6275c39
in PR3677.
[L03] Comentários enganosos
Aqui estão alguns comentários enganosos que identificamos durante nossa análise:
ChildMessengerConsumerInterface.sol
:- Linha 5 diz “mensageiro dos pais” em vez de “mensageiro das crianças”
GovernorSpoke.sol
:- Linhas 49-51 links para um
Gnosis
arquivo, mesmo que o comentário diga que o snippet foi copiado deGovernor.sol
. Além disso, o snippet não é idêntico ao doGovernor.sol
- Linhas 49-51 links para um
Update: Corrigido a partir do commit cc350f9
in PR3678.
[L04] Carimbo de dados auxiliares ausente
Ao solicitar um preço no OracleSpoke
contrato, os dados auxiliares fornecidos está carimbado com o identificador da cadeia filho. No entanto, o hasPrice
e getPrice
funções não carimbam os dados auxiliares ao identificar a solicitação de preço. Isto obriga os contratos convocatórios a aplicarem eles próprios o selo, o que provoca uma inconsistência entre os mecanismos de solicitação de preços e de recuperação de preços. Considere aplicar o carimbo no hasPrice
e getPrice
funções.
Update: Corrigido a partir do commit fdb845d
in PR3668.
[L05] Parâmetro NatSpec ausente
Muitas funções no OptimisticRewarderBase
contract estão faltando o @return
parâmetro em seus comentários de Especificação Natural. Considere incluí-lo para completar.
Update: Corrigido a partir do commit 8920f38
in PR3679.
[L06] Subsídio residual
Para invocar o Oráculo Otimista, o OptimisticRewarderBase
contract concede-lhe um subsídio simbólico, para que possa retirar os pagamentos dos títulos. Se a proposta falhar, o resgate da recompensa foi cancelado mas o subsídio não é zerado. Portanto, o Oráculo Otimista reterá uma margem residual desnecessária até a próxima vez que uma disputa for desencadeada. Considere revogar o subsídio se a proposta falhar.
Update: Corrigido a partir do commit c2d444b
in PR3698.
[L07] Endereço de reembolso inválido
O endereço L2 de reembolso do Arbitrum_ParentMessenger
é inicializado ao proprietário do contrato, que deverá ser o Governador L1. Da mesma forma, o setRefundL2Address
tem um comentário afirmando que deveria ser entregue ao governador. Entretanto, ao passar mensagens pela ponte, esse valor é definido como usuário L2, que é o endereço no Arbitrum que recebe o excesso de fundos após a resolução do ticket. Como o endereço do governador L1 não estará acessível no Arbitrum, quaisquer fundos enviados para este endereço serão perdidos.
Considere configurá-lo para um endereço L2 válido.
Update: Corrigido a partir do commit b3f2dd1
in PR3687.
[L08] Mecanismo para mudar mensageiros infantis
A GovernorSpoke
e OracleSpoke
cada contrato inicializa o mensageiro filho no construtor, sem nenhum mecanismo para atualizá-lo. Isto significa que quando o mensageiro infantil foi alterado, ambos os contratos falados tornam-se obsoletos.
Como os contratos dos raios são provavelmente mais estáveis que os mensageiros, considere incluir um mecanismo para atualizar o mensageiro nos raios.
Update: Corrigido a partir do commit 7c9e061
in PR3688.
Notas e informações adicionais
[N01] Alterar token de título
A Proposer
contrato inclui um mecanismo para o proprietário alterar o tamanho do título da proposta. Considere se eles também deveriam poder alterar o token do título. Observe que isso exigiria um mecanismo para identificar a moeda correta dos títulos quando as propostas existentes fossem resolvidas.
Update: Não é um problema. Declaração da UMA para este problema:
N01 recomenda permitir que o contrato proponente altere o token do título para algo diferente de UMA. Não temos intenção de oferecer suporte a nenhum token diferente de $UMA para esta função e, portanto, optamos por não fazer nenhuma alteração para esse problema. Além disso, um único token por contrato mantém esta lógica o mais simples possível. Por último, se fosse necessária uma mudança (no caso de uma migração de token, por exemplo), poderíamos simplesmente implantar um novo contrato de proponente com o outro token e iniciar uma proposta para migrar o sistema para usá-lo.
[N02] Interface incompleta
A ChildMessengerInterface
não especifica um processMessageFromCrossChainParent
função, mesmo que seja assumido que exista pelos mensageiros pais. Considere incluí-lo para completar.
Update: Não consertado. Declaração da UMA para este problema:
Optamos intencionalmente por deixar esta interface inconsistente, pois implementá-la dentro do ChildMessengerInterface quebra a compatibilidade com o Polygon_ChildMessenger, pois o método do Polygon para processar mensagens de outras cadeias requer uma lógica personalizada em que um método interno é chamado _processMessageFromRoot.
[N03] Interface incorreta
A GovernorSpoke
contratar incorretamente utiliza o ChildMessengerConsumerInterface
tipo para descrever seu messenger
variável. Considere usar o ChildMessengerInterface
ao invés.
Update: Corrigido a partir do commit f31a527
in PR3680.
[N04] Extrair tokens para armazenar
Em um artigo do auditoria anterior questionamos o propósito do Store
contrato payOracleFeesErc20
função (na edição L19). A equipe UMA optou por manter a função para padronizar a interface para possíveis modificações futuras. Como a finalidade da função não está totalmente especificada, não está claro se ela deve ser acionada quando o Proposer
contract confisca um título. Provavelmente deve ser usado quando o OracleHub
paga por uma solicitação de preço. Considere se a função deve ser usada em qualquer um dos cenários.
Update: Reconhecido. Declaração da UMA para este problema:
N04 recomenda usar o método payOracleFeeErc20 da Loja para pagar taxas nos contratos do Proponente e do OracleHub para ser consistente com o uso da Loja. Optamos por não usar esta função, pois isso significaria a necessidade de importar uma interface adicional (para a loja) e exigir a conversão do valor do título para um FixedPoint (o que também exigiria uma importação adicional. Para manter o código simples e limpo optamos por não fazer isso. O feedback da OZ sobre payOracleFeeErc20 na fase de auditoria 1 em abril de 2020 foi válido, pois esse método não é realmente útil, tornando esse tipo de integração mais difícil de raciocinar.
[N05] TODOs no código
Existem comentários “TODO” na base de código que devem ser rastreados no backlog de problemas do projeto. Por exemplo:
- Line 37 of
Arbitrum_ParentMessenger
contract - Line 25 of
Optimism_ChildMessenger
contract - Linhas 83 e 146 of
OracleHub
contrato.
Durante o desenvolvimento, ter comentários “TODO” bem descritos facilitará o processo de rastreamento e solução deles. Sem essas informações, esses comentários podem tender a apodrecer e informações importantes para a segurança do sistema podem ser esquecidas no momento em que são liberadas para produção.
Esses comentários TODO devem conter uma breve descrição da tarefa pendente e um link para o problema correspondente no repositório do projeto.
Considere atualizar os comentários TODO para adicionar essas informações. Para integridade e rastreabilidade, uma assinatura e um carimbo de data/hora podem ser adicionados. Por exemplo:
// TODO: point this at an interface instead.
// https://github.com/UMAprotocol/protocol/issues/XXXX
// --mrice32 - 20211209
Update: Corrigido a partir do commit 5d57b5b
in PR3684.
[N06] Erros tipográficos
A base de código contém os seguintes erros tipográficos:
- No
Admin_ChildMessenger
contrato,impleenting
deveria estarimplementing
- No
OptimisticRewarderBase
contrato,timestap
deveria estartimestamp
. - No
OptimisticRewarderBase
contrato,liveness liveness
deveria estarliveness
. - No
GovernorSpoke
contrato,only called
deveria estaronly be called
. - No
Optimism_ChildMessenger
contrato:
Update: Corrigido a partir do commit 9b92b0b
in PR3681.
[N07] Importações não utilizadas
Para melhorar a legibilidade do código, considere remover as seguintes importações não utilizadas:
Update: Corrigido a partir do commit 40b7221
in PR3682.
[N08] Pedido de transação L2
A Governor
garante as transações dentro de uma proposta são executadas em ordem. No entanto, quando essas transações envolvem transações entre cadeias, isso apenas garante que cheguem ao contrato da ponte L1 na ordem correta. No caso Arbitrum, eles podem ser reordenados antes de serem finalizados em L2. Portanto, as propostas de governança devem ser construídas para permitir a possibilidade de transações L2 reordenadas.
Update: Corrigido a partir do commit 0fb2e7b
in PR3703. O GovernorHub
agora pode retransmitir uma série de transações L2.
Conclusão
Dois problemas críticos foram encontrados na base de código. Um problema de gravidade média e várias vulnerabilidades menores foram encontrados, e foram sugeridas recomendações para correções.
- &
- 2020
- 7
- 9
- Sobre
- Contabilidade
- em
- ações
- Ad
- Adicional
- endereço
- Todos os Produtos
- Permitindo
- Abril
- auditor
- ser
- blockchain
- Caixa
- PONTE
- casos
- alterar
- criança
- reivindicações
- código
- comentários
- contém
- contract
- contratos
- poderia
- Cross-Corrente
- Moeda
- Atual
- dados,
- Descentralizada
- Desenvolvimento
- diferente
- Disputa
- distribuído
- ecossistema
- emissão
- permitindo
- ERC20
- ETH
- ethereum
- Blockchain Ethereum
- Evento
- exemplo
- esperado
- estender
- Taxas
- financeiro
- Primeiro nome
- encontrado
- Foundation
- função
- fundos
- futuro
- governo
- Governador
- ter
- titulares
- HTTPS
- identificar
- importante
- Incluindo
- INFORMAÇÕES
- integração
- Interface
- questões
- IT
- Laboratório
- Limitado
- LINK
- longo
- Fazendo
- média
- Messenger
- a maioria
- compensar
- oráculo
- ordem
- Outros
- proprietário
- pagamentos
- fase
- plataforma
- Polygon
- piscina
- preço
- processo
- Produção
- projeto
- proposta
- oferece
- fornecer
- público
- registro
- repositório
- rever
- Recompensas
- Risco
- segurança
- conjunto
- contexto
- simples
- Tamanho
- So
- solidez
- Alguém
- algo
- Declaração
- loja
- ajuda
- Suportado
- suportes
- .
- teste
- tempo
- token
- Tokens
- Rastreabilidade
- Rastreamento
- transação
- Transações
- trânsito
- Atualizar
- usuários
- valor
- Verificação
- vulnerabilidades
- semana
- QUEM
- dentro
- sem
- Atividades:
- Equivalente há
- zero