Skip to main content
  • ADR
  • ADR-020: Cross-Chain Transfers

Status

In Progress

Overview

Types of Blockchains

  1. Int3face Chain - Bridge blockchain that connects all other blockchains.
  2. IBC-Connected Chain - Blockchain connected to Int3face Chain via IBC protocol.
  3. Bitfrost-Connected Chain - Blockchain connected to Int3face Chain via the custom off-chain Bi[t]frost protocol. We can refer here two types of chains in sort of asset origination:
    • Native - Native for the asset; as example, Dogecoin for DOGE or Solana for SOL. Asset is presented as a native token on the chain.
    • Non-Native - Not native for the asset; as example, Solana for DOGE or Solana for TON. Asset is presented as a self-deployed smart contract on the chain.

Bridging Routes

Int3face as Bridge

RouteDescriptionExample
Bitfrost → Int3face → IBCTransfer of assets from a Bitfrost-connected chain to an IBC chain via the Int3face chain.Transfer of DOGE from Dogecoin to Osmosis.
IBC → Int3face → BitfrostTransfer of assets from an IBC-connected chain to a Bitfrost-connected chain via the Int3face chain.Transfer of DOGE from Osmosis to Dogecoin.
Bitfrost → Int3face → BitfrostTransfer of assets from a Bitfrost-connected to a Bitfrost-connected chain via the Int3face chain.Transfer of DOGE from Dogecoin to Solana.
IBC → Int3face → IBCTransfer of assets from an IBC-connected chain to an IBC-connected chain via the Int3face chain.Transfer of DOGE from Osmosis to CosmosHub.

Int3face as Target|Source

RouteDescriptionExample
IBC → Int3faceTransfer of assets from a IBC-connected chain to the Int3face chain.Transfer of DOGE from Osmosis to Int3face Chain.
Int3face → IBCTransfer of assets from the Int3face chain to an IBC-connected chain.Transfer of DOGE from Int3face Chain to Osmosis.
Bitfrost → Int3faceTransfer of assets from a Bitfrost-connected chain to the Int3face chain.Transfer of DOGE from Dogecoin to Int3face Chain.
Int3face → BitfrostTransfer of assets from the Int3face chain to a Bitfrost-connected chain.Transfer of DOGE from Int3face Chain to Solana.

Technical Outline

Int3face Bridge utilizes two protocols to facilitate cross-chain transfers:
  • IBC Protocol - Inter-Blockchain Communication protocol that allows the transfer of assets between two Cosmos-compatible chains.
  • Bi[t]frost Protocol - Custom off-chain protocol that allows the transfer of assets between Non-Cosmos-compatible Chains and Int3face Chain.

IBC Protocol

IBC Protocol is a standard protocol that allows the transfer of assets between two Cosmos-compatible chains. The protocol consists of the following messages to sent and receive packets:

MsgRecvPacket

The incoming message that is sent from any IBC-compatible chain (like Osmosis) and received by the Int3face chain. If it contains a valid memo field, the message is processed as cross-chain transfer.
type MsgRecvPacket struct {
    Packet  exported.Packet
    Proof   []byte
    ProofHeight clienttypes.Height
    Signer  string
}

type Packet struct {
	Sequence uint64
	SourcePort string
	SourceChannel string
	DestinationPort string
	DestinationChannel string
	Data []byte               // <----- FungibleTokenPacketData
	TimeoutHeight types.Height
	TimeoutTimestamp uint64
}

// Data field in Packet
type FungibleTokenPacketData struct {
	Denom string
	Amount string
	Sender string
	Receiver string
	Memo string // <----- IBCInboundMemo
}

// Memo field in FungibleTokenPacketData
type IBCInboundMemo struct {
	SourceChain     string  `json:"source-chain"`       // Source chain, for example: 'osmosis' <- if transfer is sent from Osmosis
	DestChain       string  `json:"dest-chain"`         // Destination chain, for example: 'dogecoin' <- if transfer is sent to Dogecoin
	DestAddress     string  `json:"dest-address"`       // Destination address, for example: 'D6Z26L69gdk9qYmMkVtL9bXGKp8Be7ZfL8' <- Dogecoin address
	RefundOnFailure bool    `json:"refund-on-failure"`  // Flag to indicate if the transfer should be refunded
}

MsgTransfer

The outgoing message that is sent by the Int3face chain to any IBC-compatible blockchain (like Osmosis). It contains the memo field with the information about the cross-chain transfer.
type MsgTransfer struct {
    SourcePort string
    SourceChannel string
    Token sdk.Coin
    Sender string
    Receiver string
    TimeoutHeight clienttypes.Height
    TimeoutTimestamp uint64
    Memo string // <----- IBCOutboundMemo
}

// Memo field in MsgTransfer
type IBCOutboundMemo struct {
    OutboundTxHash string `json:"outbound_tx_hash"` // TxHash of outbound transfer on Int3face Chain
    IsRefund       bool   `json:"is_refund"`        // Flag to indicate if the transfer is a refund
	IsRetry        bool   `json:"is_retry"`         // Flag to indicate if the transfer is a retry
}

