# A hack the protocol has not reported (/invest/incidents/hack-discovered)

Sometimes a protocol is hacked but its own records do not show it yet. The adapter keeps reporting full value, so the vault cannot see the loss by itself. Someone has to tell it. That someone is the **guardian**, a role the curator assigns to react quickly to emergencies (see [Who controls what](/invest/who-controls-what)).

The examples start from the [example vault](/invest/incidents#the-example-vault-used-on-these-pages): Alice holds 4,000 USDC of Senior, June holds 1,000 USDC of Junior, 3,000 USDC is invested in the leg and 2,000 USDC is idle cash. Each share is worth 1 USDC at the start.

## What a mark is [#what-a-mark-is]

A **mark** is a ceiling the guardian puts on a leg's value. The guardian calls `mark_leg_impaired` with a value in USDC. From then on:

- The leg counts at most at the mark, even if the protocol reports more. The mark is stored in the `Vault` account.
- The leg's mode becomes `Impaired`, so no new money can go into it.
- The leg's low value, the cautious end of its value range, is 0. Withdrawals are priced as if the leg were worth nothing until cash actually comes back.
- The difference between the old value and the mark is booked as a loss at once, Junior first. If the loss reaches Senior, the part Senior loses is recorded as Senior's **impairment**, a loss tracked so it can be repaid later.
- The vault enters **Recovery**, the state in which new deposits and investments stop while an incident is handled.
- An impaired leg no longer has to be refreshed. Its protocol can go silent without blocking the vault.

## Why it exists [#why-it-exists]

Without a mark, the people who leave first would be paid at the old, inflated value, and the people who stay would carry the whole hidden loss (see [A hack nobody has noticed yet](/invest/incidents/hack-unnoticed)). A mark lets one trusted role book a realistic value within one transaction, before anyone else exits.

The guardian can only lower a value. A second mark that is higher than the current one fails with `LimitNotLower`. Raising a mark is a governance change that waits behind the timelock, a delay that gives holders time to react, so a compromised guardian key cannot inflate a leg.

## How it works [#how-it-works]

```mermaid
sequenceDiagram
    participant G as Guardian wallet
    participant V as akashi_vault program
    participant E as Executor
    participant A as Leg adapter
    participant P as Protocol
    G->>V: mark_leg_impaired(leg, mark)
    V->>V: leg mode = Impaired, leg value = min(value, mark)
    V->>V: book the loss (Junior first), state = Recovery
    Note over V: The leg's low value is 0, so withdrawals are cautious
    E->>V: deallocate (take whatever is still there)
    V->>A: CPI aai_withdraw
    A->>P: withdraw
    P-->>A: USDC
    A-->>V: USDC into idle
    V->>V: cash above the marked value is recovery: Senior first, then Junior
```

*Figure: a mark books the loss in one guardian transaction, and every dollar that later comes back repays Senior before Junior.*

The takeaway is that the guardian's job ends with the mark. Getting money back is ordinary work for the executor (the service that moves the vault's cash into and out of legs), and the vault decides on its own who is repaid first.

## Example 1: a mark Junior can cover [#example-1-a-mark-junior-can-cover]

Suppose the leg holds only 800 USDC, and the guardian marks it at 0.

| | Before | After |
| --- | --- | --- |
| Leg value | 800 | 0 |
| Junior | 1,000 | 1,000 − 800 = 200 |
| Senior | 4,000 | 4,000 |
| Vault state | Active | Recovery, not frozen |

*Table: the 800 USDC loss is taken entirely from Junior, so Senior can still leave.*

Senior lost nothing, so Alice can withdraw 1,000 Senior shares and receive 1,000 USDC.

## Example 2: a mark larger than Junior [#example-2-a-mark-larger-than-junior]

The 3,000 USDC leg is marked at 0, a loss of 3,000. Junior loses all of its 1,000, and Senior loses the remaining 3,000 − 1,000 = 2,000 and falls to 2,000. Senior's impairment becomes 2,000. Because Senior is impaired, the vault is **frozen**: no withdrawal can be funded until the impairment is repaid.

## Example 3: a mark can be lowered again [#example-3-a-mark-can-be-lowered-again]

The guardian first marks the 3,000 USDC leg at 1,500, a loss of 1,500. Junior takes 1,000 and Senior the other 500, so Senior falls to 3,500 with an impairment of 500. News gets worse, and the guardian marks the leg again at 500. Only the extra loss of 1,500 − 500 = 1,000 is booked, all on Senior: Senior falls to 2,500 and its impairment rises to 1,500.

## Example 4: the money comes back [#example-4-the-money-comes-back]

After the mark at 0 in Example 2, the protocol turns out to be fine. The executor takes all 3,000 USDC out of the leg.

