Skip to main contentA-REX Foundation

Whitepaper · 04

Solution Overview

Architecture of A-REX Core: three tiers with one direction of dependency, the transfer pipeline, the actors, and how the pieces are deployed.

Three tiers, one direction of dependency

A-REX separates what must be standardized from what must merely work:

The four layers of the standard

flowchart TB
    L3["Layer 3 · IARexAttest<br/>attestations for a batch and a topic"]
    L2["Layer 2 · IARexHook + IARexHookManager<br/>one ordered pipeline of rules"]
    L1["Layer 1 · IARexBatch<br/>identity, status, a metadata commitment, and lineage"]
    L0["Layer 0 · ERC-1155 + ERC-165 + IERC7943MultiToken<br/>balances and an enforcement surface"]
    L3 --- L2 --- L1 --- L0
    classDef l3 fill:#edf5ff,stroke:#0f62fe,color:#161616
    classDef l2 fill:#d0e2ff,stroke:#0f62fe,color:#161616
    classDef l1 fill:#a6c8ff,stroke:#0f62fe,color:#161616
    classDef l0 fill:#78a9ff,stroke:#0043ce,color:#161616
    class L3 l3
    class L2 l2
    class L1 l1
    class L0 l0

The two tiers of the repository and the direction of dependency

flowchart LR
    STD["<b>The standard</b><br/>standard/ · contracts/standard/<br/>normative · CC0"]
    REF["<b>Reference implementation</b><br/>ARexToken · ARexAttestations<br/>MIT"]
    DEMO["<b>Demonstrations</b><br/>7 hooks · 3 extensions<br/>MIT · not normative"]
    STD -->|implemented by| REF -->|demonstrated by| DEMO
    DEMO -.->|depend only on the interfaces| STD

The standard never depends on the reference; the token never depends on the hooks. Remove every hook and every extension and a conformant token still exists. A third party obtains the normative text through early access, rather than from this public chapter.

What a batch is

A batch is an ERC-1155 token id. The field layout stays in the normative text.

Everything richer — grade, moisture, protein, packaging, GS1 identifiers, the traceability lot code, the EUDR declaration reference, lab reports, the issuer's status table — lives in the metadata document whose hash is committed on-chain. The document follows a published JSON Schema aligned with EPCIS 2.0 and the FSMA 204 key data elements.

The transfer pipeline

Every balance change — mint, transfer, burn, forced transfer, transformation — passes through one choke point in the reference token. The order is fixed and auditable:

flowchart TD
    A[safeTransferFrom / createBatch / burn / forcedTransfer / transform] --> B[reentrancy lock]
    B --> C{paused?}
    C -- yes, not forced --> X1[EnforcedPause]
    C -- no --> D{canSend from / canReceive to<br/>conjunction of ELIGIBILITY hooks}
    D -- false --> X2[ERC7943CannotSend / CannotReceive]
    D -- true --> E{per id: exists? not retired?<br/>amount ≤ balance − frozen?}
    E -- fail --> X3[ARexBatchNotFound / ARexBatchRetired /<br/>ERC7943InsufficientUnfrozenBalance]
    E -- ok --> F{per id, per CHECK hook in order:<br/>check → code}
    F -- code ≠ 0 --> X4["ARexHookRejected(hook, code)"]
    F -- all 0 --> G[balances updated · supply tracked]
    G --> H[per id, per EXECUTED hook: onExecuted]
    H --> I[unlock]

Two views replay the same logic without changing state: canTransfer (boolean, as ERC-7943 requires) and transferCheck (the first rejection code, so an interface can tell the user why).

Forced transfers skip the pause and the eligibility checks — enforcement must work when everything else is frozen — but still run the hooks with OP_FORCED_TRANSFER, so a hook can insist, for example, on a court-order reference in the transfer data.

Lineage

transform is the single operation for splitting, merging and processing:

graph LR
    W1["wheat #1<br/>250 t · farmer"] -- "transform (re-batch in place)" --> W2["wheat #2<br/>100 t · farmer"]
    W1 -- "transform (re-batch in place)" --> W3["wheat #3<br/>150 t · farmer"]
    W2 -- "transfer" --> M2["wheat #2<br/>100 t · mill"]
    M2 -- "transform (processing, TRANSFORMER_ROLE)" --> F4["flour #4<br/>75 t · mill"]
  • Re-batching (same commodity, same unit, conserved quantity) is open to any holder or approved operator as long as the outputs stay with the holder (to == from): a cooperative splitting a silo lot before allocating it to members, an exporter merging deliveries it has received. The new lots reach another holder through an ordinary transfer, which runs every transfer check and hook; re-batching straight into another account requires TRANSFORMER_ROLE.
  • Processing (anything else) additionally requires TRANSFORMER_ROLE.
  • parentsOf(4) == [2], parentsOf(2) == [1]; one BatchTransformed event per operation, which is an EPCIS TransformationEvent by construction.

