-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #45 from FuelLabs/src-10-native-bridge
SRC-10; Native Bridge Standard
- Loading branch information
Showing
7 changed files
with
244 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,5 +4,6 @@ members = [ | |
"src5-ownership", | ||
"src6-vault", | ||
"src7-metadata", | ||
"src10-native-bridge", | ||
"src20-token", | ||
] |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[project] | ||
authors = ["Fuel Labs <[email protected]>"] | ||
entry = "src10.sw" | ||
license = "Apache-2.0" | ||
name = "src10" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
<p align="center"> | ||
<picture> | ||
<source media="(prefers-color-scheme: dark)" srcset=".docs/src-10-logo-dark-theme.png"> | ||
<img alt="SRC-10 logo" width="400px" src=".docs/src-10-logo-light-theme.png"> | ||
</picture> | ||
</p> | ||
|
||
# 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](https://github.com/FuelLabs/fuel-bridge/blob/main/docs/ARCHITECTURE.md). 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](https://github.com/FuelLabs/fuel-bridge/blob/3971081850e7961d9b649edda4cad8a848ee248e/packages/fungible-token/bridge-fungible-token/src/interface.sw#L22) 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_token(token_address: b256, gateway_contract: b256)` | ||
|
||
The `register_token()` function compiles a message to be sent back to the canonical chain to register a token to be bridged. The `gateway_contract` contract on the canonical chain receives the `token_address` token address in the message such that when `token_addess` tokens are deposited on the canonical chain 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` contract, registering the specified `token_address` token that exists on the canonical chain. | ||
|
||
### - `fn process_message(message_index: 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 `message_index` index. | ||
- This function SHALL mint a token that follows the [SRC-8; Bridged Asset Standard](https://github.com/FuelLabs/sway-standards/tree/master/standards/src_8). | ||
- This function SHALL issue a refund if there is an error in the bridging process. | ||
|
||
### - `fn withdraw(to_address: b256, sub_id: SubId, gateway_contract: b256)` | ||
|
||
The `withdraw()` function accepts and burns a bridged Native Asset on Fuel and sends a message to the `gateway_contract` contract on the canonical chain to release the originally deposited tokens to the `to_address` address. | ||
|
||
- This function SHALL send a message to the `gateway_contract` contract to release the bridged tokens to the `to_address` address on the canonical chain. | ||
- This function MUST ensure the `sha256(contract_id(), sub_id)` digest matches the asset's `AssetId` sent in the transaction. | ||
- This function SHALL burn all tokens sent in the transaction. | ||
|
||
### - `fn claim_refund(to_address: b256, token_address: b256, token_id: b256, gateway_contract: 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` contract on the canonical chain to release the `token_address` token with token id `token_id` to the `to_address` address. | ||
|
||
- This function SHALL send a message to the `gateway_contract` contract to release the `token_address` token with id `token_id` to the `to_address` 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 to a 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: `b256` | ||
|
||
The `token_id` field MUST represent the token's ID on the canonical chain. The `ZERO_B256` MUST be used if this is a fungible token and no token ID exists. | ||
|
||
### Example | ||
|
||
```sway | ||
struct MessageData { | ||
amount: b256, | ||
from: b256, | ||
len: u16, | ||
to: Identity, | ||
token_address: b256, | ||
token_id: b256, | ||
} | ||
``` | ||
|
||
## Required Standards | ||
|
||
Any contract that implements the SRC-10; Native Bridge Standard MUST implement the [SRC-8; Bridged Asset Standard](https://github.com/FuelLabs/sway-standards/tree/master/standards/src_8) 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 | ||
|
||
```sway | ||
abi SRC10 { | ||
fn register_token(token_address: b256, gateway_contract: b256); | ||
fn process_message(message_index: u64); | ||
fn withdraw(to_address: b256, sub_id: SubId, gateway_contract: b256); | ||
fn claim_refund(to_address: b256, token_address: b256, token_id: b256, gateway_contract: b256); | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
library; | ||
|
||
/// Enscapsultes metadata sent between the canonical chain and Fuel. | ||
struct MessageData { | ||
/// The number of tokens. | ||
amount: b256, | ||
/// The user's address on the canonical chain. | ||
from: b256, | ||
/// The number of deposit messages. | ||
len: u16, | ||
/// The bridging target destination on the Fuel chain. | ||
to: Identity, | ||
/// The bridged token's address on the canonical chain. | ||
token_address: b256, | ||
/// The token's ID on the canonical chain. | ||
token_id: b256, | ||
} | ||
|
||
abi SRC10 { | ||
/// Compiles a message to be sent back to the canonical chain. | ||
/// | ||
/// # Additional Information | ||
/// | ||
/// * The `gateway` contract on the canonical chain receives the `token_address` ID in the message such that when assets are deposited they are reported to prevent loss of funds. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `token_address`: [b256] - The token's address on the canonical chain. | ||
/// * `gateway_contract`: [b256] - The contract that accepts deposits on the canonical chain. | ||
/// | ||
/// # Examples | ||
/// | ||
/// ```sway | ||
/// use src10::SRC10; | ||
/// | ||
/// fn foo(gateway_contract: b256, token_address: b256, bridge: ContractId) { | ||
/// let bridge_abi = abi(SRC10, bridge.value); | ||
/// bridge_abi.register_token(token_address, gateway_contract); | ||
/// } | ||
/// ``` | ||
#[storage(read, write)] | ||
fn register_token(token_address: b256, gateway_contract: b256); | ||
|
||
/// Accepts incoming deposit messages from the canonical chain and issues the corresponding bridged asset. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `message_index`: [u64] - The index of the message to parse. | ||
/// | ||
/// # Examples | ||
/// | ||
/// ```sway | ||
/// use src10::SRC10; | ||
/// | ||
/// fn foo(message_index: u64, bridge: ContractId) { | ||
/// let bridge_abi = abi(SRC10, bridge.value); | ||
/// bridge_abi.process_message(message_index); | ||
/// } | ||
/// ``` | ||
#[storage(read, write)] | ||
fn process_message(message_index: u64); | ||
|
||
/// Accepts and burns a bridged asset and sends a messages to the canonical chain to release the original deposited token. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `to_address`: [b256] - The address on the canonical chain to send the released tokens to. | ||
/// * `sub_id`: [SubId] - The SubId of the asset sent in the transaction. | ||
/// * `gateway_contract`: [b256] - The contract that holds the deposited tokens on the canonical chain. | ||
/// | ||
/// # Examples | ||
/// | ||
/// ```sway | ||
/// use src10::SRC10; | ||
/// | ||
/// fn foo(to_address: b256, asset_sub_id: SubId, gateway_contract: b256, bridge: ContractId, bridged_asset: AssetId) { | ||
/// let bridge_abi = abi(SRC10, bridge.value); | ||
/// bridge_abi { | ||
/// gas: 10000, | ||
/// coins: 100, | ||
/// asset_id: bridged_asset, | ||
/// }.withdraw(to_address, asset_sub_id, gateway_contract); | ||
/// } | ||
/// ``` | ||
#[storage(read, write)] | ||
fn withdraw(to_address: b256, sub_id: SubId, gateway_contract: b256); | ||
|
||
/// Returns a refund on the canonical chain if an error occurs while bridging. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `to_address`: [b256] - The address on the canonical chain to send the refunded tokens to. | ||
/// * `token_address`: [b256] - The token on the canonical chain to be refunded. | ||
/// * `token_id`: [b256] - The token id of the token on the canonical chain to be refunded. | ||
/// * `gateway_contract`: [b256] - The contract that holds the deposited tokens on the canonical chain. | ||
/// | ||
/// # Examples | ||
/// | ||
/// ```sway | ||
/// use src10::SRC10; | ||
/// | ||
/// fn foo(to_address: b256, token_address: b256, token_id: b256, gateway_contract: b256, bridge: ContractId) { | ||
/// let bridge_abi = abi(SRC10, bridge.value); | ||
/// bridge_abi.claim_refund(to_address, token_address, token_id, gateway_contract); | ||
/// } | ||
/// ``` | ||
#[storage(read, write)] | ||
fn claim_refund( | ||
to_address: b256, | ||
token_address: b256, | ||
token_id: b256, | ||
gateway_contract: b256, | ||
); | ||
} |