
How an entropy bug sat hidden for five years inside one of Bitcoin’s most respected hardware wallets, and let attackers steal funds without ever touching the device.
For years, the standard answer to “how do I keep my bitcoin safe?” was always the same: take it off the exchange and put it on a cold wallet, a dedicated device that keeps the keys off the internet. The advice even has its own slogan, repeated in forums and at conferences ever since Andreas Antonopoulos put it into circulation around 2016: not your keys, not your coins. If you do not hold the keys, the coins are not yours: they are a promise that somebody will hand them back when you ask. Everyone recommended it, and it is still good advice.
What everyone did not recommend was a particular brand, because there are many and they differ a lot. The two big ones, with more than seventy per cent of the market between them, are Ledger and Trezor. Behind them sits a whole ecosystem: BitBox, Blockstream Jade, Foundation Passport, Keystone, Tangem, SeedSigner for people who would rather build their own, Block’s Bitkey, and several more.
And then there was the recommendation of another crowd: the people who read the firmware, distrusted pretty apps and wanted a device that did exactly one thing. That group, small but very influential, pointed almost always in the same direction: a little black box made in Canada called Coldcard. It was nowhere near the best seller. It was the one recommended by the people who knew most, which is a different thing and, for what comes next, a more important one.
On 30 July 2026, between 01:10 and 01:51 UTC, somebody drained 1,196 bitcoin addresses. Forty-one minutes, spread across nine blocks. 1,082.65 BTC, about $70 million at that day’s price.
If you followed the case back then, you may remember a smaller figure for that same night: around 594 BTC. That was the first public count, from the CEO of AnchorWatch, and it was what could be seen at a glance across three consecutive blocks. Galaxy Research reached 1,082.65 by finding a common fingerprint in the transactions, which let them attribute addresses to the same episode that had looked unrelated. The first calculation was not wrong: it just saw part of the picture.
Six days later, Galaxy Research’s count stood at roughly 1,816 BTC pulled from more than 5,200 addresses, around $116 million. The numbers you will see in each outlet swing between $100 and $130 million, and it is not that any of them is wrong: the attack is still live as I write this, and every count is a snapshot of a different moment.
This is not the largest bitcoin theft in history. It is not close: Mt. Gox lost some 850,000 BTC. But it is the first of its kind, and that is why it matters so much. Until now the big thefts had always hit a third party: an exchange, a custodian, a company holding a lot of people’s money in one place. This time what failed was the device you buy precisely so you do not depend on any third party.
It is worth saying, though, that the bug itself is not new, even if almost nobody knows it. In December 2020 somebody drained the Chinese mining pool LuBian of 127,426 BTC, and did it for exactly the same reason: its keys were generated with 32 bits of entropy, so trying them all was enough. Nobody found out until Arkham uncovered it in 2025, five years later. By number of bitcoin it does not reach Mt. Gox, as you are about to see; by money on the day it happened it beats it, and by a lot. And it is not the only precedent: in 2023 the bug known as Milk Sad left the seeds of a tool widely used by developers confined to 32 bits as well, by seeding its generator with the system clock. What is new about Coldcard is not the class of bug: it is where it was.
Figures in BTC as of each theft, and the scale is linear: the Coldcard bar really is that short. About 200,000 were later recovered from Mt. Gox, and the Coldcard count is still rising. By number of bitcoin the largest is Mt. Gox; by money on the day it happened, LuBian, with $3.5 billion in 2020 against the $450 million the Mt. Gox coins were worth in 2014.
Jonathan Goodman, a Canadian entrepreneur, lost 18.25 bitcoin, around 1.6 million Canadian dollars. His Coldcard was in a bank safety deposit box. He put it like this: “perhaps the hardest part about this is that I did everything right. I never shared my seed phrase with anyone. My devices never touched the internet”.
He was right on all three counts. And it made no difference whatsoever, because the failure sat above everything he could control.
It failed at the one point where it could not afford to.
If you would rather watch before reading, I summed up the essentials in six minutes. The video is in Spanish, with English subtitles — turn them on with the CC button. The article goes far deeper, but the video covers what you need to know if you own a Coldcard right now.
Your wallet was not created: it already existed
Let us start with what almost nobody explains, because it changes how you understand everything else.
When you set up a bitcoin wallet you are not creating anything. There is no sign-up, no registry, no server noting that this address is yours. Addresses are not accounts that somebody opens: they are the result of applying a formula to a number. Your device does not invent an address, it calculates one and keeps quiet about the number it came from.
It is worth being exact here, because the nuance is a lovely one. The set of possible private keys was not invented by Bitcoin: it is a range of numbers defined by a mathematical curve, secp256k1, standardised in the year 2000, eight years before Bitcoin existed. That space was already there. What has changed over the years is the address format (the ones starting with 1, with 3, with bc1…), which were added through protocol upgrades. But in no case is anything created when you generate a wallet: for each format, every one of its addresses is fixed by the mathematics at the very instant the format is defined. Nobody registers them. They are computed.
How many are there: 1.46 × 1048. A forty-nine digit number. In all of Bitcoin’s history about 1.5 billion addresses have ever been used, and of those only some 58 million hold any balance today. Put that in proportion: for every address with bitcoin in it there are 2.5 × 1040 empty ones, which is a 25 followed by thirty-nine zeros.
The grid is symbolic: the real ratio, one in 2.5 × 1040, cannot be drawn on a screen.
That is why there is no account registry, no clerk checking for duplicates, no paperwork to sign you up. There is no need. The map is already drawn in full, and it is so vast that almost no point on it has ever been set foot on by anyone.
And that is exactly why the Coldcard bug is as serious as it is. The device did not have to invent anything: it had to pick a point at random on that enormous map. What happened is that, without anyone noticing, for five years it kept picking inside the same tiny corner.
The drawing is not to scale, and it cannot be. The whole map is 2160 points and Coldcard’s corner was 240: some 1036 times smaller than the red square standing in for it. The scattered dots are the addresses used in all of Bitcoin’s history, about 1.5 billion.
Bitcoins do not move: they are signed
The mining fee is left out. It is the small difference between what goes in and what comes out, and it is taken from the change.
Second idea worth having clear, because it explains why the theft was technically flawless.
There are no bitcoin coins. There is no digital object travelling from one place to another. What exists is a public ledger with a list of unspent outputs: entries saying “this amount is locked so that only whoever holds the key matching such-and-such public key can unlock it”.
When you make a transfer nothing moves. A new entry is written saying: “these outputs are now spent, and in exchange these others are created, locked to someone else”. And a signature is attached. It is closer to a land registry (where a line is struck out and another written underneath) than to an armoured truck. Nothing travels.
What the network checks is not what people imagine either. It does not check who you are, nor whether the money is yours, nor whether you are being coerced. It checks exactly one thing: that the attached signature fits mathematically with the public key that locked that output. If it fits, the transaction is valid. Full stop.
There is the key to everything that happened on 30 July. The attacker forced nothing. He did not break the cryptography, did not exploit the network, did not forge a signature. He presented perfectly correct signatures, because he held the correct keys. From Bitcoin’s point of view that was not a theft: it was people moving their own money. The protocol has no concept of “rightful owner” beyond “whoever can sign”.
And from this comes the sentence that sums up why a hardware wallet matters so much: your bitcoin was never inside the device. What was inside was the ability to sign. If somebody else has that ability, they hold it just as legitimately as you do.
The thief is not after your words
Almost everyone pictures the attack as somebody trying words: “abandon, ability, able…” until they hit your twelve. That is not how it works at all, and understanding why clears up everything else.
The words are not the secret. They are the label on the secret. The real chain, defined in the BIP-39 standard, goes like this:
- A random number is generated. The standard allows several sizes: 128 bits gives you twelve words and 256 gives you twenty-four, and Coldcard offers both. That number, and only that number, is the secret. Notice that the standard does not say who generates it, and that detail would end up being the heart of everything: the device itself can generate it, or you can supply it by rolling a die. On the affected Coldcards, the device generated it.
- A small checksum is computed, the result is split into groups of eleven bits, and each group picks a word from a list of 2,048. Out come the words. They add nothing: they are that same number in another encoding, just like hexadecimal or base64. If you wrote that same number in hexadecimal you would get exactly the same wallet. The words exist because a human copies 32 hex characters badly and copies twelve words well, and the words carry a checksum too.
- The words, together with the passphrase if there is one, go through a deliberately slow function (PBKDF2, 2,048 rounds of HMAC-SHA512) and produce a 512-bit seed.
- From that seed all your private keys are derived.
- From each private key comes a public key, and from each public key come several addresses: one for every format that exists, the ones starting with 1, with 3, with bc1q and with bc1p. They are not different wallets, they are the same key written in several ways, which is why an attacker checks them all.
Notice what those five steps have in common: each one is computed from the previous with nothing unknown. The last two, on top of that, cannot be undone, and for different reasons: from private key to public key there is no way back because of the elliptic curve discrete logarithm problem, and from public key to address there is no way back in the formats that go through two hash functions (SHA-256 and then RIPEMD-160), which are most of them. The exception is taproot addresses, the bc1p ones, which carry the public key itself in plain sight: there is no hash there to undo. The first two are reversible: the number and the words are literally the same thing written two ways. And what really matters is this: whoever holds the number from step one holds absolutely everything, without asking anyone for anything.
That is why the attacker never had to guess a single word. What he did was reproduce on his computer the step-one numbers that faulty generator was capable of producing, which were few, and from each number compute its words, which is a one-step operation with nothing unknown. From each one he derived addresses and compared them against Bitcoin’s public ledger. When one matched an address holding a balance, he already had the matching private key and could sign.
These figures are for the Coldcard Mk2 and Mk3, with 40 bits of entropy: 240 is about 1.1 trillion numbers, and walking all of them at a billion per second takes some eighteen minutes. On the Mk4, Mk5 and Q, with 72 bits, the list is far larger and the attack is no longer amateur work.
There is one more detail worth understanding, because it comes back later. In the hash-based formats, which are the ones that matter here, the address is a hash of the public key, not the public key. And a hash cannot be undone. As long as you have not spent from that address, the world sees the address but not the public key behind it. The moment you spend, the signature carries the public key inside it and that key is recorded forever.
That means an unspent address is somewhat better protected than one that has already spent. In this attack it made no difference, because the attacker was generating candidates from the start of the chain and could compute both the public keys and the addresses. But hold on to the detail: it is the piece that makes multisig dangerous.
A seed is not a key: it is the root of many
Here is something that confuses almost everyone, and with good reason, because the names do not help. Seed, private key and address all sound alike and are not the same. And above all: they do not come one at a time.
A wallet does not have one private key. It has a number that for practical purposes is infinite. What is unique is the seed, and every other key comes from it through a procedure defined in the BIP-32 standard: a function is applied to the seed and you get a child key, and you apply it again to that one and get another, and so on in the shape of a tree. Hence the technical name, hierarchical deterministic wallets.
Deterministic means the tree always comes out the same. With the same seed you get exactly the same keys, in the same order, in any software and on any device. That is why writing down twelve words is enough to recover everything: you are not storing your keys, you are storing the instructions for rebuilding them.
And why would anyone want thousands of addresses? For privacy, and it matters more than it looks. If you always got paid to the same address, anyone who had ever paid you could look at the public ledger and see your full balance, every payment you receive and when. Using a fresh address each time breaks that chain. It is not paranoia: it is the difference between your boss seeing your salary and your boss seeing your entire net worth.
So, in order: one seed → a tree of private keys → one public key for each → and from each public key, one address per format. And going back to the earlier point, the seed comes from the random number. The whole building rests on that number, and everything else is arithmetic.
What each piece opens if it is stolen
With the whole chain in front of us we can answer something that is rarely explained well: not every piece is worth the same to whoever steals it. And one of them behaves the exact opposite of what people assume.
The number, or the twelve words. They are the same thing, so they open the same thing: the seed, the whole tree and every address. It is what happened to the Coldcard victims, with the twist that nobody stole a piece of paper there: the number was reconstructed.
The seed. Here is the interesting asymmetry. The seed is the 512 bits that come out of the previous step, and by the time it exists the passphrase is already inside it. Whoever pulls those bytes out of the chip opens your real wallet and signs perfectly, without knowing your words and without being able to reconstruct them. Put another way: a passphrase protects you against the theft of your words, not against the theft of your seed. Hold on to this, because it matters later: in the Coldcard case the attacker reconstructed the number, which sits before that fork, and that is why the passphrase did change things there.
The extended public key, the xpub. With it you see everything and can spend nothing. It is surveillance, not theft: every address of yours past and future, every movement and your exact balance, forever. Plenty of people share it without a second thought, with an invoicing service or with their accountant, because “you cannot steal with it”. True, and it is still your entire net worth turned into information.
A lone private key. It is the best insulated piece in the whole system: if it is stolen, it opens its own address and no other. Not the one next door, not the one above. It is missing the chain code, the other half you need in order to derive, and without it you cannot move up or down the tree.
And the passphrase on its own: nothing. Without the words it generates no tree at all. That is why it makes sense to keep them in different places: they are two genuine factors, not two copies of the same thing.
What entropy is, and why it is called that
The word was coined by Rudolf Clausius in 1865, and he chose it carefully. He built it on the Greek ἐντροπία, which means something like transformation or turning, and shaped it deliberately so it would sound like energy, because he wanted both to read as quantities from the same family.
It was not born as a philosophical idea about chaos, but while solving a very concrete engineering problem: why no real steam engine ever reached the efficiency theory promised. Something was always lost along the way, and that something could not be recovered.
Almost a century later, in 1948, Claude Shannon took the same mathematics somewhere unexpected: communication channels. In his version, entropy no longer measures lost heat, it measures uncertainty. How much surprise there is in a message. How much you cannot predict.
That is the one that matters here, and it is why “bits of entropy” is not a pompous way of saying “bits”. It is a measure of how much ignorance whoever wants to guess your key has about it. In physics it measures the disorder you cannot undo; in cryptography, the ignorance you cannot reduce.
And that is why the bug is described as an “entropy loss” rather than a “weak password”. It is not that Coldcard’s words were bad words. It is that the attacker had far less ignorance than the design assumed.
A computer cannot do anything at random
This is the part that makes the bug almost inevitable the moment you get careless, and it deserves explaining slowly.
A processor is a deterministic machine. Give it the same inputs and it gives you the same outputs, always, without exception. That property is exactly what we want from a computer. And it is exactly the opposite of what cryptography needs.
When you ask a programming language for a “random” number, what you almost always get is a pseudorandom generator: a mathematical function that, starting from an initial value, spits out a sequence that looks disordered. Looks, but is not: if you know that initial value, you know the entire sequence, from the first number to the last. It is a deck that shuffles the same way every time if you cut it in the same place. (That initial value is also called a seed, by the way, and has nothing to do with your wallet seed. Bad luck with the names.)
To get real randomness you have to leave the digital world and measure something physical, something not even the manufacturer can predict. Serious devices carry a hardware generator for that. In the microcontroller inside the Coldcard, an STM32, it works like this according to ST’s own documentation: there are several ring oscillators, circuits that oscillate freely, and it exploits the fact that none of them oscillates at exactly the expected rate. That tiny, unrepeatable tremor is called jitter, and it comes from the thermal noise of the electrons. The outputs are sampled, combined and processed until you get numbers that are unpredictable even to whoever made the chip.
Other devices use other sources of the same kind: electrical noise, avalanches in a diode, even radioactive decay. They all share the idea. Randomness is not computed, it is harvested.
And now you can see what actually happened. The Coldcard had its hardware generator. It was fitted, it worked and it was in the firmware. What happened is that, through an integration mistake, the function that created seeds stopped asking it and started asking the software fallback generator instead. Nobody unplugged the oscillator. They simply stopped calling it.
Why nobody just tries addresses at random
Here comes the obvious question: if every address is already there and the ledger is public, with 58 million of them holding a balance, why is there not a crowd of people brute-forcing keys until they hit one?
The answer is not that it is hard. It is that it does not remotely pay off, and you can work it out.
A current graphics card derives on the order of a billion keys per second while drawing about 300 watts. With that reference, and electricity at $0.15 per kilowatt hour, searching an entire space costs this:
| Space | Cost of searching it in full |
|---|---|
| 40 bits (Coldcard Mk2 and Mk3) | 1.4 cents of electricity. Less than charging your phone. |
| 72 bits (Coldcard Mk4, Mk5 and Q) | About $59 million. Expensive, but within reach of a state. |
| 128 bits (what it should have been) | Capturing all the energy the Sun emits, in every direction, for three entire days. |
| 160 bits (every address that exists) | The Sun’s entire output for 36 million years. |
And this is not armchair theory: there has been a public experiment measuring exactly this frontier since 2015. Somebody deposited bitcoin in 256 addresses whose keys are confined to progressively larger ranges (one of 1 bit, another of 2, and so on) and left them in plain view with the prize inside. It is the official scoreboard of how far real brute force reaches.
Puzzle number 66, with 6.6 BTC inside (about $400,000), fell in September 2024. Number 67 held out until February 2025. And we are talking about people coordinating in GPU pools, with the prize visible and the range known in advance.
Place the Coldcards on that scale and the whole thing clicks. The 40 bits of the Mk3 are 67 million times easier than that puzzle 66 which took years to fall. And the 72 bits of the newer models are only 64 times harder than it: above the frontier, yes, but within sight of it. That is why Coinkite is asking those owners to migrate too.
There is also a detail that tends to surprise people: Bitcoin’s enormous mining power is no use for this. Miners’ ASICs only know how to do one thing, SHA-256, and searching for keys requires elliptic curve arithmetic, which is a completely different operation. The hardware that holds the network up is literally incapable of attacking it.
Why 72 bits is not halfway to 128
Let us translate it into time as well, which feels different from money. At the same rate of a billion attempts per second:
- 40 bits: eighteen minutes.
- 72 bits: about 150,000 years.
- 128 bits: about 780 billion times the age of the universe.
To see it from the other side: with the 128 bits that were due, every person on the planet could create 2.6 billion wallets and it would still be unlikely that any two collided. With 40, as we are about to see, things change completely.
That is the mental trap of entropy: the scale is not linear, it is exponential. Having a third of the bits does not mean being a third as safe. It means the difference between spending 1.4 cents of electricity and needing three days of everything the Sun puts out.
The silent theft that may already have happened
Here is a possibility I have not seen mentioned anywhere and which, the more I look at it, the more it unsettles me. It is speculation, and I flag it as such from the outset. But the numbers hold it up.
If the seed space had shrunk to 40 bits, you did not need an attacker for something strange to happen. It was enough for two different Coldcards to pick the same one by chance. It is the classic birthday paradox: in a class of twenty-three people it is more likely than not that two share a birthday, even though the year has 365 days.
And there is a technical detail that makes it possible rather than impossible. The faulty generator was initialised with the low part of the chip’s unique identifier, among other things. You might think that separates every device from the rest, but the technical analysis points the other way: different chips can share that low part of the identifier. The separation was not guaranteed.
The numbers, with the 40-bit space of the Mk2 and Mk3: if 100,000 seeds were generated, the probability that two collided is 0.45%. With 250,000, 2.8%. With half a million, 10.7%. And from 1.2 million seeds onwards, a collision is more likely than not.
Coinkite does not publish sales figures, so I cannot close the calculation. What we do know about the market: Ledger has shipped more than eight million devices and Trezor more than two, while specialist makers like Coinkite share out a remainder that does not reach five per cent. With that, the reasonable range leaves the probability somewhere between “unlikely” and “quite possible”, especially given that many people generate several seeds over the years: tests, reinstalls, temporary wallets.
Now the part that makes you dizzy. If it happened, the person would have seen it. When a wallet is set up, the software scans the chain looking for its addresses. If that seed matched somebody else’s, the brand new wallet would show up with a balance. Bitcoin inside. No explanation.
Picture the scene, in 2023. Somebody has just taken the device out of the box, written down their twelve words, and the software tells them they have funds. What do they conclude? Certainly not that the random number generator in their hardware wallet is broken: nobody in the world knew that yet. They would think they picked the wrong wallet, that the software glitched, or that they restored an old backup by accident.
If they look at the history, there is the detail that admits no confusion: that bitcoin arrived years before they bought the device. At that moment a fork opens that is no longer technical but moral, and the protocol has absolutely nothing to say about which branch gets taken.
Whoever decides it is not theirs has a clean exit that costs nothing: generate a new wallet, forget those words and touch not one satoshi. They cannot give it back, because the chain does not say whose it was. But there is no need either: by leaving it alone, the owner never finds out and loses nothing. It is, by a distance, the easiest thing to do.
Whoever decides to keep it signs and takes it. And here is the ugly part: on the chain that transaction is indistinguishable from any other. They hold the key, the signature is valid, and for Bitcoin that is everything there is to know about whose money it is. No record remains that anything happened there.
Only in that second branch is there somebody on the other side who, one day, opens their wallet and finds nothing. No hack, no phishing, without ever having shown their words to anyone. And with no way of finding out what happened, because the bug would not be known for another five years.
There is no way of knowing whether it occurred. Cases like that, isolated and unexplained, get filed as “user error” and leave no public trace. What we do know is that for five years it was possible, and that if it had happened, nobody would have had any way to understand it.
One small consolation: on the 72-bit models this scenario is essentially impossible. You would need to generate eighty-one billion seeds for a collision to become likely. Between 40 and 72 bits there is no step: there is a chasm.
The bug: a check that asked the wrong question
In 2021, Coldcard migrated part of its code to libsecp256k1, the cryptographic library Bitcoin Core itself uses. It was a reasonable decision: lean on heavily tested code instead of maintaining your own.
With that migration, seed generation stopped calling the hardware randomness generator directly and started calling ngu.random.bytes(). And there, at the point where two components meet, everything happened.
The library carried a safety check that said, in essence, “if there is no hardware generator, do not compile”. Written like this:
#ifndef MICROPY_HW_ENABLE_RNG
#error "get a HW TRNG plz"
#endif
#ifndef asks whether the symbol exists. It does not ask whether it is worth anything. And Coldcard had it defined… with a value of zero, because it used its own generator and wanted MicroPython’s disabled:
#define MICROPY_HW_ENABLE_RNG (0)
The symbol existed. The check declared itself satisfied and said nothing. But MicroPython, a few lines further on, did look at the value, saw a zero, and compiled its software fallback generator: a deterministic algorithm called Yasmarang.
Both implementations were called the same and had the same signature, rng_get(). The linker did not complain. The device booted. It generated valid words. It signed correct transactions. Everything worked.
It is the equivalent of an inspection that checks whether a fire extinguisher is hanging on the wall, instead of checking whether it is charged. The extinguisher was there. Red, visible, in its place, passing every inspection for five years. And empty.
Yasmarang was initialised exactly once with three things: part of the microcontroller’s unique identifier, the value of a system counter and a clock register. After that, according to the independent analysis by Block’s engineering team, it gathered not one further bit of randomness: every subsequent output was a deterministic transition from the previous state.
Coldcard then passed that result through hash functions. It does no good at all, and it is worth understanding why: a hash can scramble, it cannot create. If the generator can only produce a thousand distinct results, applying SHA-256 gives you a thousand values that look random. They are still a thousand. It is like assigning thirty-digit postcodes to a thousand houses: the codes look terribly complicated and they still point at a thousand houses.
How you steal without touching the device
We know what he was after and how he looked for it. What is left is the most striking part: how little he needed to do it.
The attacker did not connect to a single Coldcard, did not break any secure chip and did not infect anybody’s computer. What we have already seen was enough for him: reproduce on his own machine the states that generator could produce, derive the addresses of each one and look them up in the ledger. The only thing he needed to bring in from outside was a copy of the blockchain, which anyone downloads without asking permission from anyone.
And look at that last part, the looking-up-in-the-ledger, because it has a cruel twist. Bitcoin’s transparency is normally not a problem: you can publish as many addresses as you like, because nobody can search the key space. But the moment that space shrinks, that same transparency becomes the catalogue where the attacker checks whether he has hit. The network tells him, free and instantly, which of his candidates are worth money.
Bitcoin, for its part, noticed nothing odd. From the network’s side those transactions were perfectly valid: correct signatures over legitimate funds. Bitcoin does not know what a theft is. It only knows how to check signatures.
One thing worth saying: nobody serious has published how long it takes. Block explicitly declined to give an end-to-end brute force figure, because the real cost depends on how far the chip identifier can be narrowed, the boot moment, how many prior calls there were and how expensive it is to derive and check each candidate. That both available technical analyses refrain from giving a number is, in itself, information: it means anyone handing you a round figure is probably making it up.
Twenty-four hours: from “user error” to “we take responsibility”
The human part of this story is as instructive as the technical one.
The sweep happened overnight. The first victim did not surface until 13:19 UTC, telling the story on Reddit. At 17:35, Kevin Loaec, co-founder of Wizardsardine, publicly asked anyone with a Coldcard to check their balance, with a line that aged badly: “I hope it is nothing, but I am doing my job”.
At 18:10, Rodolfo Novak (NVK, founder of Coinkite) replied that there was no need to panic: that somebody had loaded a compromised seed, or that it had leaked some other way. In other words, user error.
Less than an hour later, at 19:05, Loaec changed his tone to “this is not a drill”. By then the developer known as grubles had confirmed a case, Jameson Lopp was reporting partial thefts, and among the victims were well-known, competent bitcoiners. The careless-user hypothesis no longer held.
Novak withdrew his assessment, saying he did not want incorrect information circulating. That same night Coinkite published the security advisory. The emergency firmware came out in the small hours. And on 31 July the company apologised publicly and took responsibility.
It is worth pointing out the obvious, because it is a pattern that repeats in every security incident I have watched up close: the first explanation from any manufacturer is always that the user did something wrong. Sometimes that is true. When it is not, the time lost defending that hypothesis is paid for by the users who could still have moved their funds.
Why this one hurts more: it was the one the most demanding people recommended
If this had happened to some dubious gadget that keeps your keys on a server, the conclusion would be easy: you chose badly. Coldcard does not allow that way out.
Coldcard had earned its reputation by taking things away. Bitcoin only, without the thousand coins that drag in code and formats nobody reviews. Able to run air-gapped, signing over microSD card or QR codes, never touching a USB cable. Two secure elements. Reproducible builds. Dice support so you could add your own randomness. Multisig, PSBT, the whole toolkit of the paranoid user.
For a lot of people it was the closest thing to the cypherpunk ideal you could buy. It was defended precisely by the people who worried most about this kind of risk. And that is what makes the blow interesting rather than anecdotal: a system can make an enormous number of correct decisions and still contain one catastrophic flaw.
The uncomfortable correction: Coldcard was not open source
In the last few days I have read many times that the bug proves “open source is not enough”. Before drawing that lesson we have to fix a fact almost everyone repeats wrongly.
Coldcard’s firmware had not been free software since November 2020. Until then it was GPLv3. From that point it moved to MIT with a Commons Clause, which forbids selling derived products. That makes it source-available, not open source: you can read it, compile it and verify that the binary matches, but you cannot fork it and compete. Coinkite itself stopped calling it open source and started calling it verifiable.
The chronology matters: the licence change was in November 2020, and the bug went in with version 4.0.1, in March 2021. Four months later.
Zach Herbert, founder of Foundation Devices, argues these days that the two are connected: his company was building on the GPL-licensed Coldcard and had to part ways after the change. It is worth taking with the reservations it deserves (Herbert is a direct competitor and has an obvious interest) and also worth recognising that the mechanism he describes is real and requires no bad faith: whoever forks your code is, in practice, one of your most motivated reviewers. They read every line because they are going to maintain it. When you close that door, you do not lose casual readers: you lose the one who had an economic reason to read you properly.
That said, it should not be turned into the explanation for the bug. Projects with impeccably free licences have carried holes for years. The honest lesson is more modest and more useful: “the code is public” describes a permission, not an activity. That anyone could look does not mean anyone did, still less that they looked at the right line with the right question.
Coinkite has admitted it with a candour worth acknowledging: their reviews confirmed that the correct hardware generator implementation was present in the firmware, but they did not follow, end to end, which implementation actually ran when the user pressed “create new wallet”.
Why none of its defences could have stopped it
Of the whole episode, this is the part anyone can apply to their own work, whether they own bitcoin or not. Coldcard’s defences were real and did their job well. The thing is that none of them defended against this, and there was no way they could have.
The reproducible build is the clearest example. It serves to prove that the cake you are sold matches the published recipe exactly. It is a valuable guarantee against a manufacturer slipping something in. It says absolutely nothing about whether the recipe was any good.
And from there comes the sentence that sums up the whole episode: security properties do not substitute for one another. It is not a cumulative score where five correct labels add up to “invulnerable”. Air-gapped plus secure chip plus verifiable code plus Bitcoin-only does not equal safe, because each one covers a different threat and none of them covered the one at the very top: that the secret was born predictable.
The dice: the one defence that held completely
We have seen everything that did not protect. Time to look at what did, because some people came out of this untouched, and not by luck.
Coldcard allowed something almost no manufacturer offers: rolling a physical die and feeding those rolls into seed generation. The firmware mixed them with whatever the device produced. Each roll of a six-sided die contributes about 2.58 bits of unpredictability, so fifty rolls alone already exceed 128 bits, without depending on the generator at all.
Coinkite reckons that between 50 and 98 rolls contribute at least those 128 bits, and that 99 or more approach 256. If you rolled the die at least fifty times, with an honest die, without repeating patterns and without anyone writing the results down, your seed is not at risk from this bug. The randomness the software could not predict came from your own hand.
The scale is linear and here that is faithful, because bits are already a logarithm. There is a catch: it holds if the die is fair, if you actually roll instead of picking numbers, and if nobody writes the sequence down.
It is the perfect defence against this problem for a conceptual reason: it does not trust the device. It adds a source the manufacturer does not control, cannot simulate and cannot break with a badly written macro. It is also the most inconvenient to use, which is exactly why almost nobody used it.
Careful, though, it has its own trap. If you choose the results in your head instead of rolling, if the die is biased, if you photograph the sequence or if you write a roll down wrong, you have created a new problem while trying to avoid another. Manual entropy is an advanced tool, not a ritual that makes a wallet safe by the mere act of performing it.
And now the part of this story I find hardest to digest, because nothing has to be assumed for it to be serious.
In October 2021, a user asked the Coldcard account what a retirement attack was. The answer, which is still up, was this: “it is when the project creators might have a ‘bug’ in entropy generation to recover it later”. They said it while promoting precisely the dice feature as the defence.
Read that again. Coinkite knew this threat model so well that it had given it a public name, explained it to its users and offered them the exact tool to protect themselves from it. And by then the bug had already been sitting inside their own firmware for seven months.
Some have used that tweet to insinuate it was deliberate. I do not go there, and the dates work against that reading: the bug went in in March 2021 and the tweet is from October, so it hardly announces a plan. Besides, a well-placed backdoor would be exclusive to whoever placed it, and this one left 40 bits within reach of anyone with a graphics card. Proof of that is that there are fifteen different attackers helping themselves to it today.
But no conspiracy is needed for this to be devastating, and that is why I am telling it. The failure was not not knowing. It was not verifying. The company had the threat model perfectly identified, with a name of its own and a recommended mitigation, and even so it did not check end to end which generator ended up running in its own seed creation path. They knew exactly what to look for and did not look there.
Coldcard multisig did not protect against this
Multisig is sold, rightly, as the answer to this kind of failure: if you need two keys out of three to spend, one breaking is not enough. But there is small print almost nobody read, and it has to do with something we already saw: that address is a hash.
As long as a multisig has never spent, the world only sees that hash. It does not know how many keys are behind it, nor how many are needed, nor what brand they are. The moment you spend for the first time, the full script is recorded on the chain, and with it the public keys of every participant. Forever, and in plain view of anyone.
With that, an attacker can walk the chain looking for multisig scripts containing public keys derivable from the faulty space. And there is where the argument breaks: if two of your three keys came from affected Coldcards, he has the two he needs. The threshold is met and the funds are his.
The uncomfortable detail is that this setup was common. Coldcard actively promoted multisig, plenty of people bought several from the same manufacturer to build it, and nobody thought twice: three devices are three devices. As the operator analysis at 808bits puts it, “three keys in three devices from the same brand are redundancy against loss, not against a design flaw”.
What did work was manufacturer diversity. A 2-of-3 with a Coldcard, a Trezor and a BitBox loses one key and drops below the threshold: the funds stay safe, even if you still have to migrate. The lesson is not “use multisig”, it is “use multisig with implementations that can fail in different ways”.
Why the passphrase saved some people and not others
The attacker walked away with the first rung, the number, and everything behind it follows by pure arithmetic. Everything except one fork: the step from the words to the seed. That is exactly where the passphrase comes in, because the same words, with a passphrase or without one, give two completely different seeds, and therefore two key trees and two sets of addresses with absolutely nothing to do with each other.
And here comes the part that is almost never told properly. Two claims circulate about the passphrase that seem to contradict each other: that it “only buys time” and that “the attacker cannot even see you”. Both are true, but each describes a different scenario, and between the two there is an enormous gap.
Scenario A: you never used the wallet without a passphrase. The attacker generates candidates, derives their addresses with an empty passphrase and looks them up in the public ledger. Yours are not among them, so there is no match and his sweep passes right over you without detecting you. And no, spending changes nothing: when you spend, your public key is published, but that key is not on his list either, because it was born from a different seed. The same goes for the master public key, the xpub. In this scenario you literally do not appear.
He could, admittedly, widen the search and try passphrases against every candidate. The numbers say it does not pay: even with a bad twenty-bit passphrase, like a common word, he would have to run that test against a trillion-plus candidates. With a thousand graphics cards working at once, about four years. With a thirty-bit passphrase, nearly four thousand years.
Scenario B: at some point you put something in the wallet without a passphrase. Plenty of people do, as a decoy or simply testing the device on day one. And that changes everything, because that address does show up in his sweep. The moment it does, the attacker knows three things: that you exist, which of the candidates you are, and that you very probably have a passphrase hiding the rest.
From that moment he no longer has to test anything against a trillion candidates. Only against yours. And the numbers collapse: a twenty-bit passphrase falls in under a second with a single graphics card. A thirty-bit one, in two minutes. A forty-bit one, in thirty-one hours. You have to reach sixty bits of genuine randomness, which is no longer a phrase anyone remembers, for it to become out of reach again.
Between the two scenarios there is a factor of 1.1 trillion. The same passphrase that makes you invisible in the first is worthless in the second, and the only thing separating one from the other is whether you ever sent a few satoshis to the wallet underneath.
With that, you can see why both statements were true. Against the attack as it actually happened, a mass sweep against wallets with no passphrase, whoever had one was not on the list. Against an attacker who has already located you and decides to spend compute on you specifically, a human passphrase falls. And the price of moving from one scenario to the other was a few test satoshis back in 2022.
That is why Coinkite calls it a mitigation and not a fix, and recommends migrating even if you had one. It is the correct description: you do not know which of the two scenarios you are in until it is too late, and it does not turn a faulty seed into a healthy one.
Why splitting your backup does nothing here
One defence is left that many people take for granted and which in this case contributes absolutely nothing. It deserves a short section because the confusion is very common.
Shamir, or SLIP-39, lets you split the backup of a seed into several shares, so that you need two of three, or three of five, to rebuild it. It protects very well against losing a copy, against a fire in one location and against someone robbing a safe.
But look at the order of operations: first the secret is generated, and then it is split. A 40-bit secret split into three pieces is still a 40-bit secret. Splitting it does not widen the space it came from.
And there is something worse: the attacker does not even need your shares. He is not trying to rebuild your backup, he is generating candidate secrets directly from the start of the chain. Your Shamir shares could be in three safes in three countries and it would make no difference at all.
Shamir, or SLIP-39, protects you very well against losing a copy, against a fire, or against someone robbing a safe. Against this bug it does nothing: the attacker is not trying to rebuild your backup, he generates candidate secrets from the start of the chain.
Shamir distributes custody of the backup. It does not improve the quality of what was backed up. They are two different problems and it is worth not confusing them.
Fifteen attackers, and blood in the water
What began as one theft has turned into a feeding frenzy.
When Coinkite published the advisory, it did the only thing it could: tell people so they would move their funds. But telling people also means explaining to the whole world where the hole is. And the hole is easy to exploit once you know it exists.
Alex Thorn, of Galaxy Research, estimates that there are already at least fifteen different attackers working the same vulnerability. Not one thief: fifteen, in successive waves, competing to sweep whatever is left before the owner notices.
And behind the ones who can code come the ones who can lie. Trezor and Foundation have warned of a phishing wave, and Proofpoint has documented email campaigns posing as a “coordinated hardware audit” that lead to cloned sites installing remote access software. Panic is fertile ground: there are a lot of frightened people looking for urgent instructions, and that is exactly what a scammer needs.
The ones who still do not know they have been robbed
Here is a cruelty that keeps going round in my head.
On-chain data says the stolen coins had sat unmoved for an average of 3.18 years. That is not chance or bad luck: it is the exact profile of somebody who did things right. They bought an expensive, specific device, generated their keys offline, wrote the words on paper, stored the paper and never touched it again. That was the advice. That is the advice.
And that same behaviour is what means that right now, while you read this, there are people who do not know they have nothing left. Somebody who does not check their balance, who does not follow bitcoin news, who does not even remember which firmware they set that up with in 2022. They will find out in months, or years, when they go to use it.
It is the most uncomfortable paradox of cold storage: the better you did it, the less likely you are to find out in time. The discipline of touching nothing, a virtue over ten years, becomes a liability over one week.
That is why the most useful piece of advice I can give in this article is not technical. If you know anyone who bought a Coldcard, write to them. Do not assume they have heard.
The one difference that actually matters
With all of the above on the table, we get to the question a lot of people are asking these days: if self-custody fails too, why bother?
Let us start by admitting what happened, because it is uncomfortable. After the advisory, small bitcoin transfers into exchanges hit their highest level since the FTX collapse in November 2022, about 39,600 BTC in a single day according to CryptoQuant. Which is the exact opposite of what happened back then: in 2022 people were pulling their bitcoin off exchanges, now some are handing it back.
But at the same time, and this is what almost nobody has put in its place, something else happened. Wallets that had been still for years woke up: about 6,400 BTC dormant for five to seven years moved on 31 July, and on 3 August 935 BTC that had not been touched in over a decade moved. People putting their own coins somewhere safe, by themselves, within hours.
Nick Neuman, CEO of Casa, a US multisig custody company, estimates that roughly ten times more bitcoin was protected than was stolen. It is his estimate, not an audited figure, but the direction is visible on the chain.
And there is the comparison that actually matters, which is not “self-custody versus custodian” but “this failure versus the failures of the other model”. It is worth being precise, because the two great disasters usually get lumped together and they are not the same thing. At Mt. Gox there was a theft: somebody got into the exchange’s keys and drained bitcoin for years without anyone noticing, up to some 850,000. At FTX there was no attack at all: the company itself used its customers’ money to plug the losses of another company it owned. That is fraud, not theft, and its founder was convicted for it.
Different in cause, identical in the only thing that counts here: in neither case was there anything to be done. Not one person could react, because the money was not under their control. One day you open the website and it is gone, and it makes no difference whatsoever whether you find out in the first minute or the next day. There was no window.
The “thousands” comes from on-chain movement in the days after the advisory: about 6,400 BTC dormant for five to seven years moved on July 31, and 935 BTC untouched for over a decade moved on August 3.
That is what you buy with self-custody, and it is worth understanding properly because it is not what people think. You are not buying the absence of bugs: we have just seen an enormous one. You are buying the chance to react yourself, without asking anyone for permission or waiting for a company to open its counter. Thousands of people used that window last week. At Mt. Gox nobody had one.
Which is of absolutely no use to anyone who lost their coins, and that has to be said plainly. But anyone deciding these days whether to send their bitcoin back to an exchange should look at both columns in full, not just the one that is in the news.
If you own a Coldcard
Restoring that same seed onto a Trezor or a BitBox does not fix it either, for the same reason. And never type your phrase into any site offering to “check if you are affected”: that is the second theft that always follows the first.
The procedure is: update the firmware first, generate a completely new seed, write down and verify the backup before putting anything in it, check a receiving address on the device screen, send a small amount, confirm it, and only then move the rest. Keep the old backup until everything is confirmed.
And what not to do: update the firmware and carry on using the same seed, because the problem travels with the secret and updating does not transform it. Restoring it onto a Trezor or a BitBox does not fix it either, for the same reason. And needless to say, do not type your phrase into any site offering to “check if you are affected”: that is exactly the second theft that always follows the first.
The problem with no good answer
There are two questions everyone who spends a while with this ends up asking, and neither has a comfortable answer.
The first: even if the money were recovered, it could not be returned. Imagine the thief is caught and a court orders the funds restored to their originating addresses. It would be useless. Those seeds are still weak, and always will be: the flaw travels with the secret, and the secret is public in practice. Returning bitcoin to a compromised address is leaving it on the pavement. It would last minutes, and this time there would be fifteen people watching. The only possible restitution runs through each victim generating new keys and receiving the money there, which is perfectly possible but requires identifying the victim, something the chain cannot do.
The second: what if Coinkite had found it years earlier? The obvious answer seems to be “everything would have been avoided”, and it is not, because warning people has an immediate cost: publishing the advisory is publishing the map. The moment you say “the seeds on these models have low entropy”, anyone with a graphics card and a free weekend can do what the attacker did. The company enters a race against its own users, many of whom, as we have just seen, take years to find out anything.
But that only looks at half the problem, and the other half weighs more. Every month that passed, more devices were sold that generated doomed seeds, and every month more balance piled up in the ones that already existed. Finding it in 2022 would have meant an uncomfortable advisory and a difficult migration, yes, but also tens of thousands of wallets that never came to exist. The cost of waiting was not linear: it was all the value that kept being deposited into doomed wallets from the day they were created.
So let us go through the alternatives, because they are not good either. Warning customers privately does not work: there is no complete list, plenty of people buy through third parties or second-hand, and a warning like that leaks within hours.
And here something happened that turns that dilemma into an uncomfortable case study. Coinkite did write to its customers, one by one, at email addresses going back to 2019. Many users reacted with anger, and not at the warning but at what it revealed: that the company had kept their emails for years, when its founder had publicly said they offered anonymous purchase and deleted customer data after ninety days. The company replied that it kept the address so you could log in and check that the rest of your data really was deleted, and admitted it had no deletion schedule for those.
What makes that episode fascinating is that both things are true at once. Keeping those emails contradicted what they had promised, and it is the only reason anyone could be warned at all. If they had followed their own privacy policy to the letter, the warning would have arrived only through the press, and to far fewer people. I do not know a clean way to resolve that, and I distrust anyone who says they do.
One last option is left that at first glance looks like the cleverest: publish the fixed firmware without saying why. It protects whoever updates and hands out no map. It is worth dismantling, not because it is difficult, but because there are companies that choose it.
It falls apart in two places at once. The first is that it fixes nothing for anyone already affected: a weak seed stays weak no matter how much new firmware you put on top of it, and that is the whole problem. The second is that the code is public. Anyone can diff two versions and see what changed, and a patch touching precisely the random generator path is a flare to anyone who knows how to look: there was something big here.
And there it ends up worse than telling people. Because at the same time as somebody reconstructs the bug from the patch, it is on record that the company knew and chose to keep quiet. You end up with the same victims, less time to react and considerably greater legal and moral liability.
My conclusion, and it is an opinion, is that there was no good way out and one clearly less bad: publish as early as possible, with the firmware ready, clear migration instructions and as much press coverage as you can get. That is roughly what ended up happening. Only five years late and with the thief already inside.
This is the author’s conclusion, not an industry consensus: publish as early as possible, with the firmware ready and clear instructions. It is roughly what ended up happening, five years late.
And there is one edge that makes it uglier. Bitcoin developer James O’Beirne has stated that in May of last year he warned Coinkite that the random generator implementation in that library looked questionable to him, and that they replied that if there were a real problem it would probably have been found already. This has to be said carefully: it is his account, Coinkite has not responded publicly, and warning that something “looks questionable” is not the same as reporting this specific bug. But if it is confirmed, the question stops being hypothetical.
Is this the end of Coldcard?
Coinkite does not sell plastic boxes. It sells trust, which is the only thing that justifies paying for a single-purpose device instead of writing down twelve words generated anywhere. And trust is what has broken.
The irony is that today is probably the safest moment in the product’s history. There are more eyes on that code than in the previous five years combined: independent researchers, competitors, people with personal motives and AI models combing through every old version. If another hole of this magnitude were left, it is hard to imagine it lasting weeks without surfacing. The fixed firmware, on top of that, does not just patch the line: it makes the build fail if the correct generator is not linked, which is the kind of fix that stops the entire category of error from coming back.
But technical safety and commercial survival are different things. A wallet maker lives off a reputation that takes years to build, and this one has broken with a bug that was also five years old and came with a disputed prior warning.
There is also a decision that will shape much of what comes next: Coinkite has not offered compensation. It is helping victims file police reports and insurance claims, and says its legal team will coordinate with authorities in several jurisdictions to identify those responsible. But it has not put money on the table. It is a defensible position, because nobody makes wallets on margins that could absorb $116 million, and at the same time it is what will stop a lot of people from ever buying from them again.
And here is what actually worries me, which is not the company: if Coinkite disappears, who maintains the devices already out there? A hardware wallet is not a toaster. It needs firmware, it needs somebody to answer when the next vulnerability lands, it needs compatibility with Bitcoin’s changes. A manufacturer that shuts down leaves its users with a device that works until it does not, and nobody to ask. We have seen that in other sectors and it always ends the same way.
Which, if you think about it, is another turn of the screw on the same argument as the whole article. You bought the device so you would not depend on anyone, and it turns out you depend on the company continuing to exist. It is one more argument for diversity: not only because two manufacturers make different mistakes, but because two manufacturers do not usually go bust on the same day.
What this teaches outside Bitcoin
I do not work in bitcoin, I work in networking and security. And this incident is, with the coins taken out of it, a textbook case that could have happened in any system any of us administers.
There was no function called generate_insecure_seed(). There was a macro with a value of zero, a check that asked about existence instead of value, two functions with the same signature and a linker that did its job without complaining. Each piece, looked at on its own, was correct. The bug lived between the pieces, which is exactly where nobody looks.
Three things I take from it into my own work:
- Verifying that a defence exists is not verifying that it is used. The question is not “is the hardware generator in the binary?” but “what runs when the user presses the button?”. They are different questions and only the second one matters. It happened to me rebuilding this blog: three minutes of blank page with the status code saying everything was fine.
- A warning that can fail is not a warning. The fix Coinkite published was not repairing a line: it was making the build fail if the correct implementation is not linked. Turning a whole class of error into something that breaks the build is infinitely better than trusting somebody to spot it while reading.
- Check observable properties, do not inspect components. Trezor implements a protocol in which the device commits to its entropy, the software on the computer contributes its own, and afterwards the wallet is reconstructed to verify that the device really used both. It is not infallible, but it is a different category: it does not trust the firmware to do the right thing, it tries to prove it from outside.
There is one last detail that has stuck with me. Coinkite says it assumes the attacker used AI to comb through old firmware versions, and admits that they themselves had run one of the best available models looking for vulnerabilities and it did not find this bug. Its founder put it by saying that AI-assisted code review already finds latent bugs faster than the most seasoned experts in the field.
It is worth adding that several security specialists have pushed back on that framing, and I think rightly: the compile-time option that disabled the hardware generator is a human engineering failure that a conventional review should have caught years earlier. Attributing it to AI having got very good shifts the focus away from a more uncomfortable question, which is why nobody followed that path by hand in five years.
That said, both sides have the tool. The conclusion cannot be “let us put another AI on review duty”, because the attacker has it too and only needs to be right once. The conclusion is to design systems where the failure of a single piece is not enough: entropy from more than one source, signers from more than one manufacturer, checks that break the build instead of waiting for an attentive reviewer. On what it actually costs to secure code an AI wrote, with figures and sources, I wrote separately.
Bitcoin did not fail. The cryptography did not fail. What failed was a human layer around it, at the point where two libraries met, and it sat there for five years waiting for somebody to bother following the thread to the end.
Data current as of 5 August 2026. The technical investigation and the transaction analysis are still ongoing: the figures for stolen funds are estimates drawn from the public ledger, not a confirmed victim count, and both Coinkite and Block have described their entropy estimates as preliminary.
Sources
Primary sources
- Coinkite, security advisory and migration procedure: blog.coinkite.com
- Coinkite, technical backgrounder on the entropy failure: blog.coinkite.com
- Block Engineering, independent analysis of the generator and the reseed: engineering.block.xyz
- ST application note AN4230 on the STM32 hardware generator: st.com
- The 2021 Coldcard tweet explaining what a retirement attack is: x.com
- Jonathan Goodman’s first-hand account of his loss: x.com
Figures and on-chain analysis
- Galaxy Research expands the count to 1,082.65 BTC: kucoin.com
- The first public count, of about 594 BTC: coindesk.com
- The $116 million count and the “I did everything right”: forbes.com
- Hour-by-hour timeline of the incident: bitcoinwell.com
- Fifteen different attackers and the phishing wave: decrypt.co
- The joint manufacturer warning about the phishing campaign: forklog.com
- Bitcoin inflows to exchanges: cryptoquant.com
The weak-entropy precedents
- LuBian: 127,426 BTC stolen in 2020 with 32-bit keys, uncovered in 2025: coindesk.com
- Milk Sad (CVE-2023-39910): the same bug in Libbitcoin Explorer: milksad.info
- The public puzzle that measures how far real brute force reaches: privatekeys.pw
Context and consequences
- The BIP-39 standard, which turns the number into words: github.com
- The BIP-32 standard, which turns the seed into a tree of keys: github.com
- Operator analysis of why single-brand multisig did not protect: 808bits.com
- James O’Beirne says he warned them in May of last year: bitcoinworld.co.in
- The row over the emails Coinkite had kept since 2019: news.bitcoin.com
- The FTX fraud, in the CFTC statement: cftc.gov