Appendices (A–G)

pragma solidity ^0.8.20;

/// @notice Sketch only; omitted checks, access control, and reentrancy
/// guards for brevity.

interface IJobEscrow {
    // Events
    event JobPosted(
        uint256 indexed jobId,
        address indexed poster,
        uint256 price,
        bytes32 criteriaHash,
        bytes32 geoCommit,
        uint256 challengeWindowBns,
        uint16 feeBps
    );

    event JobAccepted(
        uint256 indexed jobId,
        address indexed robot,
        bytes32 acceptCommit,
        uint256 stake
    );

    event AcceptanceRevealed(
        uint256 indexed jobId,
        address indexed robot,
        address sessionKey
    );

    event ProofSubmitted(
        uint256 indexed jobId,
        address indexed robot,
        bytes32 evidenceRoot,
        bytes cidIndexHash
    );

    event Attested(
        uint256 indexed jobId,
        address indexed oracle,
        uint8 verdict,
        uint16 score,
        bytes32 verifierCodeHash
    );

    event AttestationAggregated(
        uint256 indexed jobId,
        uint8 verdict,
        uint16 score
    );

    event Challenged(
        uint256 indexed jobId,
        address indexed challenger,
        uint256 bond
    );

    event Resolved(
        uint256 indexed jobId,
        address winner,
        uint256 payout,
        uint256 slashRobot,
        uint256 slashOracle,
        uint256 fee
    );

    // Posting
    function postJob(
        uint256 price,
        bytes32 criteriaHash,
        bytes32 geoCommit,
        uint256 challengeWindowBns,
        uint16 feeBps,
        bytes calldata meta
    ) external returns (uint256 jobId);

    // Accept/Reveal
    function acceptJob(
        uint256 jobId,
        bytes32 acceptCommit,
        uint256 stakeAmount
    ) external;

    function revealAcceptance(
        uint256 jobId,
        address sessionKey,
        bytes32 nonce
    ) external;

    // Submission and attest
    function submitProof(
        uint256 jobId,
        bytes32 evidenceRoot,
        bytes calldata cidIndex
    ) external;

    function attest(
        uint256 jobId,
        uint8 verdict,
        uint16 score,
        bytes32 verifierCodeHash
    ) external;

    // Challenge and resolve
    function challenge(
        uint256 jobId,
        bytes32 counterEvidenceRoot,
        bytes calldata cids
    ) external payable;

    function resolve(uint256 jobId) external;

    // Views
    function feeBps() external view returns (uint16);
}

Listing 1: IJobEscrow (sketch)
pragma solidity ^0.8.20;

interface IReputationRegistry {
    event ReputationUpdated(
        address indexed subject,
        uint32 newScore,
        int32 delta,
        uint256 jobId
    );

    event StakeChanged(address indexed subject, uint256 newStake);
    event TierUpdated(address indexed subject, uint8 tier);
    event Slashed(address indexed subject, uint256 amount, uint256 jobId);

    function getScore(address subject) external view returns (uint32);
    function applyDecay(address subject) external;
    function updateScore(address subject, int32 delta, uint256 jobId) external;
    function setTier(address subject, uint8 tier) external;
    function slash(address subject, uint256 amount, uint256 jobId) external;
}
Listing 2: IReputationRegistry (sketch)

Appendix B. Reputation scoring and decay

Let rt ∈ [0, 1] be the score at job t. After verdict xt ∈ [−1, 1] (1 for perfect, −1 for fraud) and decay δ ∈ (0, 1),

rt+1 = (1 − δ) rt + δ · 1/2 · ( 1 + xt / (1 + |xt|) )

Fraud: sets xt = −1 and applies multiplicative penalty rt+1 ← κ rt+1 with κ ∈ [0, 1).

Tier access: Access to tier j requires rt+1 ≥ r(j)min and stake s ≥ s(j)min.

Appendix C. Example PoPW payloads (JSON schemas)

Listing 3: Envelope

{
  "job_id": "0x5e4c...ab",
  "robot_did": "did:morph:robot:12ab...",
  "session_pubkey": "0x03a1...7c",
  "device_attestation": {
    "tee_quote": "base64...",
    "pcrs": { "pcr0": "...", "pcr1": "..." },
    "firmware_hash": "sha256:...",
    "timestamp": 1710000000
  },
  "merkle_root": "0xabc123...",
  "cid_index": [
    { "cid": "bafy...1", "type": "gps_trail", "bytes": 64211, "hash": "sha256:..." },
    { "cid": "bafy...2", "type": "image_hashes", "bytes": 22100, "hash": "sha256:..." }
  ],
  "signature": "0x..."
}

