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

The dual-state lifecycle

Separating authorization from execution creates a gap. Between the moment the reference chain authorizes a transfer and the moment it learns that the satellite executed it, the register and the satellite hold different views. The protocol manages that gap explicitly, by advancing two kinds of state at two different times, so that no inconsistent or non-compliant state ever exists.

This page follows a validation from issuance to its end. What the gap means for finality is covered in Technical finality and legal finality.

Two tracks

Compliance track
Ownership track

What it records

That a movement is authorized and may happen

That a movement has happened

Advances

At issuance

At settlement

Kind of commitment

Soft: a reservation, which can be released

Hard: a change of owner

Read with

pendingInOf, pendingOutOf, reservedOf

positionOf, bridgedBalanceOf, balanceOf

Compliance is reserved early, so that the rules stay sound under concurrency. Ownership moves late, so that the register records only what has occurred.

Why the reservation is needed

An asset caps its holders at 100 identities and has 99. Two buyers, neither of them a holder yet, are each the recipient of a transfer on a satellite, requested at the same moment.

  • Without a reservation, both requests see 99 holders and both are authorized. Both execute. The asset has 101 holders.

  • With it, the first validation counts its recipient as a holder from the moment it is issued. The second request sees the limit reached and is refused.

Neither transfer has executed when the second request is refused. The rule already holds.

The states of a validation

Status
Meaning

Pending

Issued. The amount is reserved. No settlement has arrived.

AwaitingMint

Transfer between two satellites: the sending chain reported its burn. The amount is held in transit. The receiving chain has not reported.

AwaitingBurn

Transfer between two satellites: the receiving chain reported its mint. The sending chain has not reported.

Settled

Every expected report arrived. Ownership moved. Nothing is reserved.

Expired

Pending and past the release time. This status is computed when read. It is never stored.

Discarded

The keeper gave up on it and released the reservation.

DiscardedAwaitingMint, DiscardedAwaitingBurn

Discarded, then one of two reports arrived late. The other is still owed.

LateReconciled

Every report arrived after the discard. The movement was applied anyway.

Resolved

The keeper gave up on a transfer between two satellites of which only one report ever arrived.

statusOf(validationId) returns the status. validationOf(validationId) returns the full record.

What is reserved in each state

Status
Pending amounts of the two identities
Reservation on the sending wallet
Amount in transit

Pending, Expired

Reserved

Reserved

None

AwaitingMint

Reserved

Replaced by the amount in transit

Held

AwaitingBurn

Reserved

Reserved

None

DiscardedAwaitingMint

Released

Released

Held

DiscardedAwaitingBurn

Released

Released

None

Settled, Discarded, LateReconciled, Resolved

Released

Released

None

What is reserved is derived from the status, not stored next to it. The two cannot disagree, and a reservation is released exactly once.

Two deadlines

Deadline
Enforced by
Meaning

expiry

The satellite

The transfer must execute strictly before it.

releaseAt

The reference chain

expiry plus the reconciliation window. Until then, the reservation cannot be released.

The reconciliation window is set per satellite. It covers the worst case for that chain to finalize a transaction and for its notification to arrive. The reference chain does not give up on a validation at its expiry. It waits one window longer. A transfer that executed just before its expiry is therefore settled before the reference chain would consider releasing its reservation. A genuine execution never races a rollback.

The window is governed configuration, set conservatively for each satellite by the COMPLIANCE_MANAGER.

Settlement

When a settlement notification arrives, the register checks it against the validation it issued. The checks have three possible outcomes.

Check
If it fails

The message comes through a gateway the network trusts, and through the gateway the validation went out by

The message is rejected.

Its author is the asset's T-REX Lite on that chain

The message is rejected.

The wallets and the origin chain are those of the validation

The delivery reverts. The message can be delivered again.

The amount is inside the issued range

The delivery reverts.

For the second of two reports: the amount equals the first

The delivery reverts.

The validation was issued, and this report was not already applied

Nothing is applied and the token pauses itself. See "Emergencies".

When every check passes and the movement is complete, the register does four things in one transaction: it releases the reservation, moves the positions of the two identities by the executed amount, updates the token's bridged ledger, and tells the tracker modules.

