> For the complete documentation index, see [llms.txt](https://docs.t-rex.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.t-rex.network/token-and-register/lifecycle-controls.md).

# Lifecycle controls

A register of securities has to be serviced. Units are issued and redeemed. A position is immobilized during an investigation, moved on the order of an authority, or restored to a holder who has lost access to a wallet. Trading is halted during an incident. In T-REX these are operations of the token, executed directly against the on-chain record, each gated by its own role.

## The controls

| Control               | Function                                       | Role                     | Overrides the holder |
| --------------------- | ---------------------------------------------- | ------------------------ | -------------------- |
| Issue                 | `mint`                                         | `AGENT_MINTER`           | No                   |
| Redeem                | `burn`                                         | `AGENT_BURNER`           | Yes                  |
| Freeze an amount      | `freezePartialTokens`, `unfreezePartialTokens` | `AGENT_PARTIAL_FREEZER`  | Yes                  |
| Freeze an address     | `setAddressFrozen`                             | `AGENT_ADDRESS_FREEZER`  | Yes                  |
| Forced transfer       | `forcedTransfer`                               | `AGENT_FORCED_TRANSFER`  | Yes                  |
| Recover a lost wallet | `recoveryAddress`                              | `AGENT_RECOVERY_ADDRESS` | Yes                  |
| Halt and resume       | `pause`, `unpause`                             | `AGENT_PAUSER`           | Yes                  |

Each role is granted separately. An Issuer can give minting to its issuance desk, freezing to its compliance function and recovery to its transfer agent, and none of them holds the others' powers. See [Actors and roles](/start-here/actors-and-roles.md).

These operations act on tokens held on the reference chain. A position that is active on a satellite is brought back first. See "Positions on satellite chains" below.

## Issuance and redemption

|                      | `mint(to, amount)`                                                 | `burn(from, amount)`                                          |
| -------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------- |
| **Effect**           | Creates tokens at `to`. Total supply goes up.                      | Destroys tokens held at `from`. Total supply goes down.       |
| **Eligibility**      | The recipient must be verified.                                    | Not applicable.                                               |
| **Compliance rules** | Apply to the recipient: a mint cannot take an identity past a cap. | Not applicable.                                               |
| **Frozen tokens**    | Not affected.                                                      | Released as needed: the burn unfreezes exactly what it lacks. |
| **While paused**     | Allowed                                                            | Allowed                                                       |

An agent cannot mint to an identity that is not eligible, nor past a rule. Issuance passes the same two gates as a transfer, with no sender.

A burn needs no consent from the holder and passes no gate. It works on a frozen address and on a wallet that its owner has revoked, so a redemption can always be carried out.

## Freezing

|                 | Freezing an address                                   | Freezing an amount                                                                                  |
| --------------- | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| **Function**    | `setAddressFrozen(address, true)`                     | `freezePartialTokens(address, amount)`                                                              |
| **Effect**      | The address cannot send and cannot receive transfers. | That amount cannot be sent. The rest of the balance moves normally, and the address still receives. |
| **Undone with** | `setAddressFrozen(address, false)`                    | `unfreezePartialTokens(address, amount)`                                                            |
| **Read with**   | `isFrozen(address)`                                   | `getFrozenTokens(address)`                                                                          |
| **Limit**       |                                                       | The frozen amount never exceeds the balance of the address.                                         |

What a freeze does not do:

* **It does not change ownership.** Frozen tokens are still counted in `balanceOf` and in the position of the identity. Rules about distribution still count them.
* **It does not stop the agents.** A burn, a forced transfer and a recovery go through a freeze, and release the frozen amount they need. An agent never has to unfreeze before acting.
* **It is per address, not per identity.** Freezing one address of an investor leaves its other addresses free. To immobilize an investor entirely, freeze each address that holds tokens.

A freeze is the way to keep an address out of an asset. Deleting its registration does not do that. See [The eligibility registry](/token-and-register/the-eligibility-registry.md).

## Forced transfer

`forcedTransfer(from, to, amount)` moves tokens without the holder. It exists for decisions that override the holder: a court order, a succession, the correction of an error, the enforcement of a pledge.

| Check                                          | Applies                                                                                        |
| ---------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| The token is not paused                        | Yes                                                                                            |
| The recipient is verified                      | Yes                                                                                            |
| The sender's address is not frozen             | No. A forced transfer goes through a freeze.                                                   |
| The amount is within the sender's free balance | No. Frozen tokens are released as needed.                                                      |
| The compliance rules allow the movement        | No. The compliance is told afterward, so positions stay correct and tracker modules record it. |

Two limits remain, by design. A forced transfer cannot deliver tokens to an ineligible recipient: the register never records a holding that should not exist, even on an agent's instruction. And it cannot run while the token is halted.

The event `ForcedTransfer(agent)` follows the `Transfer` event and names the agent that executed it.

## Recovering a lost wallet

`recoveryAddress(lostWallet, newWallet, identity)` restores a position to a holder who has lost access to the wallet that holds it. It moves everything from the lost wallet to a new address of the same identity.

```mermaid
sequenceDiagram
    participant INV as Investor
    participant AG as Agent
    participant T as Token
    participant REG as TREXRegistry
    participant MC as ModularCompliance

    INV->>AG: request, with proof of identity, off-chain
    AG->>T: recoveryAddress(lostWallet, newWallet, identity)
    T->>REG: new wallet belongs to this identity, or is unknown
    T->>REG: register the new wallet, if it is unknown
    T->>T: move the whole balance, with its freezes
    T->>MC: transferred(lostWallet, newWallet, amount)
    T->>REG: remove the lost wallet's local registration, if any
    T-->>AG: RecoverySuccess
```

The token requires:

* The two addresses are different.
* The lost wallet holds tokens.
* At least one of the two addresses is known to the registry.
* If the new address is known, it belongs to the identity named in the call.
* The token is not paused.

What it does:

* **Registers the new address** for the identity, when the address resolves nowhere.
* **Moves the whole balance.** Partial recovery does not exist.
* **Carries the freezes.** A frozen amount stays frozen on the new address, and a frozen address stays frozen. A recovery is not a way around a freeze.
* **Tells the compliance.** The movement is between two addresses of one identity, so no position changes and no distribution rule is involved. When the identity named in the call is not the one of the lost wallet, the position moves to the named identity: a change of ownership, which the Issuer decides and answers for.
* **Removes the local registration** of the lost wallet, when it had one.

The new address can be any address of the investor, including its ONCHAINID itself.

The contract does not verify that the person asking is the holder. That verification is the Issuer's procedure, carried out off-chain by the agent before it calls the function. The event `RecoverySuccess(lostWallet, newWallet, identity)` records each recovery for transparency.

### Which recovery

| Situation                                                                     | Who acts      | How                                                                                                                                                                                                             |
| ----------------------------------------------------------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The investor still controls its identity and wants the tokens out of a wallet | The investor  | `identityTransfer` from the wallet, through its identity. It moves the free balance. See [Identity-based control and spender compliance](/token-and-register/identity-based-control-and-spender-compliance.md). |
| The investor no longer trusts a wallet                                        | The investor  | Revokes the wallet in the global identity registry.                                                                                                                                                             |
| The investor cannot act, or part of the wallet's balance is frozen            | An agent      | `recoveryAddress`. It moves the whole balance, frozen tokens included, and keeps them frozen.                                                                                                                   |
| The investor has lost the keys of its identity                                | The guardians | Social recovery. See [Account abstraction and recovery](/identity-onchainid/account-abstraction-and-recovery.md).                                                                                               |
| The identity itself is lost for good                                          | An agent      | `forcedTransfer` to an address of the investor's new identity                                                                                                                                                   |

## The pause

`pause` halts the asset. `unpause` resumes it.

| While paused                                   |                                                                                     |
| ---------------------------------------------- | ----------------------------------------------------------------------------------- |
| `transfer`, `transferFrom`, `identityTransfer` | Blocked                                                                             |
| `forcedTransfer`, `recoveryAddress`            | Blocked                                                                             |
| Settlement of transfers executed on satellites | Blocked. The settlement stays deliverable and is recorded when the pause is lifted. |
| `mint`, `burn`                                 | Allowed                                                                             |
| Freezing and unfreezing                        | Allowed                                                                             |
| Configuration                                  | Allowed                                                                             |

The pause stops every movement between holders, including the privileged ones. During an incident, nothing is settled and nothing is moved by an agent until the pause is lifted. Issuance and redemption stay available because they are often part of the response.

Three facts about the pause:

* **A token is deployed paused.** The Issuer lifts the pause when the asset opens.
* **The token can pause itself.** If the cross-chain layer delivers a settlement that the register cannot account for, one that was already applied or that matches no validation, the token halts until an agent has investigated.
* **The pause is for the whole asset.** Stopping one satellite chain is a separate control: the issuance of validations can be paused per chain, by the `COMPLIANCE_MANAGER`.

## Positions on satellite chains

The controls above act on the reference chain. An agent cannot reach across and move, freeze or burn a position that is active on a satellite. It brings the position back, then acts.

1. The agent sends a forced-recall instruction to the satellite.
2. T-REX Lite burns the position there and sends the proof.
3. The reference chain converts the position from bridged to free, for the same identity.
4. The agent applies the control it needs: freeze, forced transfer, burn.

This is the same path a holder's own recall follows. The register never treats a position as present on the reference chain before the satellite has confirmed that it is gone there.

## What an agent cannot do

* **Deliver tokens to an ineligible recipient.** `mint` and `forcedTransfer` both require a verified recipient.
* **Issue past a rule.** A mint is subject to the compliance rules.
* **Move tokens while the asset is halted.**
* **Act without a trace.** Every control emits an event that names what was done, and the role that allows it is visible in the AccessManager.
* **Exceed its role.** A pauser cannot mint. A minter cannot force a transfer.

> **Trust statement.** The holders of these roles can freeze, move and destroy positions without the holder's consent. That is what servicing a register of securities requires, and it is the Issuer's responsibility to decide who holds each role and under what procedure.

## Audit trail

| Operation         | Events                                                                              |
| ----------------- | ----------------------------------------------------------------------------------- |
| Mint, burn        | `Transfer` from or to the zero address                                              |
| Freeze an amount  | `TokensFrozen`, `TokensUnfrozen`                                                    |
| Freeze an address | `AddressFrozen`, with the actor                                                     |
| Forced transfer   | `Transfer`, `ForcedTransfer`, and `TokensUnfrozen` when frozen tokens were released |
| Recovery          | `Transfer`, `RecoverySuccess`, and the freeze events for what was carried over      |
| Pause             | `Paused`, `Unpaused`                                                                |


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.t-rex.network/token-and-register/lifecycle-controls.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