IBC Middleware

We have a custom middleware to process the incoming & outgoing IBC packets. It makes two important tasks:
  • validation of incoming packets with memo field and creation of outbound transfers directly in the Int3face x/bridge module.
  • finalization of the outgoing transfers sent via IBC.
// When the inbound IBC packet is RECEIVED.
func (im IBCMiddleware) OnRecvPacket(
    ctx sdk.Context,
    packet channeltypes.Packet,
    relayer sdk.AccAddress,
) ibcexported.Acknowledgement {
    // Validate the packet data
    if err := im.validatePacketData(ctx, data); err != nil {
        return ibc.NewEmitErrorAcknowledgement(err)
    }
    
    // Process outbound transfer
    if err := im.bridgeKeeper.OutboundTransfer(ctx, data); err != nil {
        return nil, nil, err
    }

    // Pass the packet to the next middleware
    return im.next.OnRecvPacket(ctx, packet, data)
}

// When the outbound IBC packet is ACKNOWLEDGED.
func (im IBCMiddleware) OnAcknowledgementPacket(
    ctx sdk.Context,
    packet channeltypes.Packet,
    ack ibcexported.Acknowledgement,
    relayer sdk.AccAddress,
) error {
    // Parse packet memo
    memo, err := im.parsePacketMemo(packet)
    if err != nil {
        return err
    }
    
    if memo.IsRefund {
        // Refund the outbound transfer
        if err := im.bridgeKeeper.SetOutboundTransferRefunded(ctx, memo.OutboundTxHash); err != nil {
            return err
        }
    }
    
    // Finalize the outbound transfer
    if err := im.bridgeKeeper.SetOutboundTransferFinalized(ctx, memo.OutboundTxHash); err != nil {
        return err
    }

    // Pass the packet to the next middleware
    return im.next.OnAcknowledgementPacket(ctx, packet, ack, relayer)
}
Incoming IBC Execution Order:
Transfer(tokens_unlocked) -> IBCMiddleware(outbound_validated_and_sent)

Bi[t]frost Protocol

Bi[t]frost Protocol is a custom off-chain protocol that allows the transfer of assets between Non-Cosmos-compatible Chains and Int3face Chain. The protocol is fully-decentralized and relies on the TSS as well as Threshold Voting mechanism to process the cross-chain transfers.

MsgInboundTransfer

The message is actually a vote posted by the Int3face chain Observers to process the incoming transfer. When observers witness the deposit on the vault address they construct and broadcast Tx to vote to mint the tokens on the Int3face chain. When the threshold of votes is reached, the tokens are minted and the transfer is considered as finalized.
message MsgInboundTransfer {
  // ExternalId is a unique ID of the transfer coming from outside.
  // Serves the purpose of uniquely identifying the transfer in another chain
  // (e.g., this might be the BTC tx hash)
  string external_id = 1;
  // ExternalHeight is the height at which the transfer occurred in the external
  // chain
  uint64 external_height = 2;
  // Sender is a sender's address
  string sender = 3;
  // DestAddr is a destination Int3face address
  string dest_addr = 4;
  // AssetID is the ID of the asset being transferred
  AssetID asset_id = 5;
  // Amount of coins to transfer
  string amount = 6;
  // DestChainId is a destination chain of the transfer. If this id is not
  // Int3face chain, we need to perform forwarding of the tokens to the
  // destination chain.
  string dest_chain_id = 7;
  // SrcChainId is a source chain of the transfer origin.
  string src_chain_id = 8;
}

MsgInboundTransferRetry

The message can be sent by any user to retry the failed inbound transfer. The message is observed and processed by the Observers to retry the transfer. Each observer will try to find the transfer on the external chain and vote to mint the tokens on the Int3face chain sending MsgInboundTransfer again. Inbound is retriable when received via:
  • BITFROST - YES
  • IBC - NO
message MsgInboundTransferRetry {
  // ExternalId is a unique ID of the transfer coming from outside.
  // Serves the purpose of uniquely identifying the transfer in another chain
  // (e.g., this might be the BTC tx hash)
  string external_id = 1;
  // ExternalHeight is the height at which the transfer occurred in the external chain.
  uint64 external_height = 2;
}

MsgInboundTransferPushBack

The message is a vote on designated Inbound Transfer to push it back. The message is constructed and broadcasted by the Observers to Int3face chain to push back the transfer in case of invalid memo or impossibility to process the inbound.
message MsgInboundTransferPushBack {
  // ExternalId is a unique ID of the transfer coming from outside.
  required string external_id = 1;
  // ExternalHeight is the height at which the transfer occurred in the external chain.
  required uint64 external_height = 2;
}

MsgInboundTransferRefunded

