Skip to main contentA-REX Core

Whitepaper · 16

Apêndices

Fontes de referência: contracts/standard/ .sol (CC0) e standard/AREX CORE.md. Identificadores de interface reproduzidos por npm run interface ids.

Valor uint8 de ciclo de vida; 0 ativo, 255 baixado (terminal); 1..254 definidos pelo emissor.

Apêndice A: Referência de Interfaces

Fontes de referência: contracts/standard/*.sol (CC0) e standard/AREX-CORE.md. Identificadores de interface reproduzidos por npm run interface-ids.

A.1 Resumo de conformidade

InterfaceID ERC-165TokenHook
IERC11550xd9b67a26DEVE—
IERC7943MultiToken0x41c4fbadDEVE—
IARexBatch0xe22639e0DEVE—
IARexHookManager0x964f4861DEVE (getHooks)—
IARexAttest0xad603a6cDEVERIA (token ou complementar)—
IARexHook0x332afcbb—DEVE

A.2 IARexBatch

struct BatchInit { bytes32 commodity; bytes32 unit; uint64 producedAt; uint64 expiresAt; bytes32 originRef; bytes32 metadataHash; string uri; }
struct Batch { address issuer; uint64 createdAt; uint8 status; bytes32 commodity; bytes32 unit; uint64 producedAt; uint64 expiresAt; bytes32 originRef; bytes32 metadataHash; string uri; }


event BatchCreated(uint256 indexed id, address indexed issuer, bytes32 indexed commodity, bytes32 unit, uint256 quantity, address to);
event BatchStatusChanged(uint256 indexed id, uint8 previousStatus, uint8 newStatus, bytes32 reason);
event BatchMetadataUpdated(uint256 indexed id, bytes32 metadataHash, string uri);
event BatchTransformed(address indexed operator, uint256[] inputIds, uint256[] inputAmounts, uint256[] outputIds, uint256[] outputAmounts, bytes32 processRef);


error ARexBatchNotFound(uint256 id);
error ARexBatchRetired(uint256 id);
error ARexInvalidBatch(bytes32 reason);
error ARexInvalidStatusTransition(uint256 id, uint8 from, uint8 to);
error ARexLengthMismatch();


function createBatch(BatchInit calldata init, uint256 quantity, address to, bytes calldata data) external returns (uint256 id);
function batchOf(uint256 id) external view returns (Batch memory);
function batchExists(uint256 id) external view returns (bool);
function totalSupply(uint256 id) external view returns (uint256);
function setBatchStatus(uint256 id, uint8 status, bytes32 reason) external;
function setBatchMetadata(uint256 id, bytes32 metadataHash, string calldata uri) external;
function transform(address from, address to, uint256[] calldata inputIds, uint256[] calldata inputAmounts, BatchInit[] calldata outputs, uint256[] calldata outputAmounts, bytes32 processRef) external returns (uint256[] memory outputIds);
function parentsOf(uint256 id) external view returns (uint256[] memory);

A.3 IERC7943MultiToken (ERC-7943, literal)

event ForcedTransfer(address indexed from, address indexed to, uint256 indexed tokenId, uint256 amount);
event Frozen(address indexed account, uint256 indexed tokenId, uint256 amount);
error ERC7943CannotSend(address account);
error ERC7943CannotReceive(address account);
error ERC7943CannotTransfer(address from, address to, uint256 tokenId, uint256 amount);
error ERC7943InsufficientUnfrozenBalance(address account, uint256 tokenId, uint256 amount, uint256 unfrozen);
function forcedTransfer(address from, address to, uint256 tokenId, uint256 amount) external returns (bool result);
function setFrozenTokens(address account, uint256 tokenId, uint256 amount) external returns (bool result);
function canSend(address account) external view returns (bool allowed);
function canReceive(address account) external view returns (bool allowed);
function getFrozenTokens(address account, uint256 tokenId) external view returns (uint256 amount);
function canTransfer(address from, address to, uint256 tokenId, uint256 amount) external view returns (bool allowed);

A.4 IARexHook e IARexHookManager

interface IARexHook is IERC165 {
    error ARexHookRejected(address hook, bytes32 code);
    function hookFlags() external view returns (uint8);
    function check(uint8 op, address operator, address from, address to, uint256 id, uint256 amount, bytes calldata data) external view returns (bytes32 code);
    function onExecuted(uint8 op, address operator, address from, address to, uint256 id, uint256 amount, bytes calldata data) external;
    function canSend(address account) external view returns (bool);
    function canReceive(address account) external view returns (bool);
}
interface IARexHookManager {
    event HookRegistered(address indexed hook, uint8 flags, uint256 position);
    event HookRemoved(address indexed hook);
    error ARexHookAlreadyRegistered(address hook);
    error ARexHookNotRegistered(address hook);
    error ARexInvalidHook(address hook);
    function getHooks() external view returns (address[] memory);
    function hookFlagsOf(address hook) external view returns (uint8);
    function registerHook(address hook) external;
    function removeHook(address hook) external;
}

A.5 IARexAttest

struct Attestation { address issuer; bytes32 ref; uint64 issuedAt; uint64 expiresAt; bool revoked; }
event Attested(uint256 indexed id, bytes32 indexed topic, address indexed issuer, bytes32 ref, uint64 expiresAt);
event AttestationRevoked(uint256 indexed id, bytes32 indexed topic, address indexed issuer, bytes32 reason);
event TrustedIssuerUpdated(bytes32 indexed topic, address indexed issuer, bool trusted);
error ARexUntrustedIssuer(bytes32 topic, address issuer);
error ARexAttestationNotFound(uint256 id, bytes32 topic);
function attest(uint256 id, bytes32 topic, bytes32 ref, uint64 expiresAt) external;
function revokeAttestation(uint256 id, bytes32 topic, bytes32 reason) external;
function getAttestation(uint256 id, bytes32 topic) external view returns (Attestation memory);
function isAttested(uint256 id, bytes32 topic) external view returns (bool);
function isTrustedIssuer(bytes32 topic, address issuer) external view returns (bool);

A.6 Constantes (ARexCodes)

GrupoValores
OperaçõesOP_MINT = 1, OP_TRANSFER = 2, OP_BURN = 3, OP_FORCED_TRANSFER = 4, OP_TRANSFORM = 5
Flags de hookHOOK_CHECK = 1, HOOK_EXECUTED = 2, HOOK_ELIGIBILITY = 4
StatusSTATUS_ACTIVE = 0, STATUS_RETIRED = 255
Códigos (keccak256("AREX:…"))PAUSED, FROZEN, SENDER_INELIGIBLE, RECEIVER_INELIGIBLE, SANCTIONED, BATCH_NOT_FOUND, BATCH_RETIRED, BATCH_INACTIVE, BATCH_EXPIRED, BATCH_NOT_PRODUCED, LIMIT_EXCEEDED, DOCUMENT_MISSING, SEASON_CLOSED, IN_TRANSIT, ATTESTATION_MISSING
Auxiliarescommodity(scheme, code), unit(code), topic(name), code(namespace, name)

A.7 Papéis da implementação de referência

ISSUER_ROLE, TRANSFORMER_ROLE, STATUS_ROLE, ENFORCER_ROLE, HOOK_ADMIN_ROLE, PAUSER_ROLE, UPGRADER_ROLE, DEFAULT_ADMIN_ROLE em ARexToken (cada um keccak256("AREX_<NAME>")); ATTEST_ADMIN_ROLE em ARexAttestations. Views adicionais: isExpired(id), transferCheck(from, to, id, amount); função adicional: burn(from, id, amount); slot ERC-7201 0x8ed599b6be05dec05297c009a1279a71df771ad996fe924d0b5a47326ff60900.

A.8 Hooks e extensões de referência

ContratoTipoFunções principais
PerishabilityHookhooksetCommodityDecay, setBatchDecay, valueBps, secondsRemaining, isExpired
SeasonalHookhookaddWindow, clearWindows, windowsOf, isOpen
DeliveryHookhookschedule, pickUp, markInTransit, recordReading, confirmDelivered, cancel, dispute, resolve, getDelivery, lockedUnits
TraceabilityHookhookrecordEvent, eventCount, getEvents; flag de construtor persist
CommodityPriceOracleextensãosubmit, finalizeRound, latestAnswer, getRound, currentRound, isStale, setParameters
CarbonImmobilizationWrapperextensãorecordImmobilization, linkToBatch, retire, release, attestBacking, backingOf, linksOf
ParametricInsuranceextensãofund, issue, claim, expire, getPolicy, freeCapacity

A.9 Esquema de metadados

standard/schema/batch-metadata.schema.json (JSON Schema 2020-12). Obrigatórios: schemaVersion, commodity{scheme, code}, unit, quantity. Grupos opcionais notáveis: traceabilityLotCode, gs1{gtin, lgtin, sscc, glnProducer, digitalLink}, production, origin{country, originRef, eudr{ddsReference}, geohashPrecision, geohash}, quality{gradeScheme, grade, measurements[]}, status.table, attestations[], documents[]{type, hash, uri, registry, registryId}, epcis{bizStep, disposition, readPoint, bizLocation}, restricted{uri, hash, accessPolicy}, attributes[]. Exemplo em standard/examples/batch-metadata.example.json.

Apêndice B: Glossário

TermoSignificado
LoteUm identificador de token ERC-1155 com um registro Batch: um lote de uma commodity em uma unidade, com origem e data de produção comuns.
ReagrupamentoUma transform cujas saídas têm a mesma commodity e a mesma unidade das entradas e cujas quantidades são conservadas (divisão, união). Aberta aos titulares na implementação de referência.
ProcessamentoUma transform que altera a commodity, a unidade ou a quantidade. Exige TRANSFORMER_ROLE na implementação de referência.
LinhagemO grafo formado pelos eventos BatchTransformed e por parentsOf.
HookUm contrato que implementa IARexHook, registrado em um token e avaliado em ordem em toda operação.
Código de rejeiçãoUm bytes32 retornado por check de um hook; 0 significa permitido; convenção keccak256("NAMESPACE:NAME").
ElegibilidadePermissão, no nível da conta, para enviar ou receber, respondida por hooks sinalizados com HOOK_ELIGIBILITY; exposta como canSend/canReceive do ERC-7943.
Saldo congeladoUnidades que uma conta detém, mas não pode mover (setFrozenTokens); pode exceder o saldo.
Transferência forçadaMovimentação de unidades por ENFORCER_ROLE sem o consentimento do titular (ERC-7943).
Atestação(batch, topic) → (issuer, reference, validity) registrada por um emissor confiável para aquele tópico.
TópicoUm bytes32 que identifica o assunto de uma atestação; aberto; mapeia-se para tópicos de declaração do ERC-735 e para identificadores de esquema do EAS.
Referência de origemoriginRef: um hash ou uma referência às evidências de origem; nunca coordenadas.
Compromisso de metadadosmetadataHash, keccak256 do documento canônico off-chain em uri.
StatusValor uint8 de ciclo de vida; 0 ativo, 255 baixado (terminal); 1..254 definidos pelo emissor.
CTE / KDEEvento crítico de rastreamento / elemento-chave de dados (FSMA 204).
DDSDeclaração de devida diligência (EUDR).
EPCISGS1 Electronic Product Code Information Services, o vocabulário de eventos para rastreabilidade (versão 2.0).
CPR / CPR-eCédula de Produto Rural, o recebível de safra do Brasil; forma eletrônica registrada em entidades autorizadas.
EWRRecibo de armazém eletrônico nos termos do U.S. Warehouse Act.
MLETRLei Modelo da UNCITRAL sobre Registros Eletrônicos Transferíveis.
ERC-7943 (uRWA)Interface Universal de Ativos do Mundo Real: congelamento, transferência forçada, elegibilidade; Final em maio de 2026.
ERC-3643 (T-REX)Padrão de token permissionado para valores mobiliários sobre ERC-20; Final em dezembro de 2023.
ERC-7201Layout de armazenamento com namespace para contratos atualizáveis.

Apêndice C: Bibliografia

Padrões e especificações

  • Radomski, W. et al. "EIP-1155: Multi Token Standard." Ethereum Improvement Proposals, 2018.
  • Vogelsteller, F., Buterin, V. "EIP-20: Token Standard." 2015.
  • "ERC-165: Standard Interface Detection." 2018.
  • "ERC-3643: T-REX — Token for Regulated EXchanges." Final, 15 de dezembro de 2023. https://eips.ethereum.org/EIPS/eip-3643
  • "ERC-7943: uRWA — Universal Real World Asset Interface." Final, 27 de maio de 2026. https://eips.ethereum.org/EIPS/eip-7943
  • "ERC-7201: Namespaced Storage Layout." 2023.
  • "ERC-735: Claim Holder." 2017 (rascunho).
  • Documentação do Ethereum Attestation Service.
  • GS1. "EPCIS and CBV Standard 2.0." 2022. GS1 US. "EPCIS Recommendations for FSMA 204 Critical Tracking Events." 2024.
  • UN/CEFACT. "Recommendation No. 20: Codes for Units of Measure Used in International Trade."
  • IETF RFC 8785. "JSON Canonicalization Scheme (JCS)." 2020.
  • Documentação do OpenZeppelin Contracts 5.x; anúncio da parceria entre a OpenZeppelin e a T-REX Network, julho de 2026.

Regulamentação e legislação

  • FDA. "Requirements for Additional Traceability Records for Certain Foods." Regra final, Federal Register 87(219), 2022; "Compliance Date Extension," Federal Register, 7 de agosto de 2025.
  • Regulamento (UE) 2023/1115 (Desmatamento); Regulamento (UE) 2025/2650 (alteração); comunicado de imprensa do Conselho da UE, 18 de dezembro de 2025.
  • Regulamento (UE) 2023/1114 (MiCA); Diretrizes da ESMA sobre a qualificação de criptoativos como instrumentos financeiros, dezembro de 2024.
  • European Data Protection Board. "Guidelines 02/2025 on processing of personal data through blockchain technologies," versão 2.0, 7 de julho de 2026.
  • SEC. Release No. 33-11412, 17 de março de 2026. SEC v. W.J. Howey Co., 328 U.S. 293 (1946).
  • GENIUS Act, Public Law 119-27 (2025); regulamentação de implementação, Federal Register, 18 de agosto de 2026.
  • Uniform Commercial Code, 2022 Amendments, Article 12 (Controllable Electronic Records).
  • U.S. Warehouse Act; 7 CFR Part 869 (Electronic Warehouse Receipts).
  • UNCITRAL. "Model Law on Electronic Transferable Records." 2017. Reino Unido, Electronic Trade Documents Act 2023.
  • Comisión Nacional de Valores (Argentina). Resolución General 1150/2026. Ley 9.643 (warrants).
  • Brasil. Lei 8.929/1994, Lei 13.986/2020 (CPR); Lei 11.076/2004 (CDA/WA); Resolução CVM 88 e Consulta Pública SDM 05/2025.
  • Verra. "Verra Addresses Crypto Instruments and Tokens." 2022; VCS Program Guide.
  • Diretiva (UE) 2024/825 (empoderamento dos consumidores para a transição ecológica).

Pesquisa e indústria

  • Zhang, P., Schmidt, D. C. "Blockchain Applications in Food Supply Chain Management: A Systematic Review." Journal of Food Engineering, 279, 2020.
  • Caro, M. P. et al. "Blockchain-based Traceability in Agri-Food Supply Chain Management." IEEE, 2018.
  • FAO. "The State of Food and Agriculture." 2023.
  • World Bank. "Future of Food: Harnessing Digital Technologies to Improve Food System Outcomes." 2022.
  • ERC3643 Association. "History of ERC-3643"; anúncio da iniciativa de padronização do ISO TC 307.
  • Chainlink. "Automated Compliance Engine (ACE): Technical Overview." 2025–2026.

Apêndice D: Modelos

D.1 Hook mínimo

Fonte: contracts/examples/MyHook.sol (importa ../reference/hooks/ARexHookBase.sol e ../standard/IARexBatch.sol).

contract MyHook is ARexHookBase {
    function hookFlags() public pure override returns (uint8) {
        return ARexCodes.HOOK_CHECK;
    }


    function check(uint8 op, address, address, address, uint256 id, uint256, bytes calldata)
        external
        view
        override
        returns (bytes32)
    {
        if (op != ARexCodes.OP_TRANSFER) return ARexCodes.OK;
        IARexBatch.Batch memory b = IARexBatch(msg.sender).batchOf(id);
        b; // decide from b.commodity, b.producedAt, b.expiresAt, b.status ...
        return ARexCodes.OK;
    }
}

D.2 Implantação (plugin de atualizações)

const token = await upgrades.deployProxy(await ethers.getContractFactory("ARexToken"), [admin, baseURI], { kind: "uups" });
const attestations = await (await ethers.getContractFactory("ARexAttestations")).deploy(admin, await token.getAddress());
await token.registerHook(await (await ethers.getContractFactory("EligibilityHook")).deploy(admin));
await token.registerHook(await (await ethers.getContractFactory("ExpiryHook")).deploy(true));

D.3 Esqueleto de metadados

{ "schemaVersion": "1.0.0", "commodity": { "scheme": "HS", "code": "100199" }, "unit": "KGM", "quantity": 250000,
  "traceabilityLotCode": "…", "production": { "producedAt": "…" }, "origin": { "country": "AR", "originRef": "…" },
  "status": { "table": { "1": "IN_STORAGE" } }, "documents": [ { "type": "warehouse_receipt", "hash": "…", "registryId": "…" } ],
  "restricted": { "uri": "…", "hash": "…", "accessPolicy": "…" } }

Apêndice E: Perguntas Frequentes

O A-REX é um ERC? Ainda não. A especificação está escrita em formato ERC e será submetida após uma implantação em produção, implementações independentes e uma auditoria. Nenhum número foi atribuído; os nomes no código não usam o prefixo ERC.

É obrigatório usar o ARexToken? Não. Implemente as interfaces da maneira que preferir; a referência é apenas uma das formas.

É obrigatório usar os hooks de referência? Não. São demonstrações. Copie-os, substitua-os ou escreva os próprios.

Um hook pode bloquear uma transferência forçada? Pode retornar um código para OP_FORCED_TRANSFER, e o token reverterá. Os hooks de referência não o fazem; um hook que trate de enforcement (por exemplo, exigindo uma referência de ordem) pode.

Onde ficam as coordenadas? Em armazenamento off-chain restrito, referenciado a partir dos metadados, nunca on-chain.

Como representar uma safra futura? producedAt = 0; condicione as transferências com ExpiryHook(allowPreHarvestTransfers).

A quantidade é conservada em transform? Não pelo padrão; a referência permite que qualquer titular faça o reagrupamento quando ela é conservada e exige TRANSFORMER_ROLE nos demais casos.

O token é um valor mobiliário? O padrão não decide. A oferta é que decide. Consulte assessoria jurídica; a superfície de enforcement está presente qualquer que seja a resposta.