Skip to content

Commit

Permalink
Add Asset Conversion Guides (#5812)
Browse files Browse the repository at this point in the history
* Add Asset Conversion Guides

* Create Liquidity Pool

* Add Liquidity - example

* swap exact tokens example

* Swap to exact tokens - example

* Remove liquidity - example

* Update docs/learn/learn-asset-conversion-assethub.md

Co-authored-by: bader y <[email protected]>

* Update docs/learn/learn-asset-conversion-assethub.md

Co-authored-by: joe petrowski <[email protected]>

* Update docs/learn/learn-guides-asset-conversion.md

Co-authored-by: joe petrowski <[email protected]>

---------

Co-authored-by: bader y <[email protected]>
Co-authored-by: joe petrowski <[email protected]>
  • Loading branch information
3 people authored Apr 25, 2024
1 parent 19a9112 commit efb5c54
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 28 deletions.
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.
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.
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.
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.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 21 additions & 21 deletions docs/learn/learn-asset-conversion-assethub.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ Asset conversion is a simple AMM (Automated Market Maker) based on
[pallet on Polkadot AssetHub](https://github.com/paritytech/polkadot-sdk/tree/master/substrate/frame/asset-conversion).
In the AMM model the prices of tokens are determined by a mathematical formula based on the ratio of
tokens in a liquidity pool, unlike traditional exchanges that use an order book. This will be a
“trustless” DEX, which is controlled through Polkadot OpenGov.
“trustless” DEX, controlled through Polkadot OpenGov.

:::note

The asset pairs of the liquidity pools of AssetHub will always contain
{{ polkadot: DOT :polkadot }}{{ kusama: KSM :kusama }} as one of the asets. Provision of liquidity
{{ polkadot: DOT :polkadot }}{{ kusama: KSM :kusama }} as one of the assets. Provision of liquidity
for pools with arbitrary asset pairs is not allowed.

:::
Expand All @@ -40,24 +40,25 @@ Asset Conversion pallet allows you to:

## Fee Payment in Any Asset - Wallets

Without Asset Conversion pallet, only DOT and sufficient assets can be used for paying transaction
fees. With the Asset Conversion pallet deployed, it is possible for Wallets to enable users to pay
transaction fees through any arbitrary asset that has been made available in pools with either DOT
or sufficient assets. More specifically, this functionality is enabled through
Without Asset Conversion pallet, only DOT and [sufficient assets](./learn-assets.md#sufficient-assets) can be used for paying transaction
fees. With the Asset Conversion pallet deployed, Wallets can enable users to pay transaction fees
through any arbitrary asset made available in pools with either DOT or sufficient assets. More
specifically, this functionality is enabled through
[Asset Conversion Transaction Payment Pallet](https://github.com/paritytech/polkadot-sdk/tree/cdc8d197e6d487ef54f7e16767b5c1ab041c8b10/substrate/frame/transaction-payment/asset-conversion-tx-payment),
allowing runtimes that include it to pay for transactions in assets other than the native token of
the chain.

:::caution Handling Pools with Low Liquidity

The wallets and UIs should ensure that the user is prompted with the necessary warnings, such that
they do not accidentally spend all the funds to perform a swap on a pool with no or low liquidity.
they do not accidentally spend all of their funds to perform a swap on a pool with no or low
liquidity.

:::

## Fee Payment in Any Asset - Parachains

Parachains can pay for their XCM execution fees in any asset that has a liquidity pool on AssetHub.
Parachains can pay for their XCM execution fees in any asset with a liquidity pool on AssetHub.

## Creation of Pools with Foreign Assets - Parachains

Expand All @@ -67,18 +68,17 @@ control them.
One of the pain points of integrating parachain tokens natively on wallets and exchanges is that
they require running individual parachain infrastructure like full nodes to process deposits, and
require additional code to handle withdrawals because they need to be able to construct and
broadcast transactions on each individual parachain. These parachains could use different balances
pallets or order them differently. When Polkadot hosts hundreds of parachains (and possibly
thousands of threads), this becomes a huge burden in terms of network support. This is in contrast
to for example adding support for an additional ERC20 token; the marginal effort is very small since
an Ethereum node already serves all the data they need.

With support for these assets on AssetHub, exchanges/custodians could just monitor one chain for
deposits (applications and UIs would need to give the option to transfer to AssetHub). For
withdrawals, users could choose to withdraw to their address on AssetHub. There are two user
experience bonuses here:

- For the exchange/custodian, they only need to transact on one parachain and can access every other
without any infrastructure lift.
broadcast transactions on each parachain. These parachains could use different balances pallets or
order them differently. When Polkadot hosts hundreds of parachains (and possibly thousands of
threads), this becomes a huge burden in terms of network support. This is in contrast to adding
support for an additional ERC20 token; the marginal effort is very small since an Ethereum node
already serves all the data they need.

With support for these assets on Asset Hub, exchanges/custodians could monitor one chain for deposits
(applications and UIs would need to give the option to transfer to Asset Hub). For withdrawals, users
could choose to withdraw to their address on Asset Hub. There are two user experience bonuses here:

- The exchange/custodian only needs to transact on one parachain and can access every other without
any infrastructure lift.
- For the user, they never actually need to “see” AssetHub. It’s entirely abstracted away behind
either the parachain wallet/application or the exchange/custodian.
105 changes: 98 additions & 7 deletions docs/learn/learn-guides-asset-conversion.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,50 @@ see the [wallets](./wallets-index), [apps](./apps-index) and [dashboard](./dashb

</div>

:::info Wallet and UI Developers

The [DOT ACP UI](https://github.com/MVPWorkshop/dot-acp-ui) project is part of Polkadot initiative
for building front-end and UI for Asset Conversion Pallet on Polkadot's Asset Hub. Currently, the app
is deployed on Westend, Rococo and Kusama [here](https://app.dotacp.mvpworkshop.co/swap).

:::

The tutorial below demonstrates the complete journey from creating a liquidity pool on Rococo test
net and exploring all of the key functionalities of Asset Conversion pallet.

## Create a Liquidity Pool

If there is no existing liquidity pool for an asset on Asset Hub, the first step is to create a
liquidity pool. If you are looking for a guide on how to create an asset on Asset Hub, it is
available [here.](./learn-guides-assets-create.md)

The `create_pool` function is used to create an empty liquidity pool along with a new `lp_token`
asset. This asset's ID is announced in the `Event::PoolCreated` event. After creating a pool,
liquidity can be added to it via the `Pallet::add_liquidity` function.

For example, the snapshot below shows how to create liquidity pool with `ROC` tokens and `EDU`
tokens with the asset ID `149` on Rococo Asset Hub. Creating this extrinsic requires knowledge of
[XCM Multilocations](xcm/fundamentals/multilocation/summary.md). From the perspective of AssetHub,
an Asset Hub, the asset with an `AssetId` of `149` has a MultiLocation of

```
{
parents: 0,
interior: {
X2: [{PalletInstance: 50}, {GeneralIndex: 149}]
}
}
```

The PalletInstance of `50` represents the Assets pallet on Asset Hub and the `GeneralIndex` is the
`AssetId` of the asset.

![Create Liquidity Pool](../assets/asset-hub/Asset-Conversion-Create-Pool.png)

The `lp_token` ID created for this pool is `24`, and
[here](https://assethub-rococo.subscan.io/extrinsic/4604922-2?event=4604922-8) is the event for
reference.

## Liquidity Provision

The `add_liquidity` function allows users to provide liquidity to a pool composed of two assets. It
Expand All @@ -31,14 +69,18 @@ calculates an optimal contribution of assets, which may differ from the desired
be less than the specified minimums. Liquidity providers receive liquidity tokens representing their
share of the pool.

## Withdraw Provided Liquidity
For example, the snapshot below shows how to provide liquidity to the pool with `ROC` tokens and
`EDU` tokens with the asset ID `149` on Rococo Asset Hub. The intention is to provide liquidity of 1
`ROC` token (`u128` value of `1000000000000` as it has 12 decimals) and 100 `EDU` tokens (`u128`
value of `1000000000000` as it has 10 decimals).

The `remove_liquidity` function allows users to withdraw their provided liquidity from a pool,
receiving back the original assets. When calling this function, users specify the amount of
liquidity tokens (representing their share in the pool) they wish to burn. They also set minimum
acceptable amounts for the assets they expect to receive back. This mechanism ensures users can
control the minimum value they receive, protecting against unfavourable price movements during the
withdrawal process​.
![Provide Liquidity](../assets/asset-hub/Asset-Conversion-Add-Liquidity.png)

After successful submission of the extrinsic above, LP tokens are minted to the specified account.
Below is the snapshot of the liquidity pool on the
[DOT ACP UI.](https://github.com/MVPWorkshop/dot-acp-ui)

![Liquidity Pool Example](../assets/asset-hub/Asset-Conversion-Liquidity-Pool-Example.png)

## Swap Assets

Expand All @@ -50,10 +92,59 @@ amount of the second asset in return. This function aims to provide predictabili
outcomes, allowing users to manage their asset exchanges with confidence regarding the minimum
return.

For example, the snapshot below shows how to swap `ROC` tokens to `EDU` tokens with the asset ID
`149` on Rococo Asset Hub. The intention is to swap 0.1 `ROC` tokens (`u128` value of `100000000000`
as it has 12 decimals) to at least 9 `EDU` tokens (`u128` value of `90000000000` as it has 10
decimals).

![Swap Exact Amount](../assets/asset-hub/Asset-Conversion-Swap-Exact-Token.png)

Below is the snapshot of the liquidity pool on the
[DOT ACP UI.](https://github.com/MVPWorkshop/dot-acp-ui) after successful submission of the
extrinsic above. It can be observed that the pool now has 1.1 `ROC` tokens and around 9.06 `EDU`
tokens are transferred out of it.

![Swap Exact Amount Example](../assets/asset-hub/Asset-Conversion-Swap-Exact-Tokens-Example.png)

### Swap to an exact amount of Tokens

On the other hand, the `swap_tokens_for_exact_tokens` function allows users to trade a flexible
amount of one asset to precisely obtain a specified amount of another asset. It ensures that users
do not spend more than a predetermined maximum amount of the initial asset to acquire the exact
target amount of the second asset, providing a way to control the cost of the transaction while
achieving the desired outcome.

For example, the snapshot below shows how to swap `EDU` tokens with the asset ID `149` on Rococo
Asset Hub to `ROC` Tokens. The intention is to swap for obtaining 0.1 `ROC` tokens (`u128` value of
`100000000000` as it has 12 decimals) for a maximum of 10 `EDU` tokens (`u128` value of
`100000000000` as it has 10 decimals).

![Swap Exact Amount](../assets/asset-hub/Asset-Conversion-Swap-To-Exact-Tokens.png)

Below is the snapshot of the liquidity pool on the
[DOT ACP UI.](https://github.com/MVPWorkshop/dot-acp-ui) after successful submission of the
extrinsic above.

![Swap to Exact Amount Example](../assets/asset-hub/Asset-Conversion-Swap-To-Exact-Example.png)

## Withdraw Provided Liquidity

The `remove_liquidity` function allows users to withdraw their provided liquidity from a pool,
receiving back the original assets. When calling this function, users specify the amount of
liquidity tokens (representing their share in the pool) they wish to burn. They also set minimum
acceptable amounts for the assets they expect to receive back. This mechanism ensures users can
control the minimum value they receive, protecting against unfavourable price movements during the
withdrawal process​.

For example, the snapshot below shows how to remove liquidity by specifying the number of LP tokens.
In exchange of removing around half of the liquidity of the pool, the expecation is that we receive
at least 0.4 `ROC` tokens (`u128` value of`400000000000` as it has 12 decimals) and 40 `EDU` tokens
(`u128` value of `400000000000` as it has 10 decimals).

![Remove Liquidity](../assets/asset-hub/Asset-Conversion-Remove-Liquidity.png)

Below is the snapshot of the liquidity pool on the
[DOT ACP UI.](https://github.com/MVPWorkshop/dot-acp-ui) after successful submission of the
extrinsic above.

![Remove Liquidity Example](../assets/asset-hub/Asset-Conversion-Remove-Liquidity-Example.png)

0 comments on commit efb5c54

Please sign in to comment.