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

32. Recall a position to the reference chain

A recall returns a position that is active on a satellite to the reference chain, for the same owner. T-REX Lite burns the position on the satellite and sends a proof of the burn. When the token on the reference chain receives the proof, it converts the position from bridged back to free. A holder recalls its own position. An agent orders a recall when it needs to act on a position that is active on a satellite, because the controls of the asset operate on the reference chain.

At a glance

Triggered by

Investor, on the satellite. Or a Token Agent, from the reference chain

Actors

Investor, Token Agent, Platform

Contracts

T-REX Lite on the satellite, the ERC-7786 gateway of the route, Token, TREXRegistry

Preconditions

The wallet holds a position on the satellite (see 30); the asset is open on that satellite (see 33); the address to credit on the reference chain belongs to the same identity as the wallet; for a recall ordered by an agent, the caller holds AGENT in the asset's domain

Result

The bridged position of the satellite wallet has decreased by amount and the free balance of the holder's address on the reference chain has increased by amount

Actors and roles

Actor
Role in this flow
What they hold

Investor

Recalls its own position, from its wallet on the satellite.

A balance on T-REX Lite. An address of the same identity on the reference chain: its ONCHAINID or a linked wallet

Token Agent

Orders the recall when the Issuer needs the position back on the reference chain.

AGENT on the Token

Platform

Relays the request, tracks the proof and confirms the result.

Whatever keys the party it acts for has authorized

Sequence

Step by step

Step 1. Start the recall

There are two ways. The first is the holder's.

Who: Investor, from its wallet on the satellite

Call: The recall function of T-REX Lite, called by the holder, with the amount and the address to credit on the reference chain [[TBC: the name and the arguments of that function]]

Before the call: The Platform confirms that TREXRegistry.identity(nativeWallet) and TREXRegistry.resolveIdentity(wallet) return the same identity. It reads Token.reservedOf(wallet) on the reference chain: a recall can take tokens that an open validation was issued for, and that validation can then no longer execute.

What the contract checks: T-REX Lite checks that the caller holds the amount on the satellite.

What changes: On the satellite, T-REX Lite burns amount from the wallet and sends a burn proof to its peer. The proof carries the wallet that was burned, the amount, and the address on the reference chain to credit. The register is unchanged until the proof arrives.

Alternative: an agent orders the recall.

Who: Token Agent (AGENT)

Call: Token.dispatchRecallInstruction(chainKey, body), with body [[TBC: the content of a recall instruction]]

Before the call: The Issuer has decided that the position must return to the reference chain, for example before a freeze, a forced transfer or a burn.

What the contract checks:

  1. The caller holds AGENT in the asset's domain. Otherwise the call reverts with AccessManagedUnauthorized.

  2. The satellite is open for the asset. Otherwise ChainNotOpen.

What changes: The token sends a recall instruction to its peer on the satellite and emits ProtocolMessageSent. On delivery, T-REX Lite burns the position and answers with the same burn proof. The register is unchanged until the proof arrives.

A forced recall can fail. If the holder executed a validated transfer before the instruction arrived, the wallet no longer holds the amount. T-REX Lite then burns nothing and reports that the recall failed [[TBC: the message that reports a failed recall]]. The reference chain receives, separately, the settlement of the transfer that did execute.

Step 2. Consume the burn proof

Who: The ERC-7786 gateway delivers the proof to the Token. No actor transacts

Call: Token.receiveMessage(receiveId, sender, payload), called by the gateway

Before the call: The burn is final on the satellite for the messaging provider.

What the contract checks:

  1. The delivering gateway is trusted by the network. Otherwise ERC7786RecipientUnauthorizedGateway.

  2. The author of the message is the asset's peer on that chain. Otherwise SenderNotPeer.

  3. This gateway has not already delivered this message. Otherwise MessageAlreadyReceived.

  4. The gateway is the current route of the asset for that chain. Otherwise GatewayNotRouted.

  5. The address to credit is not zero. Otherwise ZeroAddress.

  6. The address to credit belongs to the same identity as the wallet that was burned. A recall moves location, never ownership. [[TBC: the error of this check]]

  7. The bridged position of the wallet covers the amount. Otherwise InsufficientBridgedBalance.

What changes: The token emits BurnProofReceived(chainKey, burnedWallet, nativeWallet, amount). It decreases the bridged position of the wallet and the total bridged amount by amount, increases the native balance of nativeWallet by amount, and emits Transfer(0x0, nativeWallet, amount) and Recalled(fromKey, nativeWallet, fromWallet, amount). totalSupply does not change. The position of the identity in the compliance does not change. The token emits ProtocolMessageReceived.

Step 3. Confirm, and act

Who: Platform

Call: Off-chain, using read calls

Before the call: Step 2 is confirmed.

