Canaries and slashing
Every renter's view carries made-up rows that exist nowhere else. If one surfaces outside the enclave, its secret proves which view it came from.
Canary rows
When a renter's view is created, the enclave mints twelve rows that look like real ones of each type: a name, an email at a trap domain, a phone number, a URL. Each row carries a random 32-byte secret, written into its email, URL and phone number.
The onchain proof
Before the view answers its first query, the enclave commits the merkle root of the view's canaries in Canaries.commitView. The leaf is keccak256(keccak256(abi.encode(viewId, secret))). Revealing a secret with its proof is checked by the contract and can only be done by someone who saw that row.
A case, step by step
- The keeper sweeps the trap endpoints every 10 minutes. A fetched URL or a mail to a canary address gives it the secret.
- Anyone calls
reportRenter(viewId, secret, proof, evidenceHash). The renter's deposit is frozen. - The renter has 48 hours to call
dispute. A disputed case goes to the arbiter. - Otherwise anyone calls
finalize: the whole USDG deposit moves to the uploaders.
Enclave canaries
A second set of canaries is never shown to any renter; its root is fixed when the enclave registers. If one of those surfaces, the leak came from the enclave itself: reportEnclave opens the same 48 hour case, and finalizing it slashes the operator's 100,000 $POD bond, half burned and half to the uploaders.