Skip to content

Commit

Permalink
Merge pull request #1044 from multiversx/feat/xbridge-v3.1
Browse files Browse the repository at this point in the history
Feat bridge v3.1 update
  • Loading branch information
iulianpascalau authored Feb 3, 2025
2 parents 7a65945 + 54acc54 commit b9bd7a6
Show file tree
Hide file tree
Showing 18 changed files with 1,307 additions and 53 deletions.
50 changes: 36 additions & 14 deletions docs/bridge/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,51 @@ id: architecture
title: Architecture
---

import useBaseUrl from '@docusaurus/useBaseUrl';
import ThemedImage from '@theme/ThemedImage';

[comment]: # (mx-abstract)

Ad-Astra Bridge is a system that allows for the transfer of ERC20 tokens between the Ethereum and MultiversX networks. The system is composed of several contracts and relayers that work together to facilitate the transfer of tokens.
# Architecture

Ad-Astra Bridge is a system that allows the transfer of ERC20 tokens between EVM-compatible chains and the MultiversX network.
Currently, there are 2 bridges available: between the Ethereum and MultiversX networks and between the BSC and MultiversX networks.
The system is composed of several contracts and relayers that work together to facilitate the transfer of tokens.

Without entering too many details regarding the smart-contracts interactions, this is a simplified view of the entire bridge architecture.
<!--- source file reference: /static/xbridge/xbridge-dark/light.drawio --->
<ThemedImage
alt="Bridge general architecture overview"
sources={{
light: useBaseUrl('/xbridge/general-architecture-light.png'),
dark: useBaseUrl('/xbridge/general-architecture-dark.png'),
}}
/>

[comment]: # (mx-context-auto)

## Ethereum Contracts
- **Repo**: https://github.com/multiversx/mx-bridge-eth-sc-sol
- **Safe (1)**: A contract that allows users to deposit ERC20 tokens that they want to transfer to the MultiversX network.
- **Bridge(2)**: A contract that facilitates the transfer of tokens from Ethereum to MultiversX.
## EVM-compatible chains contracts
The repository for the Solidity contracts used on the EVM-compatible side can be found here: https://github.com/multiversx/mx-bridge-eth-sc-sol
The main contracts are described below:
1. **Safe**: A contract that allows users to deposit ERC20 tokens that they want to transfer to the MultiversX network;
2. **Bridge**: A contract that facilitates the transfer of tokens from MultiversX to an EVM-compatible chain. Only the relayers are allowed to use this contract.

[comment]: # (mx-context-auto)

## MultiversX Contracts
- **Repo**: https://github.com/multiversx/mx-bridge-eth-sc-rs
- **Safe (3)**: A contract that allows users to deposit ESDT tokens that they want to transfer to the Ethereum network.
- **Bridge (4)**: A contract that facilitates the transfer of tokens from MultiversX to Ethereum.
- **MultiTransfer (5)**: A helper contract that is used to perform multiple token transfers at once.
- **BridgedTokensWrapper (6)**: A helper contract that is used to support wrapping the same token from multiple chains into a single ESDT token.
## MultiversX contracts
The repository for the Rust contracts used on the MultiversX side can be found here: https://github.com/multiversx/mx-bridge-eth-sc-rs
1. **Safe**: A contract that allows users to deposit ESDT tokens that they want to transfer to EVM-compatible networks;
2. **Bridge**: A contract that facilitates the transfer of tokens from the EVM-compatible chain to MultiversX. As the Bridge contract on the EVM-compatible chain side, this
the contract is allowed to be operated by the registered relayers;
3. **MultiTransfer**: A helper contract that is used to perform multiple token transfers at once;
4. **BridgedTokensWrapper**: A helper contract that is used to support wrapping the same token from multiple chains into a single ESDT token;
5. **BridgeProxy**: A helper contract that is used to store and handle the smart contract execution and the possible refund operation after the swap is done.

[comment]: # (mx-context-auto)

## Relayers
- **Repo**: https://github.com/multiversx/mx-bridge-eth-go
- **5 Relayers**: Managed by the MultiversX Foundation.
- **5 Relayers**: Distributed to the MultiversX validators community, with each validator having one relayer.
The repository for the code that the relayers use can be found here: https://github.com/multiversx/mx-bridge-eth-go

