The Citigroup $444bn fat finger trade of May 2022 resulted in a £61.6m FCA and PRA fine, exposing a single structural flaw: the firm's alerting system fired 711 warnings that the submitting trader could dismiss without any second-party sign-off.
On 2 May 2022 a Citigroup trader in London set out to sell a basket of equities worth about $58m. A unit error meant the basket was built at roughly $444bn instead. The firm's controls blocked around $255bn of it, but about $189bn reached the trading algorithm, and roughly $1.4bn of shares were sold across European venues before the order was stopped, briefly knocking the OMX Stockholm 30 index down around 8 percent (CNN, Bloomberg).
The detail that matters for anyone designing controls is what happened in between. A pop-up warning fired. The trader dismissed it, along with 710 others in the same session, for a total of 711 dismissed alerts (Markets Media). The system had something to say about a $444bn basket. It said it in a form the operator could click past.
In May 2024 the Financial Conduct Authority and the Prudential Regulation Authority fined Citigroup Global Markets £61.6m over the episode and the weaknesses in its trading controls (Bloomberg).
What actually failed: the governance gap
The order error was human. The control failure was structural. A basket two orders of magnitude larger than intended did not run unseen. It ran past a warning that the person submitting the trade was allowed to override.
There are two distinct gaps here. The first is the absence of a hard ceiling. A single trader's session was able to push $189bn toward live execution. Nothing in the path refused a notional that size on principle. The second is the nature of the alerts that did fire. They were advisory pop-ups, cleared by the same person who built the order, with no separate sign-off and no record that anyone else looked. An alert that the actor can clear without a second party is a prompt, not a gate.
Both gaps share a root cause. The system trusted the operator to be the final authority on actions that could move a national index. When the volume of warnings is high enough, dismissal becomes a reflex. The 711 figure is not a story about one careless click. It is what a stream of overridable warnings produces over a working session.
How MakerChecker changes the outcome
MakerChecker is built for AI agents taking consequential actions, and the same control shape applies to any automated submitter. The principle is that a high-consequence action does not depend on the actor choosing to stop.
Model order submission as a role-scoped skill, trade.submit, granted
deny-by-default. The trading role carries an explicit notional cap. A
submission of $444bn, or $189bn, is over the role cap and is refused outright
before it reaches an algorithm. This is the hard block that was missing. There
is no dialog to dismiss because the action never enters an executable state.
Below the cap, route by threshold. Orders under a routine size run on the
granted trade.submit path. Orders above a defined notional are forced through
a non-bypassable approval gate that requires n-of-m named human sign-off before
execution. The gate is a first-class step in the workflow, not a pop-up layered
on top of it. The submitter cannot clear it, and segregation of duties
(forbid_requester) means the person or agent that built the order is excluded
from approving it. A second named party has to sign, on the record, before
anything runs.
The code scenario for this entry is exactly that split: trade.submit at
$444bn is hard-denied against the role cap, and any order over the threshold is
held at a non-bypassable approval gate. Every decision, the denial, the gate
request, and each signature, is written to a tamper-evident Ed25519-signed
hash-chained audit that can be verified offline. When a regulator asks who
approved a large order and when, the answer is a signed record rather than a
recollection of a dismissed dialog.
What MakerChecker would not fix
MakerChecker would not have stopped the wrong number being typed. The unit error that turned $58m into $444bn is a data-entry mistake, and MakerChecker does not validate the economics of a trade or check that a basket matches the trader's intent. It does not judge whether $58m was itself the right size.
What it changes is narrower and more dependable. It converts an overridable warning into a step that cannot be dismissed, and it converts an implicit trust in the operator into an explicit, capped, and signed authorisation. The bad input still arrives. It just stops at a door the submitter cannot open alone. For irreversible actions, that is the difference between a control and a courtesy.
See the configuration: examples/rogue-ai/citigroup-444b-fat-finger-overridable-warning