Smart Contract Implementation

What these contracts do. EDMA’s contracts don’t run consensus—they enforce application-layer truth. Before any mint, settlement, or access:

  1. Independent attestors must verify the same evidence hash (quorum).

  2. A global One-Claim Ledger must confirm the evidence hasn’t been used elsewhere.

  3. If either fails, the call reverts.

Proof mints & conversions are gas-only on Base. Settlement uses $EDM with enforced fee/burn.

Architecture

  • Base (L2): all proof mints/conversions (gas-only) and marketplace flows.

  • Ethereum (L1): governance, fee schedule, registries, and final lineage anchoring.

  • PoV modules on-chain:

    • PoVAttestorRegistry – roles & quorum policy.

    • OneClaimLedger – route-agnostic exclusivity (claimId).

    • PoVGate – the single entrypoint for mint/settle/access (asserts quorum/equality/exclusivity).

    • Asset & Settlement contracts – proofs (ETT, EMT, Carbon NFTs, Energy NFT), reward (CLE), and EDM-settled actions.

Upgradeability. Registry/Gate may be upgradeable behind a timelocked multisig. OneClaimLedger is intentionally simple & immutable. Changes are published with on-chain change logs.

Access control. Role-based via AccessControl (e.g., GOVERNANCE_ROLE, MINTER_ROLE, TREASURY_ROLE). Critical ops require multisig.

Core PoV modules (interfaces / sketches)

One-Claim Ledger (exclusivity)

interface IOneClaimLedger {
    function firstClaimer(bytes32 claimId) external view returns (address);
    function reserve(bytes32 claimId) external returns (bool);
    function finalize(bytes32 claimId) external;
    function release(bytes32 claimId) external;
    event Finalized(bytes32 indexed claimId, address indexed claimer);
    event Released(bytes32 indexed claimId, address indexed claimer);
}

PoV Gate (the gatekeeper)

contract PoVGate {
    struct Params {
        bytes32 batchId; bytes32 deviceId; uint64 startTs; uint64 endTs;
        uint128 quantityWh; bytes32 evidenceHash; bytes32 meterUID;
        bytes32[] verificationUIDs; // EAS attestations (roles include AUDITOR)
    }

    function assertVerified(Params calldata p) external {
        // 1) compute route-agnostic claimId (deviceId,start,end,quantityWh,evidenceHash)
        // 2) OneClaimLedger.reserve(claimId)  -> revert ALREADY_CLAIMED on conflict
        // 3) load MeterReadingBatch, check schema & equality to p.evidenceHash/window/qty
        // 4) verify quorum: ≥minTotal, ≥minDistinctRoles, includes AUDITOR, all unrevoked/valid
        // 5) emit PoVPassed(claimId,...); OneClaimLedger.finalize(claimId)
    }

    event PoVPassed(bytes32 indexed claimId, bytes32 meterUID, bytes32[] verUIDs);
}

Asset contracts (proofs are non-transferable; mints are gas-only on Base)

ETT — Energy Tracking Token (proof, non-transferable)

  • Definition: 1 ETT per 10 kWh of verified generation.

  • Nature: evidence-only, non-transferable (soulbound). Stores claimId, evidenceHash, and attestation links.

  • Mint rule: only after PoVGate.assertVerified passes.

contract ETTProof is AccessControl {
    bytes32 public constant GATE_ROLE = keccak256("GATE_ROLE");
    mapping(bytes32 => address) public proofOwner; // claimId -> owner

    function mintETT(address to, bytes32 claimId) external onlyRole(GATE_ROLE) {
        require(proofOwner[claimId] == address(0), "ALREADY_MINTED");
        proofOwner[claimId] = to;
    }
    // no transfer functions; proofs are non-transferable by design
}

Energy NFT — 1 MWh certificate (from 100 ETT) or Carbon conversion

  • Mint condition: account has 100 ETT worth of the same evidenced batch (or policy-compliant grouping) OR conversion path to Carbon Credit NFTs where standards allow.

  • Gas-only mint. Stores provenance (batch/window/device, evidence hash, attestation refs).

contract EnergyNFT is ERC721, AccessControl {
    function mintFromETT(address to, bytes32[] calldata claimIds) external onlyRole(GATE_ROLE) {
        // verify claimIds sum to 1 MWh from the same evidence scope, then _safeMint(to, tokenId)
    }
}

Carbon Credit NFT — 1 tCO₂ (direct proof)

  • Mint condition: verified reduction = 1 tCO₂ with methodology metadata.

  • Gas-only mint. Supports on-chain retirement (non-transferable after retire).

EMT — Event/Milestone Token (proof, non-transferable)

  • Use: on-board / customs-cleared / delivered / assay; triggers staged releases.

  • Mint: gas-only, after Gate pass.

CLE — Clean Energy Coin (separate reward)

  • Mint rule: per verified MWh (policy ties to Energy NFT mint or batch tally).

  • Important: not derived from ETT; it’s a separate reward token. Tradable (ERC-20).

Settlement & Fee Router (EDM-based)

Where fees apply: trades, retirements, and milestone payout releases.

Where they don’t: all proof mints & conversions (ETT, Energy NFT, Carbon NFT, EMT) are gas-only on Base.

  • Energy & Carbon: 4.0% total (2% buyer + 2% seller).

  • Commodity milestones: 0.5% per tranche (caps: $5k ≤$1M, $12.5k $1–5M, $25k >$5M).

  • Split: 50% burned, 50% to treasury (rebates can reduce the treasury half only; burn is immutable).

contract FeeRouter is AccessControl {
    IERC20 public immutable EDM;
    address public immutable TREASURY;

    function settleTrade(address payer, uint256 tradeValue, uint16 bpsTotal) external {
        uint256 fee = (tradeValue * bpsTotal) / 10_000;       // bpsTotal = 400 for 4%, 50 for 0.5%
        uint256 burnAmt = fee / 2; uint256 treasAmt = fee - burnAmt;
        EDM.transferFrom(payer, address(this), fee);
        EDM.burn(burnAmt);                                    // EDM must expose burn/burnFrom
        EDM.transfer(TREASURY, treasAmt);
    }
}

No auto-swap: if the payer lacks EDM, settlement reverts. This keeps EDM’s utility real.

Revocation & Rectification (first-class)

  • If a counted verification is revoked/expired and quorum drops post-mint, dependent assets must be flagged/frozen/burned per policy until rectified.

  • Asset contracts expose flagRevoked(claimId) and emit PoVFlagged / PoVRectified. Lineage is append-only; history is never overwritten.

Oracles, evidence, and storage

  • Attestations: EAS-compatible (MeterReadingBatch.v1, Verification.v1, RevocationReason.v1).

  • Evidence: canonical JSON (sorted/minified, fixed units) → evidenceHash = SHA-256(blob).

  • Storage: raw artifacts off-chain (S3/IPFS/partner vaults) with signed URIs; hashes on-chain.

  • Ingestion: Chainlink-class transports and direct operator APIs feed attestation pipelines.

Interoperability & L2 stance

Primary home is Ethereum/Base. Where regulated programs require mirroring to legacy registries, watchers reconcile external retirements/issuances on-chain without violating One-Claim. Cross-chain mirrors (with canonical “first-seen” rules) are a future extension, not a dependency.

Last updated