The message is a vote on designated Inbound Transfer to refund it. The message is constructed and broadcasted by the Observers to Int3face chain to refund the transfer. As soon as the threshold of votes is reached, the transfer is considered as refunded.
message MsgInboundTransferRefunded {
  // ExternalId is a unique ID of the transfer coming from outside.
  required string external_id = 1;
  // ExternalHeight is the height at which the transfer occurred in the external chain.
  required uint64 external_height = 2;
}

MsgInboundTransferRefundFailed

The message is a vote on designated Inbound Transfer to mark it as refund failed. The message is constructed and broadcasted by the Observers to Int3face chain to mark the transfer as refund failed if the refund is not possible. As soon as the threshold of votes is reached, the transfer is considered as refund failed.
message MsgInboundTransferRefundFailed {
  // ExternalId is a unique ID of the transfer coming from outside.
  required string external_id = 1;
  // ExternalHeight is the height at which the transfer occurred in the external chain.
  required uint64 external_height = 2;
  // Reason is a reason of the failure.
  required string reason = 3;
}

MsgOutboundTransfer

The message can be sent by any Int3face account, and it’s not a cross-chain actually, because it’s a message to burn the tokens on the Int3face chain from the account of sender. The message is observed and processed by the Observers to construct and broadcast the transfer on the destination chain.
message MsgOutboundTransfer {
  // Sender is a sender's Int3face address
  string sender = 1;
  // DestAddr is a destination address
  string dest_addr = 2;
  // AssetID is the ID of the asset being transferred
  AssetID asset_id = 3;
  // Amount of coins to transfer
  string amount = 4;
  // DestChainId is a destination chain of the transfer.
  string dest_chain_id = 5;
}

MsgOutboundTransferRetry

The message can be sent by any user to retry the failed outbound transfer. The message is observed and processed by the Observers to retry the transfer. Each observer will try to find the transfer on the destination chain and if transfer is not found, observer will broadcast the transfer again and vote to finalize the transfer sending MsgOutboundTransferFinalized again. Outbound is retriable in case of sent via:
  • BITFROST - YES
  • IBC - YES
message MsgOutboundTransferRetry {
  // TxHash is a hash of Outbound Transfer on the Int3face chain.
  string tx_hash = 1;
}

MsgOutboundTransferFinalized

The message is a vote on designated Outbound Transfer to finalize it. The message is constructed and broadcasted by the Observers to Int3face chain to finalize the transfer once the broadcasted transfer is confirmed on the destination chain. As soon as the threshold of votes is reached, the transfer is considered as finalized.
message MsgOutboundTransferFinalized {
  // TxHash is a hash of Outbound Transfer on the Int3face chain.
  string tx_hash = 1;
  // BroadcastedTxHash is a hash of the broadcasted transaction on the destination chain.
  string broadcasted_tx_hash = 2;
}

MsgOutboundTransferFailed

The message is a vote on designated Outbound Transfer to mark it as failed. The message is constructed and broadcasted by the Observers to Int3face chain to mark the transfer as failed if the broadcasted transfer is not confirmed on the destination chain. As soon as the threshold of votes is reached, the transfer is considered as failed.
message MsgOutboundTransferFailed {
  // TxHash is a hash of Outbound Transfer on the Int3face chain.
  string tx_hash = 1;
  // Reason is a reason of the failure.
  string reason = 2;
}

Int3face Bridge State & Params

Int3face Bridge (x/bridge module) contains the two main structures stored in the state to process cross-chain transfers:

Bridge: Params

Int3face bridge module (x/bridge) has configured assets inside the module params. Query - You can query all bridge params via:
int3faced q bridge params
// Asset is a representation of the asset.
message Asset {
  // ID is the asset's primary key
  AssetID id = 1;
  // Status is a current status of the asset
  AssetStatus status = 2;
  // Exponent represents the power of 10 used for coin representation
  uint64 exponent = 3;
  // ExternalConfirmations is a number of the confirmations on the external
  // chain needed to consider the transfer confirmed
  uint64 external_confirmations = 4;
  // Minimal amount of tokens for transfer
  string min_transfer_amount = 5;
  // ExecutionPeriod defines how long transfer for the given asset required to
  // be in the execution until it can be retried.
  uint64 execution_period = 6;
  // GracePeriod defines how long after the execution period transfer for the
  // given asset can be retried.
  uint64 grace_period = 7;
  // BridgingRoutes defines the list of the chain identifiers where the asset can be transferred.
  repeated BridgingRoute bridging_routes = 8;
}

message AssetID {
  // SourceChain is a source chain name
  string source_chain = 1;
  // Denom is the SourceChain denom
  string denom = 2;
}

enum AssetStatus {
  ASSET_STATUS_UNSPECIFIED = 0;
  ASSET_STATUS_OK = 1;
  ASSET_STATUS_BLOCKED_INBOUND = 2;
  ASSET_STATUS_BLOCKED_OUTBOUND = 3;
  ASSET_STATUS_BLOCKED_BOTH = 4;
}

