Whitepaper · 08
Sicherheitsrahmen
Bedrohungsmodell, Invarianten, Zugriffskontrolle, die Vertrauensgrenze der Hooks, Schlüsselverwaltung für die Durchsetzung, Upgrade-Sicherheit und Audit-Lage der Referenzimplementierung von A-REX Core.
Sicherheitslage in einem Absatz
Der Referenz-Token hat einen zentralen Durchgangspunkt (_update), eine feste Auswertungsreihenfolge, eine Reentrancy-Sperre um die gesamte Hook-Sequenz, rollenbasierte Befugnisse, die nie aus Salden abgeleitet werden, ERC-7201-Speicher und eine kleine Angriffsfläche: acht externe zustandsändernde Funktionen jenseits von ERC-1155. Die mächtigsten Fähigkeiten – Einfrieren, erzwungener Transfer, Hook-Administration, Upgrades – sind getrennte Rollen, die für Multisigs und Timelocks vorgesehen sind, und jede Nutzung ist ein Ereignis.
Invarianten
| Invariante | Durchgesetzt durch | Getestet durch |
|---|---|---|
totalSupply(id) entspricht der Summe der Salden für id | OpenZeppelin ERC1155Supply; transform verbrennt und mintet anschließend über _update | Abstammungstests (Teilen, Zusammenführen, Verarbeiten) |
status == 255 ist terminal | setBatchStatus revertiert mit ARexInvalidStatusTransition | Statustests |
| Eine stillgelegte Charge kann nicht gemintet oder transferiert, sondern nur verbrannt werden | _update | Test für stillgelegte Chargen |
amount ≤ balance − frozen für vom Inhaber ausgelöste Bewegungen | _update; forcedTransfer senkt frozen auf balance − amount | Tests für Einfrieren und erzwungene Transfers |
| Kein Hook kann eine saldenändernde Funktion erneut betreten | Speichersperre vor den Prüfungen gesetzt, nach den Benachrichtigungen gelöscht | Test ReentrantHook |
Jede Saldenänderung wird als eigene Operation mit ihren eigenen data ausgewertet | _update liest und löscht den Operationskontext vor jeder Prüfung und jedem externen Aufruf | OpContext.test.js |
| Hooks werden in der Registrierungsreihenfolge ausgewertet; Entfernen bewahrt die Reihenfolge | Array-Verschiebung in removeHook | Reihenfolgetest |
| Eine abgelehnte Operation ändert keinen Saldo und emittiert keinen Transfer | Prüfungen laufen vor super._update | Ablehnungstest (Anzahl ausgeführter Aufrufe unverändert) |
| Befugnis leitet sich nie aus dem Saldo ab | jede zustandsändernde Funktion ist an eine Rolle oder an eine ERC-1155-Freigabe geknüpft | Tests „Das Halten von Token verleiht nichts“ |
canTransfer == (transferCheck == 0) | canTransfer ist genau so definiert | Konformitätstests |
Bedrohungsmodell
Akteure und Fähigkeiten
| Akteur | Kann | Kann nicht |
|---|---|---|
| Inhaber | nicht eingefrorene Einheiten an berechtigte Empfänger transferieren; verbrennen; Re-Batching desselben Rohstoffs und derselben Einheit bei erhaltener Menge in das eigene Konto (to == from) | den Status ändern, minten, zu einem anderen Rohstoff verarbeiten, Re-Batching in ein anderes Konto, eingefrorene Einheiten bewegen |
| Zugelassener Operator | wie der Inhaber, für das freigebende Konto | alles, was ein Inhaber nicht kann |
ISSUER_ROLE | Chargen erstellen | Token anderer bewegen |
TRANSFORMER_ROLE | Verarbeitungs-Transformationen und Transformationen, deren Ausgaben an ein anderes Konto gehen, von Token, die sie hält oder für die sie freigegeben ist | Token ohne Freigabe transformieren |
STATUS_ROLE | den Status ändern (einschließlich Stilllegung), Metadaten aktualisieren | Token bewegen |
ENFORCER_ROLE | beliebige Beträge einfrieren; beliebige Transfers erzwingen | Hooks umgehen (sie laufen mit OP_FORCED_TRANSFER) |
HOOK_ADMIN_ROLE | Hooks hinzufügen/entfernen | Salden direkt ändern |
PAUSER_ROLE | alles außer erzwungenen Transfers anhalten | — |
UPGRADER_ROLE | Implementierung ersetzen | – (das ist uneingeschränkte Macht; siehe Schlüsselverwaltung) |
ATTEST_ADMIN_ROLE | festlegen, welchen Ausstellern für welches Attestierungsthema vertraut wird; in den Referenz-Releases bis 2.0.0-alpha.4 außerdem jede Attestierung widerrufen (ADR-019, Vorgeschlagen: einen administrativen Widerruf SOLLTE es in 2.x NICHT geben, und ab 3.0 DARF es ihn NICHT geben) | im Namen eines Ausstellers attestieren |
| Vertrauenswürdiger Aussteller | Chargen zu seinen Themen attestieren; eigene Attestierungen widerrufen oder den Widerruf delegieren | zu einem Thema attestieren, für das ihm nicht vertraut wird |
| Hook-Contract | Operationen ablehnen; sie beobachten; Berechtigungsanfragen beantworten | erneut eintreten; Salden ändern |
Szenarien
Bösartiger oder fehlerhafter Hook (Denial of Service). Ein Hook, der stets ablehnt, blockiert alle Transfers des Tokens; ein Hook, der in check revertiert, bewirkt dasselbe. Gegenmaßnahme: HOOK_ADMIN_ROLE kann jeden Hook jederzeit entfernen (Reihenfolge bleibt erhalten); PAUSER_ROLE kann während der Untersuchung anhalten; erzwungene Transfers laufen weiterhin, sodass die Durchsetzung nicht verloren geht. Die Registrierung prüft die ERC-165-Unterstützung und Flags ungleich null und weist EOAs zurück. Empfehlung: Hooks vor der Registrierung auditieren; die Anzahl klein halten; den Administrator hinter einen Timelock legen, damit Hook-Änderungen sichtbar sind, bevor sie wirksam werden.
Reentrancy durch einen Hook. onExecuted eines Hooks ruft safeTransferFrom zurück auf. Gegenmaßnahme: die Sperre; der Aufruf revertiert mit ARexReentrantCall. Zu beachten ist, dass der Empfänger-Callback von ERC-1155 (onERC1155Received) wie bei jedem ERC-1155-Token nach der Freigabe der Sperre läuft; der Zustand des Tokens ist dann bereits endgültig.
Operationskontext in Empfänger-Callbacks. Ein Vertrag als Empfänger startet aus onERC1155Received heraus einen Transfer oder einen Burn. Dieser verschachtelte Aufruf ist ein OP_TRANSFER oder OP_BURN mit seinen eigenen data, nicht Teil der Operation, die die Token geliefert hat. Bis 2.0.0-alpha.2 hielt der Referenz-Token die äußere Operation im Speicher, bis der äußere Aufruf zurückkehrte; ein verschachtelter Aufruf nach einem forcedTransfer lief daher als OP_FORCED_TRANSFER (unter Umgehung von Pause, Berechtigung und eingefrorenen Salden), und einer nach einem transform lief als OP_TRANSFORM, das Hooks, die nur OP_TRANSFER prüfen, durchließen. Gegenmaßnahme: _update liest und löscht den Operationskontext vor jeder Prüfung und jedem externen Aufruf, sodass ein aus einem Callback gestarteter Aufruf als er selbst ausgewertet wird; OpContext.test.js verwendet einen Empfänger, der aus seinem Callback heraus transferiert und verbrennt.
Lieferung durch Re-Batching. Beide Teilvorgänge eines transform führen die Hooks mit OP_TRANSFORM aus. Könnte ein Inhaber ein Re-Batching in ein anderes Konto vornehmen, wechselten Güter den Besitzer ohne die Prüfungen von Hooks, die nur OP_TRANSFER prüfen, etwa eine vor dem Verkauf erforderliche Attestierung oder für eine Lieferung gesperrte Einheiten. Gegenmaßnahme: Ohne TRANSFORMER_ROLE ist ein Re-Batching nur zulässig, wenn to == from; neu aufgeteilte Güter gelangen über einen gewöhnlichen Transfer zu einem anderen Inhaber, der jede Transferregel durchläuft (ADR-007, geändert am 2026-10-20).
Umgehung einer Sperre durch Burn oder Re-Batching. Hook-Zustand, der pro Chargen-ID geführt wird, folgt einer Charge nicht in ihre Ausgaben. Ein Hook, der Einheiten sperrt und nur OP_TRANSFER prüft, hindert den Inhaber nicht daran, die gesperrten Einheiten zu verbrennen oder sie im eigenen Konto in eine neue ID aufzuteilen, die die Sperre nicht abdeckt. Gegenmaßnahme: DeliveryHook lehnt mit IN_TRANSIT jeden Burn und jeden Eingangsteilvorgang eines transform ab, der den Saldo unter die gesperrten Einheiten senken würde; erzwungene Transfers bleiben unbeschränkt, und nach einer Beschlagnahme gibt der Hook einen Code zurück, statt zu revertieren. Hooks, die Einheiten reservieren, sollten neben OP_TRANSFER auch OP_BURN und OP_TRANSFORM prüfen.
Kompromittierter Durchsetzungsschlüssel. Wer ENFORCER_ROLE hält, kann beliebige Token bewegen. Gegenmaßnahme: Multisig mit einem dokumentierten Verfahren (Gerichtsbeschluss, Pfandvertrag, Sanktionsmitteilung); jede Aktion emittiert ForcedTransfer/Frozen; Hooks können eine Anordnungsreferenz in den Transferdaten verlangen (OP_FORCED_TRANSFER ist nicht von den Hooks ausgenommen). Für nicht dringliche Durchsetzungsmaßnahmen ist ein Timelock in Erwägung zu ziehen.
Kompromittierter Upgrader. Totale Kompromittierung. Gegenmaßnahme: Multisig plus Timelock; OpenZeppelin-Upgrade-Validierungen in der CI; ERC-7201-Speicher, um Layout-Unfälle zu vermeiden.
Missbrauch des Status. STATUS_ROLE kann eine Charge stilllegen, die von anderen gehalten wird. Das ist beabsichtigt – ein Lager, ein Prüfer oder eine Aufsichtsbehörde erklärt eine Charge für untauglich – und muss den Inhabern offengelegt werden. Gegenmaßnahme: einer rechenschaftspflichtigen Institution zuweisen; jede Änderung ist ein Ereignis mit einem Grund.
Betrug durch den Aussteller. ISSUER_ROLE kann eine Charge erstellen, die physisch nicht existiert. Der Token kann dies nicht verhindern; er macht es zuordenbar (issuer, originRef, metadataHash) und ermöglicht es, über AttestationHook Attestierungen unabhängiger Parteien (Lager, Prüfer, Register) vor dem Transfer vorauszusetzen.
In der Herkunftsreferenz versteckter Standort. Ein Hash, ein Geohash oder eine andere Kodierung von Parzellenkoordinaten in originRef wirkt anonym, lässt sich aber aus einer erratenen Parzelle neu berechnen und kann nie aus dem Ledger gelöscht werden. Gegenmaßnahme: originRef ist eine Referenz auf einen Nachweis oder eine Zufallsreferenz; die Geolokalisierung bleibt Off-Chain (für die EUDR im EU-Informationssystem). Der mit ADR-019 (Vorgeschlagen) eingebrachte Entwurf macht „niemals aus dem Standort abgeleitet“ zu einer MUSS-Anforderung; entschieden war es bereits mit ADR-008.
Unverifizierte Upstream-Referenzen. Eine Charge, die aus der Charge eines anderen Tokens hergestellt wurde, benennt diese in der Liste upstream ihrer Metadaten. Das ist die Behauptung des nachgelagerten Ausstellers: Er kann eine Charge nennen, die er nie gehalten hat, oder eine weglassen, die er gehalten hat. Gegenmaßnahme: Indexer, Auditoren und Rückrufwerkzeuge prüfen jede Referenz am vorgelagerten Token (die Charge existiert, der Metadaten-Hash stimmt überein, der Transfer an den Aussteller hat stattgefunden, sofern ein Transaktionshash angegeben ist) und weisen die Referenzen, die sie nicht prüfen konnten, als unverifiziert aus.
Austausch der Metadaten. setBatchMetadata ändert Hash und URI. Gegenmaßnahme: rollengesteuert; die Ereignisse BatchMetadataUpdated und URI bewahren die Historie; frühere Dokumente bleiben anhand früherer Hashes überprüfbar.
Front-Running von transferCheck. Eine Vorabprüfung kann veralten, bevor die Transaktion ausgeführt wird (der Zustand eines Hooks ändert sich). Die Transaktion wertet erneut aus; im schlimmsten Fall kommt es zu einem Revert mit einem präzisen Code.
Gas-Griefing durch Hooks. Jeder Hook fügt pro betroffener ID und Phase einen externen Aufruf hinzu. Ein Hook mit unbegrenzten Schleifen macht Transfers unbezahlbar. Gegenmaßnahme: Regeln für die Hook-Entwicklung (begrenztes check), Prüfung vor der Registrierung.
Vertrauen in upgradefähige Hooks. Ein hinter einem Proxy ausgerollter Hook kann die Transferrichtlinie ändern, ohne dass sich am Token etwas ändert. Gegenmaßnahme: Administratorschlüssel von Hooks mit derselben Sorgfalt behandeln wie HOOK_ADMIN_ROLE; im Produktivbetrieb unveränderliche Hooks bevorzugen.
Zugriffskontrollmodell
OpenZeppelin AccessControl mit acht Rollen am Token und einer am Attestierungsregister; DEFAULT_ADMIN_ROLE verwaltet sie alle. Empfohlene Aufteilung im Produktivbetrieb:
| Rolle | Inhaber |
|---|---|
DEFAULT_ADMIN_ROLE, UPGRADER_ROLE, HOOK_ADMIN_ROLE | Governance-Multisig hinter einem Timelock |
ENFORCER_ROLE | Durchsetzungs-Multisig (Compliance + Recht) |
PAUSER_ROLE | Schlüssel für die Störfallreaktion (schnell) |
ISSUER_ROLE, STATUS_ROLE, TRANSFORMER_ROLE | operative Dienste mit minimalen Rechten, rotiert |
ATTEST_ADMIN_ROLE | die Governance des Tokens: Sie legt fest, welchen Ausstellern je Thema vertraut wird, nicht, was diese attestieren |
initialize überträgt aus Bequemlichkeit alles an einen Administrator; die Deployment-Checkliste verlangt vor dem Produktivbetrieb eine Neuverteilung.
Semantik von Durchsetzung und Pause
- Die Pause blockiert Mints, Transfers, Burns und Transformationen; sie blockiert erzwungene Transfers nicht, sodass eine rechtmäßige Anordnung während eines Störfalls ausgeführt werden kann.
- Erzwungene Transfers überspringen
canSend/canReceiveund die Prüfung des eingefrorenen Saldos, senken den eingefrorenen Betrag auf den verbleibenden Rest und führen die Hooks weiterhin mitOP_FORCED_TRANSFERaus. Referenz-Hooks liefern für diese OperationOK; ein Hook, der die Durchsetzung regelt, kann Anordnungsreferenzen indataverlangen. - Das Einfrieren darf den Saldo übersteigen (ERC-7943), sodass ein Pfandrecht auch künftige Zugänge erfassen kann.
Fähigkeiten im Standard, Richtlinien in Profilen
ADR-019 (Vorgeschlagen) zieht eine Linie durch jede Durchsetzungsfunktion. Der Standard legt fest, was existiert und was es garantiert: die Rollen, die Ereignisse, was eine Pause anhält, die Codes AREX:PAUSED und AREX:SANCTIONED, wer eine Attestierung widerrufen darf, und die Datenschutzregeln. Ein Richtlinienprofil, geführt je Rechtsordnung und je Organisation und wie eine Verordnung mit Daten versioniert, sagt, wer jede Fähigkeit nutzen darf und unter welchen Bedingungen:
| Fähigkeit | Vom Standard festgelegt | Vom Richtlinienprofil festgelegt |
|---|---|---|
| Einfrieren und erzwungener Transfer | setFrozenTokens, forcedTransfer, ihre Ereignisse, eine eigene, von der Administration getrennte Rolle, Hooks laufen mit OP_FORCED_TRANSFER | ob die Rolle überhaupt aktiviert werden darf, wer sie hält und mit wie vielen Unterzeichnern, welche rechtliche Referenz jede Nutzung tragen muss, wer zu benachrichtigen ist |
| Pause | was eine Pause anhält, AREX:PAUSED, erzwungene Transfers bleiben erlaubt | wer pausieren und die Pause aufheben darf, welche Bestätigung und welcher Grund erforderlich sind, wer informiert wird |
| Sanktionen | AREX:SANCTIONED und die Bedeutung von canSend / canReceive | welche amtlichen Listen gelten (UN, OFAC, EU, OFSI oder eine Kombination), wie sie aktuell gehalten werden und dass ein Mensch einen Treffer bestätigt, bevor ein Konto markiert wird |
| Widerruf von Attestierungen | der Aussteller widerruft, ein von ihm beauftragter Widerrufsberechtigter darf es; eine administrative Rolle sollte es in 2.x nicht und darf es ab 3.0 nicht | welchen Ausstellern ein Token je Thema vertraut; wie ein Betreiber einen Streitfall festhält |
| Datenschutz der Herkunft | originRef enthält keine Koordinaten oder personenbezogenen Kennungen und ist nicht aus dem Standort abgeleitet | welche Referenz ein Aussteller verwendet und wo die Geolokalisierung Off-Chain aufbewahrt wird |
Eine Gesetzesänderung wird damit zu einer Aktualisierung des Profils, nie zu einem neuen Contract oder einer neuen Version des Standards.
Upgrade-Sicherheit
- UUPS;
_authorizeUpgradedurchUPGRADER_ROLEabgesichert. - ERC-7201-Speicher-Struct mit Namensraum; nur Anhängen erlaubt.
- Die Validierungen des OpenZeppelin-Upgrades-Plugins laufen in den Tests und sollten vor jeder Upgrade-Transaktion in der CI laufen.
- Die dateibezogene Einstellung
optimizer.runs = 1hält die Implementierung unter EIP-170; eine Änderung, die sie darüber hebt, schlägt beim Kompilieren mit einer Warnung und beim Deployment mit einem Revert fehl.
Sicherheit von Abhängigkeiten und Build
- OpenZeppelin Contracts und Contracts-Upgradeable auf 5.3.0 fixiert; Lockfile eingecheckt; die CI verwendet
npm ci. - Solidity 0.8.22, viaIR, EVM
paris(keine Abhängigkeit von Transient Storage, auf Chains einsetzbar, die Cancun nicht übernommen haben). - Keine externen Bibliotheken gelinkt; kein delegatecall außerhalb des UUPS-Proxys.
Audit-Lage
- 46 Tests für die Referenzimplementierung, die Hooks und die Erweiterungen decken jede der oben genannten Invarianten ab, einschließlich eines mit festem Seed randomisierten Invariantenlaufs.
- Gas und Größe werden durch Skripte im Repository gemessen.
- Ein Audit von
ARexToken,ARexAttestationsund den Referenz-Hooks durch Dritte ist eine erklärte Voraussetzung für einen Anker im Produktivbetrieb und für die Einreichung des ERC (siehe Zukünftige Entwicklungen). - Die formale Verifikation der Pipeline-Invarianten steht auf der Roadmap; die Invarianten sind klein genug, um als Eigenschaften formuliert zu werden.
Sicherheitshinweise
| Hinweis | Betrifft | Behoben in | Probleme |
|---|---|---|---|
| AREX-2026-001 | Referenzimplementierung bis einschließlich 2.0.0-alpha.2 | 2.0.0-alpha.3 | Operationskontext gelangte in ERC-1155-Empfänger-Callbacks; Re-Batching ohne Rolle konnte Güter an einen anderen Inhaber an OP_TRANSFER-Hooks vorbei liefern; Sperren von DeliveryHook ließen sich durch Burn oder Re-Batching umgehen |
2.0.0-alpha.3 ersetzt 2.0.0-alpha.2. Bereitgestellte Token-Proxys werden über UPGRADER_ROLE auf die neue Implementierung aktualisiert; das Speicherlayout bleibt unverändert. DeliveryHook ist nicht upgradefähig: die neue Version bereitstellen, sie mit registerHook registrieren, die alte mit removeHook entfernen und aktive Lieferungen neu planen, da ihre Sperren im Speicher des alten Hooks liegen. Integrationen, die direkt in das Konto eines Käufers teilen oder zusammenführen, müssen im eigenen Konto neu aufteilen und dann transferieren oder ein Konto mit TRANSFORMER_ROLE verwenden. Die Schnittstellen des Standards ändern sich nicht.
Restrisiken, die der Standard nicht beseitigt
- Die physische Existenz und die Qualität einer Charge werden attestiert, nicht bewiesen; der Token macht Aussagen zuordenbar, nicht wahr.
- Die Verfügbarkeit von Off-Chain-Metadaten hängt vom gewählten Speicher ab; der Hash garantiert Integrität, nicht Verfügbarkeit.
- Die Governance von Hooks und Modulen ist nur so gut wie die Schlüssel, die sie kontrollieren.