30 min

The mark price: a number an attacker cannot shove

A liquidation trigger needs a price nobody can move on purpose, so venues liquidate on a smoothed mark blended from an index and local trading rather than on the last print.

Where you are. Module 5 built margin and liquidation and left one thing unexamined: the price the engine reads. On a traditional exchange that question is dull. Here it is an attack surface.

A trader is long, leveraged, and comfortably above their maintenance level. An attacker with enough capital sells hard into a thin local market for one moment, prints a price far below the market, and buys straight back.

If the liquidation engine was reading that print, the position is gone. The attacker bought the liquidated inventory cheaply and the price returned to where it was within seconds. Nothing was hacked; the engine did exactly what it was told, on a number somebody paid to create.

The idea in one paragraph

Any price that a single trade can move is a price somebody will move on purpose when enough money depends on it. So a venue does not liquidate on its last traded price. It liquidates on a mark: a blend of an external index, drawn from several venues, with a smoothed average of local trading, weighted so that local prints inform the number without being able to dictate it. The effect is that shoving the local price costs an attacker the full size of the trade and moves the mark by a fraction of it, which is exactly the asymmetry that makes the attack not worth doing.

image/svg+xml Matplotlib v3.11.1, https://matplotlib.org/ 0 10 20 30 40 50 60 round 60 70 80 90 100 price liquidate below here one shoved print the mark barely moves
The index, the local price and the mark through a one-tick manipulation spike, against the level that triggers liquidation

What the spike does

The exercise runs sixty rounds where the index and the local price mostly agree, then shoves the local price to sixty for exactly one round.

An engine reading the local price fires a liquidation on that round: the print is far below the maintenance level and the rule is the rule. An engine reading the mark does not, because at that round the mark is 97.45. The spike is one of five rounds in the smoothing window and carries a fifth of the weight, so a forty percent shove moves the mark by about two and a half percent.

Away from the spike the mark tracks the market closely, which is the other half of the requirement. A number that ignores manipulation by ignoring the market would be useless.

the engine readsvalue at round 30liquidations fired
the local price60.001, and it was false
the mark price97.450

n = 60 trials · one shoved print at round 30, maintenance level 80.00

Why this is the module’s quiet centrepiece

Module 5’s machinery all assumed a price. Every threshold, every ratio, every trigger read one, and the question of where it came from never arose because a traditional venue’s price is the aggregate of a deep market that is expensive to move.

On a shared ledger with a thin local market and a public rulebook, that assumption fails, and everything downstream of the price inherits the failure. The mark price is the repair, and its existence is a reminder worth carrying: when a rule is enforced automatically, the inputs to the rule become the thing worth attacking. Publishing the rule is what makes the input valuable.

Check yourself

1. Why can a venue not liquidate on its last traded price?

Because a single trade can set it, so anybody with enough capital can print a price far from the market for one moment and trigger liquidations against it. The rule is public and automatic, which makes its input worth paying to manipulate.

2. A forty percent shove moves the mark by about two and a half percent. Why?

Because the spike is one round inside a five-round smoothing average, and that average carries only a fraction of the blend against the external index. The attacker pays the full cost of the trade and gets a fraction of the effect, which is the asymmetry the design is buying.

3. What does the smoothing cost?

Speed in a real crash. The mark lags a genuine collapse, so positions are closed later and at worse prices than they should have been, and the shortfall falls on the pool the next lesson builds. Resistance to manipulation and responsiveness to real moves are the same dial turned in opposite directions.

4. What general lesson does the mark price carry?

That automating a rule makes the rule’s inputs worth attacking. A published, mechanical trigger is exactly as trustworthy as the number it reads, so the number needs to be chosen for how expensive it is to move rather than for how current it is.

Do this

Build the mark and shove the market.

python3 code/mark_price.py

The starter generates the index and local series with a single manipulated print, and leaves you mark_price: average the recent local prices, then blend that average with the index at the given weight. The assertions check that the raw local price fires exactly one liquidation, that the mark fires none, and that away from the spike the mark still tracks the index closely.

The completed version is in solutions/mark_price.py.

What you can now do. You can build a manipulation-resistant mark, show it ignoring a spike that would otherwise fire a liquidation, and name what the resistance costs. The next lesson builds the engine that acts on it.

What you can now do

You can build a mark price and show it ignores a manipulation spike that would otherwise fire a liquidation.