1. The 3,000 USDC is above the leg's marked value of 0, so it counts as **recovery**.
2. Recovery repays Senior first: Senior goes from 2,000 back to 4,000 and its impairment to 0. That uses 2,000.
3. Then it repays Junior with the remaining 1,000: Junior goes from 0 back to 1,000 and its impairment to 0.
4. The admin calls `retire_leg` (the leg is now empty), then `resume`. The vault is **Active** again.

## Example 5: the protocol repays victims [#example-5-the-protocol-repays-victims]

Some protocols compensate users after a hack. After the mark at 0 in Example 2, the protocol sends 2,500 USDC back to the leg's own token account. The executor moves it into the vault with `sweep_leg_transit`.

- Senior's 2,000 impairment is repaid first: Senior is back to 4,000.
- The remaining 2,500 − 2,000 = 500 goes to Junior: Junior is 500, with 1,000 − 500 = 500 of Junior impairment still open.

## Example 6: repayment after settlement started [#example-6-repayment-after-settlement-started]

After the mark at 0 in Example 2, the admin starts **Settlement**, the final wind-down in which all cash is paid out and the vault closes. Senior is entitled to its value plus its impairment, 2,000 + 2,000 = 4,000, and Junior to 0 + 1,000 = 1,000. Cash is paid Senior first.

1. Alice converts her Senior shares with `settle_shares` and receives 2,000 USDC, all the idle cash there is.
2. Months later, the protocol pays the full 3,000 back.
3. Alice calls `settle_shares` again with 0 shares. Her `SettlementClaim` account stays open, so this collects what has accrued since her last collection: the 2,000 USDC still owed to Senior. She has now received her full 4,000.
4. June converts her Junior shares only now. She receives the remaining 3,000 − 2,000 = 1,000, Junior's full entitlement.

The takeaway is that settlement never closes the door on late money. A holder who converts early is not penalised, and one who converts late loses nothing.

## Example 7: a precautionary mark [#example-7-a-precautionary-mark]

The guardian is worried but does not know the size of the loss. They mark the 3,000 USDC leg at its current value of 3,000.

- No loss is booked: Junior stays at 1,000 and Senior at 4,000.
- But the leg's low value is now 0. At the cautious low end the vault is worth only its 2,000 USDC of idle cash, less than Senior's 4,000. The vault is **frozen**, and not even Senior can leave.
- When the worry is over, the admin queues a `RaiseMark` change with a mark at or above the leg's real position. After the governance delay (by default 86,400 seconds, which is 1 day; the curator can set another delay), anyone calls `execute_change`. The impairment is lifted and the leg becomes `CloseOnly`: money can be taken out of it but not added. The admin then calls `resume`, and the vault is **Active** with the leg still open.

The takeaway: a mark is a strong tool even at full value, because it removes the leg from the cautious withdrawal price.

## Example 8: only the guardian or admin can mark [#example-8-only-the-guardian-or-admin-can-mark]

A stranger who calls `mark_leg_impaired` gets `NotGuardian`, and nothing changes.

## The mark's life cycle [#the-marks-life-cycle]

```mermaid
stateDiagram-v2
    [*] --> Active: leg added
    Active --> Impaired: mark_leg_impaired
    CloseOnly --> Impaired: mark_leg_impaired
    Suspended --> Impaired: mark_leg_impaired
    Impaired --> Impaired: mark_leg_impaired (lower only)
    Impaired --> CloseOnly: RaiseMark to the position or above
    Impaired --> Retired: retire_leg (value 0)
    CloseOnly --> Active: UpdateLeg (governance)
    Retired --> [*]
```

*Figure: the modes a leg passes through after a mark; only governance can lift it, and only to close-only.*

## Advanced details [#advanced-details]

- Any leg that is not `Retired` can be marked, including a suspended one; the mark replaces the suspension. A mark is refused during Settlement (`VaultNotActive`). It also lowers the leg's high value to the mark.
- `mark_leg_impaired` records the leg as impaired in the `Vault` account. `resume` requires that no leg is impaired and that Senior's impairment is 0 (`RecoveryNotFinished` otherwise).
- An impaired leg is valued at the lower of its reported book value and its mark, with a low value of 0. A reported value above the mark is ignored, and cash above the marked value counts as recovery.
- A `RaiseMark` to a mark that is not higher than the current one fails with `MarkNotHigher` when it executes. A raise to less than the leg's reported position keeps the leg impaired at the new mark, and the difference between the new and the old mark counts as recovery.
- `resume` clears Junior's impairment. Any Junior loss not yet repaid at that moment becomes permanent.
- Tests on copies of every real protocol check the same behaviour: after a mark, the protocol still answers, so the leg is valued again but stays capped at its mark.
