Withdrawal System Model

When the Bank Is Closed and Everyone Wants Out

There is a specific kind of weekend dread that treasury people at crypto exchanges know well.

It is Saturday morning. Markets opened the night before to bad news — a large exchange posted something vague about “temporary withdrawal delays.” The phrase spread on CT within the hour. By midnight, the withdrawal queue was five times normal volume. By 3am, it was ten times.

You are staring at a dashboard showing fiat withdrawal requests accumulating faster than your gateway can process them. Your CEO is on the phone. The CFO wants a number — specifically, how many hours until the fiat reserve runs dry.

The problem: your bank is closed. It is Saturday. It will not open until Monday morning. You cannot top up. Whatever fiat you had in the payment gateway when this started is all you have.

How much was enough? Did you know? Did anyone?


I spent a significant amount of time thinking about this problem — not because I was ever in that exact situation, but because I kept noticing that the tools the industry uses to answer this question are not actually designed to answer it.

Proof of Reserve attestations have become the standard response to “is this exchange safe?” After FTX, every major exchange published one. Binance, OKX, Bybit — Merkle tree attestations showing that crypto assets held equal or exceed crypto liabilities. Users can verify their own balance is included. Auditors can confirm the totals.

That is genuinely useful. But it answers a different question than the one the Saturday morning scenario is asking.

A PoR attestation tells you the crypto side of the ledger is intact at a point in time. It says nothing about the fiat side. It does not tell you whether the exchange can process USD or IDR withdrawals over a weekend when bank rails are offline. It does not model what happens when withdrawal velocity doubles. It does not tell you whether the exchange’s “reserves” include assets that would collapse in value under the exact scenario being used to justify them — which is what FTT was in FTX’s reserve portfolio.

The attestation is a photograph. What the Saturday morning scenario requires is a simulation.


The second thing I kept noticing was a category error in how withdrawal risk gets modeled.

The standard approach is to look at average daily withdrawal volume and hold some multiple of that as a buffer. Maybe 3 days of average withdrawals. Maybe 5. The multiple is usually a judgment call dressed up as policy.

The problem is that withdrawal behavior is not average. It is two completely different processes happening simultaneously, and treating them as one produces a reserve that is right on average and catastrophically wrong in the tail.

Retail users withdraw continuously. On any given hour, thousands of small decisions are being made — someone needs money for rent, someone got nervous and wants their funds back, someone just saw a scary tweet. No single user matters. The aggregate flow is smooth, predictable within a range, and behaves like what it is: the sum of many independent small events. For modeling purposes, this is a Gamma distribution problem. The flow has a mean, a variance, and a shape you can estimate from historical data.

Institutional users are different in kind, not just in size. A hedge fund does not gradually trickle out of an exchange. It decides — on a specific day, in response to a specific trigger — to move $50 million in a single transaction. Then nothing for three weeks. Then, if confidence breaks, another $200 million. And then, if the exchange looks shaky, every institutional account on the platform reaches the same conclusion at approximately the same time, because they are all watching the same signals.

That is not a flow. That is a jump process. The relevant question is not “how much per hour?” but “how many events arrive in this window, and how large is each one?”

When you model retail and institutional behavior as the same process — just different sizes — you build a reserve sized for the average. The average does not save you on Saturday morning. What saves you is sizing for the tail, and the tail is almost entirely institutional.


There is also the derivatives problem, which the industry discusses less openly.

A spot-only exchange is supposed to be simple: user deposits fiat, exchange holds fiat, user withdraws fiat, 1:1 backed at all times. PoR works reasonably well for this case.

The moment an exchange introduces perpetual futures or CFD equity — and most do, because derivatives volume is where the fees are — the 1:1 rule starts to have footnotes.

When a trader’s leveraged position moves against them faster than their margin can cover it, the exchange absorbs the shortfall. This is called the insurance fund. The exchange maintains a pool of capital to cover these socialized losses, and in normal markets it works fine — liquidations are orderly, the fund is replenished by liquidation fees, nobody notices.

