Skip to main contentA-REX Foundation

Whitepaper · 08

Estrutura de Segurança

Modelo de ameaças, invariantes, controle de acesso, o limite de confiança dos hooks, gestão das chaves de enforcement, segurança das atualizações e postura de auditoria da implementação de referência do A-REX Core.

A postura de segurança em um parágrafo

O token de referência tem um único ponto de passagem (_update), uma ordem fixa de avaliação, uma trava de reentrância em torno de toda a sequência de hooks, uma autoridade baseada em papéis que nunca deriva de saldos, armazenamento ERC-7201 e uma superfície pequena: oito funções externas que alteram estado, além das do ERC-1155. As capacidades mais poderosas — congelamento, transferência forçada, administração de hooks, atualizações — são papéis separados, destinados a multisigs e timelocks, e todo uso delas é um evento.

Invariantes

InvarianteGarantido porTestado por
totalSupply(id) é igual à soma dos saldos de idERC1155Supply do OpenZeppelin; transform queima e depois cunha por meio de _updatetestes de linhagem (divisão, união, processamento)
status == 255 é terminalsetBatchStatus reverte com ARexInvalidStatusTransitiontestes de status
Um lote baixado não pode ser cunhado nem transferido, apenas queimado_updateteste de lote baixado
amount ≤ balance − frozen para movimentações iniciadas pelo titular_update; forcedTransfer reduz frozen para balance − amounttestes de congelamento/transferência forçada
Nenhum hook pode reentrar em uma função que altera saldostrava de armazenamento definida antes das verificações e liberada depois das notificaçõesteste ReentrantHook
Os hooks são avaliados na ordem de registro; a remoção preserva a ordemdeslocamento do array em removeHookteste de ordenação
Uma operação rejeitada não altera nenhum saldo e não emite nenhuma transferênciaas verificações são executadas antes de super._updateteste de rejeição (contagem de execuções inalterada)
A autoridade nunca deriva do saldotoda função que altera estado é protegida por papel ou por aprovação do ERC-1155testes "possuir tokens não confere nada"
canTransfer == (transferCheck == 0)canTransfer é definido dessa formatestes de conformidade

Modelo de ameaças

Atores e capacidades

AtorPodeNão pode
Titulartransferir unidades não congeladas a destinatários elegíveis; queimar; reagrupar a mesma commodity/unidade com quantidade conservadaalterar o status, cunhar, processar em outra commodity, mover unidades congeladas
Operador aprovadoo mesmo que o titular, em relação à conta que o aprovouqualquer coisa que um titular não possa
ISSUER_ROLEcriar lotesmover tokens de terceiros
TRANSFORMER_ROLEtransformações de processamento de tokens que detém ou para os quais tem aprovaçãotransformar tokens sem aprovação
STATUS_ROLEalterar o status (inclusive dar baixa), atualizar metadadosmover tokens
ENFORCER_ROLEcongelar qualquer quantidade; forçar qualquer transferênciacontornar os hooks (eles são executados com OP_FORCED_TRANSFER)
HOOK_ADMIN_ROLEadicionar/remover hooksalterar saldos diretamente
PAUSER_ROLEinterromper tudo, exceto as transferências forçadas—
UPGRADER_ROLEsubstituir a implementação— (este é um poder total; ver gestão de chaves)
Contrato de hookrejeitar operações; observá-las; responder sobre elegibilidadereentrar; alterar saldos

Cenários

Hook malicioso ou com defeito (negação de serviço). Um hook que sempre rejeita bloqueia todas as transferências do token; um que reverte em check faz o mesmo. Mitigação: HOOK_ADMIN_ROLE pode remover qualquer hook a qualquer momento (ordem preservada); PAUSER_ROLE pode interromper a operação durante a investigação; as transferências forçadas continuam sendo executadas, de modo que o enforcement não se perde. O registro verifica o suporte a ERC-165 e flags diferentes de zero, e rejeita EOAs. Recomendação: auditar os hooks antes de registrá-los; manter seu número pequeno; colocar a administração atrás de um timelock, para que as mudanças de hooks sejam visíveis antes de entrarem em vigor.

Reentrância de hook. O onExecuted de um hook chama de volta safeTransferFrom. Mitigação: a trava; a chamada reverte com ARexReentrantCall. Observe-se que o callback de recebimento do ERC-1155 (onERC1155Received) é executado depois de a trava ser liberada, como em todo token ERC-1155; o estado do token já é definitivo nesse momento.

Chave de enforcement comprometida. Quem detém ENFORCER_ROLE pode mover quaisquer tokens. Mitigação: multisig com um procedimento documentado (ordem judicial, contrato de penhor, notificação de sanções); toda ação emite ForcedTransfer/Frozen; os hooks podem exigir uma referência de ordem nos dados da transferência (OP_FORCED_TRANSFER não está isento dos hooks). Pode-se considerar um timelock para o enforcement não urgente.

Atualizador comprometido. Comprometimento total. Mitigação: multisig mais timelock; validações de atualização do OpenZeppelin na CI; armazenamento ERC-7201 para evitar acidentes de layout.

