On this page

Transfer lifecycle

An Omniassets transfer has separate source and destination states. A confirmed source transaction means the token was locked or burned and the LayerZero message was submitted. It does not yet prove destination delivery.

1. Source settlement

The source transaction is atomic:

  • an original ERC-20 is transferred into the Vault and its actual received amount is recorded; or
  • an Omniasset is burned from the sender;
  • the protocol fee is collected;
  • the LayerZero message is submitted;
  • BridgeMessageSent emits its GUID.

If this transaction reverts, no transfer started.

2. Message verification

LayerZero verifies the configured pathway and delivers the message to the destination Router. The Router accepts calls only from the local LayerZero endpoint and only for an active configured peer.

The GUID is the primary correlation key across chains.

3. Destination settlement

The destination Router executes the payload once:

  • on the original chain, the Vault unlocks the original ERC-20;
  • on another chain, the Registry deploys the Omniasset if needed and the core mints it.

A successful execution marks the GUID consumed and emits BridgeMessageReceived.

Failed destination execution

If a trusted transfer message reaches the Router but settlement reverts, the Router stores the message under its GUID and emits MessageFailed. The LayerZero channel is not blocked by that application failure.

Read the cached state through the core contract:

function failedMessages(bytes32 guid)
    external
    view
    returns (
        bool exists,
        uint32 srcEid,
        bytes32 sender,
        uint64 nonce,
        bytes message,
        bytes32 messageHash,
        bytes32 reasonHash,
        uint256 failedAt
    );

Do not submit the original transfer again. Choose one recovery path for the existing GUID.

Retry

Anyone can retry a cached destination message:

function retryFailedMessage(bytes32 guid) external;

A successful retry performs the original destination settlement, deletes the cached failure, marks the GUID consumed, and emits FailedMessageRetried.

Retry when the failure was temporary or its cause has been fixed.

Restore

Anyone can pay to return the asset to the original source sender:

function quoteRestore(bytes32 guid, bytes options) external view returns (uint256);

function restoreFailedMessage(bytes32 guid, bytes options)
    external
    payable
    returns (MessagingReceipt memory);

Quote restore options with sufficient receive gas, then pay the exact LayerZero fee. Restore consumes the failed GUID and sends a new message back to the source chain. The restored recipient is fixed to the original sender; the caller cannot redirect it.

Terminal states

For client state, use:

StateEvidence
SentSource receipt with BridgeMessageSent
DeliveredDestination BridgeMessageReceived
FailedDestination Router MessageFailed and failedMessages(guid).exists
RetriedFailedMessageRetried, followed by destination settlement
RestoringFailedMessageRestored with a new restore GUID
RestoredRestore GUID delivered on the original source chain

See Events for exact signatures and Errors for source reverts.

Introducing Omnipad-Launch tokens between chains