message BridgingRoute {
  // SourceChain is a source chain name
  string source_chain = 1;
  // DestinationChain is a destination chain name
  string destination_chain = 2;
  // RefundEnabled indicates whether the asset can be refunded back to the source chain by this route
  bool refund_enabled = 3;
}

Bridge: Inbound Transfers

Structure to store the information about the inbound transfers. It`s created after the first vote on the MsgInboundTransfer and contains the information about the votes and finalization status. Key - The key of the inbound transfer is a hash of the external transaction ID and the external chain height. Bitfrost Inbound: Key = sha256(external_id + external_height) IBC Inbound: Key = sha256(source_channel + destination_channel + sequence) Query - You can query inbound transfers via: Bitfrost Inbound:
int3faced q bridge inbound-transfer [external-id/external-height]
IBC Inbound:
int3faced q bridge inbound-transfer [source-channel/dest-channel/sequence]
All Inbound transfers:
int3faced q bridge inbound-transfers --limit 100
message InboundTransfer {
  // Status is a current status of the inbound transfer
  required InboundTransferStatus status = 1;
  // ExternalId is a unique ID of the transfer coming from outside.
  // Serves the purpose of uniquely identifying the transfer in another chain
  // (e.g., this might be the BTC tx hash).
  // Or in case of IBC transfer, it's a {source_channel}-{destination_channel}-{sequence}
  // Example: channel-8836-channel-0-234
  required string external_id = 2;
  // ExternalHeight is the height at which the transfer occurred in the external chain.
  // In case of IBC transfer, it will be zero, because IBC doesn't have the height in transfer data.
  required uint64 external_height = 3;
  // AssetID is the ID of the asset being transferred
  required AssetID asset_id = 4;
  // Amount of coins to transfer
  required string amount = 5;
  // SrcAddr is a source address to refund the tokens in case of the transfer failure.
  required string src_addr = 6;
  // SrcChainId is a source chain of the transfer origin.
  required string src_chain_id = 7;
  // DestAddr is a destination address
  required string dest_addr = 8;
  // DestChainId is a destination chain of the transfer. If this id is not
  // Int3face chain, we need to perform outbound transfer of the tokens to the destination chain.
  required string dest_chain_id = 9;
  // RefundOnFailure indicates whether the transfer can be refunded in case of failure.
  // Tokens will be refunded on the SrcChainId to the SrcAddr.
  required bool refund_on_failure = 10;
  // Voters is a list of validators signed this transfer
  required InboundTransferVotes votes = 11;
  // FinalizedTxHash is a hash of the final int3face transaction which finalized the transfer and minted the tokens.
  required string finalized_tx_hash = 12;
  // ReceivedVia is a channel that was used to receive the transfer.
  required TransferProtocol received_via = 13;
  // CreationTimestamp is a timestamp when the inbound transfer was created
  required uint64 creation_timestamp = 14;
  // LastUpdateAt is a timestamp when the inbound transfer was updated
  required uint64 last_update_timestamp = 15;
}

message AssetID {
  // SourceChain is a source chain name
  required string source_chain = 1;
  // Denom is the SourceChain denom
  required string denom = 2;
}

message InboundTransferVotes {
  // Finalized is a list of validators signed this transfer on finalization
  repeated VoteOnFinalization finalized = 1;
  // PushBack is a list of validators signed this transfer on push back (in case of invalid memo and impossibility to process inbound)
  repeated VoteOnPushBack push_back = 2;
  // Refunded is a list of validators signed this transfer on refunding
  repeated VoteOnRefund refunded = 3;
  // RefundFailed is a list of validators signed this transfer on refunding failure
  repeated VoteOnFailure refund_failed = 4;
}

message VoteOnFinalization {
  // Voter is a validator signed this transfer on finalization
  required string voter = 1;
}

message VoteOnPushBack {
  // Voter is a validator signed this transfer on push back
  required string voter = 1;
  // Reason is a reason of the push back
  required string reason = 2;
}

message VoteOnRefund {
  // Voter is a validator signed this transfer on refunding
  required string voter = 1;
  // BroadcastedTxHash is a hash of the broadcasted transaction on the source chain
  required string broadcasted_tx_hash = 2;
}

message VoteOnFailure {
  // Voter is a validator signed this transfer on refunding
  required string voter = 1;
  // Reason is a reason of the refunding
  required string reason = 2;
}

enum TransferProtocol {
  IBC = 0;
  BITFROST = 1;
}

enum InboundTransferStatus {
  PROCESSING = 0;
  FINALIZED = 1;
  REFUNDING = 2;
  REFUNDED = 3;
  REFUND_FAILED = 4;
}

Bridge: Outbound Transfers

Structure to store the information about the outbound transfers. It`s created after the first vote on the MsgOutboundTransfer and contains the information about the votes and finalization status. Key - The key of the outbound transfer is a hash of the int3face transaction where the outbound transfer was created. OutboundTransferKey = sha256(int3face-tx-hash) ⚠️ Important Note: We are relaying on only one outbound transfer per int3face transaction. If we have multiple outbound transfers in one transaction, first finalized transfer will overwrite the others. Query - You can query outbound transfers via:
int3faced q bridge outbound-transfer [int3face-tx-hash]
int3faced q bridge outbound-transfers --limit 100

