For the complete documentation index, see llms.txt. This page is also available as Markdown.

36. Handle a late reconciliation or a halt

The cross-chain layer raises three kinds of alarm on the reference chain. A settlement arrives after its validation was discarded: a late reconciliation. A transfer between two satellites is resolved with one report missing. Or a trusted gateway delivers a settlement the register cannot account for, and the token halts itself. This guide is the Issuer's response to each: what the protocol already did, what to check, and how operation resumes.

At a glance

Triggered by

An event on the reference chain: LateReconciliation, ValidationIssuancePaused, ValidationResolved, or ReplayedSettlement with Paused

Actors

Issuer, Token Agent, Validation Keeper, Network governance, Platform

Contracts

ModularCompliance, Token, TrustedGatewayRegistry

Preconditions

The asset is open on at least one satellite (see 33); the Platform indexes the events of the compliance and of the token; the Issuer and its agents hold COMPLIANCE_MANAGER, IDENTITY_MANAGER and AGENT_PAUSER in the asset's domain

Result

The cause is established, the positions are regularized where needed, and issuance for the chain, or the token itself, is resumed

Actors and roles

Actor
Role in this flow
What they hold

Issuer

Investigates, decides how to regularize, and lifts the pause on issuance.

COMPLIANCE_MANAGER on the ModularCompliance. IDENTITY_MANAGER on the Token

Token Agent

Lifts the pause of the token, and applies the controls the Issuer decides.

AGENT_PAUSER, and the agent roles the regularization needs

Validation Keeper

The keeper run by the T-REX Network. It stops discarding for the chain concerned while the incident is open, at the Issuer's request.

VALIDATION_KEEPER

Network governance

Removes a gateway that misbehaved, for every asset.

INTEROP_MANAGER on the TrustedGatewayRegistry

Platform

Detects the alarm, gathers the facts and relays the calls.

Read access, and whatever keys the Issuer has authorized

Sequence

Step by step

Step 1. Identify the alarm

Who: Platform

Call: Off-chain, from events and read calls

Before the call: The Platform watches the events of the compliance and of the token.

What happens: The Platform classifies what it saw.

Events
What happened
What the protocol already did

LateReconciliation(validationId, chainKey) alone

A report arrived after its validation was discarded, and the result respects the rules.

Applied the movement. The validation is LateReconciled, or awaits its second report. Nothing is paused.

LateReconciliation and ValidationIssuancePaused(chainKey)

Same, and the executed amount exceeds what the rules allow now.

Applied the movement. Paused the issuance of validations for that chain.

ValidationResolved(validationId, 0) and ValidationIssuancePaused(chainKey)

The keeper resolved a transfer between two satellites of which only the mint was reported.

Paused issuance for the sender's chain. Moved nothing.

ValidationResolved(validationId, amount) with a positive amount

The keeper resolved a transfer of which only the burn was reported.

Returned the amount held in transit to the sender's wallet on the register. Paused nothing.

ReplayedSettlement(validationId, chainKey) and Paused on the token

A trusted gateway delivered a settlement for a validation that was never issued, a report that was already applied, or a report for a resolved validation.

Applied nothing. The token paused itself.

It reads ModularCompliance.validationOf(validationId) and statusOf(validationId), the positions of the identities concerned with positionOf, and Token.pinnedRouteFor(validationId, chainKey), the gateway the validation went out through.

What changes: Nothing on-chain.

Step 2. Contain

Only when the facts point to a satellite or a gateway that cannot be relied on.

Who: Issuer (COMPLIANCE_MANAGER for the issuance pause, IDENTITY_MANAGER for the route)

Call: ModularCompliance.setIssuancePaused(chainKey, true), and Token.setRoute(chainType, chainReference, 0x0) to close the chain

Before the call: Step 1 shows an anomaly that may repeat.

What the contract checks:

  1. The caller holds the role of the function in the asset's domain. Otherwise AccessManagedUnauthorized.

What changes: With the issuance pause, the compliance emits ValidationIssuancePaused(chainKey) and refuses every new validation that involves that chain. Settlements of transfers already executed are still recorded. With the route set to zero, the token emits RouteSet(chainKey, 0x0), stops sending to that chain, and refuses burn proofs from it. A settlement of a validation already sent is still accepted through the gateway it went out by.

When the gateway itself is in doubt, the Issuer alerts Network governance. Removing the gateway from the TrustedGatewayRegistry severs every route through it at once, for every asset.

When the satellite itself can no longer be relied on, it is marked as compromised: its positions are recalled to the identities their wallets are linked to, and transactions from or to it are treated as invalid. See Emergency behavior.

Step 3. Investigate and regularize

Who: Issuer, with the Token Agent for any control on positions

Call: Off-chain. The controls used are other flows

Before the call: Step 1 is done, and step 2 where needed. The Issuer has asked the T-REX Network to hold the keeper back for the chain concerned, or has revoked VALIDATION_KEEPER until the incident is closed.

What happens: The Issuer establishes the cause and decides what to do about the state the register now records. One principle governs every case: a transaction that executed on a satellite is final there, and the register is reconciled to it, even when the result breaches a rule of the asset. Satellites could not rely on finality otherwise. The breach, if there is one, is the Issuer's to resolve afterward. It is never resolved by rejecting the settlement.

Alarm
What to establish
Regularization

Late settlement, no breach

Why the report was slow: the provider, the satellite's finality, a window that is too short.

None on positions. Lengthen the reconciliation window if late reports recur: 33.

Late settlement with a breach

