Compliance Transfer
Step-by-step sequence for how DALP validates token transfers through the compliance engine, from identity resolution through sequential module evaluation to post-transfer state updates.
Purpose
Step-by-step reference for the compliance validation sequence that every token transfer passes through before execution.
- Doc type: Reference (flow)
- What you'll find here:
- Complete transfer validation sequence with numbered steps
- Identity resolution and module evaluation order
- Post-transfer state update hooks
- Failure behavior and revert semantics
- Related:
- Identity & Compliance — architecture explanation
- Compliance Modules — module catalog
- Signing Flow — complete transaction security sequence
- SMART Protocol integration (ERC-3643) — core protocol architecture
Transfer validation sequence
Every token transfer (including mints, burns, and redemptions) passes through the compliance engine before any state changes occur.
Step-by-step flow
- Transfer initiation — User calls
transfer(to, amount)on the token contract - Compliance check — Token contract calls
canTransfer(from, to, amount)on the compliance contract before any state changes - Identity resolution — Compliance contract queries the identity registry to map wallet addresses to OnchainID contracts for both sender and recipient. Missing mappings fail immediately with "Identity not registered"
- Sequential module evaluation — Compliance contract iterates through modules in configuration order:
- Each module receives token address, sender, recipient, amount, and encoded parameters
- Modules that require claims query the sender's/recipient's OnchainID contracts
- Claim validation checks: claim exists for required topic, trusted issuer issued it, claim has not expired, claim data matches expected values
- First module returning
falseimmediately reverts the entire transaction with a reason string (fail-fast)
- Balance transfer — After all modules pass, token contract executes
_transfer(from, to, amount) - State update hooks — Token contract calls
transferred(from, to, amount)on the compliance contract, which forwards to all configured modules for state updates:- Investor count modules increment/decrement holder counts
- Supply tracking modules update accumulation
- Time lock modules record acquisition timestamps
- Transfer approval modules consume single-use approvals

Key invariants
- Pre-execution validation:
canTransfercompletes before any balance changes, so failed checks cost only validation gas - Fail-fast evaluation: First failing module stops all evaluation — no unnecessary gas spent on subsequent modules
- Atomic state updates: Post-transfer hooks must all succeed or the entire transfer reverts
- Module ordering matters: Modules evaluate in configuration order. Place restrictive checks (country, identity) before expensive checks (supply tracking, investor counting)
Failure modes
| Failure | Cause | Behavior |
|---|---|---|
| Identity not registered | Wallet has no OnchainID mapping | Immediate revert, no module evaluation |
| Claim missing | Required claim topic not found on identity | Module returns false, transaction reverts with module reason |
| Untrusted issuer | Claim exists but issuer not in trusted registry | Module returns false, same as missing claim |
| Expired claim | Claim's expiry timestamp < block.timestamp | Module returns false, revert with "Claim expired" |
| Module limit exceeded | Supply cap, investor count, or holding period violated | Module returns false with specific reason string |
| State hook failure | Post-transfer module state update fails | Entire transfer reverts |
See also
- Identity & Compliance — OnchainID architecture and two-layer policy model
- Compliance Modules — full catalog of built-in modules
- Signing Flow — end-to-end transaction signing including custody layer
Asset Issuance
Step-by-step flow for issuing a new digital asset on the DALP platform, from infrastructure deployment through identity setup, compliance configuration, and initial token operations.
Feeds update flow
End-to-end lifecycle of publishing, validating, and consuming feed values in DALP, covering both issuer-signed scalar feeds and Chainlink adapter reads.