Skip to main contentA-REX Foundation

Whitepaper · 07

Hooks e Módulos de Referência

Como a funcionalidade é acrescentada a um token conforme sem tocar no padrão: o contrato de hook, os hooks de referência, as extensões complementares e como escrever, testar e registrar um hook próprio.

Módulos são demonstrações, e não o padrão

A relação entre o A-REX Core e seus módulos é a mesma que existe entre o ERC-3643 e os módulos de conformidade do T-REX: a interface pela qual os módulos se conectam é padronizada; os módulos, não. Um token conforme com zero hooks é um token A-REX válido. Um hook escrito por qualquer pessoa é compatível com todos os tokens conformes. É isso que faz o ecossistema crescer sem que o padrão mude.

graph LR
    T["ARexToken<br/>token conforme"] -->|"check / onExecuted / canSend / canReceive"| H1[EligibilityHook]
    T --> H2[ExpiryHook]
    T --> H3[AttestationHook]
    T --> H4["Seu hook"]
    H3 --> A[ARexAttestations]

O contrato de hook

CallbackQuandoDeve
checkantes de os saldos mudarem, por id afetado, hooks na ordem de registro, parando no primeiro código diferente de zeroser uma view; nunca reverter por motivo de política
onExecuteddepois de os saldos mudarem, por id, em ordemnão chamar as funções do token que alteram saldos (o token está travado)
canSend / canReceiveem toda transferência e para as views do ERC-7943 do tokenser views

op é um entre OP_MINT (1), OP_TRANSFER (2), OP_BURN (3), OP_FORCED_TRANSFER (4), OP_TRANSFORM (5). Em uma transformação, as entradas chegam com to == 0 e as saídas com from == 0. data são os dados de transferência do ERC-1155: abi.encode(processRef) para transformações e vazio para transferências forçadas.

O token chamador é msg.sender. Um hook que precisa do lote lê IARexBatch(msg.sender).batchOf(id).

Hooks de referência

EligibilityHook — permitir, bloquear, sancionar

Demonstra HOOK_ELIGIBILITY. Mantém uma lista de permissão opcional, uma lista de bloqueio e uma lista de sanções; canSend/canReceive retornam a conjunção delas; check retorna SANCTIONED, SENDER_INELIGIBLE ou RECEIVER_INELIGIBLE para que as interfaces possam explicar a recusa. As transferências forçadas são sempre permitidas: apreender bens de uma conta sancionada é o propósito do enforcement. Em produção, as listas são alimentadas por um registro de identidade (ONCHAINID, EAS, credenciais verificáveis) ou por um oráculo de sanções; o hook é indiferente quanto a isso.

ExpiryHook — perecibilidade sem um módulo

Sem estado. Lê expiresAt e producedAt do lote. Bloqueia cunhagens e transferências de lotes vencidos (BATCH_EXPIRED), mas não queimas (baixa por perda) nem transferências forçadas (enforcement). Opcionalmente bloqueia transferências de lotes ainda não produzidos (BATCH_NOT_PRODUCED) — uma plataforma que financia a pré-colheita define a flag para permiti-las; um marketplace à vista a define para bloqueá-las. Esse único hook cobre a parte de bloqueio da perecibilidade; as curvas de decaimento passam a ser uma função auxiliar de view ou uma valoração off-chain.

AttestationHook — condicionamento regulatório por commodity

Mapeia um código de commodity para um tópico de atestação exigido. Antes de uma transferência, lê o lote, consulta o requisito, pergunta ao registro de atestações isAttested e retorna ATTESTATION_MISSING caso contrário. "O café precisa de uma referência de devida diligência do EUDR", "lotes com rótulo orgânico precisam de um certificado orgânico válido", "o gado precisa de um certificado sanitário" são, cada um, uma chamada a setRequirement.

PerishabilityHook — modelos de decaimento

Configuração de decaimento por código de commodity, com sobrescrita por lote; modelos NONE, LINEAR (até um piso no vencimento), EXPONENTIAL (meia-vida) e STEP (queda a cada intervalo). Views valueBps, secondsRemaining, isExpired. Bloqueia cunhagens e transferências de lotes vencidos (BATCH_EXPIRED) e transferências de lotes cujo valor restante é zero (PERISH:NO_VALUE); nunca bloqueia queimas nem enforcement.

