# DBIS Rail Technical Spec v1 **Network:** DBIS Mainnet (ChainID 138) **Purpose:** Bank-rail settlement + GRU mint orchestration using ISO-20022–anchored authorizations. ## 0. Scope and Non-Goals ### In-scope * A standardized **message-to-settlement lifecycle** rooted in ISO-20022 evidence, but executed as **compact on-chain authorizations**. * On-chain contracts that: * enforce **participant allowlisting** * validate **threshold signer** authorization * provide **replay protection** * record immutable **settlement + accounting references** * gate GRU minting so it is only possible after compliant authorization ### Out-of-scope (v1) * On-chain parsing of ISO-20022 XML/JSON payloads. * ZK proofs or light-client proofs of bank-rail events. * Fully automated validator rotation on-chain (documented operationally for v1). --- ## 1. Definitions ### Terms * **FI**: Financial Institution participant on the DBIS rail (bank, MSB, custodian, trustee, operator). * **ISO Gateway**: Off-chain service that ingests ISO-20022 messages, runs compliance + accounting, and produces signed on-chain authorizations. * **Mint Authorization (MintAuth)**: A compact signed instruction authorizing settlement recording and GRU minting. * **Funds Status**: * `ON_LEDGER_FINAL`: funds final in DBIS-controlled ledger domain (core/omnibus/segregated reserve). * `OFF_LEDGER_FINAL`: funds final via external rail + reconciliation per DBIS policy. * **Accounting Reference (accountingRef)**: Immutable identifier for the journal/batch/posting in DBIS ledger domain. ### Design principle **The chain never "decides" fiat finality.** Fiat finality, compliance, and accounting occur in the regulated domain; the chain enforces **authorization integrity and policy**. --- ## 2. System Overview ### 2.1 Contract set (v1) 1. **DBIS_RootRegistry** 2. **DBIS_ParticipantRegistry** 3. **DBIS_SignerRegistry** 4. **DBIS_SettlementRouter** 5. **DBIS_GRU_MintController** > Note: Existing registries (e.g., UniversalAssetRegistry, ChainRegistry, GRU Diamond facets) remain valid. v1 adds DBIS Rail components in a way that can "wrap" or "gate" existing mint paths. ### 2.2 Roles * **ROOT_ADMIN**: owns RootRegistry configuration. * **PARTICIPANT_ADMIN**: can onboard/update participants. * **SIGNER_ADMIN**: manages signer allowlist and quorum rules. * **ROUTER_ADMIN**: can pause router, update policy caps. * **MINTER**: **only** DBIS_SettlementRouter (for GRU mint execution). --- ## 3. Network and Governance Baseline (Chain 138) ### 3.1 Consensus * **Besu QBFT** (permissioned) with ~2s block time, epoch ~30k blocks (document actual values used in current deployment). * **Node allowlists** enforced by Besu permissioning config (`permissions-nodes-config-file`, `permissions-accounts-config-file`). ### 3.2 Governance in v1 * Validator management remains operational + infra-managed for v1. * Contract governance uses a multisig or your GovernanceController/timelock pattern for admin roles. --- ## 4. Data Model ### 4.1 Participant Participant represents an FI / operator entity allowed to initiate or receive settlement/mint instructions. **Participant fields** * `participantId: bytes32` (stable ID, e.g., hash of legal name + jurisdiction) * `legalName: string` * `jurisdiction: string` * `entityType: enum` (BANK, MSB, CUSTODIAN, TRUSTEE, OPERATOR, AUDITOR) * `status: enum` (ACTIVE, SUSPENDED, REVOKED) * `policyTags: bytes32[]` (corridors, product permissions) * `operationalWallets: address[]` (approved wallets for receipts/payouts) * `signingKeys: address[]` (if participant is also a signer entity) ### 4.2 Mint Authorization (MintAuth) MintAuth is a compact, deterministic struct signed by an allowlisted signer set. ```solidity enum FundsStatus { ON_LEDGER_FINAL, OFF_LEDGER_FINAL } enum AssetClass { GRU_M00, GRU_M0, GRU_M1 } // optional mapping; v1 can use GRU_M00 only struct MintAuth { // Identity / Evidence bytes32 messageId; // unique; derived from UETR/EndToEndId/instructionId bytes32 isoType; // e.g., keccak256("pacs.008"), keccak256("camt.054") bytes32 isoHash; // hash of canonical ISO payload bundle (off-chain) bytes32 accountingRef; // journal/batch/posting reference in DBIS ledger domain FundsStatus fundsStatus; // ON_LEDGER_FINAL or OFF_LEDGER_FINAL // Settlement intent bytes32 corridor; // optional (e.g., USD->XAU->GRU, internal corridor tag) AssetClass assetClass; // GRU tier/class address[] recipients; // 1..N uint256[] amounts; // matched length, base units // Policy & replay window uint64 notBefore; // unix seconds uint64 expiresAt; // unix seconds // Domain separation uint256 chainId; // MUST be 138 address verifyingContract;// SettlementRouter address } ``` **Rules** * `recipients.length == amounts.length` * `expiresAt > notBefore` * `chainId == 138` * `verifyingContract == address(DBIS_SettlementRouter)` * `messageId` must be unique (replay protection) --- ## 5. Message Lifecycle ### 5.1 Off-chain (ISO Gateway) steps 1. **Ingest ISO-20022** message(s) and evidence: * pacs / camt / pain family as applicable * cash receipt evidence for M0 if used 2. **Canonicalize** and compute: * `isoHash = hash(canonical_bundle)` * `messageId = deterministicUniqueId(...)` * `isoType = keccak256(typeString)` 3. Determine **funds status**: * ON_LEDGER_FINAL: final posting in DBIS ledger domain * OFF_LEDGER_FINAL: external finality + reconciliation 4. Perform required **double-entry accounting**: * must produce `accountingRef` 5. Run compliance gates: * KYC, sanctions, AML rules, limits, exception flags 6. Emit **MintAuth** and obtain **threshold signatures** from allowlisted signers. 7. Relayer submits to chain calling `submitMintAuth(MintAuth, signatures)`. ### 5.2 On-chain steps (SettlementRouter) 1. Verify signatures meet quorum for the corridor/product/participant class. 2. Check time window + chainId + verifyingContract. 3. Enforce replay protection. 4. Enforce router policy caps. 5. Record settlement. 6. Call GRU mint controller to mint to recipients. 7. Emit events for audit. --- ## 6. Contract Specifications ### 6.1 DBIS_RootRegistry **Purpose:** Single source of truth for DBIS rail component addresses + versioning. **State** * `address participantRegistry` * `address signerRegistry` * `address settlementRouter` * `address gruMintController` * `string railVersion` (e.g., "v1") **Functions** * `setComponent(bytes32 key, address addr)` (admin) * `getComponent(bytes32 key) returns (address)` **Events** * `ComponentUpdated(bytes32 indexed key, address indexed addr, string railVersion)` --- ### 6.2 DBIS_ParticipantRegistry **Purpose:** Institution onboarding + wallet bindings + policy tags. **Functions** * `registerParticipant(Participant calldata p)` (admin) * `setParticipantStatus(bytes32 participantId, Status s)` (admin) * `addOperationalWallet(bytes32 participantId, address wallet)` (admin) * `removeOperationalWallet(bytes32 participantId, address wallet)` (admin) * `isOperationalWallet(address wallet) returns (bool)` * `getParticipantByWallet(address wallet) returns (bytes32 participantId)` **Events** * `ParticipantRegistered(bytes32 indexed participantId, string legalName, string jurisdiction, uint8 entityType)` * `ParticipantStatusChanged(bytes32 indexed participantId, uint8 status)` * `OperationalWalletAdded(bytes32 indexed participantId, address wallet)` * `OperationalWalletRemoved(bytes32 indexed participantId, address wallet)` --- ### 6.3 DBIS_SignerRegistry **Purpose:** Maintain signer allowlist + roles + quorum policy. #### Signer model (v1) * Allowlisted signer addresses with categories: * OPS * COMPLIANCE * CUSTODY * RISK * AUDITOR (optional but recommended) #### Quorum (default v1) * `requiredSignatures = 3` * `requiredCategories`: must include at least: * COMPLIANCE (mandatory) * and any 2 of OPS/CUSTODY/RISK/AUDITOR **Functions** * `addSigner(address signer, uint8 category)` (admin) * `removeSigner(address signer)` (admin) * `setQuorum(uint8 requiredSigs, uint256 categoryMaskRequired, uint256 categoryMaskAllowed)` (admin) * `isSigner(address signer) returns (bool)` * `validateSigners(address[] signers) returns (bool ok, string reason)` (view) **Events** * `SignerAdded(address indexed signer, uint8 category)` * `SignerRemoved(address indexed signer)` * `QuorumUpdated(uint8 requiredSigs, uint256 requiredMask, uint256 allowedMask)` --- ### 6.4 DBIS_SettlementRouter **Purpose:** Verify MintAuth signatures, enforce rail policy, record settlement, and trigger GRU mint. #### State * `RootRegistry root` * `mapping(bytes32 => bool) usedMessageIds` * policy: * `uint256 maxAmountPerMessage` * `mapping(bytes32 corridor => uint256 corridorDailyCap)` * `mapping(bytes32 corridor => mapping(uint256 day => uint256 usedToday))` * `bool paused` #### Core function `submitMintAuth(MintAuth calldata auth, bytes[] calldata signatures)` **Validation** * `paused == false` * `auth.chainId == 138` * `auth.verifyingContract == address(this)` * `block.timestamp in [auth.notBefore, auth.expiresAt]` * `!usedMessageIds[auth.messageId]` * `recipients/amounts lengths match` * total amount <= `maxAmountPerMessage` * `ParticipantRegistry` check: * every recipient must be an operational wallet of an ACTIVE participant **OR** * allow "unhosted wallets" only if corridor policy permits (default: hosted-only) * Signature validation: * EIP-712 typed hash of MintAuth * recover signers from signatures * require unique signers * require signer allowlist + quorum per SignerRegistry **Effects** * mark `usedMessageIds[messageId] = true` * update daily corridor usage * record settlement data in storage (optional; events are mandatory) * call `DBIS_GRU_MintController.mintFromAuthorization(auth)` #### Events (audit-grade) * `SettlementRecorded(bytes32 indexed messageId, bytes32 indexed isoType, bytes32 isoHash, bytes32 accountingRef, uint8 fundsStatus, bytes32 corridor, uint8 assetClass, uint256 totalAmount)` * `MintExecuted(bytes32 indexed messageId, address indexed recipient, uint256 amount, uint8 assetClass)` * `MessageIdConsumed(bytes32 indexed messageId)` * `RouterPaused(bool paused)` --- ### 6.5 DBIS_GRU_MintController **Purpose:** Only mint GRU when invoked by SettlementRouter with a validated MintAuth. #### State * `address settlementRouter` * `address gruTokenOrDiamond` (depending on your GRU deployment) * `bool paused` #### Function `mintFromAuthorization(MintAuth calldata auth)` **Rules** * `msg.sender == settlementRouter` * `paused == false` * mint exactly `amounts[i]` to `recipients[i]` * emit per-recipient mint event (or rely on SettlementRouter's MintExecuted event) **Integration notes** * If GRU is minted via Diamond facets: * MintController should call the GRU mint facet method. * If GRU is represented as a CompliantFiatToken (ERC-20): * MintController must be granted MINTER_ROLE, and **all other direct mint paths must be disabled** or moved behind router gating. --- ## 7. Signature Standard (EIP-712) ### Domain * `name: "DBISSettlementRouter"` * `version: "1"` * `chainId: 138` * `verifyingContract: DBIS_SettlementRouter` ### Typed data MintAuth struct fields as defined in §4.2. ### Signature set * `bytes[] signatures` (each 65-byte ECDSA signature) * `address[] recoveredSigners` computed on-chain * signers must be unique and satisfy SignerRegistry quorum rules > v1 uses "multi-sig by aggregation" (array of signatures). True threshold crypto can be introduced in v2 without changing MintAuth. --- ## 8. Policy Controls ### 8.1 Default policy (recommended v1) * Hosted wallets only (participants) unless corridor allows unhosted. * Mandatory COMPLIANCE signer present for all authorizations. * `expiresAt` maximum horizon (e.g., <= 15 minutes) to reduce replay/exfiltration risk. * Daily corridor caps + per-message cap. ### 8.2 Emergency controls * Router pause (ROUTER_ADMIN) * Mint controller pause (ROUTER_ADMIN) * Signer revocation (SIGNER_ADMIN) * Participant suspension (PARTICIPANT_ADMIN) --- ## 9. Replay Protection and Idempotency ### Replay * `messageId` is consumed once. Submitting same messageId reverts. ### Idempotency (optional extension) If you want "retry safe" behavior: * allow resubmission if exact same auth hash and messageId already consumed → return success without minting (but emit a "duplicate accepted" event). Default v1: revert on reuse. --- ## 10. Reporting and Audit ### Required on-chain audit events * SettlementRecorded (includes isoHash + accountingRef) * MintExecuted per recipient (or token Transfer + SettlementRecorded) ### Off-chain reporting (DBIS Rail Rulebook v1) * Maintain mapping from `messageId → ISO evidence bundle` and `accountingRef → ledger postings`. * Support camt-like extracts for: * completed settlements * exceptions / rejected authorizations * signer approvals and revocations * participant status changes --- ## 11. Backward Compatibility / Migration Plan ### Immediate hardening steps (recommended) * Identify and eliminate "owner mint" pathways for GRU/c* tokens on chain 138: * Either revoke direct mint permissions or route them exclusively through DBIS_GRU_MintController. * For any existing MintController pattern: * adapt it so `MINTER_ROLE` = SettlementRouter only. * require MintAuth signature validation at router level. ### Naming/identity alignment * Update chain metadata artifacts so canonical identity is DBIS Mainnet (Chain 138). * Keep a compatibility alias field if needed, but ensure DBIS is primary. --- ## 12. Open Items for v1 Freeze These are the only "knobs" that change code/constants: 1. **Quorum rule** (3-of-5 default) and required categories. 2. Hosted-only vs allow unhosted corridors. 3. Per-message and daily caps. 4. Whether messageId reuse reverts or is idempotent. --- ## Appendix A — Recommended Quorum Defaults **Signer categories:** OPS, COMPLIANCE, CUSTODY, RISK, AUDITOR **Default quorum:** 3-of-5 **Required:** COMPLIANCE + any 2 of {OPS, CUSTODY, RISK, AUDITOR} Rationale: ensures compliance sign-off and prevents single-domain control. --- ## Appendix B — Minimal Event Field Set **SettlementRecorded** * `messageId` * `isoType` * `isoHash` * `accountingRef` * `fundsStatus` * `corridor` * `assetClass` * `totalAmount` **MintExecuted** * `messageId` * `recipient` * `amount` * `assetClass` --- ## Appendix C — v1.5 Add-Ons (AAA+++) The v1.5 add-ons extend this Spec for examiner-credible completeness. They are implemented via the following documents; only summary points are repeated here. 1. **[DBIS_RAIL_LEDGER_ATTESTATION_ADDON_V1_5.md](DBIS_RAIL_LEDGER_ATTESTATION_ADDON_V1_5.md)** — LPA state machine (POSTED_FINAL, POSTED_ADJUSTMENT, POSTED_REVERSAL, DISPUTED_HOLD), Reversal Policy Matrix (before mint: invalidate; after mint: primary offset/corridor restriction, secondary burn, tertiary debt/dispute), and **mandatory signer effective/revoked block enforcement**: SignerRegistry adds `effectiveFromBlock` and `revokedAtBlock` per signer; SettlementRouter validates each recovered signer is active at `block.number`. 2. **[DBIS_RAIL_CONVERSION_ROUTER_SPEC_V1_5.md](DBIS_RAIL_CONVERSION_ROUTER_SPEC_V1_5.md)** — SwapAuthorization (SwapAuth) EIP-712 struct, quorum (2-of-4 small / 3-of-5 + COMPLIANCE large), best execution and MEV posture, quote provenance (quoteHash, quoteIssuer), venue allowlist, sanctions/AML (blocklist, Compliance for elevated swaps and new venues), and ConversionExecuted event. 3. **[DBIS_RAIL_STABLECOIN_POLICY_V1_5.md](DBIS_RAIL_STABLECOIN_POLICY_V1_5.md)** — Canonical stablecoin definition: Stablecoin Reference Registry (tokenSymbol, tokenAddress, issuer/bridge, legalClaimType, redemptionPath, reserveDisclosureRef, riskTier, pauseAuthority, stablecoinStatus); Rulebook addendum that only ACTIVE registered stablecoins may be used for routing; monitoring (peg deviation, bridge health, emergency corridor halt). 4. **[DBIS_RAIL_HASH_CANONICALIZATION_AND_TEST_VECTORS_V1_5.md](DBIS_RAIL_HASH_CANONICALIZATION_AND_TEST_VECTORS_V1_5.md)** — LEB/LPA/ISO schemas, canonicalization rules (UTF-8 NFC, sorted keys, fixed decimal and timestamp, rounding policy), and test vectors for lebHash, lpaId, isoHash, and accountingRef so that any auditor can reproduce hashes.