Skip to content

Commit

Permalink
Update SRC-10 with new canonical Fuel bridge design (#84)
Browse files Browse the repository at this point in the history
* Udpate SRC-10 for new bridge design

* Add missing import
  • Loading branch information
bitzoic authored May 1, 2024
1 parent 6f63eb7 commit a001d3c
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 58 deletions.
107 changes: 80 additions & 27 deletions SRCs/src-10.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,6 @@ The following functions MUST be implemented to follow the SRC-10; Native Bridge

## 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.
Expand All @@ -41,12 +33,12 @@ The `process_message()` function accepts incoming deposit messages from the cano
- This function SHALL mint an asset that follows the [SRC-8; Bridged Asset Standard](./src-8.md).
- 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)`
### - `fn withdraw(to_address: 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.
The `withdraw()` function accepts and burns a bridged Native Asset on Fuel and sends a message to the bridge 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 send a message to the bridge contract to release the bridged tokens to the `to_address` address on the canonical chain.
- This function MUST ensure the asset's `AssetId` sent in the transaction matches a bridged asset.
- This function SHALL burn all coins sent in the transaction.

### - `fn claim_refund(to_address: b256, token_address: b256, token_id: b256, gateway_contract: b256)`
Expand All @@ -58,9 +50,35 @@ The `claim_refund()` function is called if something goes wrong in the bridging

## Required Data Types

### `MessageData`
### `DepositType`

The `DepositType` enum decribes whether the bridged deposit is made to a address, contract, or contract and contains additional metatdata. There MUST be the following varients in the `DepositType` enum:

#### Address: `()`

The `Address` varient MUST represent when the deposit is made to an address on the Fuel chain.

#### Contract: `()`

The `Contract` varient MUST represent when the deposit is made to an contract on the Fuel chain.

#### ContractWithData: `()`

The following describes a struct that encapsulates various message metadata to a single type. There MUST be the following fields in the `MessageData` struct:
The `ContractWithData` varient MUST represent when the deposit is made to an contract and contains additional metadata for the Fuel chain.

#### Example

```sway
pub enum DepositType {
Address: (),
Contract: (),
ContractWithData: (),
}
```

### `DepositMessage`

The following describes a struct that encapsulates various deposit message metadata to a single type. There MUST be the following fields in the `DepositMessage` struct:

#### - amount: `u256`

Expand All @@ -70,10 +88,6 @@ The `amount` field MUST represent the number of tokens.

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.
Expand All @@ -86,16 +100,56 @@ The `token_address` field MUST represent the bridged token's address on the cano

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.

#### - decimals: `u8`

The `decimals` field MUST represent the bridged token's decimals on the canonical chain.

#### - deposit_type: `DepositType`

The `deposit_type` field MUST represent the type of bridge deposit made on the canonical chain.

#### Example

```sway
pub struct DepositMessage {
pub amount: b256,
pub from: b256,
pub to: Identity,
pub token_address: b256,
pub token_id: b256,
pub decimals: u8,
pub deposit_type: DepositType,
}
```

### `MetadataMessage`

The following describes a struct that encapsulates the metadata of token on the canonical chain to a single type. There MUST be the following fields in the `MetadataMessage` struct:

#### 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.

#### name: `String`

The `name` field MUST represent the bridged token's name field on the canonical chain.

#### symbol: `String`

The `symbol` field MUST represent the bridged token's symbol field on the canonical chain.

### Example

```sway
struct MessageData {
amount: b256,
from: b256,
len: u16,
to: Identity,
token_address: b256,
token_id: b256,
pub struct MetadataMessage {
pub token_address: b256,
pub token_id: b256,
pub name: String,
pub symbol: String,
}
```

Expand All @@ -115,9 +169,8 @@ This standard is compatible with the SRC-20 and SRC-8 standards.

```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 withdraw(to_address: b256);
fn claim_refund(to_address: b256, token_address: b256, token_id: b256, gateway_contract: b256);
}
```
63 changes: 32 additions & 31 deletions standards/src/src10.sw
Original file line number Diff line number Diff line change
@@ -1,46 +1,47 @@
library;

/// Enscapsultes metadata sent between the canonical chain and Fuel.
struct MessageData {
use std::string::String;

/// Specifies the type of deposit made.
pub enum DepositType {
/// The deposit was made to an Address.
Address: (),
/// The deposit was made to a Contract.
Contract: (),
/// The deposit was made to a Contract and contains additioanl data for the Fuel chain.
ContractWithData: (),
}

/// Enscapsultes metadata sent between the canonical chain and Fuel when a deposit is made.
struct DepositMessage {
/// The number of tokens.
pub amount: b256,
/// The user's address on the canonical chain.
pub from: b256,
/// The number of deposit messages.
pub len: u16,
/// The bridging target destination on the Fuel chain.
pub to: Identity,
/// The bridged token's address on the canonical chain.
pub token_address: b256,
/// The token's ID on the canonical chain.
pub token_id: b256,
/// The decimals of the token.
pub decimals: u8,
/// The type of deposit made.
pub deposit_type: DepositType,
}

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);
pub struct MetadataMessage {
/// The bridged token's address on the canonical chain.
pub token_address: b256,
/// The token's ID on the canonical chain.
pub token_id: b256,
/// The bridged token's name on the canonical chain.
pub name: String,
/// The bridged token's symbol on the canonical chain.
pub symbol: String,
}

abi SRC10 {
/// Accepts incoming deposit messages from the canonical chain and issues the corresponding bridged asset.
///
/// # Arguments
Expand Down Expand Up @@ -73,17 +74,17 @@ abi SRC10 {
/// ```sway
/// use src10::SRC10;
///
/// fn foo(to_address: b256, asset_sub_id: SubId, gateway_contract: b256, bridge: ContractId, bridged_asset: AssetId) {
/// fn foo(to_address: 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);
/// }.withdraw(to_address);
/// }
/// ```
#[storage(read, write)]
fn withdraw(to_address: b256, sub_id: SubId, gateway_contract: b256);
fn withdraw(to_address: b256);

/// Returns a refund on the canonical chain if an error occurs while bridging.
///
Expand Down

0 comments on commit a001d3c

Please sign in to comment.