Technical Deep Dive

Why 3Commas Lost $22M
and TVSBot's Design Wouldn't

2026-06-03·8 min read·Architecture / Security

In December 2022, the largest brand in crypto automated trading — 3Commas — suffered the worst API key leak in the industry's history. One million exchange keys were sitting in their database, 100,000 leaked, and on-chain analyst ZachXBT verified 44 victims with $14.8M in losses, with the total damage estimated at $22M.

This isn't a "they got hacked" story. It's a "the custodial model has a single point of failure" story. This post unpacks the incident, explains why this design was always going to break, and shows how TVSBot avoids it.

Act 1: The Timeline

October-November 2022: Users started reporting "I didn't place any orders, but my account is auto-trading FTT on FTX." 3Commas's initial response was "users got phished themselves."

December 28, 2022: An attacker publicly posted a batch of API keys on Twitter with download links. Cross-verified by ZachXBT and independent researchers, the corresponding accounts had indeed seen unauthorized trades.

December 29: 3Commas CEO Yuriy Sorokin acknowledged the incident and asked Binance, OKX, KuCoin, and other exchanges to cooperate by "revoking all API keys held by 3Commas." That request itself revealed a key truth — 3Commas could not directly remediate user losses, because the keys belong to other platforms. All they could do was ask someone else to revoke them.

Act 2: The Technical Root Cause

The standard architecture for a hosted bot platform looks like this:

User → bot platform
        ├── Encrypted API key + secret stored (database)
        ├── Decrypts to call exchange API and place orders
        └── Reports results back to user

It looks reasonable — the keys are encrypted, after all. But this design has a shared single point of failure: the database plus the decryption key form one trust boundary shared by a million users.

The moment the database is dumped (via SQLi, a cloud misconfiguration, or an insider leak), if the decryption key is also exposed (most platforms store the key in the same cloud environment as the DB), every user's key is compromised at once.

That's exactly what happened to 3Commas: per the incident report, key management lived in the same cloud service as the database. One breach took everything down.

It gets worse: hosted keys often have Trade + Withdraw permissions

Many bot platforms encourage users to enable Withdraw permissions too, "so you can run more strategy types" (auto-rebalancing, cross-coin arbitrage, etc). Some 3Commas victims were in exactly this state — attackers simply withdrew straight from the exchange to their own wallets.

Act 3: Why TVSBot's Architecture Is Different

We designed around this failure mode from day one. Three things specifically:

1. Keys with Withdraw permission are rejected at binding (the most important one)

When you add an API key, the system asks the exchange which permissions the key has. On Binance, OKX and Bitget, a key with Withdraw enabled, or one whose permissions we can't confirm, is rejected and never saved. Bybit, BingX and Gate.io can't be checked automatically yet, so please verify yourself that Withdraw is off. For keys added earlier, pressing "Check" re-checks the withdraw permission and shows a warning if it is on.

What this means: as long as the key has no Withdraw permission, even a stolen key cannot be used to withdraw. The worst case is a wash trade burning some fees — the funds stay locked inside the exchange account.

2. Encryption key physically separated from the DB

The database lives on Supabase (one cloud provider). The FERNET_MASTER_KEY lives in Fly secrets (a different cloud provider). An attacker would have to compromise two independent cloud environments simultaneously to decrypt any key — orders of magnitude harder than breaking one.

The key never enters git, never enters DB backups, never gets written to any log. Even our own admins querying the DB directly only see base64-encrypted strings.

3. IP allowlists: we have no fixed IP today, so please don't enable one

Every major exchange API supports IP allowlisting, and in theory that's a great extra layer. Honestly though: TVSBot's backend runs on Fly.io's shared egress and has no fixed outbound IP, so there is no address we can give you to put in an allowlist — adding one would just get your orders rejected. Until we buy a dedicated egress IP, please leave allowlists off and reduce risk with “Trade permission only, no withdrawals, key on a sub-account” instead. Once we have a fixed IP we'll show it right on the API Keys page.

4. Dual signal verification

Each user's webhook URL carries an independent token, with a separate secret embedded in the payload for dual verification. Leaking one doesn't bypass the other — an attacker would need to steal both the URL token and the secret to forge a signal.

Act 4: "But you're custodial too" — clearing up the confusion

Some people ask: "Doesn't TVSBot also custody API keys? Same design as 3Commas?"

Technically, yes, the keys live in our database. But the substantive differences are enormous:

DimensionTVSBot3Commas (at the time)
Withdrawal riskLow (keys with Withdraw are rejected at binding; verify Bybit / BingX / Gate.io yourself)Yes, some users had Withdraw enabled
Encryption key locationSeparate cloud providerSame cloud environment
Encryption algorithm public✓ Fernet AES-128-CBCImplementation details not public
Bug bounty✓ (see /security)None at the time
Disclosure timeline commitmentWithin 72 hoursAcknowledged 2 months after incident

Act 5: What You Can Do

Whether you use TVSBot or any other bot platform, these three are on you — no one can do them for you:

  1. Do not enable Withdraw permissions — this is the single most important rule, more important than any technical design
  2. Do not enable an IP allowlist — TVSBot has no fixed outbound IP today, so adding one just gets your orders rejected; use “Trade permission only, no withdrawals, key on a sub-account” instead
  3. Rotate keys regularly — at least every 3 months, shorter is better

Closing: Trust Isn't Free

After the 3Commas incident, the crypto bot industry collectively recognized that the "custodial model" is the core problem. Some platforms pivoted to pure non-custodial (browser extensions, local agents); others doubled down on encryption design (HSMs, multi-sig).

Our choice is "pragmatic non-custodial": custodial on the technical surface, but structurally guaranteeing fund safety (withdraw-enabled keys rejected at binding + physically separated encryption keys + multi-layer verification).

We think this trade-off strikes the best balance between user experience (no need to install an extension) and security guarantees. But everyone's risk tolerance is different — if you want fully non-custodial, we get it.

For any security suggestions or vulnerability reports, please email security@tvsbot.com. Bug bounty details on the /security page.