For each existing bridge, the following list applies:
- **5 Relayers** are managed by the MultiversX Foundation;
- **5 Relayers** are distributed to the MultiversX validators community, with each validator having one relayer.
17 changes: 0 additions & 17 deletions docs/bridge/multiple-chains.md

This file was deleted.

72 changes: 72 additions & 0 deletions docs/bridge/token-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
id: token-types
title: Token Types
---

import useBaseUrl from '@docusaurus/useBaseUrl';
import ThemedImage from '@theme/ThemedImage';

[comment]: # (mx-abstract)

# Token Types

With the release of the bridge v3.0 & v3.1 different token types are allowed to be bridged. By token type, we refer to how the
tokens are locked/burnt or unlocked/minted along with the chain side on which they are native. The decision of how the token should
be configured in the bridge depends on the availability of the minter/burner role on the EVM-compatible chain side along with
the marketing decision of "on which chain the token should be native (a.k.a. where it was first minted)"

[comment]: # (mx-abstract)

**1. Mint/Burn & Native on MultiversX < - > EVM-chain has Mint/Burn & Non-Native**

This bridge token-type configuration has the advantage of not holding a single token in the bridge.
The swapped tokens are minted/burned on both sides. The total token quantity on both chains equals the (minted - burned) on MultiversX
added with the (minted - burned) on the EVM-compatible chain side. The initial supply & mint is done on MultiversX.

<!--- source file reference: /static/xbridge/xbridge-dark/light.drawio --->
<ThemedImage
alt="mint/burn tokens"
sources={{
light: useBaseUrl('/xbridge/mint-burn-tokens-light.png'),
dark: useBaseUrl('/xbridge/mint-burn-tokens-dark.png'),
}}
/>

[comment]: # (mx-abstract)

**2. Mint/Burn & Non-Native on MultiversX < - > EVM-chain has Mint/Burn & Native**

This has the same advantages as 1. but the initial minting is done on the EVM-compatible chain side.

[comment]: # (mx-abstract)

**3. Mint/Burn & Non-Native on MultiversX < - > EVM-chain has Locked/Unlocked & Native**

This bridge token configuration type will need to be initiated on the EVM-compatible chain side and the tokens transferred to
MultiversX will be locked in the bridge contract (no minter role is needed on the EVM-compatible chain as opposed to 1 & 2) and
will be unlocked when swaps from MultiversX to the EVM-compatible chain are done. On the MultiversX side, there will be mint/burn
actions. The total quantity of tokens on both chains will be equal to the supply on the EVM-compatible chain. Everything that is
locked in the bridge contract will equal to what was minted - burned on MultiversX side.

:::warning
This configuration will also require an intermediate token as to allow the bridging on more than one EVM-compatible chain.
It also can create discrepancies between the allowed supplies to bridge between multiple chains.
:::

Example: if tokens are being brought to MultiversX from EVM-compatible chain 1 and then the tokens are bridged out from
MultiversX to EVM-compatible chain 2, then the bridge for EVM-compatible chain 2, at some point, will be unable to process
swaps because it will run out of its intermediary tokens. The solution here is to manually bridge in the reversed order
as described (an operation that consumes time & fees).

<!--- source file reference: /static/xbridge/xbridge-dark/light.drawio --->
<ThemedImage
alt="mint/burn with lock/unlock tokens"
sources={{
light: useBaseUrl('/xbridge/lock-unlock-tokens-light.png'),
dark: useBaseUrl('/xbridge/lock-unlock-tokens-dark.png'),
}}
/>

**Note:** The diagram above is a little bit misleading because the ERC20 contracts hold the address/balance ledgers inside
them. For the sake of simplicity, the tokens are depicted stored inside the bridge **Safe** contracts
(just as MultiversX ESDTs).
121 changes: 105 additions & 16 deletions docs/bridge/transfer-flows.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,116 @@ id: transfer-flows
title: Transfer Flows
---

import useBaseUrl from '@docusaurus/useBaseUrl';
import ThemedImage from '@theme/ThemedImage';

[comment]: # (mx-abstract)

The main functionality of the bridge is to transfer tokens from a network to another. For example, a user can transfer tokens from Ethereum to MultiversX or from MultiversX to Ethereum.
The following sections describe the transfer flows for both directions.
# Transfer Flows

