Authorization before execution
The principle that keeps satellites honest is that they never decide compliance. A satellite executes a transfer only against an authorization that the reference chain has already issued for that exact transfer. Compliance is a precondition, established where the complete distribution of the asset is known. It is not a reconciliation performed afterward.
The authorization is an object called a compliance validation. This page describes what it contains, how it is requested, how its amount is decided and what issuing it writes on the register.
Three steps
Authorize. The transfer is requested on the reference chain. The compliance evaluates it against the global state of the asset and, if it passes, issues a validation for exactly this transfer.
Execute. The validation travels to the satellite. T-REX Lite executes the transfer against it and consumes it.
Settle. T-REX Lite notifies the reference chain, which records the change of ownership.
A transfer that would breach the rules of the asset never executes anywhere. It is refused at step 1.
The validation
validationId
A number, unique for the asset and increasing by one. It identifies the validation on both sides and is used once.
from
The sender's wallet, on a satellite, as an interoperable address.
to
The recipient's address, as an interoperable address: on the same satellite, on another satellite, or on the reference chain.
spender
The party allowed to execute the transfer for the sender. Empty means the sender alone.
amountMin, amountMax
The inclusive range in which the executed amount must fall.
token
The address of the asset on the reference chain.
expiry
The time before which the satellite must execute.
reconciliationWindow
How long the reference chain keeps the reservation after the expiry, waiting for the settlement.
The compliance keeps a record of every validation it has issued, permanently. Any settlement that arrives, at any time, can be classified against what was issued.
Requesting a validation
ModularCompliance.requestTransferValidation(from, to, requestedMin, requestedMax, spender) returns the identifier of the validation it issues.
The compliance answers five questions, in order.
Where is this going?
Both addresses are well-formed. The sender is on a satellite chain.
NonCanonicalInteroperableAddress, SenderNotOnSatellite
May the caller ask?
The sending wallet resolves to an identity. The caller is that identity, or holds the AGENT role.
UnverifiedWallet, NotAuthorizedForWallet
By when?
The validity window is set. Each satellite involved has a reconciliation window and is not paused for issuance.
ValidityWindowNotSet, ReconciliationWindowNotSet, ValidationIssuancePaused
How much?
The recipient is eligible. The range is narrowed to what the wallet can send and to what the rules allow. Something is left of it.
UnverifiedWallet, EmptyValidationRange, ZeroValue
Who executes?
If a spender is named, every SPENDER module accepts it.
ValidationSpenderRefused
When the validation is sent, the token requires every satellite involved to be open for the asset. Otherwise the whole request reverts with ChainNotOpen and nothing is recorded.
Who asks
A wallet on a satellite does not request a validation for itself. Its identity does, on the reference chain, because the identity is where authority over the holder's positions lives. An agent holding the AGENT role can also request a validation on behalf of a holder.
The sender is on a satellite
A validation always moves tokens out of a satellite wallet. The reason is structural: the T-REX Lite that executes a validation has to hold the position it moves. A balance on the reference chain stays free to leave between the issuance and the settlement, so nothing would guarantee that it is still there.
Tokens on the reference chain reach a satellite by movements that start on the reference chain, not through a validation: a delegation-out for one's own position, a direct transfer or a direct mint to someone else's wallet on a satellite. See Movement types.
The recipient
On the same satellite as the sender
That satellite
One notification
On another satellite
Both satellites. The sending one consumes it.
Two notifications, one from each
On the reference chain
The sender's satellite
One notification. The recipient is credited on the reference chain.
A range, not an amount
The caller proposes a range, typically an amount and a tolerance around it. A transfer that settles a trade on a venue does not always execute for the amount first intended, and a fixed amount would fail whenever it differs by one unit.
The compliance narrows the range. It never widens it.
What the wallet can send. The maximum is capped at the wallet's bridged position less what earlier validations already reserve from it. A wallet cannot obtain validations for more than it holds.
What the rules allow. Each
RULEmodule answers the largest amount it allows. The maximum is capped at the smallest answer.What is left. If the minimum the caller asked for is above the narrowed maximum, no validation is issued.
Because the satellite may execute any amount inside the range, the register treats the maximum as the amount that moves, for every rule, until the transfer settles.
Between two wallets of one identity
When the sender and the recipient belong to the same identity, the movement changes no position. The rules about distribution are not asked and nothing is reserved against the identity. The wallet's own limit and the spender policy still apply: who executes is not a question about distribution.
What issuing writes
Issuing a validation changes the state of the register, before anything has happened on the satellite.
The record of the validation
ModularCompliance
Its terms, its deadlines and its status, Pending. Kept permanently.
The pending amounts
ModularCompliance
The maximum is added to what is promised out of the sender's identity and to what is promised to the recipient's identity. Rules count it from now on.
The reservation on the wallet
Token
The maximum is reserved against the sending wallet's bridged position. It cannot be promised to another validation.
The route
Token
The gateway each message went out through is recorded for this validation. Its settlement is accepted from that gateway only.
The event TransferValidationIssued carries the identifier, both addresses, the spender, the final range, the expiry and the reconciliation window.
The reservation is what makes concurrent requests safe. Two validations competing for the last room under a cap cannot both be issued: the first one takes the room when it is issued, and the second one finds none. What happens to the reservation afterward is described in The dual-state lifecycle.
The settings
Validity window
setDefaultValidityWindow(duration)
The asset
No validation can be issued.
Reconciliation window
setReconciliationWindow(chainKey, duration)
One satellite
No validation can be issued for that chain.
Issuance pause
setIssuancePaused(chainKey, paused)
One satellite
Not paused.
All three require the COMPLIANCE_MANAGER role. The expiry of a validation is the time of issuance plus the validity window. The reconciliation window is fixed for a validation when it is issued, so a later change never moves a deadline that is already running. A transfer between two satellites takes the larger of the two chains' windows.
Why a satellite cannot cheat the register
It cannot transfer without a validation. T-REX Lite executes a transfer only against a stored validation, and mints only on an instruction from the reference chain or on a proof of burn from a peer.
It cannot reuse a validation. A validation is consumed by its execution, and the register accepts one settlement per validation and per chain.
It cannot exceed the validation. A settlement for an amount outside the issued range is refused.
It cannot substitute the parties. A settlement must name the wallets and come from the chain and the gateway that were recorded at issuance.
It cannot invent tokens that then circulate. A wallet obtains a validation only up to the position the register records for it.
Last updated