A cheating provider against the live protocol
A script played a dishonest provider on NEAR testnet: bad files, forged calls, a replayed verdict. Each attempt below really happened, and each outcome was checked automatically and read back from the chain.
outcomes went exactly as the protocol promises. The cheater was paid 0.0000 NEAR.
Four layers, different trust
Access key
Each agent signs with a key limited to its own contract methods. A call outside that list is refused by NEAR before it runs, and no transaction is recorded.
Contract
Rules enforced on-chain for everyone: who may submit, who may judge, when money can move. No server of ours can override them.
Evaluator
Deterministic checks on the delivered file, re-runnable by anyone with the files. Each verdict is bound on-chain to the exact file and report.
API
Accepts a file only if its hash is the one committed on-chain, so the evaluator judges exactly what was committed.
Every attempt
Run 2026-11-04 12:32 UTC against kavren.lahd-kavren.testnet.
| # | Attempt | Stopped by | What happened | Proof |
|---|---|---|---|---|
| 1 | Open isolated job 7 (job 7) | Setup | As promised Open | |
| 2 | Upload a file with no on-chain submission (job 7) | API | As promised 409: no on-chain submission is awaiting a file | None: an answer from the API, not a transaction |
| 3 | Provider gives itself a PASS verdict (job 7) | Access key (NEAR runtime) | As promised refused before execution, no transaction on-chain: “MethodNameMismatch” | None: NEAR refused it before it reached the chain |
| 4 | Buyer agent submits work on its own job (job 7) | Access key (NEAR runtime) | As promised refused before execution, no transaction on-chain: “MethodNameMismatch” | None: NEAR refused it before it reached the chain |
| 5 | Provider spends the owner's budget (create_job) (job 7) | Access key (NEAR runtime) | As promised refused before execution, no transaction on-chain: “MethodNameMismatch” | None: NEAR refused it before it reached the chain |
| 6 | Buyer agent's key tries to withdraw the owner's budget (job 7) | Access key (NEAR runtime) | As promised refused before execution, no transaction on-chain: “MethodNameMismatch” | None: NEAR refused it before it reached the chain |
| 7 | Buyer refunds early (deadline not reached, attempts left) (job 7) | Contract | As promised rejected on-chain: “no refund condition holds” | |
| 8 | Provider withdraws pay without any PASS (job 7) | Contract | As promised rejected on-chain: “nothing to withdraw” | |
| 9 | Empty file (job 7) | Evaluator | As promised FAIL; failing: C1 (BAD_DIALECT); C2–H1 skipped; report hash matches the chain | |
| 10 | Replay the old verdict as PASS (evaluator key) (job 7) | Contract | As promised rejected on-chain: “no submission awaiting a verdict” | |
| 11 | Silently deleted rows (job 7) | Evaluator | As promised FAIL; failing: C2 (MISSING_RECORD); report hash matches the chain | |
| 12 | Upload a different file than the hash committed on-chain (job 7) | API | As promised 409: file hash does not match the hash submitted on-chain | None: an answer from the API, not a transaction |
| 13 | Made-up value (invented email) (job 7) | Evaluator | As promised FAIL; failing: C7 (NOT_DERIVED_FROM_INPUT); report hash matches the chain | |
| 14 | Submit again after all attempts are used (job 7) | Contract | As promised rejected on-chain: “no attempts left” | |
| 15 | Refund job 7 (attempts exhausted, no PASS) (job 7) | Contract | As promised Refunded | |
| 16 | Open isolated job 8 (job 8) | Setup | As promised Open | |
| 17 | False rejection reason (good rows rejected as INVALID_EMAIL) (job 8) | Evaluator | As promised FAIL; failing: C2 (REASON_NOT_TRUE), C8 (REJECT_CAP_EXCEEDED); report hash matches the chain | |
| 18 | Fake merge (two different people merged) (job 8) | Evaluator | As promised FAIL; failing: C2 (MERGE_KEY_MISMATCH); report hash matches the chain | |
| 19 | Passes every public check, mishandles hidden control records (job 8) | Evaluator (hidden canaries) | As promised FAIL; public checks C1–C8 all pass; H1 fails (3 hidden control records wrong, not named in the report); report hash matches the chain | |
| 20 | Submit again after all attempts are used (job 8) | Contract | As promised rejected on-chain: “no attempts left” | |
| 21 | Refund job 8 (attempts exhausted, no PASS) (job 8) | Contract | As promised Refunded |
What it cost
0.4800 NEAR was escrowed and 0.4800 NEAR refunded. The contract kept 0.0351 NEAR for storing the two jobs, and the agents paid 0.0048 NEAR in gas. Testnet tokens only.