Skip to content

Commit 68fd4f5

Browse files
authored
Merge pull request #45 from FuelLabs/src-10-native-bridge
SRC-10; Native Bridge Standard
2 parents 96a223c + b16db31 commit 68fd4f5

File tree

7 files changed

+244
-1
lines changed

7 files changed

+244
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ If you don't find what you're looking for, feel free to create an issue and prop
4848
### Bridge
4949

5050
- [SRC-8; Bridged Asset](./standards/src8-bridged-asset/) defines the metadata required for an asset bridged to the Fuel Network.
51+
- [SRC-10; Native Bridge Standard](./standards/src10-native-bridge/) defines the standard API for the Native Bridge between the Fuel Chain and the canonical base chain.
5152

5253
### Documentation
5354

5455
- [SRC-2; Inline Documentation](./standards/src2-inline-docs/) defines how to document your Sway files.
5556

56-
5757
## Using a standard
5858

5959
To import a standard the following should be added to the project's `Forc.toml` file under `[dependencies]` with the most recent release:

standards/Forc.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ members = [
44
"src5-ownership",
55
"src6-vault",
66
"src7-metadata",
7+
"src10-native-bridge",
78
"src20-token",
89
]
20.4 KB
Loading
23.3 KB
Loading
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[project]
2+
authors = ["Fuel Labs <[email protected]>"]
3+
entry = "src10.sw"
4+
license = "Apache-2.0"
5+
name = "src10"
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<p align="center">
2+
<picture>
3+
<source media="(prefers-color-scheme: dark)" srcset=".docs/src-10-logo-dark-theme.png">
4+
<img alt="SRC-10 logo" width="400px" src=".docs/src-10-logo-light-theme.png">
5+
</picture>
6+
</p>
7+
8+
# Abstract
9+
10+
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.
11+
12+
# Motivation
13+
14+
A standard interface for bridges intends to provide a safe and efficient bridge between the settlement or canonical chain and the Fuel Network.
15+
16+
# Prior Art
17+
18+
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.
19+
20+
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.
21+
22+
# Specification
23+
24+
The following functions MUST be implemented to follow the SRC-10; Native Bridge Standard:
25+
26+
## Required Functions
27+
28+
### - `fn register_token(token_address: b256, gateway_contract: b256)`
29+
30+
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.
31+
32+
> **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.
33+
34+
- 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.
35+
36+
### - `fn process_message(message_index: u64)`
37+
38+
The `process_message()` function accepts incoming deposit messages from the canonical chain and issues the corresponding bridged asset.
39+
40+
- This function MUST parse a message at the given `message_index` index.
41+
- 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).
42+
- This function SHALL issue a refund if there is an error in the bridging process.
43+
44+
### - `fn withdraw(to_address: b256, sub_id: SubId, gateway_contract: b256)`
45+
46+
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.
47+
48+
- 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.
49+
- This function MUST ensure the `sha256(contract_id(), sub_id)` digest matches the asset's `AssetId` sent in the transaction.
50+
- This function SHALL burn all tokens sent in the transaction.
51+
52+
### - `fn claim_refund(to_address: b256, token_address: b256, token_id: b256, gateway_contract: b256)`
53+
54+
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.
55+
56+
- 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.
57+
- This function MUST ensure a refund was issued.
58+
59+
## Required Data Types
60+
61+
### `MessageData`
62+
63+
The following describes a struct that encapsulates various message metadata to a single type. There MUST be the following fields in the `MessageData` struct:
64+
65+
#### - amount: `u256`
66+
67+
The `amount` field MUST represent the number of tokens.
68+
69+
#### - from: `b256`
70+
71+
The `from` field MUST represent the bridging user’s address on the canonical chain.
72+
73+
#### - len: `u16`
74+
75+
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.
76+
77+
#### - to: `Identity`
78+
79+
The `to` field MUST represent the bridging target destination `Address` or `ContractId` on the Fuel Chain.
80+
81+
#### - token_address: `b256`
82+
83+
The `token_address` field MUST represent the bridged token's address on the canonical chain.
84+
85+
#### - token_id: `b256`
86+
87+
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.
88+
89+
### Example
90+
91+
```sway
92+
struct MessageData {
93+
amount: b256,
94+
from: b256,
95+
len: u16,
96+
to: Identity,
97+
token_address: b256,
98+
token_id: b256,
99+
}
100+
```
101+
102+
## Required Standards
103+
104+
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.
105+
106+
# Rationale
107+
108+
The SRC-10; Native Bridge Standard is designed to standardize the native bridge interface between all Fuel instances.
109+
110+
# Backwards Compatibility
111+
112+
This standard is compatible with the SRC-20 and SRC-8 standards.
113+
114+
# Example ABI
115+
116+
```sway
117+
abi SRC10 {
118+
fn register_token(token_address: b256, gateway_contract: b256);
119+
fn process_message(message_index: u64);
120+
fn withdraw(to_address: b256, sub_id: SubId, gateway_contract: b256);
121+
fn claim_refund(to_address: b256, token_address: b256, token_id: b256, gateway_contract: b256);
122+
}
123+
```
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
library;
2+
3+
/// Enscapsultes metadata sent between the canonical chain and Fuel.
4+
struct MessageData {
5+
/// The number of tokens.
6+
amount: b256,
7+
/// The user's address on the canonical chain.
8+
from: b256,
9+
/// The number of deposit messages.
10+
len: u16,
11+
/// The bridging target destination on the Fuel chain.
12+
to: Identity,
13+
/// The bridged token's address on the canonical chain.
14+
token_address: b256,
15+
/// The token's ID on the canonical chain.
16+
token_id: b256,
17+
}
18+
19+
abi SRC10 {
20+
/// Compiles a message to be sent back to the canonical chain.
21+
///
22+
/// # Additional Information
23+
///
24+
/// * 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.
25+
///
26+
/// # Arguments
27+
///
28+
/// * `token_address`: [b256] - The token's address on the canonical chain.
29+
/// * `gateway_contract`: [b256] - The contract that accepts deposits on the canonical chain.
30+
///
31+
/// # Examples
32+
///
33+
/// ```sway
34+
/// use src10::SRC10;
35+
///
36+
/// fn foo(gateway_contract: b256, token_address: b256, bridge: ContractId) {
37+
/// let bridge_abi = abi(SRC10, bridge.value);
38+
/// bridge_abi.register_token(token_address, gateway_contract);
39+
/// }
40+
/// ```
41+
#[storage(read, write)]
42+
fn register_token(token_address: b256, gateway_contract: b256);
43+
44+
/// Accepts incoming deposit messages from the canonical chain and issues the corresponding bridged asset.
45+
///
46+
/// # Arguments
47+
///
48+
/// * `message_index`: [u64] - The index of the message to parse.
49+
///
50+
/// # Examples
51+
///
52+
/// ```sway
53+
/// use src10::SRC10;
54+
///
55+
/// fn foo(message_index: u64, bridge: ContractId) {
56+
/// let bridge_abi = abi(SRC10, bridge.value);
57+
/// bridge_abi.process_message(message_index);
58+
/// }
59+
/// ```
60+
#[storage(read, write)]
61+
fn process_message(message_index: u64);
62+
63+
/// Accepts and burns a bridged asset and sends a messages to the canonical chain to release the original deposited token.
64+
///
65+
/// # Arguments
66+
///
67+
/// * `to_address`: [b256] - The address on the canonical chain to send the released tokens to.
68+
/// * `sub_id`: [SubId] - The SubId of the asset sent in the transaction.
69+
/// * `gateway_contract`: [b256] - The contract that holds the deposited tokens on the canonical chain.
70+
///
71+
/// # Examples
72+
///
73+
/// ```sway
74+
/// use src10::SRC10;
75+
///
76+
/// fn foo(to_address: b256, asset_sub_id: SubId, gateway_contract: b256, bridge: ContractId, bridged_asset: AssetId) {
77+
/// let bridge_abi = abi(SRC10, bridge.value);
78+
/// bridge_abi {
79+
/// gas: 10000,
80+
/// coins: 100,
81+
/// asset_id: bridged_asset,
82+
/// }.withdraw(to_address, asset_sub_id, gateway_contract);
83+
/// }
84+
/// ```
85+
#[storage(read, write)]
86+
fn withdraw(to_address: b256, sub_id: SubId, gateway_contract: b256);
87+
88+
/// Returns a refund on the canonical chain if an error occurs while bridging.
89+
///
90+
/// # Arguments
91+
///
92+
/// * `to_address`: [b256] - The address on the canonical chain to send the refunded tokens to.
93+
/// * `token_address`: [b256] - The token on the canonical chain to be refunded.
94+
/// * `token_id`: [b256] - The token id of the token on the canonical chain to be refunded.
95+
/// * `gateway_contract`: [b256] - The contract that holds the deposited tokens on the canonical chain.
96+
///
97+
/// # Examples
98+
///
99+
/// ```sway
100+
/// use src10::SRC10;
101+
///
102+
/// fn foo(to_address: b256, token_address: b256, token_id: b256, gateway_contract: b256, bridge: ContractId) {
103+
/// let bridge_abi = abi(SRC10, bridge.value);
104+
/// bridge_abi.claim_refund(to_address, token_address, token_id, gateway_contract);
105+
/// }
106+
/// ```
107+
#[storage(read, write)]
108+
fn claim_refund(
109+
to_address: b256,
110+
token_address: b256,
111+
token_id: b256,
112+
gateway_contract: b256,
113+
);
114+
}

0 commit comments

Comments
 (0)