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

30. Delegate a position out to a satellite

A delegation-out makes a position active on a satellite chain. The holder moves tokens from its free balance on the reference chain to one of its own wallets on a satellite, where T-REX Lite creates the corresponding balance. Ownership does not change: the same identity owns the same tokens, and the register records them as bridged to that wallet. It is how a holder takes its own position to a satellite.

At a glance

Triggered by

Investor

Actors

Investor, Identity Owner, Platform

Contracts

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

Preconditions

The asset is open on the satellite (see 33); the holder has a free balance on the reference chain (see 08); the destination wallet on the satellite is linked to the holder's ONCHAINID (see 07); the token is not paused

Result

The holder's free balance has decreased by amount, the bridged position of its wallet on the satellite has increased by amount, and T-REX Lite holds the same amount for that wallet

Actors and roles

Actor
Role in this flow
What they hold

Investor

Delegates part of its position to its own wallet on a satellite.

A free balance at one of its addresses on the reference chain. A wallet on the satellite

Identity Owner

The Investor in its capacity as controller of the identity that both addresses belong to.

An ONCHAINID to which the satellite wallet is linked

Platform

Runs the pre-checks, relays the call and tracks the delivery on the satellite.

Whatever keys the Investor has authorized

Sequence

Step by step

Step 1. Confirm the delegation can execute

Who: Platform, on behalf of the Investor

Call: Off-chain, using read calls

Before the call: The Investor has chosen the satellite, its wallet there and the amount. The Platform encodes that wallet as an ERC-7930 interoperable address in canonical form, toWallet.

What happens: The Platform reads Token.isChainOpen(chainKey), which must be true, and Token.freeBalanceOf(holder), which must cover the amount. It reads TREXRegistry.identity(holder) and TREXRegistry.resolveIdentity(toWallet), which must return the same identity. It reads Token.paused() and Token.isFrozen(holder), which must both be false.

What changes: Nothing on-chain.

Step 2. Delegate out

Who: Investor, from the address that holds the tokens

Call: [[TBC: the function a holder calls on the Token to delegate a position out to a satellite wallet]]

Before the call: Step 1 passed.

What the contract checks:

  1. The token is not paused.

  2. The holder's address is not frozen.

  3. The destination is a canonical interoperable address on another chain than the reference chain. Otherwise NonCanonicalInteroperableAddress or NotASatelliteWallet.

  4. The destination wallet belongs to the same identity as the holder's address. A delegation-out moves a position, never its ownership.

  5. The amount is within the holder's free balance. Otherwise ERC20InsufficientBalance.

  6. The satellite is open for the asset: it has a route, the routed gateway is trusted by the network at this instant, and the peer is known. Otherwise ChainNotOpen.

[[TBC: the errors of checks 1, 2 and 4, and whether eligibility and the compliance rules are evaluated for the holder at this point]]

What changes: In one transaction, the token decreases the holder's native balance by amount and emits Transfer(holder, 0x0, amount). It increases the bridged position of toWallet and the total bridged amount by amount, and emits DelegatedOut(holder, toKey, toWallet, amount). totalSupply does not change: it counts the bridged positions. The position of the identity in the compliance does not change. The token sends a mint instruction to its peer on the satellite through the routed gateway and emits ProtocolMessageSent with the message type, the chain key and the identifier the gateway returned.

The delegation is final on the reference chain at this point. The register does not wait for an answer from the satellite.

Step 3. Mint on the satellite

Who: The ERC-7786 gateway and T-REX Lite. No actor transacts

Call: Delivery of the mint instruction to T-REX Lite [[TBC: the content of the mint instruction, and the function of T-REX Lite that receives it]]

Before the call: Step 2 is confirmed on the reference chain. The messaging provider carries the message.

What happens: T-REX Lite accepts the message only if it comes through the trusted gateway and its author is the asset's token on the reference chain. It mints amount to the wallet. It sends nothing back.

What changes: On the satellite, the balance of the wallet on T-REX Lite increases by amount. On the reference chain, nothing.

Step 4. Confirm the position

Who: Platform

Call: Off-chain, using read calls

