Diagramas · 03
Pipeline de transferência
Toda mudança de saldo no token de referência passa por uma única função. A ordem abaixo é fixa; transferCheck e canTransfer a reproduzem como views.
Sequência de uma transferência com dois hooks
sequenceDiagram
autonumber
participant U as Titular / operador
participant T as ARexToken._update
participant E as EligibilityHook (CHECK, ELIGIBILITY)
participant X as ExpiryHook (CHECK)
participant R as TraceabilityHook (EXECUTED)
U->>T: safeTransferFrom(from, to, id, amount, data)
T->>T: trava (reentrância) · não pausado
T->>E: canSend(from) / canReceive(to)
E-->>T: true / true
T->>T: lote existe · status != RETIRED · amount ≤ balance − frozen
T->>E: check(OP_TRANSFER, operator, from, to, id, amount, data)
E-->>T: OK
T->>X: check(OP_TRANSFER, …)
X-->>T: OK
T->>T: super._update (saldos, oferta)
T->>R: onExecuted(OP_TRANSFER, …)
R-->>T: emite evento no formato EPCIS
T->>T: libera a trava
T-->>U: TransferSingleO que acontece na rejeição
flowchart LR
A["check retorna código ≠ 0"] --> B["revert ARexHookRejected(hook, code)"]
B --> C["nenhum saldo alterado"]
B --> D["nenhum TransferSingle emitido"]
B --> E["o front-end mapeia código → mensagem<br/>p. ex. keccak256('AREX:BATCH_EXPIRED')"]Ordem de avaliação e quem pode dispensar o quê
| Etapa | Transferência do titular | forcedTransfer (ENFORCER_ROLE) | transform |
|---|---|---|---|
| trava | sim | sim | sim |
| pausa | bloqueia | não bloqueia | bloqueia |
canSend / canReceive | sim | dispensado | sim (entradas de from, saídas para to) |
| saldo congelado | aplicado | reduzido para balance − amount | aplicado |
hooks check | OP_TRANSFER | OP_FORCED_TRANSFER | OP_TRANSFORM para entradas e saídas |
hooks onExecuted | sim | sim | sim |