The main functionality of the bridge is to transfer tokens from one network to another. For example, a user can transfer tokens from an EVM-compatible chain to MultiversX or from MultiversX to an EVM-compatible chain.
Besides the main functionality, there is the possibility to call a smart contract on MultiversX when doing a swap.

[comment]: # (mx-context-auto)

# 1. Simple token transfer functionality

[comment]: # (mx-context-auto)
## 1.a. EVM-compatible chain to MultiversX

## Ethereum to MultiversX
1. A user deposits the ERC20 tokens that they want to transfer to the MultiversX network on the **Safe(1)** contract.
2. The **Safe(1)** contract groups multiple deposits into batches.
3. After a certain period of time, each batch becomes final and is processed by the relayers.
4. The relayers propose, vote, and perform the transfer using the **Bridge (4)** contract with a consensus of 7/10 votes.
5. On the MultiversX network, the same amount of ESDT tokens are minted as were deposited on the Ethereum network.
6. The user receives the equivalent amount of ESDT tokens on their recipient address on the MultiversX network.
Let's suppose Alice has x tokens on an EVM-compatible chain and wants to transfer them to MultiversX at the address she owns
(or it might be Bob's address on MultiversX, the bridge does not care). The steps and flow are the following:
* Alice deposits the ERC20 tokens that she wants to transfer to the MultiversX network in the EVM-compatible chain's **Safe** contract;
* The EVM-compatible chain's **Safe** contract groups multiple deposits into batches;
* After a certain period of time (defined by the finality parameters of the EVM-compatible chain), each batch becomes final and starts being processed by the relayers;
* The relayers propose, vote, and perform the transfer using MultiversX's **Bridge** contract with a consensus of a minimum of 7 out of 10 votes;
* On the MultiversX network, the same amount of ESDT tokens are minted or released, depending on the token's settings;
* The destination address receives the equivalent amount of ESDT tokens on the MultiversX network.

[comment]: # (mx-context-auto)

## MultiversX to Ethereum
1. A user deposits the ESDT tokens that they want to transfer to the Ethereum network on the **Safe(3)** contract.
2. The **Safe(3)** contract groups multiple deposits into batches.
3. After a certain period of time, each batch becomes final and is processed by the relayers.
4. The relayers propose, vote, and perform the transfer using the **Bridge (2)** contract with a consensus of 7/10 votes.
5. The user receives the equivalent amount of ERC20 tokens on their recipient address on the Ethereum network.
6. On the MultiversX network, the ESDT tokens that were transferred are burned.
## 1.b. MultiversX chain to an EVM-compatible chain

Now let's suppose Alice wants her x tokens on MultiversX to transfer them to an EVM-compatible chain in the address she owns
(or it might be Bob's address on the EVM-compatible chain, again, the bridge does not care). The steps and flow are the following:

* Alice deposits the ESDT tokens that she wants to transfer to the EVM-compatible network in MultiversX's **Safe** contract;
* The MultiversX's **Safe** contract groups multiple deposits into batches;
* After a certain period of time, each batch becomes final and ready to be processed by the relayers;
* The relayers propose, vote, and perform the transfer using the EVM-compatible chain's **Bridge** contract with a consensus of exactly 7 out of 10 votes;
* The user receives the equivalent amount of ERC20 tokens on their recipient address on the EVM-compatible network minus the fee for this operation;
* On the MultiversX network, the ESDT tokens that were transferred are burned or locked, depending on the token's settings.

# 2. Token transfer with smart-contract call on MultiversX side

Starting with bridge v3.0, swaps from the EVM-compatible chains can invoke a smart contract on the MultiversX side.
Let's suppose Alice has x tokens on an EVM-compatible chain and wants to transfer them to MultiversX to a contract while invoking
a function on that contract. The steps and flow are the following:

* Alice deposits the ERC20 tokens that she wants to transfer to the MultiversX network in the EVM-compatible chain's **Safe** contract,
on a special endpoint also providing the MultiversX's contract address, function, the parameters for the invoked function, and a minimum
gas-limit to be used when invoking the function;
* The EVM-compatible chain's **Safe** contract groups multiple deposits into batches, regardless of whether the deposits are of this type or 1.a. type;
* After a certain period of time (defined by the finality parameters of the EVM-compatible chain), each batch becomes final and starts being processed by the relayers;
* The relayers propose, vote, and perform the transfer using MultiversX's **Bridge** contract with a consensus of a minimum of 7 out of 10 votes;
* On the MultiversX network, the same amount of ESDT tokens are minted or released, depending on the token's settings;
* The minted or released tokens, along with the smart-contract call parameters (contract address, function, parameters, and minimum gas limit) are then moved in
the specialized contract called **BridgeProxy**;
* On the **BridgeProxy** contract there is an endpoint for executing the smart-contract call. Alice or any MultiversX entity willing to
spend the gas for execution can call the endpoint. The minimum gas limit for the execution is the one specified by Alice, or it can be higher;
* The entity triggering the execution flow will pay the gas limit and the **BridgeProxy** will handle the execution which can have 2 outcomes:
* The call was successful: in this case, the contract will be credited with the tokens sent by Alice, and the invoked function would have produced the desired effects;
* The call was unsuccessful: in this case, the **BridgeProxy** received back the tokens and will mark the transfer as failed.
* The **BridgeProxy** can then be called on another endpoint to attempt the refund mechanism. Alice or any other MultiversX entity willing
to spend gas limit can invoke that endpoint;
* Whoever calls the **BridgeProxy** refund endpoint, will pay the gas limit for the reversed transfer operation. This will also attempt to subtract the fee
as for any normal MultiversX to EVM-compatible chain transfer;
* The transfer is placed in a MultiversX batch and eventually, Alice will get her tokens back on the originating EVM-compatible chain minus the fee.
As stated, the operations on the **BridgeProxy** can be done manually, or by using the **scCallsExecutor** tool provided here https://github.com/multiversx/mx-bridge-eth-go/blob/feat/v3.1/cmd/scCallsExecutor

The README.md file contained in this directory is a good place to start on how to manually configure the tool and run it (on a dedicated host or VM)

## Notes regarding smart-contract invoked on MultiversX from an EVM-compatible chain:

The next diagram explains what happens with a token transfer with a smart-contract call in the direction EVM-compatible chain -> MultiversX when the tokens are unlocked/minted on the MultiversX chain.
The transfer is stored in the **BridgeProxy** (Step 1) and then, anyone can initiate the execution (Step 2). The tokens reach the 3-rd-party smart contract along with the function required to be called
and the provided parameters.

<!--- source file reference: /static/xbridge/xbridge-dark/light.drawio --->
<ThemedImage
alt="SC bridge proxy happy flow"
sources={{
light: useBaseUrl('/xbridge/bridge-proxy-ok-call-light.png'),
dark: useBaseUrl('/xbridge/bridge-proxy-ok-call-dark.png'),
}}
/>

As stated above, this is the "happy flow" in which the smart contract call succeeds on the 3-rd-party contract. But what
happens if the invoked function fails? This is described in the next diagram. Step 1 was identical to the previous diagram
and it was omitted. Step 2 got a new step 2.c in which the tokens return to the **BridgeProxy** contract and the whole transfer
is marked as failed and ready to be refunded on the original source EVM-compatible chain **to the original sender address**.
There is another Step 3 involved, in which, anyone can call the refund method.

<!--- source file reference: /static/xbridge/xbridge-dark/light.drawio --->
<ThemedImage
alt="SC bridge proxy with refund flow"
sources={{
light: useBaseUrl('/xbridge/bridge-proxy-refund-call-light.png'),
dark: useBaseUrl('/xbridge/bridge-proxy-refund-call-dark.png'),
}}
/>

Step 2 and Step 3 can be automatically triggered with the help of the **scCallsExecutor** tool referenced above.

:::important
The SC call data will need to be assembled from the EVM-compatible chain side and should respect the MultiversX Rust Framework
encoding for all provided parameters.
:::

The following resource will exemplify how the correct endpoint is to be called on the EVM-compatible chain side:
https://github.com/multiversx/mx-bridge-eth-sc-sol/blob/main/tasks/depositSC.ts

The correct encoded data can be generated by using the `encodeCallData` function provided in this typescript implementation
https://github.com/multiversx/mx-sdk-js-bridge/blob/main/helpers/encodeCallData.ts
or, using the `EncodeCallDataStrict` function from the Golang implementation
https://github.com/multiversx/mx-bridge-eth-go/blob/feat/v3.1/parsers/multiversxCodec.go
Loading

0 comments on commit b9bd7a6

Please sign in to comment.