message OutboundTransfer {
  // Status is a current status of the outbound transfer
  required OutboundTransferStatus status = 1;
  // SentVia is a protocol used for the transfer to sent
  required TransferProtocol sent_via = 2;
  // SrcChainId is a source chain of the transfer origin.
  required string src_chain_id = 3;
  // DestChainId is a destination chain of the transfer
  required string dest_chain_id = 4;
  // DestAddr is a destination address on the destination chain
  required string dest_addr = 5;
  // AssetId is the asset is being transferred
  required AssetID asset_id = 6;
  // Amount of coins to transfer
  required string amount = 7;
  // CreationTimestamp is a timestamp when the outbound transfer was created
  required uint64 creation_timestamp = 8;
  // ResolutionTimestamp is a timestamp when the outbound transfer was updated last time
  required uint64 last_update_timestamp = 9;
  // OutboundTransferVotes is a list of different votes collected during the outbound transfer lifecycle
  required OutboundTransferVotes votes = 10;
  // RefundOnFailure indicates whether the transfer can be refunded in case of failure
  required bool refund_on_failure = 11;
  // InboundContext is a context of the inbound transfer that was used to create the outbound transfer
  optional InboundTransferContext inbound_context = 11;
}

message AssetID {
  // SourceChain is a source chain name
  required string source_chain = 1;
  // Denom is the SourceChain denom
  required string denom = 2;
}

message InboundTransferContext {
  // ExternalId is a unique ID of the transfer coming from outside.
  // Serves the purpose of uniquely identifying the transfer in another chain
  // (e.g., this might be the BTC tx hash).
  // Or in case of IBC transfer, it's a {source_channel}-{destination_channel}-{sequence}
  // Example: channel-8836-channel-0-234
  required string external_id = 1;
  // ExternalHeight is the height at which the transfer occurred in the external chain.
  // in case of IBC transfer, it will be zero, because IBC doesn't have the height in transfer data.
  optional uint64 external_height = 2;
}

message OutboundTransferVotes {
  // Finalized is a list of validators signed this transfer on finalization
  repeated VoteOnFinalization finalized = 1;
  // Failed is a list of validators signed this transfer on failure
  repeated VoteOnFailure failed = 2;
}

message VoteOnFinalization {
  // Voter is a validator signed this transfer on finalization
  required string voter = 1;
  // BroadcastedTxHash is a hash of the broadcasted transaction on the destination chain
  required string broadcasted_tx_hash = 2;
}

message VoteOnFailure {
  // Voter is a validator signed this transfer on refunding
  required string voter = 1;
  // Reason is a reason of the refunding
  required string reason = 2;
}

enum OutboundTransferStatus {
  PROCESSING = 0;
  FINALIZED = 1;
  FAILED = 2;
  REFUNDED = 3;
}

enum TransferProtocol {
  IBC = 0;
  BITFROST = 1;
}

Bitfrost Observer: Points of reaction

Bitfrost observer constantly scans and monitors the Int3face chain blocks for the events related to transfers and reacts on the following Messages:
Message TypeTarget ActionConditionsProcessing
MsgOutboundTransferOUTBOUND_TRANSFERAlwaysCreate and broadcast the withdrawal transaction on the destination chain.
MsgInboundTransferOUTBOUND_TRANSFERInbound transfer is finalized and destination_chain is not int3face.Create and broadcast the withdrawal transaction on the destination chain.
MsgRecvPacketOUTBOUND_TRANSFERPacket is received via IBCCreate and broadcast the withdrawal transaction on the destination chain.
MsgInboundTransferPushBackREFUNDInbound transfer is refunding (enough votes to push back)Create and broadcast the withdrawal transaction on the source chain.
MsgOutboundTransferFailedREFUNDOutbound transfer is failed, route is refundable, and refund_on_failure is trueCreate and broadcast the withdrawal transaction on the source chain.
MsgInboundTransferRetryINBOUND_TRANSFERInbound transfer is not finalized or refunded, execution_period is gone, and grace period is activeCreate and broadcast the MsgInboundTransfer message again to vote on the transfer finalization.
MsgOutboundTransferRetryOUTBOUND_TRANSFEROutbound transfer is not finalized or refunded, execution_period is gone, and grace period is activeCreate and broadcast the withdrawal transaction on the destination chain.

Bridging Implementation

Bitfrost -> Int3face -> IBC

