dollar-signContract headers

Design stance: Settlement law is encoded in non-upgradeable cores (PoV Gate → EMT → Settlement flip; One-Claim; Fee burn). Tunables (checklists, clocks, splits) live behind a ParameterStore controlled by Governor+Timelock with bounds. All modules emit receipts (PoV hash, claim id, burn hash) for audit replay.

A. Common types & EIP-712

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

library Types {
  // Role tags (Attestor Registry)
  bytes32 constant ROLE_INSPECTOR      = keccak256("INSPECTOR");
  bytes32 constant ROLE_TERMINAL       = keccak256("TERMINAL");
  bytes32 constant ROLE_CARRIER        = keccak256("CARRIER");
  bytes32 constant ROLE_DC3PL          = keccak256("DC_3PL");
  bytes32 constant ROLE_REGISTRY       = keccak256("REGISTRY");
  bytes32 constant ROLE_METROLOGY      = keccak256("METROLOGY");
  bytes32 constant ROLE_SENSOR_OEM     = keccak256("SENSOR_OEM");

  // Domain tags
  bytes8  constant CLM_DOMAIN = 0x45444d412f434c4d; // "EDMA/CLM"
  bytes4  constant CLM_V1     = 0x00000001;

  struct Attestation {
    bytes32 role;          // e.g. ROLE_INSPECTOR
    bytes32 entityId;      // registry id for the signer
    bytes32 keyId;         // current active key id
    bytes   signature;     // EIP-712 / secp256k1 signature
  }

  struct ProofBundle {
    bytes32  schemaId;     // keccak256("TRADE.ON_BOARD.v1")
    bytes32  povHash;      // sha256(canonical_json_bytes)
    bytes    dossierBytes; // canonical JSON (optional echo)
    bytes    keyBlob;      // normalized identity fields blob
    Attestation[] atts;    // role-signed attestations bound to povHash
  }
}

EIP-712 typed data (attestor side, summary): TypedData(domain="EDMA/POV", message={schemaId, orderOrListing, stageOrUnit, povHash}, roleKey).

B. PoV Gate

  • Validates: schema, quorum, freshness, equality on povHash, must-fund (Trade post-production), and atomically reserves One-Claim.

  • Returns: a gatePassId consumed by Settlement (Trade) or Tokens (mint/settle).

C. One-Claim

  • Reserve→finalize: happens in the same tx as EMT/settle to prevent races.

D. EMT (Event/Milestone Token)

  • Receipt with a switch: Only Settlement flips money.

E. Trade Settlement

F. Tokens

  • Mint: binds PoV & One-Claim; settle/retire charges 4% and burns 50% in EDM.

G. Fee Router / Burner

  • If fee paid in EDSD/USD: Router converts the burn half to EDM at release, then burns; treasury-half routed to buckets. No gas burn ever.

H. Registry Mirror

  • Mirrors: bind a serial to a single claim; later changes freeze → replace (append-only).

I. Attestor Registry

J. ParameterStore

  • Examples: TRADE_REVIEW_WINDOW_HOURS (0..4), TRADE_TOPUP_DEADLINE_HOURS (12..72), payout schedules (banded), tolerance tables, treasury split (non-burn half only).

K. Governor / Timelock

  • Only ParameterStore/TreasurySplitter/allowlists are governed: Constitutional brakes (PoV/EMT/One-Claim/Locked→Unlocked/50% burn/fee constants) sit outside governance.

L. Treasury Splitter

M. EDSD Treasury & Proof-of-Reserves

  • EDSD is platform-bound: mint/burn/transfer are restricted to settlement modules and whitelisted flows; cash-out after schedule completion only.

N. Bridge Gateway

  • Bridges: mint representations only; EDMA remains canonical for claims. EDSD and EMT are not bridged.

O. Error catalog

  • E_CANONICAL_DRIFT / E_FORMAT_INVALID / E_SET_NOT_SORTED / E_FILE_MISSING / E_HASH_MISMATCH: serialization & evidence hygiene

  • E_QUORUM_MISSING / E_STALE_ATTEST / E_KEY_REVOKED: attestor/quorum freshness

  • E_PENDING_FUNDS: must-fund before shipping unmet

  • E_ONECLAIM_TAKEN: uniqueness already finalized

  • E_DUP_RELEASE / AlreadyMinted / AlreadyRetired: idempotency/monotonicity

  • E_BURN_CONVERSION_UNAVAILABLE: burn-half conversion to EDM deferred (release waits)

P. Events you will index

  • GatePass(schemaId, claimId, povHash)

  • EMTMinted(orderId, stageId, subLotId, claimId, povHash)

  • ReleasePosted(orderId, stageId, amountEdsd, fee, burnHash)

  • TokenMinted(tokenId, claimId, povHash)

  • TokenSettled(tokenId, buyer, fee, burnHash)

  • TokenRetired(tokenId, beneficiary, fee, burnHash)

  • FeeBurned(ref, fee, burnedEdm, burnTx)

  • MirrorCreated(mirrorId, claimId, programId) / MirrorReplaced(oldId, newId)

  • AttestorAdded(entity) / AttestorSuspended(entity)

  • ParamChanged(key, oldVal, newVal, effectiveFrom)

  • PoRSnapshot(snapshotHash, tBill, cash, asOf)

Q. Invariants

  • No EMT → no release: release requires Gate PASS + EMT + One-Claim FINAL + must-fund (Trade post-production gates).

  • Conservation (Trade): Locked + Unlocked = funded – refunds per order at all times.

  • Fee constants/caps: Trade 0.5%/milestone with $5k/$25k/$50k caps; Tokens 4%; burn exact 50% in EDM at event; gas never burns.

  • Uniqueness: claim_id finalizes once globally; replacements are new ids with lineage; mirrors bind to exactly one claim.

  • Idempotency: (order, stage, subLot) or tokenId settle once; replays are no-ops.

  • Append-only: revocations & replacements never delete; proof pages show original + correction.

Use these headers to wire clients, index receipts, and write off-chain services (ERP/TMS/WMS/ESG). For full ABIs, event topics, and test vectors (including canonical JSON and claimId fixtures), pull the SDK or query /v1/contracts and /v1/schemas.

Last updated