Abuso de status. STATUS_ROLE pode dar baixa em um lote detido por terceiros. Isso é intencional — um armazém, um inspetor ou um regulador declarando um lote impróprio — e deve ser divulgado aos titulares. Mitigação: atribuir a uma instituição responsável; toda mudança é um evento com um motivo.

Fraude do emissor. ISSUER_ROLE pode criar um lote que não existe fisicamente. O token não pode impedir isso; torna o fato atribuível (issuer, originRef, metadataHash) e permite exigir, antes da transferência, atestações de partes independentes (armazém, inspetor, registro) por meio de AttestationHook.

Substituição de metadados. setBatchMetadata altera o hash e a URI. Mitigação: protegida por papel; os eventos BatchMetadataUpdated e URI mantêm o histórico; documentos anteriores continuam verificáveis em relação aos hashes anteriores.

Front-running de transferCheck. Uma verificação prévia pode ficar desatualizada antes de a transação ser executada (o estado de um hook muda). A transação reavalia; o pior caso é uma reversão com um código preciso.

Gas griefing por meio de hooks. Cada hook acrescenta uma chamada externa por id afetado por fase. Um hook com laços ilimitados torna as transferências financeiramente inviáveis. Mitigação: regras de autoria de hooks (check limitado), revisão antes do registro.

Confiança em hooks atualizáveis. Um hook implantado atrás de um proxy pode mudar a política de transferência sem qualquer alteração no token. Mitigação: tratar as chaves de administração dos hooks com o mesmo cuidado dado a HOOK_ADMIN_ROLE; preferir hooks imutáveis em produção.

Modelo de controle de acesso

O AccessControl do OpenZeppelin, com oito papéis no token e um no registro de atestações; DEFAULT_ADMIN_ROLE administra todos eles. Disposição recomendada para produção:

PapelTitular
DEFAULT_ADMIN_ROLE, UPGRADER_ROLE, HOOK_ADMIN_ROLEmultisig de governança atrás de um timelock
ENFORCER_ROLEmultisig de enforcement (conformidade + jurídico)
PAUSER_ROLEchave de resposta a incidentes (rápida)
ISSUER_ROLE, STATUS_ROLE, TRANSFORMER_ROLEserviços operacionais com privilégio mínimo, com rotação
ATTEST_ADMIN_ROLEautoridade de certificação ou plataforma

initialize concede tudo a um único administrador por conveniência; a lista de verificação de implantação exige a redistribuição antes da produção.

Semântica de enforcement e de pausa

  • A pausa bloqueia cunhagens, transferências, queimas e transformações; não bloqueia as transferências forçadas, de modo que uma ordem legal possa ser executada durante um incidente.
  • As transferências forçadas dispensam canSend/canReceive e a verificação de saldo congelado, reduzem o valor congelado ao que resta e ainda executam os hooks com OP_FORCED_TRANSFER. Os hooks de referência retornam OK para essa operação; um hook que trate de enforcement pode exigir referências de ordem em data.
  • O congelamento pode exceder o saldo (ERC-7943), de modo que um gravame pode cobrir depósitos futuros.

Segurança das atualizações

  • UUPS; _authorizeUpgrade protegido por UPGRADER_ROLE.
  • Estrutura de armazenamento com namespace ERC-7201; somente acréscimos.
  • As validações do plugin de atualizações do OpenZeppelin são executadas nos testes e deveriam ser executadas na CI antes de qualquer transação de atualização.
  • A configuração optimizer.runs = 1 por arquivo mantém a implementação abaixo do EIP-170; uma alteração que a ultrapasse falha em tempo de compilação, com um aviso, e na implantação, com um revert.

Segurança de dependências e de build

  • OpenZeppelin Contracts e Contracts-Upgradeable fixados na versão 5.3.0; lockfile versionado; a CI usa npm ci.
  • Solidity 0.8.22, viaIR, EVM paris (sem dependência de armazenamento transitório, implantável em redes que não adotaram o Cancun).
  • Nenhuma biblioteca externa vinculada; nenhum delegatecall fora do proxy UUPS.

Postura de auditoria

  • 46 testes sobre a implementação de referência, os hooks e as extensões cobrem todas as invariantes acima, inclusive uma execução de invariantes randomizada com semente.
  • O gás e o tamanho são medidos por scripts do repositório.
  • Uma auditoria de terceiros de ARexToken, ARexAttestations e dos hooks de referência é uma pré-condição declarada para uma âncora de produção e para a submissão do ERC (ver Desenvolvimentos Futuros).
  • A verificação formal das invariantes do pipeline está no roteiro; as invariantes são pequenas o bastante para serem enunciadas como propriedades.

Riscos residuais que o padrão não elimina

  • A existência física e a qualidade de um lote são atestadas, e não comprovadas; o token torna as afirmações atribuíveis, e não verdadeiras.
  • A disponibilidade dos metadados off-chain depende do armazenamento escolhido; o hash garante a integridade, e não a disponibilidade.
  • A governança de hooks e módulos é tão boa quanto as chaves que a controlam.