1. Inbound Transfer Processing

  • Inbound Transfer Initiation:
    • User Action:
      Deposits tokens to a UTXO Vault address or a Smart Contract address on the source chain.
    • Observers:
      Witness the deposit transaction and submit votes via the MsgInboundTransfer to mint/unlock the corresponding tokens on the Int3face chain.
    • Status Update:
      The transfer is marked as PROCESSING once the inbound transfer is created.
  • Finalization of Inbound Transfer
    • Threshold Achievement:
      Once the required number of votes is reached, the InboundTransfer status updates to FINALIZED.
    • Token Minting/Unlock:
      Tokens are minted/unlocked on the Int3face chain vault address.
Inbound Transfer Processing

2. Outbound Transfer Processing

  • Outbound Transfer Initiation:
    • Bridge Module Action:
      After the Inbound Transfer is FINALIZED, the bridge module triggers a MsgTransfer to send tokens to the IBC-connected chain. This includes a designated memo field (IBCOutboundMemo: { OutboundTxHash, IsRefund }).
    • Status Update:
      The outbound transfer is created in the x/bridge module with the status PROCESSING.
  • Finalization of Outbound Transfer
    • Acknowledgement Receipt:
      Upon receiving the IBC transfer acknowledgement, the OutboundTransfer status updates to FINALIZED.
Outbound Transfer Processing

3. PushBack and Refund Mechanisms

  • PushBack for Inbound Transfers:
    • Invalid Memo Handling:
      If an inbound transfer has an invalid memo, Observers send a MsgInboundTransferPushBack message to return the transfer to the sender.
    • Status Update:
      Once the push-back vote threshold is met, the status changes to REFUNDING.
    • Refund Process:
      • Success:
        Observers send MsgInboundTransferRefunded to mark as REFUNDED.
      • Failure:
        Observers send MsgInboundTransferRefundFailed to mark as REFUND_FAILED.
  • Refund for Outbound/Inbound Transfers:
    • Failure Handling: If an OutboundTransfer fails (due to timeout or acknowledgement failure) and is refundable with the refund_on_failure flag enabled, tokens are unlocked on the Int3face chain.
    • Status Update:
      • The Outbound transfer is marked as REFUNDED.
      • The Inbound transfer is marked as REFUNDING.
    • Refund Process:
      • Success:
        Observers send MsgInboundTransferRefunded to mark the InboundTransfer as REFUNDED.
      • Failure:
        Observers send MsgInboundTransferRefundFailed to mark the InboundTransfer as REFUND_FAILED.
PushBack and Refund Mechanisms

4. Retry Mechanisms

  • Inbound Transfer Retry:
    • Eligibility:
      Transfer finalized on external (source) chain. Transfer can be retried if not FINALIZED or REFUNDED, and the execution period has elapsed with an active grace period.
    • User Action:
      Sends MsgInboundTransferRetry.
    • Observer Action:
      Votes to mint tokens again on the Int3face chain.
    • Finalization:
      Upon reaching the vote threshold, the status updates to FINALIZED.
  • Inbound Refund Retry:
    • Eligibility:
      Applicable if the status is not FINALIZED or REFUNDED, and within the grace period.
    • User Action:
      Retries using the TxHash from MsgInboundTransferRefundFailed or MsgInboundTransferPushBack.
    • Observer Action:
      Witnesses MsgOutboundTransferRetry on the Int3face chain and initiates a refund transaction.
    • Refund Process:
      • Success:
        Marks as REFUNDED.
      • Failure:
        Marks as REFUND_FAILED.
  • Outbound Transfer Retry:
    • Eligibility:
      Transfer can be retried if not FINALIZED or REFUNDED and within the grace period.
    • User Action:
      Sends MsgOutboundTransferRetry.
    • Bridge Module Action:
      Initiates another IBC transfer.
    • Finalization:
      Upon acknowledgement, status updates to FINALIZED; otherwise, marked as FAILED.
Retry Mechanisms

IBC -> Int3face -> Bitfrost

1. Inbound Transfer Processing

  • Inbound Transfer Initiation & Finalization:
    • IBC Packet Processing:
      User sends an IBC packet with the designated memo field.
    • Int3face Node Action:
      Processes the IBC packet and creates the InboundTransfer in the x/bridge module.
    • Status Update:
      Once transfer is created, the transfer is marked as FINALIZED.
Inbound Transfer Processing

3. Outbound Transfer Processing

  • Outbound Transfer Initiation:
    • Bridge Module Action:
      Once tokens are unlocked, the bridge module creates the OutboundTransfer in the x/bridge module with the status PROCESSING.
  • Broadcast and Feedback
    • Observer Broadcasting:
      Observers witness the OutboundTransfer and then create and broadcast withdrawal transactions to send the tokens to the destination chain.
    • Feedback Collection:
      • Success:
        Observers send MsgOutboundTransferFinalized to finalize the OutboundTransfer.
      • Failure:
        Observers send MsgOutboundTransferFailed to mark the OutboundTransfer as failed.
Outbound Transfer Processing

