The largest theft in the history of this asset class broke no cryptography. No signing key was extracted. The multisig worked. The Safe contracts did exactly what they were told.
What the attacker compromised was a developer machine, and through it the Safe interface. Malicious JavaScript made the screen show a routine transfer to a warm wallet while the underlying transaction logic and destination had been replaced. 401,347 ETH left a cold wallet.
Every control that was supposed to prevent this was present and functioning. The decision point was that qualified people, holding hardware, operating a multisig, each approved a payload they could not independently verify, because the screen in front of them said it was fine.
The previous lesson gave you a taxonomy. This lesson is about the condition that makes the taxonomy useless: when you cannot tell which row you are in.
What blind signing is
Your wallet receives a payload from a website. It has two options.
It can decode the payload into human-readable intent, so the screen reads something like "Approve USDC spending by 0x1f98..., limit 500." That is clear signing.
Or it can show you the bytes. A block of hex. Maybe a function selector. That is blind signing, and the name is exact: you are signing something you cannot read.
The critical part is what happens to your trust when decoding fails. It does not disappear. It moves.
When the device cannot tell you what the payload does, the only remaining description of it is the one on the website. You are no longer trusting your wallet. You are trusting the site, its front end, its dependencies, its CDN, and everyone with commit access to any of them. The hardware is now an expensive rubber stamp.
That is the entire mechanism of the autopsy above, and of the front-end injection in the previous lesson. Both attacks live in the gap between what the interface claims and what the payload does. Clear signing closes that gap. Blind signing is the gap.
Why the usual defences do not apply
This is where people who have done everything right still lose money, so it is worth being blunt about each one.
Hardware wallets. A hardware wallet keeps the private key off a networked computer. That defeats key extraction. It does nothing about intent. If the device shows hex and you press confirm, it produces a perfectly valid signature over something hostile.
Multisig. Requiring several approvals raises the bar against one compromised individual. It does not raise the bar against one compromised interface, because every signer is looking at the same one. Five signers blind signing the same payload is not five checks. It is one check performed five times with the same blindfold.
Audits. An audit covers the contract. Blind signing is about which contract you are talking to and with what arguments. A perfectly audited contract will happily transfer your tokens to an attacker if that is what you signed.
I checked the URL, so the request is safe.
The BadgerDAO users checked the URL too. It was correct. Domain verification tells you where the request came from and nothing about what it asks for. Those are separate questions and only one of them is answered by the address bar.
Reading a device screen
The practical skill is short. On any confirmation, look for three things.
Is there a decoded action? A verb and an object, in words. "Approve", "Swap", "Transfer", with amounts and a counterparty. If all you have is a hash, a selector like 0xa9059cbb, or a block of hex, decoding did not happen.
Does the decoded action match what you asked for? You clicked "swap 100 USDC". If the screen says approve, or says unlimited, or names a token you did not choose, the interface and the payload disagree. The payload is what executes.
Does the counterparty match? Full address, on the device, compared character by character against the contract you intended. Not the first four and last four. Lesson 4 is entirely about why truncated comparison fails.
If any of the three is missing, you are blind signing, whatever the interface calls it.
What to do instead
When decoding fails you have three real options and one fake one.
- Stop. This is correct far more often than people expect, and it costs nothing except the opportunity you were being rushed toward.
- Verify independently. Read the contract on a block explorer. Confirm it is verified, confirm the address matches, confirm the function you are calling does what you think. F105-05 and J306 build this skill properly.
- Simulate. Wallets and standalone tools can execute the transaction against current state and report the resulting balance changes before you sign. A simulation that shows an unexpected token leaving your account is the answer. At least two categories of tool do this: wallet-integrated simulation, and independent simulation services. Use whichever you have; do not treat any single vendor's verdict as authoritative.
- The fake option is sign a small amount first. It does not work against anything in the previous lesson's second group. An approval is not sized by the transaction that carries it.
Some legitimate interactions with novel or complex contracts still cannot be decoded by some devices. That is a real constraint and pretending otherwise would be dishonest. The correct response is not to sign anyway. It is to decide that this action is not worth doing from this account, and if it must be done, to do it from an account whose entire balance you are prepared to lose. That is what the burner tier in F104 is for.
Clear signing means your device tells you what you are authorising. Blind signing means the website tells you, and you have no way to check. Everything else in your setup, the hardware, the multisig, the audits, protects the key rather than the intent, which is why a $1.5B theft happened to people doing almost everything correctly. If the device cannot tell you what you are signing, do not sign.