SettleMint
ArchitectureFlows

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:

Transfer validation sequence

Every token transfer (including mints, burns, and redemptions) passes through the compliance engine before any state changes occur.

Rendering diagram...

Step-by-step flow

  1. Transfer initiation — User calls transfer(to, amount) on the token contract
  2. Compliance check — Token contract calls canTransfer(from, to, amount) on the compliance contract before any state changes
  3. 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"
  4. 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 false immediately reverts the entire transaction with a reason string (fail-fast)
  5. Balance transfer — After all modules pass, token contract executes _transfer(from, to, amount)
  6. 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

Compliance verification checks gate all token transfers

Key invariants

  • Pre-execution validation: canTransfer completes 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

FailureCauseBehavior
Identity not registeredWallet has no OnchainID mappingImmediate revert, no module evaluation
Claim missingRequired claim topic not found on identityModule returns false, transaction reverts with module reason
Untrusted issuerClaim exists but issuer not in trusted registryModule returns false, same as missing claim
Expired claimClaim's expiry timestamp < block.timestampModule returns false, revert with "Claim expired"
Module limit exceededSupply cap, investor count, or holding period violatedModule returns false with specific reason string
State hook failurePost-transfer module state update failsEntire transfer reverts

See also

On this page