3. PushBack and Refund Mechanism

  • PushBack for Inbound Transfers:
    • Invalid Memo Handling:
      If the receiver is the Int3face vault address and the memo is invalid, the InboundTransfer is NOT CREATED an IBC packet pushed back to the sender via IBC protocol.
  • Refund for Outbound/Inbound Transfers:
    • Failure Handling:
      If an OutboundTransfer fails (due to withdrawal tx failures) and is refundable with the refund_on_failure flag enabled, tokens are minted back to the Int3face chain.
    • Status Update:
      • The Outbound transfer is marked as REFUNDED.
      • The Inbound transfer is marked as REFUNDING.
    • Bridge Module Action:
      Initiates a refund IBC transaction.
    • Refund Process:
      • Success:
        Observers send MsgInboundTransferRefunded to mark the InboundTransfer as REFUNDED.
      • Failure:
        Observers send MsgInboundTransferRefundFailed to mark the InboundTransfer as REFUND_FAILED.
PushBack and Refund Mechanisms

4. Retry Mechanisms

  • Outbound Transfer Retry:
    • Eligibility:
      Transfer can be retried if not FINALIZED or REFUNDED and within the grace period.
    • User Action:
      Sends MsgOutboundTransferRetry using the TxHash from MsgRecvPacket.
    • Bridge Module Action:
      Initiates another Outbound Transfer.
    • Observer Action:
      Witnesses the retry and initiates a refund transaction if the route is refundable.
    • Finalization: Upon acknowledgement, status updates to FINALIZED; otherwise, marked as FAILED.
  • Inbound Refund Retry:
    • Eligibility:
      Applicable if the status is not FINALIZED or REFUNDED, and within the grace period.
    • User Action:
      Sends MsgOutboundTransferRetry using the TxHash from final MsgOutboundTransferFailed.
    • Bridge Module Action:
      Initiates new IBC refund transaction.
    • Refund Process:
      • Success:
        Marks as REFUNDED when the refund is IBC packet acknowledged.
      • Failure:
        Marks as REFUND_FAILED if IBC packet acknowledgment fails or times out.
Retry Mechanisms

Bitfrost -> Int3face -> Bitfrost

1. Inbound Transfer Processing

  • Inbound Transfer Initiation:
    • User Action:
      Deposits tokens to a Vault address or a Smart Contract address on the Bitfrost chain.
    • Observers:
      Witness the deposit transaction and submit votes via the MsgInboundTransfer to mint/unlock the corresponding tokens on the Int3face chain.
    • Status Update:
      The transfer is marked as PROCESSING once the inbound transfer is created.
  • Finalization of Inbound Transfer:
    • Threshold Achievement:
      Once the required number of votes is reached, the InboundTransfer status updates to FINALIZED.
    • Token Unlocking:
      Tokens are minted/unlocked on the Int3face chain vault address.

2. Outbound Transfer Processing

  • Outbound Transfer Initiation:
    • Bridge Module Action:
      Once tokens are minted/unlocked, the bridge module creates the OutboundTransfer in the x/bridge module with the status PROCESSING.
  • Broadcast and Feedback
    • Observer Broadcasting:
      Observers witness the OutboundTransfer and then create and broadcast withdrawal transactions to send the tokens to the destination chain.
    • Feedback Collection:
      • Success:
        Observers send MsgOutboundTransferFinalized to finalize the OutboundTransfer.
      • Failure:
        Observers send MsgOutboundTransferFailed to mark the OutboundTransfer as failed.

3. PushBack and Refund Mechanisms

  • PushBack for Inbound Transfers:
    • Invalid Memo Handling:
      If an inbound transfer has an invalid memo, Observers send a MsgInboundTransferPushBack message to return the transfer to the sender.
    • Status Update:
      Once the push-back vote threshold is met, the status changes to REFUNDING.
    • Refund Process:
      • Success:
        Observers send MsgInboundTransferRefunded to mark as REFUNDED.
      • Failure:
        Observers send MsgInboundTransferRefundFailed to mark as REFUND_FAILED.
  • Refund for Outbound/Inbound Transfers:
    • Failure Handling:
      If an OutboundTransfer fails (due to timeout or acknowledgement failure) and is refundable with the refund_on_failure flag enabled, tokens are unlocked on the Int3face chain.
    • Status Update:
      • The Outbound transfer is marked as REFUNDED.
      • The Inbound transfer is marked as REFUNDING.
    • Refund Process:
      • Success:
        Observers send MsgInboundTransferRefunded to mark the InboundTransfer as REFUNDED.
      • Failure:
        Observers send MsgInboundTransferRefundFailed to mark the InboundTransfer as REFUND_FAILED.

