25attack tests. The limits held.

Payrein holds the agent’s money on NEAR, tested against live Intents code.

Payrein, demo run
13:28:28Report Shop0.002Settled report delivered
13:28:38attacker.test.near0.002Refused not allowlisted
13:28:46attacker.test.near0.002Refused leaked key
13:28:52Report Shop0.008Waiting owner approval
13:35:49Report Shop8 × 0.004Settled 7 Refused 1 queue full

Spent today0.030 of 0.030 wNEAR

The owner app after a demo run. The vault holds 9.998 wNEAR with a 0.01 per-payment and 0.03 daily limit. The agent’s log shows a merchant’s injected instruction to pay attacker.test.near, two refusals marked MerchantNotAllowed, and a 0.008 payment waiting for the owner’s approval.

After four demo steps on a local chain: one purchase settled, two attacks refused, one payment waiting.

Numbers from the last full run

Local run, 22 October 2026, against the intents.near binary pinned from mainnet block 220928157.

27
unit tests on the contractcargo test -p policy-vault
25
attack tests against the real Intents codemake test-security
5of 5
mutations caught; each removed check failsscripts/mutation-check.py
0
access keys on the vault, so nobody can redeploy itview_access_keys

Four attacks, the same answer

Each runs in the demo with a scripted stand-in for the model, made to act compromised.

The invoice says pay someone else

The merchant’s text moves the payment account to attacker.test.near, and the agent obeys.

Refused MerchantNotAllowed

A plain wallet key pays the attacker.

The agent’s log: the merchant’s injected notice, the model deciding to pay attacker.test.near, and the vault’s answer, refused: MerchantNotAllowed.

Where the money sits

The agent never holds a balance. One restricted key lets it ask; the contract decides.

Agent one function-call key Vault contract allowlisted merchants per-payment limit daily limit, reserved first approval above a threshold no access keys NEAR Intents holds the wNEAR Merchant verifies, then delivers Owner approves in a wallet request_payment mt_transfer receipt approve(op)

What a deployment needs

  • ToolchainRust 1.93+ (wasm32 target), cargo-near 0.22, Node 22.13+, pnpm 11, Python 3
  • Ownera NEAR account; a wallet that shows full call arguments
  • Fundsone token balance on NEAR Intents
  • Agenta function-call key limited to request_payment
  • Testnetabout 19.6 NEAR; it deploys its own copy of Intents

What it does not protect

  • The owner’s keyStolen, it changes the policy and withdraws.
  • DeliveryA merchant can take payment and not deliver. The limits cap the loss.
  • PriceA merchant can quote one price and invoice a higher one within the caps. The contract admits it; the agent’s own check refuses an invoice that differs from its quote and pays nothing.
  • Intents adminsCan pause, lock, force-transfer the vault’s balance and upgrade Intents.
  • A lost callbackKeeps its slot and day’s reservation until the owner resolves it after ten minutes.
  • Midnight UTCThe cap resets; up to twice it can move across the boundary. Accepted.

Built in the open, dated

Work since the 19 October announcement counts, per the organisers’ FAQ; this repository started on 21 October.

WhenWhatCheck
Contract, tests, attack suite, merchant, agent, owner app, demo, testnet bootstrapgit history
Owner app layout with numbered steps, evidence rerun, submission kitevidence/local-run.md
Claims matched to tests, product thesisdocs/threat-model.md
Demo video recorded from the local runevidence/video-*.png
Repository public, submitted; review findings fixed: bootstrap keys, merchant redelivery; second merchant and the quote checkdocs/review-2026-11-02.md
Testnet deployment; every demo check passes on chainevidence/testnet-run.md
to 14 Nov 2026Planned: the wallet check on testnet, real-model runREADME, status

Run it in three commands

A local chain, two merchants, the agent, the owner app. Prerequisites in the README.

pnpm install
make test-security
make demo-local
The vault summary: balance 9.998 wNEAR on Intents, per payment 0.01 with approval above 0.005, daily limit 0.03 paying only Report Shop, status active, and today’s bar at 0.002 spent.