Skip to content

Commit

Permalink
XCM Adjustments
Browse files Browse the repository at this point in the history
  • Loading branch information
acatangiu authored Oct 2, 2024
1 parent 86d9c29 commit 6c8df9b
Showing 1 changed file with 41 additions and 39 deletions.
80 changes: 41 additions & 39 deletions bridges/snowbridge/docs/v2.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Snowbridge V2

This design lowers fees and improves relayer decentralization.
This design lowers fees, improves UX, improves relayer decentralization and allows "transacting" over the bridge, making it a general-purpose bridge rather than just a token bridge.

We're grateful to Adrian Catangui, Francisco Aguirre, and others from the Parity XCM/Bridges team for their help and collaboration on this design.
We're grateful to Adrian Catangiu, Francisco Aguirre, and others from the Parity XCM/Bridges team for their help and collaboration on this design.

# Summary

Expand All @@ -26,7 +26,7 @@ The fee amounts in this message should be high enough to enable dry-running, aft
## Step 2: User agent estimates fees

- Given source parachain $S$, with native token $S^{'}$ and the initial xcm $x_0$ to be executed on $S$.
- The native currency $P^{'}$of the Polkadot relay chain, and $E^{'}$ of Ethereum.
- The native currency $P^{'}$ of the Polkadot relay chain, and $E^{'}$ of Ethereum.
- Suppose that the user agent chooses relayer reward $r$ in $E^{'}$.
- Suppose that the exchange rates $K_{P^{'}/S^{'}}$ and $K_{E^{'}/S^{'}}$. The user agent chooses a multiplier to $\beta$ to cover volatility in these rates.

Expand All @@ -53,9 +53,9 @@ The user agent calls `pallet_xcm::execute` with the initial xcm $x_0$
WithdrawAsset (KLT, 100)
PayFees (KLT, 20)
InitiateAssetsTransfer asset=(KLT, 60) remoteFee=(KLT, 20) dest=AH
ExchangeAsset give=(KLT, 20) want=(WETH, 1)
ExchangeAsset give=(KLT, 20) want=(WETH, 1)
InitiateAssetsTransfer asset=(KLT, 40) remoteFee=(WETH, 1) dest=Ethereum
DepositAsset (KLT, 40) dest=Bob
DepositAsset (KLT, 40) beneficiary=Bob
```

## Step 4: AH executes message x1
Expand All @@ -65,21 +65,21 @@ The message $x_1$ is application-specific:
```
ReserveAssetDeposited (KLT, 80)
PayFees (KLT, 20)
SetAssetClaimer Alice
AliasOrigin Alice
SetAssetClaimer Kilt/Alice
AliasOrigin Kilt/Alice
ExchangeAsset give=(KLT, 20) want=(WETH, 1)
InitiateAssetsTransfer asset=(KLT, 60) remoteFee=(WETH, 1) dest=Ethereum
DepositAsset (KLT, 60) dest=Bob
DepositAsset (KLT, 60) beneficiary=Bob
```

or
```
*ReserveAssetDeposited (KLT, 80)
*PayFees (KLT, 20)
*SetAssetClaimer Alice
*AliasOrigin Alice
*SetAssetClaimer Kilt/Alice
*AliasOrigin Kilt/Alice
ExchangeAsset give=(KLT, 20) want=(WETH, 1)
InitiateAssetsTransfer asset=(KLT, 60) remoteFee=(WETH, 1) dest=Ethereum
DepositAsset (KLT, 60) dest=Bob
DepositAsset (KLT, 60) beneficiary=Bob
Transact Bob.hello()
```

Expand All @@ -88,16 +88,16 @@ In all cases, $x_1$ should contain the necessary instructions to:
1. Pay fees for local execution using `PaysFees`
2. Obtain WETH for remote delivery fees.

The `SovereignPaidExporter` on AH will charge a small fee to prevent spamming BH with bridge messages. This is necessary since the `ExportMessage` instruction in message $x_2$ will have no execution fee on BH. For a similar reason, we should also impose a minimum relayer reward of at least the existential deposit 0.1 DOT, which acts as a deposit to stop spamming messages with 0 rewards.
The XCM bridge-router on AH will charge a small fee to prevent spamming BH with bridge messages. This is necessary since the `ExportMessage` instruction in message $x_2$ will have no execution fee on BH. For a similar reason, we should also impose a minimum relayer reward of at least the existential deposit 0.1 DOT, which acts as a deposit to stop spamming messages with 0 rewards.

## Step 5: BH executes message x2

Message $x_2$ is parsed by the `SnowbridgeMessageExporter` with the following effects:

- A bridge command $m$ is committed to MMR structure $M$.
- The transferred asset is parsed from `ReserveAssetDeposited` , `WithdrawAsset` or `TeleportedAssetReceived` instructions for the local, destination and teleport asset transfer types respectively.
- The original origin is preserved in the `AliasOrigin` instruction. This will allow us to resolve agents for the case of `Transact`.
- The message exporter must be able to support multiple assets and reserve types in the same message and potentially multiplier `Transacts`.
- The original origin is preserved through the `AliasOrigin` instruction. This will allow us to resolve agents for the case of `Transact`.
- The message exporter must be able to support multiple assets and reserve types in the same message and potentially multiple `Transacts`.
- The Message Exporter must be able to support multiple Deposited Assets.
- The Message Exporter must be able to parse `SetAssetClaimer` and allow the provided location to claim the assets on BH in case of errors.
- Given relayer reward $r$, set storage $P(\mathrm{hash}(m)) = r$. This is parsed from the `WithdrawAsset` and `PayFees` instruction.
Expand All @@ -109,29 +109,29 @@ Message $x_2$ is parsed by the `SnowbridgeMessageExporter` with the following ef
*ReserveAssetDeposited (KLT, 60)
*WithdrawAsset (WETH, 1)
*PayFees (WETH, 1)
*SetAssetClaimer Alice
*AliasOrigin Alice
DepositAsset (KLT, 60) dest=Bob
*SetAssetClaimer Kilt/Alice
*AliasOrigin Kilt/Alice
DepositAsset (KLT, 60) beneficiary=Bob
```

or
```
!WithdrawAsset(DOT, 10)
!PayFees (DOT, 10)
!ExportMessage dest=Ethereum
*ReserveAssetDeposited (KLT, 80)
*PayFees (KLT, 20)
*SetAssetClaimer Alice
*AliasOrigin Alice
DepositAsset (KLT, 60) dest=Bob
*SetAssetClaimer Kilt/Alice
*AliasOrigin Kilt/Alice
DepositAsset (KLT, 60) beneficiary=Bob
Transact Bob.hello()
```

## Step 6: Relayer relays message to Gateway

1. A relayer *Charlie* inspects storage $P$ to look for new messages to relay. Suppose it finds $\mathrm{hash}(m)$ giving reward $r$.
2. The relayer queries from m from M and constructs the necessary proofs.
2. The relayer queries $m$ from $M$ and constructs the necessary proofs.
3. The relayer dry-runs m on Ethereum to decide whether the message is profitable to deliver.
4. The relayer finally delivers the message together with an relayer-controlled address $u$ on AH where the relayer reward will be lazily deposited.
4. The relayer finally delivers the message together with a relayer-controlled address $u$ on AH where the relayer reward will be lazily deposited.

## Step 7: Relayer delivers proof of delivery to BH

Expand All @@ -146,11 +146,11 @@ When BH processes the proof of delivery:

## Step 1: Submit send on Gateway

The interface that the Gateway will use to initiate transfers will copy the interface from `transfer_assets_using_type_and_then` extrinsic that we currently use to initiate transfers from the Polkadot to Ethereum direction.
The interface that the Gateway will use to initiate transfers will be similar to the interface from `transfer_assets_using_type_and_then` extrinsic that we currently use to initiate transfers from the Polkadot to Ethereum direction.

1. It must allow multiple assets to be transferred and specify the transfer type: Local, Destination or Teleport asset transfer types. It is the job of the User Agent/UX layer to fill in this information correctly.
2. It must allow specifying a destination which is `Address32` , `Address20` or a custom scale-encoded XCM payload that is executed on the destination. This is how we will support `Transact` , the User Agent/UX layer can build a scale-encoded payload with an encoded transact call.
3. The same interface is used for both PNA and ERC20 tokens. Internally we will still look up whether the token is registered as a PNA or ERC20 for the purpose of minting/locking burning/unlocking logic. The asset transfer type chosen by the UX layer will inform the XCM that is built from the message on BH.
3. The same interface is used for both PNA (Polkadot Assets) and ERC20 tokens. Internally we will still look up whether the token is registered as a PNA or ERC20 for the purpose of minting/locking burning/unlocking logic. The asset transfer type chosen by the UX layer will inform the XCM that is built from the message on BH.

```solidity
enum Kind {
Expand All @@ -166,7 +166,7 @@ struct Beneficiary {
}
enum AssetTransferType {
LocalReserve, DestinationReserve, Teleport
ReserveDeposit, ReserveWithdraw, Teleport
}
struct Token {
Expand All @@ -189,7 +189,7 @@ send(
3022, // KILT Para Id
Address32(0x0000....),
[
(DestinationReserve, KLT, 100)
(ReserveWithdraw, KLT, 100)
],
10, // WETH
)
Expand All @@ -203,7 +203,7 @@ send { value: 3 }( // Send 3 Eth for fees and reward
Transact Bob.hello()
),
[
(DestinationReserve, KLT, 100)
(ReserveWithdraw, KLT, 100)
],
1, // 1 ETH of 3 needs to be for the reward, the rest is for fees
)
Expand All @@ -213,7 +213,7 @@ The User Agent/UX layer will need to estimate the fee required to be passed into

## Step 2: Relayer relays message to Bridge Hub

Exchange rate is eliminated. Users pay remote delivery costs in ETH, and this amount is sent with the message as WETH. The delivery fee can be claimed by the relayer on BH.
On-chain exchange rate is eliminated. Users pay remote delivery costs in ETH, and this amount is sent with the message as WETH. The delivery fee can be claimed by the relayer on BH.

The user agent applies a similar dry-running process as with [Step 2: User agent estimates fees](https://www.notion.so/Step-2-User-agent-estimates-fees-113296aaabef8159bcd0e6dd2e64c3d0?pvs=21).

Expand All @@ -230,7 +230,7 @@ PayFees (WETH, 1)
SetAssetClaimer Bob // derived from beneficiary
AliasOrigin Ethereum/Alice // derived from msg.sender
InitiateAssetsTransfer asset=(KLT, 100) remoteFee=(WETH, 1) dest=KLT
DepositAsset (KLT, 100) dest=Bob
DepositAsset (KLT, 100) beneficiary=Bob
```

```
Expand All @@ -240,30 +240,32 @@ PayFees (WETH, 1)
SetAssetClaimer Ethereum/Alice // derived from beneficiary
AliasOrigin Ethereum/Alice // derived from msg.sender
InitiateAssetsTransfer asset=(KLT, 100) remoteFee=(WETH, 1) dest=KLT
DepositAsset (KLT, 100) dest=Bob
DepositAsset (KLT, 100) beneficiary=Bob
Transact Bob.hello()
```

## Step 4: KILT Receives XCM from AH

The flowing XCM $x_1$ is received from BH on AH.
The following XCM $x_1$ is received from BH on AH.

```
*WithdrawAsset (KLT, 100)
*ReserveAssetDeposited (WETH, 1)
*PayFees (WETH, 1)
*SetAssetClaimer Bob
*SetAssetClaimer Ethereum/Alice
*AliasOrigin Ethereum/Alice // origin preserved from AH
DepositAsset (KLT, 100) dest=Bob
SetAssetClaimer Bob
DepositAsset (KLT, 100) beneficiary=Bob
```

```
*WithdrawAsset (KLT, 100)
*ReserveAssetDeposited (WETH, 1)
*PayFees (WETH, 1)
*SetAssetClaimer Bob
*SetAssetClaimer Ethereum/Alice
*AliasOrigin Ethereum/Alice // origin preserved from AH
DepositAsset (KLT, 100) dest=Bob
SetAssetClaimer Bob
DepositAsset (KLT, 100) beneficiary=Bob
Transact Bob.hello() // executes with the origin from AH
```

Expand All @@ -277,11 +279,11 @@ $$
\mathrm{claim}(o,w)
$$

For tax accounting purposes might be desirable that $o \neq w$.
For tax accounting purposes it might be desirable that $o \neq w$.

# Top-Up

Top-up on the destination is viable to implement.
Top-up of the relayer reward is viable to implement for either direction as extrinsics on Bridge Hub, respectively Ethereum.

## Origin Preservation

Expand Down

0 comments on commit 6c8df9b

Please sign in to comment.