Asset contracts
What “asset contracts” are on EDMA
They are the on-chain objects that represent what passed (and, for Tokens, what you can transfer/retire). In Trade, the asset is a milestone fact—a non-transferable EMT that flips money from Locked EDSD to Unlocked EDSD. In Tokens, the assets are evidence-backed units (e.g., Energy 1 MWh, Carbon 1 tCO₂e, hourly attributes) that can be bought or retired. Asset contracts do not decide who gets paid; they bind PoV to state and emit the facts the rest of the system (router, ledger, explorer, DeFi) rely on.
One sentence to remember: PoV proves it, the asset contract records it, and—only then—Treasury flips money and burns fees.
Trade assets — EMT (Event/Milestone Token)
Nature: An EMT is a stage-specific, non-transferable token (soulbound to the order/sub-lot) that says: “this gate passed, at this time, for these goods, under this dossier (PoV hash).” Minting an EMT is the switch that allows the Treasury to change money state.
How it mints (always via the Gate): povGate.pass checks quorum, equality, One-Claim, funding present (must-fund before shipping). If PASS, the EMT contract mints the stage token in the same transaction; One-Claim finalizes atomically.
What it stores (minimal and deterministic): stage (e.g., PRE_SHIP, ON_BOARD, CUSTOMS, ARRIVAL_QA); order_id, sub_lot (container set or ASN); claim_id (One-Claim) and pov_hash (canonical dossier hash); attestor_refs (role ids + key ids; no raw files); timestamp (L2 block time)
What it triggers (not inside EMT): Emits EMTMinted(stage, order_id, sub_lot, claim_id, pov_hash). Treasury/Router listens and flips Locked EDSD → Unlocked EDSD, posts the fee line, and burns 50% of that stage’s fee in EDM.
What you can do with it: Read (proof pages & receipts index EMTs); Replace (append-only) if a revocation forces a corrective EMT; lineage links replaces/replaced_by; Never transfer. EMTs are receipts with a switch, not tradable assets.
Tokens assets — evidence-backed units
Nature: ERC-721/1155-style contracts that represent 1 MWh (Energy), 1 tCO₂e (Carbon), or hourly attributes. Each token binds to a PoV dossier and a One-Claim key; it can be listed, bought, and retired. Settlement and retirement call the Fee Router; 50% of the 4% fee burns in EDM at that moment.
Mint & settle rules (contract enforces): Mint only via povGate.pass with the correct schema; store pov_hash, claim_id, method/region/vintage. Settle/retire only if listing is PoV-valid and One-Claim is free (or already bound to this token); on settle, mark as owned; on retire, mark irreversible and emit a retirement receipt.
Metadata (enough for a receipt, nothing private): method, region, vintage (or device/time window for Energy); quantity (fixed: 1 MWh, 1 t, or 1 hour unit); claim_id, pov_hash, attestor_refs; (Optional) mirror_ref to external registry serial/URL
Events you depend on: TokenMinted(id, claim_id, pov_hash); TokenSettled(id, buyer, fee, burn_hash); TokenRetired(id, beneficiary, retirement_receipt_uri)
What can freeze a token: Revocation of a counted attestation → ListingFrozen(id, reason); trades halt until a corrective mint links replaces.
Shared invariants
Bound to PoV. No mint without a Gate PASS that references the same pov_hash and One-Claim fields.
One-Claim atomicity. Reserve→finalize happens in the same transaction as mint/settle to prevent races.
Append-only lineage. Replacements link; we never delete.
No early money. Asset events never move EDSD directly; Treasury/Router does—after the asset says it’s allowed.
Burn truth. Every settlement/release event includes the fee line and emits a burn hash; Explorer binds that hash to the proof page.
Splits, merges, and replacements
Trade splits. Each sub-lot gets its own EMT keyed by {BL, seal, containers_subset}. Downstream gates accept multiple child EMTs.
Token splits/merges. ERC-1155 streams multiple identical units; settlement/retirement handles partial quantities. ERC-721 stays single-unit; batch ops settle/retire multiple ids.
Replacement on revocation. A new EMT/token mints with a new pov_hash and claim_id; lineage records replaces; downstream slices resume.
Interfaces & events
Trade (EMT path):
POST /v1/trade/proof/{order}/{stage} → Gate PASS/FAIL (+ reason).
POST /v1/trade/release/{order}/{stage} → emits EMTMinted → Router flips EDSD, fee posts, burn 50%.
Webhooks: pov.gate.pass, oneclaim.finalized, trade.milestone.passed, trade.release.posted.
Tokens:
POST /v1/tokens/mint (via Gate) → TokenMinted.
POST /v1/tokens/settle → TokenSettled (+ burn hash).
POST /v1/tokens/retire → TokenRetired (retirement receipt).
Webhooks: tokens.listing.frozen/unfrozen, tokens.settlement.posted, tokens.retirement.proofpack.ready.
Security properties
Determinism. Same dossier → same pov_hash → same outcome.
Uniqueness. claim_id finalizes once globally; duplicates revert.
Non-bypassable. Sequencer ordering can’t mint or pay early; PoV/One-Claim/Router rules sit in contracts.
Isolation. A frozen or revoked claim pauses only related EMTs/tokens and downstream slices; paid slices remain paid.
Auditability. Every asset event carries pov_hash, claim_id, fee, and burn hash; L1 blobs anchor it.
Governance knobs
Schemas & role quorums per lane; freshness windows for evidence.
Allowed token types and metadata fields per category (Energy, Carbon, hourly).
Revocation policy (auto-freeze windows, approved neutrals for re-inspection).
Explorer visibility (which fields surface on public pages).
Governance cannot: mint without PoV PASS, override One-Claim, move money without EMT/settle, or discount the 50% burn.
Plain recap
Last updated