A settlement is accepted for a Pending validation whatever the clock says. Until the keeper has discarded it, an expired validation still settles normally.

Transfers between two satellites

Two chains cannot act atomically. The sending chain destroys the tokens on its side first, and sends a proof of the burn to the receiving chain, which creates them on its side. Each reports its own half to the reference chain. The two reports travel separately, so the register accepts them in either order.

  • The burn arrives first. It proves the tokens are gone from the sender's wallet. The register takes the amount out of that wallet's bridged position and holds it in transit. The sender's identity still owns it. Status AwaitingMint.

  • The mint arrives first. Nothing moves yet. Status AwaitingBurn.

  • The second report arrives. It must carry the same amount. The register applies the whole movement at once. Status Settled.

Once one report has arrived, the validation can no longer be discarded. One satellite has executed its half, irreversibly.

When nothing arrives

A validation that is never executed must release its reservation, or it would block others indefinitely.

Release is never automatic. Past releaseAt, the status reads Expired, and the reservation stays in place until the Validation Keeper calls discardExpiredValidations for it. The discard releases the reservation, and issuance continues as if the validation had never existed. Nothing is undone on the ownership track, because nothing had moved.

The keeper is a restricted role, by design. Discarding is what turns a slow settlement into a late one, and a late settlement can stop a chain from issuing. That power is not given to everyone. The T-REX Network operates the keeper, and an Issuer grants it the VALIDATION_KEEPER role for its asset.

When a settlement arrives late

A settlement can arrive after its validation was discarded: the satellite executed in time, and the notification took longer than the window.

The register applies it, always, even when the result breaches a rule of the asset. The execution on the satellite is final, and nothing on the reference chain can undo it. Refusing the settlement would make the register wrong, and satellites could not rely on finality if the reference chain could reject what they executed. A state that breaches a rule is resolved by the Issuer of the asset, not by rejecting the settlement.

The register
Why

Applies the movement, status LateReconciled

The record must reflect what happened.

Emits LateReconciliation

Every late settlement is visible.

Checks whether the executed amount exceeds what the rules allow now

The reservation was released, so other movements may have used the room.

Pauses the issuance of validations for that chain, if it does

No further transfer is authorized there until someone has looked into it.

A late settlement that breaches nothing does not pause the chain. Late delivery is easy to cause, and pausing on it alone would let anyone stop a satellite. The COMPLIANCE_MANAGER lifts the pause once the exception is resolved.

When half a transfer is stuck

A transfer between two satellites can stay with one report forever, if the other chain never reports. The keeper resolves it with resolveStuckValidation, after a second reconciliation window past releaseAt, so that a report that is merely slow still arrives as a late reconciliation.

The report that arrived
What the resolution does

The burn

The amount held in transit returns to the wallet it was burned from. Whatever is still reserved is released.

The mint

Nothing on the reference chain can be returned. The burn happened, since the receiving chain minted against its proof, and its report is missing. The sending chain is paused for issuance, and the Issuer investigates.

The status becomes Resolved. A report that arrives after that is treated as an emergency.

A resolution closes the validation on the register. It does not change what the satellites executed. The Issuer establishes what happened on each satellite and brings the register and the satellites back in line.

Emergencies

Two situations mean that a trusted gateway delivered something the protocol cannot account for.

  • A settlement for a validation that was never issued.

  • A settlement whose report was already applied, or whose validation was already resolved.

Neither is applied. The compliance emits ReplayedSettlement and the token pauses itself. Every movement between holders stops until an agent has investigated and lifted the pause. While the token is paused, settlements are not applied: their delivery reverts and they remain deliverable.

What can stop, and who restarts it

What stops
Triggered by
Lifted by

Issuance of validations for one satellite

A late settlement that breaches a rule. A stuck transfer of which only the mint arrived. The COMPLIANCE_MANAGER.

COMPLIANCE_MANAGER, with setIssuancePaused

The whole token

A replayed or unknown settlement. The AGENT_PAUSER.

AGENT_PAUSER, with unpause

One validation

The keeper's discard, after releaseAt

Nothing. The holder requests a new validation.

Last updated