# Trove Manager (State Machine)

This page explains the **TroveManager** integration surface for developers: the **trove status state machine**, the **branch lifecycle gates**, and the most reliable ways to **read state** and **index events**.

{% hint style="warning" %}
**No addresses here** — Contract addresses must be sourced from official deployment artifacts / on-chain registries / verified explorers.
{% endhint %}

## At a glance

* A **Trove** is a position; the **TroveManager** is the per-branch contract that tracks its accounting and enforces liquidation/redemption rules.
* Troves have an explicit **status enum** (`active`, `zombie`, `closedByOwner`, `closedByLiquidation`, …).
* Most user write flows go through **BorrowerOperations**; TroveManager exposes **read** APIs and emits **events** that indexers can rely on.
* Branches can become **Pending / Active / Deprecated** (via CollateralRegistry config), and can enter **shutdown** (`shutdownTime`).

## Where TroveManager fits

Conceptually:

* **BorrowerOperations** is the primary write entrypoint for end users and integrators (“open/adjust/close”).
* **TroveManager** is the branch coordinator: it stores per-trove fields, computes “latest” debt/collateral views, and executes liquidations/redemptions under protocol rules.
* **TroveNFT** represents ownership of troves (ERC‑721). TroveManager mints/burns it on open/close.

{% @mermaid/diagram content="flowchart LR
UI\[Integrator / UI] -->|Write txs| BO\[BorrowerOperations]
UI -->|Read state| TM\[TroveManager]
BO -->|permissioned updates| TM

TM --> NFT\[TroveNFT]
TM --> ST\[SortedTroves]
TM --> SP\[Stability Pool]
TM --> CR\[CollateralRegistry]" %}

## Trove status enum (what each means)

In the `ITroveManager` interface, troves have:

| Status                | Meaning                                 | Typical UI / indexer interpretation                   |
| --------------------- | --------------------------------------- | ----------------------------------------------------- |
| `nonExistent`         | Trove ID has no recorded state          | Not opened (or invalid ID)                            |
| `active`              | Normal live position                    | Borrow/repay/adjust allowed (subject to branch gates) |
| `zombie`              | Live, but treated specially (see below) | Still your trove; can be adjusted or liquidated       |
| `closedByOwner`       | Closed voluntarily                      | Final state; NFT burned                               |
| `closedByLiquidation` | Closed via liquidation                  | Final state; NFT burned                               |

## Trove lifecycle (state machine)

{% @mermaid/diagram content="stateDiagram-v2
\[\*] --> nonExistent

nonExistent --> active: open (via BorrowerOperations)

active --> zombie: redemption leaves debt < MIN\_DEBT
zombie --> active: adjust + setTroveStatusToActive

active --> closedByOwner: close (repay all debt)
zombie --> closedByOwner: close (repay all debt)

active --> closedByLiquidation: liquidation
zombie --> closedByLiquidation: liquidation

closedByOwner --> \[*]
closedByLiquidation --> \[*]" %}

## The “zombie” state (why it exists, what changes)

A trove can become `zombie` during redemption flows when its remaining debt becomes **tiny** (below `MIN_DEBT`).

From the TroveManager implementation logic:

* `zombie` is used to prevent redemption loops from being griefed by many tiny troves.
* When a trove becomes zombie, it is removed from the `SortedTroves` ordering.
* A pointer (`lastZombieTroveId`) can cause the next redemption to check a pending zombie trove first.

Developer implications:

* Treat `zombie` as a **live** position, not a closure.
* Liquidation logic treats both `active` and `zombie` as eligible.
* UI can surface `zombie` as “special state after redemptions; adjust to restore normal status”.

## Branch lifecycle gates (CollateralRegistry + shutdown)

TroveManager also enforces **branch-level rules**:

### 1) Collateral status gating

TroveManager queries `CollateralRegistry` for the collateral branch status.

High-level behavior:

| Branch status | Meaning          | What is blocked                                                                   |
| ------------- | ---------------- | --------------------------------------------------------------------------------- |
| `Pending`     | Not yet active   | New troves and adjustments are blocked                                            |
| `Active`      | Normal operation | —                                                                                 |
| `Deprecated`  | Wind-down mode   | **Net debt increases** are blocked (you can repay/close, but can’t increase debt) |

If you build a frontend, expect reverts like `CollateralStatusForbidsOperation()` and display an explicit “branch is pending/deprecated” message rather than a generic failure.

### 2) Shutdown (`shutdownTime`)

TroveManager exposes `shutdownTime()`:

* `0` means “not shut down”
* `> 0` means the branch entered shutdown at that timestamp

Shutdown affects accounting and allowed operations. One observable behavior is interest accrual semantics:

* before shutdown: interest accrues up to “now”
* at/after shutdown: interest accrues at most up to `shutdownTime` for positions not updated since shutdown

## Read APIs (recommended for UIs and indexers)

### Prefer “latest” views for user-facing numbers

* `getLatestTroveData(troveId)` returns a `LatestTroveData` snapshot including:
  * `entireDebt` (includes interest accrual)
  * `entireColl` (includes redistribution gains)
  * `accruedInterest`, redistribution deltas, and rate metadata

This is usually the safest data source for showing “current debt/collateral” in a UI.

### Use raw storage for status and configuration

* `Troves(troveId)` returns raw stored fields (recorded debt/coll, status, rate, batch manager, …).
* `getTroveStatus(troveId)` returns the status enum directly.

### CR helpers

* `getCurrentICR(troveId, price)` returns the current collateral ratio at a provided price.

Integrators should treat the price input as part of the contract: pass the correct branch oracle price. If you pass a different price source, the CR number is not meaningful.

## Events to index (ITroveEvents)

For indexers and analytics, the most useful events are in `ITroveEvents`:

* `TroveUpdated(troveId, debt, coll, stake, annualInterestRate, …)` — snapshot of a trove’s latest state
* `TroveOperation(troveId, operation, … deltas …)` — what changed and why
* `Liquidation(...)` — aggregate liquidation totals
* `Redemption(...)` and `RedemptionFeePaidToTrove(troveId, fee)` — redemption totals + per-trove fee accounting
* `BatchUpdated(...)` / `BatchedTroveUpdated(...)` — batch manager changes (if your deployment uses batches)

{% hint style="info" %}
Events can be emitted by both TroveManager and BorrowerOperations depending on the action. Index the deployed contracts’ ABIs and events rather than relying on a single emitter.
{% endhint %}

## Integration checklist (practical)

* **UI / wallet integration**
  * discover troves by indexing `TroveNFT` `Transfer` events
  * for each troveId, show: `status` + `getLatestTroveData` + derived CR/liquidation price in your UI
  * handle `zombie` explicitly (do not show it as “closed”)
  * on write failures, map common reverts to user-facing messages (branch pending/deprecated, shutdown, slippage/routing failures, …)
* **Indexer / analytics**
  * treat “close” as terminal: trove NFT burn + status becomes `closedByOwner` or `closedByLiquidation`
  * use `TroveOperation` as your “what happened” log and `TroveUpdated` as your “latest snapshot” stream
  * handle batch manager events if enabled (batch shares affect per-trove debt accounting)

## Next reads

* Surface overview: [Smart Contracts](https://hann-finance.gitbook.io/hann-finance/developers/smart-contracts)
* Architecture map: [Technical Overview](https://hann-finance.gitbook.io/hann-finance/developers/technical-overview)
* Practical checklist: [Integrator Guide](https://hann-finance.gitbook.io/hann-finance/developers/integrator-kit)
