← All posts

An agent was talked into sending $150,000 in Morse code

No exploit and no stolen key, just a message the model agreed to act on. Prompt injection is not a bug you patch, so what can a persuaded model express?

Security5 min readDeFiLoops

In May 2026 somebody took $150,000 out of an AI-integrated wallet without finding a single bug.

They sent a membership NFT to the wallet, which silently moved it into a higher permission tier. Then they posted a reply on X with an instruction hidden inside Morse code. The agent — Grok, wired into a trading bot — decoded the Morse, read the instruction, decided it was a legitimate command, and authorised the transfer.

No exploit. No stolen key. No compromised server. The model was simply asked nicely, in a format nobody had thought to distrust.

Two failures, and only one of them gets discussed

Both have names. They are OWASP LLM01:2025 and LLM06:2025 — the first and sixth entries in the standard list of ways language-model applications fail.

Before

The model could not tell an instruction from its principal apart from an instruction in its input. Everyone is working on this. Nobody has solved it.

After

Once persuaded, the model was able to express “send everything to this address.”

This one is not a model problem at all. It is a question about what the surrounding system permits to be written down.

The first failure is the one that gets the headlines. The second is the one that decided how much it cost.

If injection is going to happen, the design question is not how do we stop the model being fooled. It is what can a fooled model actually do.

The industry’s answer, and why it stops short

Read a dozen vendor pages on agentic wallet security and you get the same list: least privilege, scoped session keys, per-transaction and daily caps, a recipient allowlist, human confirmation for anything irreversible, keys isolated from the reasoning process.

All of it is good. Some of it is not happening — 45.6% of teams still share one API key across their agents, which makes it close to impossible to trace or stop an agent that has turned. The reported dollar totals for agent breaches are worth treating carefully — the headline Q1 2026 figure is dominated by a single incident that primary reporting attributes to compromised executive laptops rather than to anything about agents. The failure mode that is well evidenced is narrower and more useful: attacks on agents’ memory and on the protocols connecting them to their tools.

But the deeper issue is that the whole list shares an assumption:

Permission scopes must be defined precisely, but defining them precisely is hard, because agents act on language-based intent and language is ambiguous.

That sentence, or one almost exactly like it, appears across the field. It is treated as a hard problem to be managed with ever-tighter scopes.

It is a hard problem. It is only unavoidable if the model is composing calls.

We took the field out instead

The agent here does not write instructions. It fills in a fixed form of labelled boxes, drawn from a closed catalogue of operations.

What the form can carry
amount
A quantity, in the asset's own scale
asset
A symbol from the network's list — never an address
network
One of the supported networks
role
A named destination, such as "the owner's account" — never a raw address
market
A curated market name, never an identifier
basis points, deadline, price, tick
Bounded numeric kinds

So run the Morse code attack against this. The model is persuaded — assume that completely. It now wants to send your funds to an attacker.

It cannot write that down. Destinations are roles, resolved from your account at the moment the step runs. There is no field where an attacker’s address could go, so nothing has to detect the attempt.

  1. An operation not on the list cannot be named

    A plan naming anything outside the catalogue is refused when it is written, not attempted and failed halfway.

  2. Anything produced goes to you

    The destination is a role looked up from your account, never a value the plan supplies.

  3. Caps are fixed in your account

    Per asset, per period. Nothing on our side can raise them.

  4. The agent is a contract, not a key

    A key can be stolen and used by whoever holds it. A contract can only be appointed or not — and the appointment is one-way, so an account can never be re-pointed at a different agent.

Where this stops being comfortable

Everything above is real and none of it makes us safe in general. Three things you should weigh against it:

Those are reachable in two situations: a permissive mode we do not run in by default, and anywhere somebody holds the keeper key directly and therefore never goes through our signing service. In normal operation that service will not produce the shape of instruction that reaches them. That is a real protection and it is not the same as the hole being closed.

Second: there is no external audit. Every assurance here is our own testing.

Third: the service holding the keeper key refuses to start in a production setting, on purpose, because it currently keeps that key in memory.

What to actually take from the Morse code story

Not that one product was careless. The specific mistake — an NFT transfer silently raising a permission tier — is unusual, but the shape is not.

The shape is: a system where being persuaded and being able to act are the same event.

Injection you cannot prevent. Expressiveness you can remove.

The only structural defence we know

If you are evaluating any agent that touches money, that is the question worth asking, and it is answerable without trusting anybody’s security page. Ask what the agent is able to write down. If the answer includes an address, every other control is a filter standing between a persuadable model and your funds — and filters are evaluated against the attacks somebody already thought of.

Ours does not include an address. We would still rather you assumed we had missed something, because on four occasions we had.