Contract 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