In abnormal markets, the cascade begins. A price shock triggers liquidations. Liquidated positions are sold into the market, amplifying the price move. The amplified move triggers more liquidations. The insurance fund, sized for normal conditions, drains quickly. When it hits zero, losses get clawed back from profitable traders — or, in the worst case, the exchange absorbs losses that exceed its own capital.

None of this shows up in a PoR attestation. The attestation snapshots assets against liabilities at a moment in time. It does not model what happens to the insurance fund if BTC drops 40% in 48 hours, or how many margin calls that triggers, or how the cascade interacts with the withdrawal run happening simultaneously.

The Saturday morning scenario, for a derivatives exchange, is not one problem. It is two problems running in parallel, both claiming the same pool of capital.


The model I built is an attempt to make this concrete.

It starts with the question every FinOps team should be able to answer before Friday evening: given what we know about our user base, our open interest, and the range of scenarios that could unfold over the next 64 hours, what is the minimum fiat reserve we need to hold right now?

The 64 hours is specific. Friday 5pm to Monday 9am is when bank rails go dark in most jurisdictions. It is also — and this is not a coincidence — when crypto market stress events disproportionately occur. The correlation is real: bad news in crypto tends to land on weekends because that is when low-liquidity conditions amplify price moves, and because institutional actors who want to exit quietly prefer to do so when bank processing makes it harder to follow the money.

The model runs the withdrawal simulation twice — once for the retail component as a continuous flow, once for the institutional component as a jump process with a Poisson arrival rate that rises sharply under stress. In normal conditions, maybe half an institutional event per day. In a severe scenario, six per day. That 12× increase in arrival rate, not the size of individual withdrawals, is what drives the tail. A reserve sized against expected withdrawals will survive normal conditions and fail exactly when it needs to hold.

On top of the withdrawal model sits a three-layer VaR framework — historical simulation as the empirical floor, EWMA-filtered simulation to adjust for current volatility, and stress scenarios calibrated to LUNA and FTX as the forward-looking ceiling. The reason for three layers is that historical VaR has a specific failure mode: it can only see risks that already happened. Every major crypto crisis was out-of-sample for historical VaR at the time it occurred. The stress scenarios exist precisely for the cases where history is not a reliable guide.

For derivatives exchanges, the insurance fund module adds the cascade simulation — five iterations of liquidation triggering further price pressure, sized against the exchange’s open interest and leverage distribution.

The output is not a percentage. It is a dollar amount, an annual cost, and a probability. The reserve I recommend holding. What holding it costs in foregone yield. The probability of running out anyway under each scenario.

That is the number the CFO needs on Saturday morning. The model’s job is to make sure it was calculated on Thursday.


A few things I did not build, and why they matter.

The Poisson arrival model assumes each institutional withdrawal decision is independent of the others. In reality, it is not. When one large fund exits, others observe it and accelerate their own decisions. The technical term is a self-exciting process — each event increases the probability of the next. This is almost certainly what happened in the FTX withdrawal run, where early institutional exits triggered retail panic which triggered more institutional exits in a feedback loop.

Modeling this correctly requires a Hawkes process rather than a plain Poisson, and the parameterization is not straightforward without real data. I named it as a known limitation rather than approximate it badly.

Multi-currency fiat is also out of scope for this version. USD on hand does not help if users want EUR and the EUR account is thin. A proper treasury system needs separate reserve optimization per currency, with FX conversion risk explicitly modeled. That is a meaningful extension that would require a different data architecture.

The limitations section of any model is where intellectual honesty lives. A model that knows what it cannot do is more useful than one that does not.


The industry’s standard answer to exchange safety is a snapshot. What exchange safety actually requires is a simulation.

The difference matters most at the moment it matters most — which is the moment the snapshot is least useful, because prices are moving, users are withdrawing, and the bank is closed.


The full model, assumptions documentation, and interactive dashboard are available at GitHub →. Technical architecture and methodology are on the project page.