Enforcement

ENFORCER_ROLE can freeze any amount for any account (setFrozenTokens, may exceed the balance, as ERC-7943 specifies) and move tokens without the holder's consent (forcedTransfer). This is what makes a batch token usable outside a demo: a lender executing a warrant, a court ordering the seizure of stored grain, a warehouse recovering a lot after a customer loses keys. Every enforcement action is an event.

Hooks

A hook is a contract with five functions and a constant flags bitmap. The token caches the flags at registration, so a transfer costs one external call per interested hook, not one interface probe per capability per module. A hook learns which token is calling from msg.sender; one deployment can serve many tokens.

Reference hooks demonstrate the three capabilities:

HookCapabilityWhat it proves
EligibilityHookCHECK + ELIGIBILITYallow/block lists and sanctions feed canSend / canReceive and produce precise codes
ExpiryHookCHECKperishability and pre-harvest gating derived purely from the batch record
AttestationHookCHECK"coffee needs an EUDR declaration attested before it can be sold"
PerishabilityHookCHECKdecay models and value views; expired or valueless lots do not move
SeasonalHookCHECKharvest and trading windows per commodity
DeliveryHookCHECK + EXECUTEDcustody lock during delivery that transfers, burns and re-lotting cannot get around; settlement is the transfer itself, identified by data
TraceabilityHookEXECUTEDEPCIS-shaped event log of every operation plus manual critical tracking events

Companion extensions (not hooks): CommodityPriceOracle, CarbonImmobilizationWrapper, ParametricInsurance.

Attestations

A companion contract records (batch, topic) → (issuer, reference, validity). Only issuers trusted for a topic can attest; revocation, expiry and loss of trust all make isAttested false. Topics are bytes32, so ERC-735 claim topics, Ethereum Attestation Service schema ids and hashes of certification names all work without a table in the standard.

Actors and roles

ActorTypical role in the reference tokenTypical action
Originator platform, cooperative, elevatorISSUER_ROLEcreateBatch
Farmer / holdernonetransfer, re-batch in place, burn
Mill, packer, processorTRANSFORMER_ROLEprocessing transform
Warehouse, inspector, platformSTATUS_ROLEsetBatchStatus, setBatchMetadata
Certifier, laboratory, authoritytrusted issuer for a topicattest
Lender, court-appointed custodian, complianceENFORCER_ROLEsetFrozenTokens, forcedTransfer
Governance (multisig, timelock)DEFAULT_ADMIN_ROLE, HOOK_ADMIN_ROLE, UPGRADER_ROLE, PAUSER_ROLEroles, hooks, upgrades, pause

Nothing in the standard fixes these roles; they are how the reference implementation exercises the MUSTs ("restricted to an authorized role").

Deployment shapes

  • Public L2 (Polygon, Arbitrum, Base, Optimism): cheapest, most composable; suited to commodity trading and financing where counterparties are businesses.
  • Permissioned EVM chain: where data-protection authorities or the anchor institution require it; the EDPB expressly encourages permissioned designs. The standard is chain-agnostic.
  • Hybrid: batches on a public chain, restricted data (plot polygons, producer identity) behind access-controlled storage referenced from metadata.

The reference stack deploys with one Ignition module or one script: token proxy, attestation registry, eligibility and expiry hooks.

Design decisions and the alternatives they replace

Alternative consideredA-REX CoreReason
a wide core interface with enums for commodity, grade, state8-function IARexBatch with open codesnothing to redeploy for a new crop, scheme or lifecycle
capability interfaces probed on every transferone hook interface, flags cachedgas linear in hooks, not in ids × modules × probes
string reasonsbytes32 codes and typed errorsmachine-readable, indexable
lifecycle state changeable by any holderrole only; RETIRED terminalsecurity
harvest date required in the pastproducedAt == 0 allowedpre-harvest financing
no split / merge / processingtransform + parentsOftraceability, recalls, EPCIS
no freeze or forced transferERC-7943enforceability
coordinates stored on-chainorigin reference onlyGDPR / EDPB 02/2025
registry and identity contracts requirednothing requiredno imposed identity stack