Which rule is exceeded, and for which identity. The transfer is final on the satellite and recorded on the register.

The Issuer brings the position back within the rule: a recall ordered by an agent (32), then a forced transfer (14) or a redemption (09). Or it accepts the exception and documents it.

Resolution, mint only

That the transfer executed: the receiving satellite mints only against a proof of burn, so the burn happened and its report is missing. The recipient holds tokens on its satellite that the register does not record as its own.

The register is brought in line with what the satellites executed. [[TBC: the operations that reconcile the register with a satellite after a resolution]]

Resolution, burn only

Whether the receiving satellite minted. The register shows the amount back on the sender's wallet, and the sending satellite burned it.

Same principle: what the satellites executed is final, and the register follows. [[TBC: the operations that reconcile the register with a satellite after a resolution]]

Replayed or unknown settlement

Which gateway delivered it, read from the Paused event, and whether the validation was ever issued. The register applied nothing, so no position is wrong.

None on positions. The question is whether the gateway and the satellite can still be trusted. Close the route or ask Network governance to remove the gateway if not.

What changes: Whatever the controls chosen change. Each is recorded by its own events.

Step 4. Resume

Who: Issuer (COMPLIANCE_MANAGER) for a chain. Token Agent (AGENT_PAUSER) for the token

Call: ModularCompliance.setIssuancePaused(chainKey, false). Token.unpause()

Before the call: The cause is established and the Issuer has decided that operation can resume.

What the contract checks:

  1. The caller holds COMPLIANCE_MANAGER, or AGENT_PAUSER, in the asset's domain. Otherwise AccessManagedUnauthorized.

  2. For unpause: the token is paused. Otherwise ExpectedPause.

What changes: The compliance emits ValidationIssuanceUnpaused(chainKey) and validations can be issued for that chain again. The token emits Unpaused(agent): transfers execute again, and settlements that were refused during the pause are applied when they are delivered again.

State after the flow

  • ModularCompliance.isIssuancePaused(chainKey) is false for every chain the Issuer has resumed.

  • Token.paused() is false, if the token had halted.

  • The validation concerned keeps its final status: LateReconciled, Resolved, or the status it had when a replay was refused. The record is permanent.

  • Positions reflect what executed on the satellites, plus any control the Issuer applied.

  • The events of the incident stay on-chain: what arrived, what was paused, who resumed.

Failure modes

Symptom
Cause
Fix

Reverts with AccessManagedUnauthorized

The caller does not hold the role of the function (check 1 of steps 2 and 4)

Grant the role: 25

unpause reverts with ExpectedPause

The token is not paused (step 4, check 2)

Nothing to do

Issuance is paused again right after being resumed

Another late settlement from the same chain breached a rule, or the keeper resolved another validation

Find out why reports from that chain are late before resuming. Ask the T-REX Network to hold the keeper back

The token halts again right after unpause

The same message, or another replay, was delivered again

Contain first: close the route (step 2), or have the gateway removed

Late reconciliations keep occurring without any breach

The reconciliation window of the chain is shorter than its real latency, or the keeper discards too early

Lengthen the window. Ask the T-REX Network to discard with a larger margin after releaseAt

Settlements are not applied after the incident

The token is still paused, or the gateway they must come through was removed from the registry

Unpause. A settlement is accepted only through the gateway its validation went out by, and only while the network trusts that gateway

A chain is closed and positions are still recorded there

Closing a route does not move positions

Reopen a route to recall them. If the satellite is lost or compromised, it is marked as such and its positions are recalled to their owners: see Emergency behavior

A validation request reverts with ValidationIssuancePaused

The chain is paused for issuance

Intended until step 4

Common misunderstandings

Wrong: "A late settlement is rejected."

Right: It is applied, always. The transfer executed on the satellite and is final there. Refusing it would make the register wrong, and satellites could not rely on finality. What a late settlement adds is a warning, and a pause of that chain when the result breaches a rule. The breach is then the Issuer's to resolve.

Wrong: "Any late settlement stops the chain."

Right: Only one whose executed amount exceeds what the rules allow at that moment. Late delivery is easy to cause, and pausing on it alone would let anyone stop a satellite.

Wrong: "When the token halts itself, the register is corrupted."

Right: The halt is what prevents corruption. The message that triggered it was not applied. Every position is as it was. The halt says that a trusted gateway delivered something the register could not have issued or had already recorded, and that every settlement is suspect until someone has looked.

Wrong: "Unpausing fixes the incident."

Right: unpause and setIssuancePaused(chainKey, false) are the last step. They resume operation after the cause is established. Resuming without containing a faulty gateway leads to the same halt.

Integration notes

  • Alert on four events of the compliance: LateReconciliation, ValidationIssuancePaused, ValidationResolved and ReplayedSettlement. Alert on Paused on the token when the account is not an agent.

  • Keep, for every validation, the gateway it went out through. ValidationRoutePinned gives it at issuance, and pinnedRouteFor reads it later.

  • A pause of issuance set by the protocol and one set by the Issuer are the same flag. Lifting it is always an explicit call.

  • While the token is paused, settlements revert and stay deliverable. How a message is delivered again depends on the messaging provider.

  • These alarms depend on the interoperability solution behind each gateway. While it works as designed, a replayed or unknown settlement does not occur.

  • An issuance pause is per chain and per asset. It does not stop the settlement of transfers already executed, and it does not affect other chains.

  • Write the incident down off-chain: the cause, the decision and who took it. The chain records the events, not the reasoning.

Last updated