Listing 4: GPS trail leaf

{
  "t": 1710000123,
  "lat": 37.4221,
  "lon": -122.0841,
  "alt": 12.4,
  "dop": 0.9,
  "speed": 2.3,
  "nonce": "0x9f..",
  "sig": "0x.."
}

Listing 5: Image hash leaf

{
  "t": 1710000133,
  "image_cid": "bafy...img",
  "hash": "sha256:...",
  "challenge_code": "H3K7",
  "sig": "0x.."
}

Appendix D. Threat model and mitigations table

Threat

Description

Mitigation

Replay

Reuse of old evidence roots

Job-specific nonces, freshness windows, beacon challenges

Signature theft

Session key exfiltration

TEE-protected keys, short-lived sessions, revocation events

Committee bribery

Bribe subset of oracles

VRF sampling, stake caps, slashable oracles, public audits

Front-running

Acceptance sniped on-chain

Commit-then-reveal for acceptance

Censorship

Robot submissions ignored

Multiple oracles, permissionless relays, L2 fallback

Data misuse

Raw media leaks

Encryption, access logs, legal contracts off-chain

Appendix E. Glossary

  • CID: Content Identifier

  • DID: Decentralized Identifier

  • TEE/TPM: Trusted hardware for attestation

  • VRF: Verifiable Random Function

  • Quorum: Minimum stake-weighted agreement for verdicts

  • Challenge window (Tc): Period to dispute attestations

Appendix F. Reference verifier pseudocode

def verify(job, manifest, cid_index):
    assert hash(job.criteria) == job.criteria_hash
    assert manifest.job_id == job.id
    assert verify_sig(manifest.session_pubkey, manifest.signature)

    # 1) Load artifacts
    gps = load_cid(cid_index, type='gps_trail')
    images = load_cid(cid_index, type='image_hashes')

    # 2) Check chains
    check_attestation(manifest.device_attestation)
    check_merkle(manifest.merkle_root, gps, images)

    # 3) Deterministic scoring
    coverage = polygon_coverage(gps, job.polygon)
    overlap = compute_overlap(images)
    stability = imu_smoothness(gps)

    q = 0.5*coverage + 0.3*overlap + 0.2*stability
    verdict = int(q >= job.threshold)
    return verdict, q

Listing 6: Verifier pipeline for area-coverage jobs (sketch)

Appendix G. Monte Carlo robustness sketch

import random
from math import comb, exp

def quorum_capture_prob(m=7, tau=2/3, rho=0.25, trials=100000):
    q = 0
    t = int(tau*m)
    for _ in range(trials):
        bad = sum(random.random() < rho for _ in range(m))
        if bad >= t:
            q += 1
    return q / trials

def watcher_miss_prob(lambda_w=1/1800, Tc=1800):
    # Poisson miss probability
    return exp(-lambda_w*Tc)

Listing 7: Estimate quorum-capture probability and watcher miss rate

References

  1. S. Nakamoto, “Bitcoin: A Peer-to-Peer Electronic Cash System,” 2008.

  2. G. Wood, “Ethereum: A Secure Decentralised Generalised Transaction Ledger (Yellow Paper),” 2014.

  3. S. Nazarov et al., “Chainlink: A Decentralized Oracle Network,” 2017.

  4. W3C, “Decentralized Identifiers (DIDs) v1.0,” 2022.

  5. Intel Corporation, “Intel Software Guard Extensions (SGX) Developer Guide,” 2016.

  6. A. Rahman and M. Moresio, “Security Analysis of IoT Sensor Telemetry and Attestation,” 2019.

  7. V. Buterin, “Why and How Rollups,” 2020.

  8. E. Ben-Sasson et al., “Scalable, Transparent, and Post-Quantum Secure Computational Integrity,” 2018.

  9. Y. Dodis and A. Yampolskiy, “A Verifiable Random Function with Short Proofs and Keys,” 2005.

  10. V. Buterin, “A note on slashing conditions,” 2019.

  11. P. Daian et al., “Flash Boys 2.0: Frontrunning, Transaction Reordering, and Consensus Instability,” 2020.

  12. D. Hardman et al., “DIDComm Messaging,” 2021.