What happens: The Platform reads Token.bridgedBalanceOf(wallet) and Token.freeBalanceOf(nativeWallet). After a recall ordered by an agent, the Token Agent now applies the control it needed on the reference chain: a freeze, a forced transfer, a burn or a recovery.

What changes: Nothing on-chain in this step.

State after the flow

  • On the satellite, the balance of the wallet on T-REX Lite has decreased by amount.

  • Token.bridgedBalanceOf(wallet) and Token.totalBridged() have decreased by amount.

  • Token.balanceOf(nativeWallet) and Token.freeBalanceOf(nativeWallet) have increased by amount.

  • Token.totalSupply() is unchanged.

  • ModularCompliance.positionOf(identity) is unchanged. The owner is the same.

  • An indexer has seen Transfer(0x0, nativeWallet, amount) followed by Recalled. It is not an issuance.

Failure modes

Symptom
Cause
Fix

dispatchRecallInstruction reverts with AccessManagedUnauthorized

The caller does not hold AGENT in the asset's domain (step 1, alternative, check 1)

Grant the role: 25

dispatchRecallInstruction reverts with ChainNotOpen

The asset has no usable route to that chain (step 1, alternative, check 2)

Restore a route: 33

The burn is done on the satellite and the free balance does not appear

The burn proof is not delivered yet

Wait for the messaging provider. The position is in neither place in the meantime, and the register still records it as bridged to the wallet

The delivery of the proof reverts with GatewayNotRouted

The proof came through a gateway that is not the asset's current route for that chain: the Issuer changed or closed the route after the burn (step 2, check 4)

The Issuer sets the route back to the gateway that carries the proof, so that it can be delivered

The delivery of the proof reverts with SenderNotPeer

The message does not come from the asset's T-REX Lite on that chain (step 2, check 2)

Nothing to do. The message is not the asset's

The delivery of the proof reverts with ZeroAddress

The proof names no address to credit (step 2, check 5)

An anomaly of the satellite. The Issuer investigates

The proof is refused because the address to credit belongs to another identity

A recall cannot change ownership (step 2, check 6)

Recall to an address of the same identity, then transfer on the reference chain: 10

The delivery of the proof reverts with InsufficientBridgedBalance

The register records less for that wallet than the proof claims: a settlement is still missing, or tokens appeared on the satellite without a recorded position (step 2, check 7)

Wait for pending settlements. If the difference remains, the Issuer investigates the satellite

A validation issued before the recall can no longer execute

The tokens it was issued for left the satellite. A recall and a validation are independent

Nothing to repair. The validation expires, and the Validation Keeper discards it: 35

A forced recall has no effect

The holder transferred the tokens on the satellite before the recall instruction arrived. T-REX Lite reported the failure

Read the settlement of that transfer on the register. The position now belongs to the recipient. Order a new recall there if it is still needed

Common misunderstandings

Wrong: "A recall is a transfer back to the reference chain."

Right: A recall changes where a position is active, not who owns it. The address credited belongs to the same identity as the wallet that was burned. To deliver tokens from a satellite to another holder on the reference chain, use a transfer with a validation.

Wrong: "The reference chain credits the holder when the recall is requested."

Right: It credits the holder when it receives the proof that the satellite burned the position. Acting earlier would leave the position usable on both chains at once.

Wrong: "An agent can freeze or seize a position on a satellite directly."

Right: The controls of the asset act on the reference chain. An agent orders a recall, the satellite burns and proves it, the position returns to the same owner on the reference chain, and the agent then applies the control there.

Wrong: "The recall mints new tokens, since a Transfer from the zero address is emitted."

Right: The supply does not change. The event makes balanceOf rise visibly on the reference chain. Recalled, emitted with it, says that a bridged position became a free balance.

Integration notes

  • The address to credit can be the holder's ONCHAINID itself. A holder does not need a wallet on the reference chain to recall.

  • A recall does not look at validations. Recalling tokens that an open validation was issued for is allowed: the validation expires. Tell the holder when its recall drops a pending transfer.

  • The holder pays for the burn and for the message that carries the proof, directly or through a paymaster. An agent pays for the recall instruction it sends. The burn of a forced recall and its proof happen inside the delivery of that instruction. [[TBC: who pays for a message that T-REX Lite sends while a delivery is executed]]

  • An indexer that tracks the bridged total subtracts the amounts of Recalled from those of DelegatedOut. The Transfer from the zero address of a recall is not an issuance.

  • Track the proof with the tools of the messaging provider. On the reference chain, BurnProofReceived and Recalled mark its arrival.

  • An agent that recalls a position to act on it plans two transactions on the reference chain: the control it needs comes after the proof has arrived.

  • Keep the route of a chain in place while proofs are in flight. A burn proof is accepted through the asset's current route only.

Last updated