> For the complete documentation index, see [llms.txt](https://docs.hann.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hann.finance/developers/trove-manager.md).

# Trove lifecycle

TroveManager accounting, position states, branch restrictions, read methods, and events for integrations.

Each collateral branch has a **TroveManager** that stores Trove accounting and processes liquidations and redemptions. User opening, adjustment, and closing operations enter through **BorrowerOperations**. The app's Zappers handle collateral conversions and wallet flows before calling that entry point.

## Contract responsibilities

| Contract             | Responsibility                                                                                                    |
| -------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `BorrowerOperations` | Opening, collateral/debt adjustments, rate management, full repayment and closure, and collateral-surplus claims. |
| `TroveManager`       | Position and batch accounting, current debt/collateral reads, liquidation, redemption, and lifecycle updates.     |
| `TroveNFT`           | ERC-721 ownership. TroveManager mints it on opening and burns it on closure or liquidation.                       |
| `SortedTroves`       | The live redemption ordering by annual interest rate.                                                             |
| `StabilityPool`      | USDHN deposits used to offset liquidated debt, and the resulting collateral and yield accounting.                 |
| `CollateralRegistry` | Branch registration and status, and routing normal USDHN redemptions across branches.                             |

TroveManager's `onOpenTrove`, `onAdjustTrove`, and other borrower-update methods accept calls from BorrowerOperations. They are not direct wallet entry points. `batchLiquidateTroves` is public; normal `redeemCollateral` accepts calls from CollateralRegistry.

Resolve the contracts and ABIs for the selected deployment profile and branch as described in [Smart contracts](/developers/smart-contracts.md). `kaia-prod` and `kaia-qa` both use chain ID `8217`, but have separate profile identities. `kairos-dev` uses `1001`.

## Trove identity and ownership

The opening ID is calculated inside BorrowerOperations:

```solidity
troveId = uint256(keccak256(abi.encode(msg.sender, owner, ownerIndex)));
```

Here `msg.sender` is the caller seen by BorrowerOperations, such as a Zapper contract. The same owner and index can produce different IDs through different entry points. Record the ID from the opening receipt and NFT mint event, along with its branch.

Index `TroveNFT.Transfer` to follow ownership. A mint has a zero-address sender; a burn has a zero-address recipient. Retain the last owner in history after a burn because `ownerOf` no longer returns an owner for that NFT.

## Position states

`ITroveManager.Status` uses this enum order:

| Value | Status                | Meaning                                                                                                |
| ----- | --------------------- | ------------------------------------------------------------------------------------------------------ |
| `0`   | `nonExistent`         | This ID has no opened position.                                                                        |
| `1`   | `active`              | An open position in the sorted list. Borrower operations also apply branch and ratio checks.           |
| `2`   | `closedByOwner`       | Voluntary closure. Accounting fields are cleared and the NFT is burned.                                |
| `3`   | `closedByLiquidation` | Liquidation closure. Accounting fields are cleared and the NFT is burned.                              |
| `4`   | `zombie`              | An open position removed from the regular sorted list after a redemption leaves debt below `MIN_DEBT`. |

### State transitions

| Starting state       | Operation                                                  | Result                                     |
| -------------------- | ---------------------------------------------------------- | ------------------------------------------ |
| `nonExistent`        | `openTrove` or `openTroveAndJoinInterestBatchManager`      | `active`; NFT minted.                      |
| `active`             | Redemption leaves debt below `MIN_DEBT`, including zero    | `zombie`; removed from `SortedTroves`.     |
| `zombie`             | `adjustZombieTrove` meets the debt and ratio requirements  | `active`; reinserted using ordering hints. |
| `zombie`             | `applyPendingDebt` leaves current debt at least `MIN_DEBT` | `active`; reinserted using ordering hints. |
| `active` or `zombie` | `closeTrove` settles all current debt                      | `closedByOwner`; NFT burned.               |
| `active` or `zombie` | Liquidation with current `ICR < MCR`                       | `closedByLiquidation`; NFT burned.         |

`MIN_DEBT` is a debt floor used by borrowing and redemption accounting. Use the value belonging to the selected deployment. A rehearsal constant and a parameter copied from a different profile do not establish that deployment's debt floor.

### Zombie accounting

A zombie retains its NFT, collateral, and remaining debt. Removing small positions from the normal redemption list limits repeated traversal through them. If a newly created zombie has nonzero debt, `lastZombieTroveId` points to it so the next redemption considers it first. The pointer is cleared when that zombie is fully redeemed, restored, or closed.

Normal `adjustTrove` requires an active position. Restore a zombie through `adjustZombieTrove`, which enforces `MIN_DEBT`, applies the changes, and reinserts it. `applyPendingDebt` can also restore a zombie whose updated debt has reached the floor. A fully redeemed zombie can be closed to reclaim its collateral and gas deposit with zero USDHN repayment.

Liquidation eligibility includes both `active` and `zombie`. A fully redeemed position has no debt to liquidate. Marking every zombie as closed would hide collateral still held for its owner.

## Branch status and shutdown

TroveManager resolves its branch through `findCollateralByTroveManager` and reads `CollateralRegistry.collateralConfig(index).status`.

| Registry status | New Troves                                        | Collateral/debt adjustments                                                                                                              |
| --------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `Pending`       | Blocked.                                          | Blocked.                                                                                                                                 |
| `Active`        | Allowed after the debt, oracle, and ratio checks. | Allowed after the position and branch checks.                                                                                            |
| `Deprecated`    | Blocked.                                          | A requested debt increase greater than the requested debt decrease is blocked. Other adjustments remain subject to the remaining checks. |

`CollateralStatusForbidsOperation()` identifies a registry-status rejection. Shutdown is a separate condition:

* `shutdownTime() == 0`: the branch has not entered shutdown.
* `shutdownTime() > 0`: the value records the shutdown timestamp.
* BorrowerOperations blocks new borrowing and ordinary adjustments after shutdown. Full repayment and closure remain available.
* Before shutdown, interest accrues from `lastDebtUpdateTime` to the current time. After shutdown, an earlier last-update time accrues to `shutdownTime`; an update at or after shutdown has no further accrual period.
* Normal redemptions require a non-shutdown branch with `TCR >= SCR`. `urgentRedemption` requires shutdown and uses explicit Trove IDs.

Before shutdown, voluntary closure must leave `TCR >= CCR` and at least one other tracked Trove. Shutdown lifts those two restrictions for voluntary closure. Liquidation still cannot remove the last tracked Trove: `OnlyOneTroveLeft()` reverts that operation.

## Current-state reads

Use `getLatestTroveData(troveId)` for a current debt/collateral display. It calculates pending accrual and redistribution rather than returning only the last stored values.

| Field                                   | Contents                                                                                                     |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `entireDebt`                            | Recorded debt plus accrued interest, redistributed USDHN debt, and the Trove's accrued batch management fee. |
| `entireColl`                            | Recorded collateral plus pending redistributed collateral.                                                   |
| `recordedDebt`                          | Debt already recorded in the position or attributed through its batch shares.                                |
| `accruedInterest`                       | Interest since the last accounting update, using shutdown semantics.                                         |
| `redistUSDHNDebtGain`, `redistCollGain` | Pending debt and collateral allocated by branch redistributions.                                             |
| `annualInterestRate`                    | The position rate or current batch rate.                                                                     |
| `weightedRecordedDebt`                  | Recorded debt multiplied by the annual interest rate.                                                        |
| `accruedBatchManagementFee`             | The position's share of accrued batch fees.                                                                  |
| `lastInterestRateAdjTime`               | The latest relevant position or batch rate-change time.                                                      |

For a batched Trove, debt, interest, and management fees use its `batchDebtShares / totalDebtShares`. Redistribution follows the Trove's collateral stake, so a pro-rata share of total batch debt does not replace the entire-debt calculation.

| Read method                                                 | Use                                                                                                    |
| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `Troves(troveId)`                                           | Raw stored fields: debt, collateral, stake, status, timestamps, rate, batch manager, and batch shares. |
| `getTroveStatus(troveId)`                                   | The status enum.                                                                                       |
| `getTroveAnnualInterestRate(troveId)`                       | The position's effective rate, including its batch rate.                                               |
| `getLatestBatchData(batchAddress)`                          | Batch totals, debt shares, accrued interest, and management fees.                                      |
| `getCurrentICR(troveId, price)`                             | Current collateral ratio using latest debt/collateral and the supplied price.                          |
| `getTroveIdsCount()` and `getTroveFromTroveIdsArray(index)` | The current tracked-ID array. Closure removes IDs; the count is not a lifetime creation count.         |

Pass the correct branch price and scale to `getCurrentICR`. Price and ratio use `1e18` precision; a ratio of `1.2e18` represents `120%`. A result calculated from a market quote describes that quote, not the protocol's oracle liquidation check.

## Events and history

Index the deployed TroveManager and BorrowerOperations ABIs, plus the TroveNFT ownership events. Event snapshots describe the operation's accounting; future accrued interest still requires a current-state read.

| Event                      | Information to retain                                                                                                                |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `TroveUpdated`             | Trove ID, recorded debt/collateral, stake, rate, and redistribution snapshots.                                                       |
| `TroveOperation`           | Operation kind and separate debt/collateral changes from redistribution, upfront fees, and the requested action.                     |
| `Liquidation`              | Debt offset and redistributed, collateral sent to the Stability Pool and redistribution, compensation, surplus, and execution price. |
| `Redemption`               | Attempted and actual USDHN redemption, collateral sent, fee, and prices.                                                             |
| `RedemptionFeePaidToTrove` | Fee accounting for the individual redeemed Trove.                                                                                    |
| `BatchUpdated`             | Batch operation, totals, rate, management fee, shares, and upfront-fee changes.                                                      |
| `BatchedTroveUpdated`      | Trove collateral, stake, debt shares, batch manager, and redistribution snapshots.                                                   |
| `Transfer` on TroveNFT     | Creation, ownership transfer, and burn.                                                                                              |

Keep transaction order and branch identity when applying events. Treat `closedByOwner` and `closedByLiquidation` as terminal states and retain history after the NFT burn. Resolve both regular and batched event paths; batched position debt needs batch-share accounting.

## Transaction failures

| Revert                                    | Affected input or state                                                             |
| ----------------------------------------- | ----------------------------------------------------------------------------------- |
| `CollateralStatusForbidsOperation()`      | The selected branch is not permitted to create or adjust this position.             |
| `IsShutDown()`                            | The requested borrower action is stopped after shutdown.                            |
| `ICRBelowMCR()` or `ICRBelowMCRPlusBCR()` | Resulting collateral ratio is below the required threshold.                         |
| `TCRBelowCCR()`                           | The requested operation violates the branch's total collateral-ratio check.         |
| `DebtBelowMin()`                          | Resulting debt is below the floor.                                                  |
| `UpfrontFeeTooHigh()`                     | The execution fee exceeds the accepted maximum.                                     |
| `NotEnoughUSDHNBalance()`                 | The repayment caller lacks the USDHN required to burn.                              |
| `OnlyOneTroveLeft()`                      | The operation would remove the final tracked Trove under the current closure rules. |

Show the affected amount, branch restriction, or position state in the action flow. Zapper routing and slippage failures belong to their own transaction path. The [technical overview](/developers/technical-overview.md) connects the contracts, and the [integrator guide](/developers/integrator-kit.md) covers the broader API and wallet flow.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.hann.finance/developers/trove-manager.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
