On May 4, 2026, about 3 billion DRB tokens left a wallet linked to the @grok account on X, worth roughly $150,000 to $200,000 depending on who you read. By the public accounts, no smart contract was broken. About 80% of the funds later came back.

Most coverage led with the Morse code, because Morse code is funny. I think it is the least important part of the story.

What was publicly reported

Bankr automatically provisions a wallet for X accounts that interact with its bot, and Grok had one. As reported by Giskard and others, the chain had three links:

  1. An attacker sent a Bankr Club Membership NFT to Grok's wallet, which reportedly unlocked transfer capabilities that were not available before.
  2. The attacker posted an encoded message and asked Grok to translate it. Grok did.
  3. Bankrbot read Grok's translated reply as a command and moved the tokens.

The reported three-step chain: a stranger sends an NFT, the model translates a message, a bot acts on the reply

SlowMist classified it as permission-chain abuse, not as a simple model failure. Bankr's operator gave the detail that interests me most: an earlier version of the agent had a hardcoded block on replies from Grok, meant to stop model-to-model injection chains, and that block did not survive a later rewrite. They have since added a more robust block on that account.

The encoding was never the vulnerability

You can add Morse to a filter. Then someone uses Base64, or a language your filter does not read, or a story about a grandmother. A filter over model text is a list of the attacks you already thought of.

Look at the two decisions that actually moved the money:

  • Authority came from something the account received. Anyone can send a token to an address. If holding it widens what an agent may do, then outsiders can write to your permission system.
  • Output from a model was accepted as an instruction. The reply was authenticated in the sense that it really came from @grok. It said nothing about whether any person with authority over those funds wanted the transfer.

And then the rewrite. A guardrail that exists as a special case is a guardrail one refactor away from gone. I do not say that to single out Bankr's engineers: every team ships rewrites, and this kind of check is exactly the kind that gets lost, because nothing breaks when it disappears. The tests pass. The product works better than ever, right up to the moment it matters.

The new block on Grok's account fixes Grok's account. The next model-operated account is a different string.

Default deny has a different failure mode

The alternative is not a better list. It is changing what happens when nobody wrote a rule.

Deleting a special-case check fails open; deleting a required signed grant fails closed

I modeled the chain locally, using capability tokens from my project CleiMesh and a dispatch gate written from an open draft RFC. To be clear about what this is: a small simulation of the publicly described chain. It contains none of Bankr's code, touches no live service, and every "transfer" in it is a boolean. The code is about 250 lines, and you can run it yourself.

Model only: no real wallet, chain or service is involved. A. Authority inferred from a gifted NFT, translated text as a command transfer executed: true B. The same gift, but authority must be signed by the owner Err("tool transfer not granted") C. Transfers granted, but only to a payee the owner named Err("argument to out of bounds") D. Capability is fine, but the call was not approved by a human capability: Ok(()) dispatch: Refuse(MissingBinding) E. Approved by a human, then the destination is swapped as approved: Admit swapped: Refuse(DigestMismatch) 

Five cases of the local model: only the case with authority inferred from an NFT runs the transfer

Three things to notice:

  • The gift grants nothing (B). Authority is a token the owner signed. No asset an outsider sends can produce that signature, so there is no rule to remember and none to lose.
  • Grants are narrow (C). Even with transfers allowed, the owner named the payee.
  • A valid capability is still not consent (D, E). With no human approval bound to the call, the host refuses. With one, the host recomputes what is about to run and refuses if the destination moved.

Where this stops working

This is not a magic fix, and I would rather you hear that from me.

  • A rewrite can also delete a verification call. The structural protection only holds if the component that executes the transfer cannot act without a valid token, so that deleting the check breaks the feature instead of quietly opening it.
  • In this model the gate stops the attack and also stops any autonomous transfer, since no human approved it. For agents that are supposed to act alone, you need consent that is delegated ahead of time, within limits. I am still working on that.
  • If the screen lied before the human approved, the binding faithfully records the lie. It gives integrity of the action about to run, not proof of what a person's eyes saw.
  • Bankr's real architecture is more complicated than five steps. I am working from public reports, and details differ between them.

The question to ask about your own agent

Forget the encoding. Open your agent's permission path and ask: what can a stranger send me that changes what my agent is allowed to do? Then ask the second one: if someone deletes this check in a refactor, does the system fail closed or fail open?

If the honest answer to the second is "it would just keep working", you have the same bug. You just have not had your May 4 yet.

Written with AI assistance. The argument, the decisions and the final review are mine.

Open to consulting and collaboration on agent security: threat modeling, consent and trusted-path design, guardrail audits. I prefer async and written communication.

— Cleiton Augusto Correa Bezerra