4. Retry Mechanisms

  • Inbound Transfer Retry:
    • Eligibility:
      Transfer can be retried if not FINALIZED or REFUNDED, and the execution period has elapsed with an active grace period.
    • User Action:
      Sends MsgInboundTransferRetry.
    • Observer Action:
      Votes to mint/unlock tokens again on the Int3face chain.
    • Finalization:
      Upon reaching the vote threshold, the status updates to FINALIZED.
  • Inbound Refund Retry:
    • Eligibility:
      Applicable if the status is not FINALIZED or REFUNDED, and the execution period has elapsed with an active grace period.
    • User Action:
      Retries using the TxHash from MsgInboundTransferRefundFailed or MsgInboundTransferPushBack.
    • Observer Action:
      Witnesses MsgOutboundTransferRetry on the Int3face chain and initiates a refund transaction to the source chain.
    • Refund Process:
      • Success:
        Marks as REFUNDED.
      • Failure:
        Marks as REFUND_FAILED.
  • Outbound Transfer Retry:
    • Eligibility:
      Transfer can be retried if not FINALIZED or REFUNDED and the execution period has elapsed with an active grace period.
    • User Action:
      Sends MsgOutboundTransferRetry.
    • Observer Action:
      Witnesses MsgOutboundTransferRetry on the Int3face chain and initiates a retry transaction to the destination chain.
    • Retry Process:
      • Success:
        Marks as FINALIZED.
      • Failure:
        Marks as FAILED.

IBC -> Int3face -> IBC

1. Inbound Transfer Processing

  • Inbound Transfer Initiation:
    • User Action:
      Initiates a transfer by sending an IBC packet with the designated memo field (IBCInboundMemo: { SourceChain, DestChain, DestAddress, RefundOnFailure }) from the IBC-connected source chain.
    • Int3face Node Action:
      Processes the incoming IBC packet and creates an InboundTransfer entry in the x/bridge module on the Int3face chain.
    • Status Update:
      The transfer is marked as PROCESSING once the InboundTransfer is created.
  • Finalization of Inbound Transfer:
    • Threshold Achievement:
      Observers submit votes via the MsgInboundTransfer. Once the required number of votes is reached, the InboundTransfer status updates to FINALIZED.
    • Token Unlocking:
      Tokens are unlocked on the Int3face chain vault address, making them available to the user.

2. Outbound Transfer Processing

  • Outbound Transfer Initiation:
    • Bridge Module Action:
      After the Inbound Transfer is FINALIZED, the bridge module triggers a MsgTransfer to send tokens back to the IBC-connected destination chain. This includes a designated memo field (IBCOutboundMemo: { OutboundTxHash, IsRefund }).
    • Status Update:
      The outbound transfer is created in the x/bridge module with the status PROCESSING.
  • Finalization of Outbound Transfer:
    • Acknowledgement Receipt:
      Upon receiving the IBC transfer acknowledgement from the destination chain, the OutboundTransfer status updates to FINALIZED.

3. PushBack and Refund Mechanisms

  • PushBack for Inbound Transfers:
    • Invalid Memo Handling:
      If the receiver is the Int3face vault address and the memo is invalid, the InboundTransfer is NOT CREATED an IBC packet pushed back to the sender via IBC protocol.
  • Refund for Outbound/Inbound Transfers:
    • Failure Handling:
      If an OutboundTransfer fails (due to timeout or acknowledgement failure) and is refundable with the refund_on_failure flag enabled, tokens are unlocked on the Int3face chain.
    • Status Update:
      • The OutboundTransfer is marked as REFUNDED.
      • The InboundTransfer is marked as REFUNDING.
    • Refund Process:
      • Success:
        Observers send MsgInboundTransferRefunded to mark the InboundTransfer as REFUNDED.
      • Failure:
        Observers send MsgInboundTransferRefundFailed to mark the InboundTransfer as REFUND_FAILED.

4. Retry Mechanisms

  • Inbound Transfer Retry:
    • Eligibility:
      Transfer can be retried if it is not FINALIZED or REFUNDED, and the execution period has elapsed with an active grace period.
    • User Action:
      Sends MsgInboundTransferRetry.
    • Observer Action:
      Votes to unlock tokens again on the Int3face chain.
    • Finalization:
      Upon reaching the vote threshold, the status updates to FINALIZED.
  • Inbound Refund Retry:
    • Eligibility:
      Applicable if the status is not FINALIZED or REFUNDED, and within the grace period.
    • User Action:
      Retries using the TxHash from MsgInboundTransferRefundFailed or MsgInboundTransferPushBack.
    • Observer Action:
      Witnesses MsgOutboundTransferRetry on the Int3face chain and initiates a refund transaction to the source chain.
    • Refund Process:
      • Success:
        Marks as REFUNDED.
      • Failure:
        Marks as REFUND_FAILED.
  • Outbound Transfer Retry:
    • Eligibility:
      Transfer can be retried if it is not FINALIZED or REFUNDED, and the execution period has elapsed with an active grace period.
    • User Action:
      Sends MsgOutboundTransferRetry.
    • Bridge Module Action:
      Initiates another IBC transfer to the destination chain.
    • Finalization:
      Upon acknowledgement, status updates to FINALIZED; otherwise, marked as FAILED.