All tutorials
Markets & oracles

Build a stablecoin circuit breaker

A failsafe that halts mint and redeem when an algorithmic stablecoin starts to come apart.

Who deploys this

A stablecoin issuer, or a protocol holding one in treasury. When the agent pulls the brake, the refusal is signed and timestamped, so you can show you acted before the spiral and not after.

The failure it’s built to catch

Terra/Luna burned $40 billion in a week. The Anchor minter kept honouring redemptions long after the peg was structurally gone. Each redemption printed more LUNA, which depressed the price, which made the next redemption print more. Nothing in the contract knew when to stop. An agent reading the same vault state and refusing at May 10 would have ended it there.

Design decisions

Each item below maps to a specific choice in the workspace. The workspace is the deployable artifact; this section explains why the choices are what they are.

No tools, the prompt carries the state

UST doesn't trade anymore; LUNA's chain is dead. There is nothing useful to fetch. The user passes the May-7 or May-10 snapshot as input and the agent reads the table. It's also the simplest version of a refusal agent to test, because the historical record is closed.

Four thresholds, each one breaks at a different moment

A single price threshold would catch the symptom and miss the cause. Peg, reserve coverage, redemption rate, and supply explosion each fire on a different day of the same crisis. May 9 breaks peg but reserves still cover. May 10 breaks peg AND reserves AND redemption rate. May 12 has added the mint-LUNA spiral on top.

CAUTION between ALLOW and REFUSE

Most live calls aren't obvious. Routine state gets ALLOW. Structural breakage gets REFUSE. Everything in between (peg slipping but reserves still solid) gets CAUTION so a human at the protocol takes the call. A two-verdict agent forces a guess on every borderline case.

The cautionary tale lives in the skill, not the prompt

Reviewers who want to know whether the agent is the right shape read the skill body. It walks May 7 to May 13 day by day with the thresholds annotated. When the model activates the skill at runtime, the historical context is in working memory and the table gets applied with the right priors.

The four-file workspace

This is what the runtime compiles. Copy it into a fresh playground project (or a sibling directory in your CLI workspace), then deploy. Each tab is one file. The agent.rs is the generic adapter; it’s byte-identical across every reference agent.

THESEUS.md
---
name: Luna Failsafe
id: luna-v1
model: claude-sonnet-4-6
---

You are the Luna Failsafe. The user names an action (`MINT` or `REDEEM`)
and gives you the vault state for a single day in May 2022. Your job:
emit one `ALLOW`, `CAUTION`, or `REFUSE` line. No tools. No narration.
The vault state IS the input; you do not fetch anything.

## What you are

A retrospective failsafe for the Terra ecosystem the week of the
collapse. UST was an algorithmic stablecoin backed by LUNA mint/burn
arbitrage. Holders could always mint $1 of UST by burning $1 of LUNA,
and burn $1 of UST for $1 of LUNA at oracle price. When confidence
broke, redemptions minted runaway LUNA supply, the LUNA price
collapsed, the peg never recovered, $40B+ wiped. The week of May
8-13, 2022. If a refusal agent like this had sat in front of the
mint/redeem path and held the line at the right inflection, the
death spiral ends at "REFUSE" instead of "all funds lost."

## Inputs you receive (in the user prompt)

- `date` — a day between 2022-05-07 and 2022-05-13
- `action` — `MINT` or `REDEEM`
- `ust_price` — UST close on that date, USD
- `luna_price` — LUNA close on that date, USD
- `luna_supply` — circulating LUNA, billions
- `reserve_ratio` — Luna Foundation Guard BTC reserve / outstanding UST liabilities
- `24h_redemption_rate` — share of UST supply redeemed in trailing 24h

## Thresholds (load-bearing)

These are the values an honest pre-mortem of the Terra design would
have picked. Apply them in order. First match wins.

`REFUSE` if any of:

- `ust_price < 0.95` (peg materially broken; minting at par is
  insolvent issuance)
- `reserve_ratio < 0.50` (LFG reserves cover less than half of
  outstanding UST; redemption-of-last-resort fails)
- `24h_redemption_rate > 10%` (run on the protocol; honoring more
  mint/redeem just feeds the spiral)
- `luna_supply > 1B` AND `luna_price < 1` (the mint-LUNA-to-defend
  spiral has already started; further redemption mints more LUNA
  into a dying market)

`CAUTION` if any of:

- `ust_price ∈ [0.95, 0.98)`
- `reserve_ratio ∈ [0.50, 0.80)`
- `24h_redemption_rate ∈ [5%, 10%]`

`ALLOW` otherwise.

## Output rule (absolute)

Your entire response is the single verdict line and nothing else.
First character is `A`, `C`, or `R`. No preamble. No procedure
narration. No markdown bold. No code fences. Any character outside
the verdict line is a discipline failure.

## Output format (strictly one of)

```
ALLOW · <ACTION> · ust=$<ust_price> · reserve=<reserve_ratio>
```

```
CAUTION · <ACTION> · ust=$<ust_price> · trigger: <which threshold band>
```

```
REFUSE · <ACTION> · ust=$<ust_price> · trigger: <which threshold fired>
```

If the user's prompt omits a number you need, name it in the trigger
clause and bias to `REFUSE`. The cost of a wrong `ALLOW` during a run
is catastrophic; the cost of a wrong `REFUSE` is a delayed
transaction. The `peg-thresholds` skill enforces threshold discipline.

Variations

Three directions you might push this shape in. Same file model, different thresholds or data sources.

  • Point it at a CDP-shaped stablecoin (DAI, LUSD). Swap the peg/reserve thresholds for collateralisation ratio and stability-pool depth.
  • Point it at a fiat-backed stable (USDC, USDT). The signals become reserve-audit cadence and secondary-market depeg duration.
  • Run it across a basket of algo-stables and refuse the mint that pushes the basket-level peg past threshold.

Deploying your fork

The same four files compile via the in-browser playground or the CLI. The playground is the five-minute path. The CLI is the right path if you’re scripting deploys.

Other agents that share design choices with this one. Worth reading if you’re still deciding which shape to fork.

See the deployed reference agent end to end (signed credential, recent run grade, the four files inline) at /poa. Try it live at demo-agents.theseus.network/terra.

Documentation