SeasonalHook — janelas de colheita e de negociação

Janelas absolutas [start, end] por commodity e por operação (no máximo 16 por chave). Uma commodity/operação sem janelas não tem restrição. Uso típico: OP_MINT limitado à janela de colheita, OP_TRANSFER à janela de negociação; SEASON_CLOSED nos demais casos.

DeliveryHook — custódia e liquidação

Um remetente agenda uma entrega de amount unidades a um destinatário por meio de uma transportadora; as unidades são travadas (um contador O(1), de modo que check nunca itera sobre o histórico). A transportadora e os sensores registram a coleta, o trânsito e as leituras de temperatura (flag de violação); o destinatário confirma a entrega; as disputas vão a um árbitro. A liquidação é a própria transferência ERC-1155: remetente → destinatário, quantidade exata, com data = abi.encode(deliveryId); check só a permite quando a entrega está DELIVERED, e onExecuted a marca como SETTLED e destrava. As unidades livres (não travadas) continuam a circular.

TraceabilityHook — log de eventos no formato EPCIS

Observa cada operação do token e a classifica com etapas de negócio do CBV (commissioning, shipping, destroying, transforming) e disposições (active, in_transit, destroyed, seized); RECORDER_ROLE registra eventos críticos de rastreamento que não envolvem o token (resfriamento, embalagem, recebimento) com readPoint e bizLocation. Dois modos: apenas emitir (cerca de +17 k de gás por transferência; um indexador reconstrói o log) ou persistir (cerca de +184 k; getEvents responde on-chain, com paginação).

Extensões complementares

Três preocupações nunca precisaram ser regras de transferência; são contratos simples que leem ou escrevem atestações:

ExtensãoO que faz
CommodityPriceOracleos reportadores enviam preços por commodity; as rodadas são numeradas e finalizadas por quórum com a mediana, ou manualmente quando um mínimo é atingido; latestAnswer, isStale
CarbonImmobilizationWrapperregistra créditos imobilizados em um registro (registro, faixa de números de série, vintage, toneladas, prova), vincula toneladas a lotes, espelha a aposentadoria e a liberação, grava a atestação AREX:CARBON:IMMOBILIZED; nunca cunha créditos
ParametricInsurancepool ERC-20; apólice por lote com um tópico de gatilho; o sinistro é pago quando o gatilho é atestado antes do vencimento

Como escrever um hook próprio

O exemplo contracts/examples/SeasonHook.sol permanece no repositório. test/standard/ImplementationGuide.test.js o exercita para leitores com acesso. SeasonalHook é o módulo de referência para várias janelas por commodity e por operação.

Regras práticas:

  1. Os símbolos OK e OP_FORCED_TRANSFER são definidos no texto normativo.
  2. O comportamento da queima é definido no texto normativo.
  3. A chamada check é definida no texto normativo.
  4. Nomes de código como ARexCodes.code("MYNS", "NAME") são definidos no texto normativo.
  5. Os valores das flags são definidos no texto normativo.
  6. As chamadas onExecuted e check são definidas no texto normativo.

Registro e ordenação

Coloque primeiro as regras baratas e de alta taxa de rejeição. HOOK_ADMIN_ROLE deveria ficar atrás de um multisig ou timelock: quem controla o pipeline controla quais transferências são possíveis.

Testes

test/standard/helpers.js implanta a pilha de referência. RecordingHook registra cada callback e pode ser instruído a rejeitar com qualquer código; ReentrantHook tenta reentrar no token a partir de onExecuted e comprova a trava. DomainHooks.test.js e Extensions.test.js cobrem os hooks e os complementares migrados; Invariants.test.js executa uma sequência aleatória de operações com semente e verifica a conservação da oferta, o status terminal e que canTransfer prevê todos os resultados.

Interoperabilidade com a conformidade do ERC-3643

Um módulo de conformidade do ERC-3643 expõe moduleCheck(from, to, value, compliance). Um hook que o chama para OP_TRANSFER e mapeia false para um código torna restrições por país, limites de saldo e bloqueios temporais, escritos para tokens de valores mobiliários, reutilizáveis em tokens de lote. O caminho inverso — expor um hook do A-REX a um token ERC-3643 — é igualmente mecânico. O Automated Compliance Engine da Chainlink se integra pelo mesmo esquema: seu mecanismo de políticas se torna um hook.