Before the call: Step 3 has been delivered.

What happens: The Platform reads Token.bridgedBalanceOf(toWallet) on the reference chain and the balance of the wallet on T-REX Lite on the satellite. Both show the delegated amount.

What changes: Nothing on-chain.

State after the flow

  • Token.balanceOf(holder) and Token.freeBalanceOf(holder) have decreased by amount.

  • Token.bridgedBalanceOf(toWallet) and Token.totalBridged() have increased by amount.

  • Token.totalSupply() is unchanged.

  • ModularCompliance.positionOf(identity) is unchanged. The identity owns the same total, part of it active on the satellite.

  • On the satellite, T-REX Lite holds amount for the wallet.

  • The delegated tokens can no longer be transferred, frozen, burned or forced on the reference chain. They move on the satellite, against validations.

Failure modes

Symptom
Cause
Fix

Reverts with ChainNotOpen

The asset has no route to that chain, the routed gateway is no longer trusted, or no peer is known (step 2, check 6)

The Issuer opens the chain: 33

Reverts with NotASatelliteWallet

The destination is an address on the reference chain (step 2, check 3)

Use a transfer on the reference chain: 10

Reverts with NonCanonicalInteroperableAddress

The destination is not a canonical ERC-7930 address (step 2, check 3)

Encode the chain and the address in canonical form

Reverts with ERC20InsufficientBalance

The amount exceeds the free balance: part of the balance is frozen, or it is not there (step 2, check 5)

Read freeBalanceOf(holder). Reduce the amount

Refused because the destination wallet is not the holder's

The wallet on the satellite is not linked to the holder's identity (step 2, check 4)

Link it first: 07. To deliver to someone else, see the first integration note

Refused because the token is paused or the address frozen

Step 2, checks 1 and 2

Wait for the Issuer's agents

The delegation is confirmed and the balance does not appear on the satellite

The mint instruction is not delivered yet

Wait for the messaging provider. The register already records the position as bridged to that wallet, and it cannot be used anywhere else in the meantime

balanceOf dropped and the holder thinks the tokens are gone

balanceOf counts the reference chain only

Show the bridged position next to the native balance

Common misunderstandings

Wrong: "Delegating out is bridging: the tokens are locked on one chain and wrapped on another."

Right: Nothing is locked in an escrow and nothing is wrapped. The register records the position as bridged to a wallet of the same owner, and T-REX Lite holds its executable representation. The position never leaves the register.

Wrong: "A delegation-out changes who owns the tokens."

Right: The destination is a wallet of the holder's own identity. The identity's position is the same before and after. Only where it can move has changed.

Wrong: "The reference chain waits for the satellite to confirm."

Right: The delegation is final on the reference chain in the transaction that makes it. The tokens leave the free balance before the satellite is told, so they cannot be used in two places. A slow delivery delays the use on the satellite. It creates no inconsistency.

Wrong: "The supply of the asset decreased, because a burn event was emitted."

Right: Transfer(holder, 0x0) makes balanceOf drop visibly. totalSupply counts native and bridged positions together and does not move. DelegatedOut is the event that says what happened.

Integration notes

  • A delegation-out is for the holder's own wallet. To deliver tokens to another holder's wallet on a satellite, the protocol has a one-step transfer from the reference chain, and an agent can mint directly to a satellite wallet. See Movement types.

  • The holder pays for the transaction and for the mint instruction it sends, directly or through a paymaster.

  • An indexer that derives the supply by summing Transfer events under-reports by the bridged total. Add DelegatedOut and subtract Recalled and SettledToNative, or read totalSupply() and totalBridged().

  • Show a holder three figures: free, frozen, and bridged per satellite wallet. IdentityFactory.getAccounts(identity, start, end) lists the wallets of an identity, and Token.bridgedBalanceOf(wallet) gives each bridged position.

  • Track the mint instruction with the identifier in ProtocolMessageSent, in the tools of the messaging provider.

  • Delegate only what is meant to be active on the satellite. The agent operations of the asset do not reach a bridged position without a recall.

  • To bring the position back, the holder recalls it: 32.

Last updated