SRC-10; Native Bridge Standard
bitzoic opened this issue · 3 comments
Abstract
The following standard allows for the implementation of a standard API for Native Bridges using the Sway Language. The standardized design has the bridge contract send a message to the origin chain to register which token it accepts to prevent a loss of funds.
Motivation
A standard interface for bridges intends to provide a safe and efficient bridge between the settlement or canonical chain and the Fuel Network.
Prior Art
The standard is centered on Fuel’s Bridge Architecture. Fuel's bridge system is built on a message protocol that allows to send (and receive) messages between entities located in two different blockchains
The following standard takes reference from the FungibleBridge ABI defined in the fuel-bridge repository.
Specification
The following functions MUST be implemented to follow the SRC-10; Native Bridge Standard:
Required Functions
- fn register_bridge(token: b256, gateway: b256)
The register_bridge()
function compiles a message to be sent back to the canonical chain. The gateway
contract on the canonical chain receives the token
ID in the message such that when assets are deposited they are reported to prevent loss of funds.
NOTE:* Trying to deposit tokens to a contract ID that does not exist or does not implement the Fuel Messaging Portal would mean permanent loss of funds.
- This function MUST send a message on the canonical chain to the
gateway
contract, registering the specifiedtoken
.
- fn process_message(msg_idx: u64)
The process_message()
function accepts incoming deposit messages from the canonical chain and issues the corresponding bridged asset.
- This function MUST parse a message at the given
msg_idx
index. - This function SHALL mint a token that follows the SRC-8; Bridged Asset Standard.
- This function SHALL issue a refund if there is an error in the bridging process.
- fn withdraw(to: b256, sub_id: b256, gateway: b256)
The withdraw()
function accepts and burns a bridged asset and sends a message to the gateway
contract on the canonical chain to release the original deposited token to the to
address.
- This function SHALL send a message to the
gateway
contract to release the bridged tokens to theto
address on the canonical chain. - This function MUST ensure the
sha256(contract_id(), sub_id)
matches the asset'sAssetId
sent in the transaction. - This function SHALL burn all tokens sent in the transaction.
- fn claim_refund(to: b256, token: b256, token_id: b256, gateway: b256)
The claim_refund()
function is called if something goes wrong in the bridging process and an error occurs. It sends a message to the gateway
contract on the canonical chain to release the token
token with token id token_id
to the to
address.
- This function SHALL send a message to the
gateway
contract to release thetoken
token with idtoken_id
to theto
address on the canonical chain. - This function MUST ensure a refund was issued.
Required Data Types
MessageData
The following describes a struct that encapsulates various message metadata single type. - There MUST be the following fields in the MessageData
struct:
- amount: u256
The amount
field MUST represent the number of tokens.
- from: b256
The from
field MUST represent the bridging user’s address on the canonical chain.
- len: u16
The len
field MUST represent the number of the deposit messages to discern between deposits that must be forwarded to an EOA vs deposits that must be forwarded to a contract.
- to: Identity
The to
field MUST represent the bridging target destination Address
or ContractId
on the Fuel Chain.
- token_address: b256
The token_address
field MUST represent the bridged token's address on the canonical chain.
- token_id: Option<b256>
The token_id
field MUST represent the token's ID on the canonical chain. MUST be None
if this is a fungible token and no token ID exists
Example
struct MessageData {
amount: b256,
from: b256,
len: u16,
to: Identity,
token_address: b256,
token_id: Option<b256>,
}
Required Standards
Any contract that implements the SRC-10; Native Bridge Standard MUST implement the SRC-8; Bridged Asset Standard for all bridged assets.
Rationale
The SRC-10; Native Bridge Standard is designed to standardize the native bridge interface between all Fuel instances.
Backwards Compatibility
This standard is compatible with the SRC-20 and SRC-8 standards.
Example ABI
abi SRC10 {
fn register_bridge(token: b256, gateway: b256);
fn process_message(msg_idx: u64);
fn withdraw(to: b256, sub_id: b256, gateway: b256);
fn claim_refund(to: b256, token_address: b256, token_id: b256, gateway: b256);
}
lgtm, though chain_id
is making some noise for me (not only here, but in other SRCs), because so far we can only anchor to a canonical chain, and we do not get info about the chain id when we parse the input message. The standard is ahead of the spec, so to speak - I have the feeling I have discussed this somewhere else, but I think it 's good to have it present here too.
Just for reference this is the related current implementation:
// FuelMessagePortal.sol
emit MessageSent(sender, recipient, nonce, uint64(amount), data);
And the format in the spec: https://github.com/FuelLabs/fuel-specs/blob/master/src/tx-format/input.md#inputmessage
Can you expand a bit on register_bridge
, what does it do and what's the purpose?
Can you expand a bit on
register_bridge
, what does it do and what's the purpose?
It is a function that compiles a message to be sent back to the L1 counterpart of the bridge. The L1 contract receives the contract ID and the supported token address in this message, so that when assets are deposited, the target contract ID has self reported its ability to hold them. It is a protection mechanism to prevent loss of funds. Trying to deposit tokens to a contract ID that does not exist or does not implement the MessageReceiver
trait would mean permanent loss of funds.