Skip to main contentA-REX Foundation

Decision records · ADR-007

ADR-007: Lineage through an atomic transform operation

Split, merge and processing are one operation, transform, which burns inputs, mints outputs, records their parents on-chain and emits one event that maps to an EPCIS TransformationEvent.

Accepted
Document ID
ADR-007
Date
2026-09-21
FieldValue
IDADR-007
Subject areaTraceability
StatusAccepted
Date2026-09-21
OwnersA-REX Contributors
Related requirementsFR-04 (SDD §3)
Supersedes / superseded by— (amended 2026-10-20, see Amendment)

Context

Lots become other lots: a truckload is split between buyers, silos are merged, wheat is milled into flour. FSMA 204's transformation critical tracking event and GS1 EPCIS 2.0's TransformationEvent both link inputs to outputs with quantities. The earlier design had a PROCESSED state but no way to create the processed lot, and its documentation described parent mappings that did not exist in the code.

Issue

How does a token record that one lot became another, so that recalls and mass-balance audits can follow it?

Assumptions

  • Regulators and buyers ask for input-to-output links with quantities.
  • Re-batching by holders is routine and should not need an institution.

Constraints

  • The link must be atomic with the balance changes.
  • Hooks must be able to see and govern the operation.

Alternatives considered

AlternativeForAgainstOutcome
An administrative setParent mappingSimpleNot atomic, no quantities, can be forged after the factRejected
Separate split, merge and process functionsExplicitThree functions and events for one operation with different cardinalitiesRejected
One transform(from, to, inputIds, inputAmounts, outputs, outputAmounts, processRef)Atomic, quantified, one event, one EPCIS mappingCallers build arraysAccepted

Decision

transform burns the inputs from from and mints the outputs to to in one transaction, records parentsOf(output) = inputIds, emits one BatchTransformed, and runs every hook with OP_TRANSFORM on each leg. In the reference, a re-batch (same commodity and unit, Σ inputs = Σ outputs) needs only ownership or approval; any other transformation also needs TRANSFORMER_ROLE.

Argument

Making lineage an operation rather than a record means it cannot be written without the units actually moving, and it gives indexers one event per transformation instead of a reconstruction from transfers.

Consequences

Positive

  • A recall walks parentsOf backwards and BatchTransformed forwards.
  • Holders can split and merge without waiting for an institution.

Negative

  • The standard does not enforce quantity conservation for processing, because yields vary; that is a policy of the reference and of hooks.

Obligations it creates

  • Processors hold TRANSFORMER_ROLE; yield rules, if any, are hooks.

Implementation and evidence

WhatWhere
OperationARexToken.transform, _isRebatch
Split, merge, processing, roletest/standard/ARexToken.test.js: splits a batch without any role…, merges two batches into one, processing into another commodity requires TRANSFORMER_ROLE
Executed walkthrough and lineage graphtest/standard/ImplementationGuide.test.js

Amendment 2026-10-20: re-batching keeps goods with the holder

The sections above are the decision as recorded on 2026-09-21 and are left unchanged. This amendment narrows one part of it.

What changed. The Decision said that in the reference implementation a re-batch (same commodity and unit, Σ inputs = Σ outputs) needs only ownership or approval. That allowed a holder to re-batch with to set to another account. Both legs of a transform run hooks with OP_TRANSFORM, so hooks that gate only OP_TRANSFER (AttestationHook, DeliveryHook) never saw the hand-over: a holder could deliver unattested lots, or lots locked for a delivery, to a buyer in one call. The same assumption ("re-batching by holders is routine") holds for re-lotting one's own goods, not for handing them to someone else.

Amended rule (reference implementation, arex-contracts commit f71d808 on branch fix/op-context-reentry). Without TRANSFORMER_ROLE, a re-batch is allowed only when to == from. Delivering the outputs of any transform to another account requires TRANSFORMER_ROLE. A holder who wants to split and sell re-lots in place and then transfers, which runs every OP_TRANSFER rule. A related fix (arex-contracts commit 8313698, same branch) makes DeliveryHook reject OP_BURN and the burn leg of OP_TRANSFORM that would take a holder below its locked units, so a lock cannot be escaped by burning or re-lotting in place.

Standard. The interfaces and the MUST text of AREX-CORE.md §3.4 are unchanged: msg.sender must still be from or its approved operator, and implementations may require stronger authorization. AREX-CORE.md 2.1.0-alpha.0 §8 makes the to == from rule RECOMMENDED ("Re-batching to another holder") and asks hooks that lock units to also gate burns and the burn leg of OP_TRANSFORM ("Locks, burns and re-lotting in place"). Making the rule a MUST is deferred to a 3.0 major version and is the owner's decision; it is also raised as an open question for the ERC review.

Consequences.

  • Positive: every movement of goods between holders without a privileged role is an OP_TRANSFER, so transfer rules cannot be bypassed through lineage.
  • Negative: a holder can no longer split and deliver in one transaction; it takes a transform and a transfer. Processors that deliver outputs directly to a buyer need TRANSFORMER_ROLE.

Evidence. test/standard/ARexToken.test.js in arex-contracts: a re-batch to another account requires TRANSFORMER_ROLE, also for an approved operator, a TRANSFORMER_ROLE holder may re-batch to another account, re-batching cannot deliver goods past hooks that gate OP_TRANSFER. Background in the security note on operation context in arex-contracts (docs/SECURITY-NOTE-op-context.md).

  • ADR-002: ERC-1155 as the base token standard
  • ADR-006: Open codes instead of closed enumerations
  • ADR-010: Authority comes from roles, never from balances; RETIRED is terminal