From 8b58ae5dd51eb77f19dd56ead3c09640d214c25e Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Thu, 27 Jun 2024 14:26:51 +0200 Subject: [PATCH 01/22] Draft Signed-off-by: Chris Chinchilla --- docs/develop/09_polarpath/01_overview.md | 75 +++++++++++++++++++++++ docs/develop/09_polarpath/_category_.json | 5 ++ docusaurus.config.js | 25 ++++++++ 3 files changed, 105 insertions(+) create mode 100644 docs/develop/09_polarpath/01_overview.md create mode 100644 docs/develop/09_polarpath/_category_.json diff --git a/docs/develop/09_polarpath/01_overview.md b/docs/develop/09_polarpath/01_overview.md new file mode 100644 index 000000000..3b45ec428 --- /dev/null +++ b/docs/develop/09_polarpath/01_overview.md @@ -0,0 +1,75 @@ +--- +id: what-is-polarpath +title: Overview +--- + + +Polar path consists of an `asset-swap` pallet for KILT chain runtimes and extrinisics that let parachain-based chain developers to make their native token accessible on the Ethereum network using [the Snowbridge bridge](https://docs.snowbridge.network) between Polkadot and Ethereum. + +Polar path provides parachains with a solution for creating an ERC-20 wrapper around their native tokens, enabling a trustless conversion of any existing native parachain token (PARA) into a wrapped parachain token (wPARA) on Ethereum while maintaining the trustlessness guarantees Snowbridge provides. + +The pallet enables a configured conversion rate of parachain tokens on the origin chain to an ERC-20 wrapper token on Polkadot’s AssetHub. + +## Setup + +:::tip Asset Hub +The Polkadot Relay Chain doesn't natively support assets apart from DOT. Instead, parachains support this functionality, and for Polkadot, this parachain is the [Asset Hub](https://wiki.polkadot.network/docs/build-integrate-assets). +::: + +Making a Parachain Token to be usable on Ethereum requires the following steps: +1. Deploy an ERC-20 contract token to Ethereum with a fixed supply based on the parachain needs. +2. [Disable the token issuer rights](https://ethereum.org/en/guides/how-to-revoke-token-access/) on the ERC-20 contract. +3. [Register the ERC-20 token on Asset Hub](https://wiki.polkadot.network/docs/learn-assets#creation-and-management). +4. The entity holding ERC-20 funds performs a one-time transfer of all tokens from their Ethereum account to the parachain's sovereign account on Asset Hub. +5. Parachain governance recognizes the wrapper around the ERC-20 token by pairing the ERC-20 token to the parachain token in the swap pallet and enable the token issuer rights. + +Holders of the token on the parachain can can now switch tokens between it and Ethereum. + +## Use cases + +After setup, the following flows are possible: + +:::tip XCM +Polar path uses Polkadot's [Cross-Consensus Message Format (XCM)](https://wiki.polkadot.network/docs/learn-xcm), a messaging format and language used to communicate between consensus systems. +::: + +### Sending tokens from the parachain to Ethereum + +1. Transmit custom parachain tokens, "PARA", from the parachain to wrapped tokens "wPARAs" on Asset Hub via XCM +2. Send wPARAs from Asset Hub to the ERC-20 contract on Ethereum via Snowbridge + +### Sending tokens from Ethereum to the parachain + +1. Send wPARAs from the ERC-20 contract on Ethereum to Asset Hub via Snowbridge +2. Transmit wPARAs on Asset Hub to PARAs on the parachain via XCM + + + + + + +Extrinsics + +`setSwapPair` +Create a new switch pair between a parachain token and an ERC-20 token. Returns a result and takes the following parameters: + + origin: OriginFor, + reserve_location: Box, + remote_asset_id: Box, + remote_fee: Box, + total_issuance: u128, + circulating_supply: u128, + + +`removeSwapPair` + +`pauseSwapPair` +Pause switching assets for a specific parachain token and ERC-20 pair. + + +`resumeSwapPair` +Restart switching assets for a specific parachain token and ERC-20 pair. + +`swap` +Allow any user with enough local asset balance to send them to the pool account for this specific swap pair and get issued a corresponding amount of remote asset from the parachain’s sovereign account on remote location, to a `MultiLocation` of their choice. + diff --git a/docs/develop/09_polarpath/_category_.json b/docs/develop/09_polarpath/_category_.json new file mode 100644 index 000000000..e617cba37 --- /dev/null +++ b/docs/develop/09_polarpath/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "Polar path", + "collapsible": true, + "collapsed": true +} diff --git a/docusaurus.config.js b/docusaurus.config.js index 26bab7d0b..1a0a0a401 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -282,5 +282,30 @@ module.exports = { }, }, ], + [ + 'docusaurus-plugin-remote-content', + { + // Pulls external files and adds them as files in the Docusaurus folder, rewriting the title and the file name + name: 'swap-pallet', + // TODO: Temp URL + sourceBaseUrl: + 'https://raw.githubusercontent.com/KILTprotocol/kilt-node/b23207e9782ea024cde8f4883cb4029eebb1735f/pallets/pallet-asset-swap/', + outDir: 'docs/develop/09_polarpath', + documents: ['README.md'], + // modifyContent(filename, content) { + // if (filename.includes('README')) { + // var trimContent = content.replace( + // '# Decentralized Identity Provider (DIP) consumer pallet', + // '# Consumer pallet' + // ) + // return { + // filename: '03_consumer.md', + // content: trimContent, + // } + // } + // return undefined + // }, + }, + ], ], } From 20e26ba35d23fefb9cac4ba4b32cce7b00be1273 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Tue, 2 Jul 2024 09:54:14 +0200 Subject: [PATCH 02/22] Draft Signed-off-by: Chris Chinchilla --- docs/develop/09_polarpath/01_overview.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/develop/09_polarpath/01_overview.md b/docs/develop/09_polarpath/01_overview.md index 3b45ec428..03d258e2c 100644 --- a/docs/develop/09_polarpath/01_overview.md +++ b/docs/develop/09_polarpath/01_overview.md @@ -50,6 +50,11 @@ Polar path uses Polkadot's [Cross-Consensus Message Format (XCM)](https://wiki.p Extrinsics +:::tip Remote asset +A remote asset is the identifier of the asset considered to be the other side of the switch pair. For an ERC20 token, this is a [MultiLocation](https://wiki.polkadot.network/docs/learn/xcm/fundamentals/multilocation-summary) (in XCM terms) pointing to an address on one of the many EVM-based deployments. + +::: + `setSwapPair` Create a new switch pair between a parachain token and an ERC-20 token. Returns a result and takes the following parameters: @@ -71,5 +76,9 @@ Pause switching assets for a specific parachain token and ERC-20 pair. Restart switching assets for a specific parachain token and ERC-20 pair. `swap` -Allow any user with enough local asset balance to send them to the pool account for this specific swap pair and get issued a corresponding amount of remote asset from the parachain’s sovereign account on remote location, to a `MultiLocation` of their choice. +// Pool account Asset Hub +// Remote asset? +// Sovereign account? + +Allow any user with enough parachain asset balance to send them to the [Asset Hub pool account](https://docs.rs/pallet-asset-conversion/latest/pallet_asset_conversion/pallet/struct.Pallet.html#method.create_pool) for this specific switch pair and receive a corresponding amount of remote asset from the parachain's sovereign account on remote location, to a `MultiLocation` of their choice. From b085dafd9dd13315fff1347ef468d853bc6dfca2 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Tue, 9 Jul 2024 15:55:43 +0200 Subject: [PATCH 03/22] Draft Signed-off-by: Chris Chinchilla --- docs/develop/09_polarpath/01_overview.md | 55 +++++++++++++----------- docs/develop/09_polarpath/README.md | 11 +++++ docusaurus.config.js | 5 +++ 3 files changed, 47 insertions(+), 24 deletions(-) create mode 100644 docs/develop/09_polarpath/README.md diff --git a/docs/develop/09_polarpath/01_overview.md b/docs/develop/09_polarpath/01_overview.md index 03d258e2c..06ce829f9 100644 --- a/docs/develop/09_polarpath/01_overview.md +++ b/docs/develop/09_polarpath/01_overview.md @@ -3,12 +3,11 @@ id: what-is-polarpath title: Overview --- - Polar path consists of an `asset-swap` pallet for KILT chain runtimes and extrinisics that let parachain-based chain developers to make their native token accessible on the Ethereum network using [the Snowbridge bridge](https://docs.snowbridge.network) between Polkadot and Ethereum. Polar path provides parachains with a solution for creating an ERC-20 wrapper around their native tokens, enabling a trustless conversion of any existing native parachain token (PARA) into a wrapped parachain token (wPARA) on Ethereum while maintaining the trustlessness guarantees Snowbridge provides. -The pallet enables a configured conversion rate of parachain tokens on the origin chain to an ERC-20 wrapper token on Polkadot’s AssetHub. +The pallet enables a configured conversion rate of parachain tokens on the origin chain to an ERC-20 wrapper token on Polkadot's AssetHub. ## Setup @@ -17,6 +16,7 @@ The Polkadot Relay Chain doesn't natively support assets apart from DOT. Instead ::: Making a Parachain Token to be usable on Ethereum requires the following steps: + 1. Deploy an ERC-20 contract token to Ethereum with a fixed supply based on the parachain needs. 2. [Disable the token issuer rights](https://ethereum.org/en/guides/how-to-revoke-token-access/) on the ERC-20 contract. 3. [Register the ERC-20 token on Asset Hub](https://wiki.polkadot.network/docs/learn-assets#creation-and-management). @@ -43,42 +43,49 @@ Polar path uses Polkadot's [Cross-Consensus Message Format (XCM)](https://wiki.p 1. Send wPARAs from the ERC-20 contract on Ethereum to Asset Hub via Snowbridge 2. Transmit wPARAs on Asset Hub to PARAs on the parachain via XCM +## Extrinsics +Before performing a switch, you first need to create a switch pair between the parachain token and the ERC-20 token using the `setSwitchPair` extrinisc. Then you can use any of the other extriniscs with the switch pair, including performing the switch itself using the `switch` extrinisc. +:::tip Remote asset +A remote asset is the identifier of the asset considered to be the other side of the switch pair. For an ERC20 token, this is a [MultiLocation](https://wiki.polkadot.network/docs/learn/xcm/fundamentals/multilocation-summary) (in XCM terms) pointing to an address on one of the many EVM-based deployments. +::: +### `setSwitchPair` +Create a new switch pair between a parachain token and an ERC-20 token. Returns a result and takes the following parameters: -Extrinsics +- `origin`: Polkadot [Junction](https://wiki.polkadot.network/docs/learn/xcm/fundamentals/multilocation-junctions) defining the +- `reserve_location`: +- `remote_asset_id`: +- `remote_fee`: +- `total_issuance`: A `u128` defining +- `circulating_supply`: A `u128` defining, -:::tip Remote asset -A remote asset is the identifier of the asset considered to be the other side of the switch pair. For an ERC20 token, this is a [MultiLocation](https://wiki.polkadot.network/docs/learn/xcm/fundamentals/multilocation-summary) (in XCM terms) pointing to an address on one of the many EVM-based deployments. +### `removeSwitchPair` -::: +Remove an existing switch pair. Returns a result and takes the following parameters: -`setSwapPair` -Create a new switch pair between a parachain token and an ERC-20 token. Returns a result and takes the following parameters: +- `remote_asset_id`: + +### `pauseSwitchPair` - origin: OriginFor, - reserve_location: Box, - remote_asset_id: Box, - remote_fee: Box, - total_issuance: u128, - circulating_supply: u128, +Pause an existing switch pair. Returns a result and takes the following parameters: +- `remote_asset_id`: -`removeSwapPair` +### `resumeSwitchPair` -`pauseSwapPair` -Pause switching assets for a specific parachain token and ERC-20 pair. +Resume a paused an existing switch pair. Returns a result and takes the following parameters: +- `remote_asset_id`: -`resumeSwapPair` -Restart switching assets for a specific parachain token and ERC-20 pair. +### `switch` -`swap` -// Pool account Asset Hub -// Remote asset? -// Sovereign account? +Allow any user with enough parachain asset balance to send them to the [Asset Hub pool account](https://docs.rs/pallet-asset-conversion/latest/pallet_asset_conversion/pallet/struct.Pallet.html#method.create_pool) for a specific switch pair and receive a corresponding amount of remote asset from the parachain's sovereign account on the remote location, to a `MultiLocation` of their choice. -Allow any user with enough parachain asset balance to send them to the [Asset Hub pool account](https://docs.rs/pallet-asset-conversion/latest/pallet_asset_conversion/pallet/struct.Pallet.html#method.create_pool) for this specific switch pair and receive a corresponding amount of remote asset from the parachain's sovereign account on remote location, to a `MultiLocation` of their choice. +Returns a result and takes the following parameters: +- `from`: T::AccountId +- `to`: VersionedMultiLocation +- `amount`: LocalCurrencyBalanceOf diff --git a/docs/develop/09_polarpath/README.md b/docs/develop/09_polarpath/README.md new file mode 100644 index 000000000..3dcaa4867 --- /dev/null +++ b/docs/develop/09_polarpath/README.md @@ -0,0 +1,11 @@ +WIP. + +# TODO + +Besides the TODOs in the code, the following points must be tackled (ordered by importance): +* [REQUIRED FOR V1] Allow for DOT transfers to KILT to be paid with those DOTs +* [REQUIRED FOR V1] Allow for eKILT transfers to KILT (to be swapped for KILTs) to be paid with those eKILTs +* [REQUIRED FOR V2] Add hook to check the swap parameters (restricting where remote assets can be sent to). +* [REQUIRED FOR V1] Add integrity tests to check invariant that total issuance - remote balance = local pool balance (circulating supply) -> especially useful when adding token ratios, to avoid rounding errors +* [OPTIONAL] Add configurable ratio for local/remote swaps. +* [OPTIONAL] Delegate XCM message composition to a trait Config as well, depending on the destination (choosing which asset to use for payments, what amount, etc). diff --git a/docusaurus.config.js b/docusaurus.config.js index 1a0a0a401..81151f6b6 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -104,6 +104,11 @@ module.exports = { docId: 'develop/opendid/what-is-opendid', label: 'OpenDID Documentation', }, + { + type: 'doc', + docId: 'develop/polarpath/what-is-polarpath', + label: 'Polar path Documentation', + }, ], }, { From d01d4fc1d88722a737d6353ab1ff6b148da7e70d Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Thu, 11 Jul 2024 09:03:13 +0200 Subject: [PATCH 04/22] Draft Signed-off-by: Chris Chinchilla --- docs/develop/09_polarpath/01_overview.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/develop/09_polarpath/01_overview.md b/docs/develop/09_polarpath/01_overview.md index 06ce829f9..b24d39158 100644 --- a/docs/develop/09_polarpath/01_overview.md +++ b/docs/develop/09_polarpath/01_overview.md @@ -47,8 +47,12 @@ Polar path uses Polkadot's [Cross-Consensus Message Format (XCM)](https://wiki.p Before performing a switch, you first need to create a switch pair between the parachain token and the ERC-20 token using the `setSwitchPair` extrinisc. Then you can use any of the other extriniscs with the switch pair, including performing the switch itself using the `switch` extrinisc. -:::tip Remote asset -A remote asset is the identifier of the asset considered to be the other side of the switch pair. For an ERC20 token, this is a [MultiLocation](https://wiki.polkadot.network/docs/learn/xcm/fundamentals/multilocation-summary) (in XCM terms) pointing to an address on one of the many EVM-based deployments. +:::tip Local and remote assets +A **local asset** is the identifier of the asset considered to be the parachain token. +This is a [Junction](https://wiki.polkadot.network/docs/learn/xcm/fundamentals/multilocation-junctions) type, refering where in the current hierachy to find the asset. + +A **remote asset** is the identifier of the asset considered to be the other side of the switch pair. +For an ERC20 token, this is a [MultiLocation](https://wiki.polkadot.network/docs/learn/xcm/fundamentals/multilocation-summary) type (in XCM terms) pointing directly to an address on one of the many EVM-based deployments. ::: ### `setSwitchPair` @@ -56,29 +60,29 @@ A remote asset is the identifier of the asset considered to be the other side of Create a new switch pair between a parachain token and an ERC-20 token. Returns a result and takes the following parameters: - `origin`: Polkadot [Junction](https://wiki.polkadot.network/docs/learn/xcm/fundamentals/multilocation-junctions) defining the -- `reserve_location`: -- `remote_asset_id`: -- `remote_fee`: -- `total_issuance`: A `u128` defining +- `reserve_location`: `MultiLocation` defining the location of the remote asset. +- `remote_asset_id`: Box +- `remote_fee`: Box +- `total_issuance`: A `u128` defining , - `circulating_supply`: A `u128` defining, ### `removeSwitchPair` Remove an existing switch pair. Returns a result and takes the following parameters: -- `remote_asset_id`: +- `remote_asset_id`: Box, ### `pauseSwitchPair` Pause an existing switch pair. Returns a result and takes the following parameters: -- `remote_asset_id`: +- `remote_asset_id`: Box, ### `resumeSwitchPair` Resume a paused an existing switch pair. Returns a result and takes the following parameters: -- `remote_asset_id`: +- `remote_asset_id`: Box, ### `switch` @@ -88,4 +92,4 @@ Returns a result and takes the following parameters: - `from`: T::AccountId - `to`: VersionedMultiLocation -- `amount`: LocalCurrencyBalanceOf +- `amount`: LocalCurrencyBalanceOf From c01a7c9f5a3b91ef2916978f73683139d1278034 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Tue, 23 Jul 2024 10:38:16 +0200 Subject: [PATCH 05/22] Update docs/develop/09_polarpath/01_overview.md --- docs/develop/09_polarpath/01_overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/09_polarpath/01_overview.md b/docs/develop/09_polarpath/01_overview.md index 06ce829f9..c8b99cf40 100644 --- a/docs/develop/09_polarpath/01_overview.md +++ b/docs/develop/09_polarpath/01_overview.md @@ -19,7 +19,7 @@ Making a Parachain Token to be usable on Ethereum requires the following steps: 1. Deploy an ERC-20 contract token to Ethereum with a fixed supply based on the parachain needs. 2. [Disable the token issuer rights](https://ethereum.org/en/guides/how-to-revoke-token-access/) on the ERC-20 contract. -3. [Register the ERC-20 token on Asset Hub](https://wiki.polkadot.network/docs/learn-assets#creation-and-management). +3. [Register the ERC-20 token on Asset Hub](https://docs.snowbridge.network/applications/token-transfers#token-registration). 4. The entity holding ERC-20 funds performs a one-time transfer of all tokens from their Ethereum account to the parachain's sovereign account on Asset Hub. 5. Parachain governance recognizes the wrapper around the ERC-20 token by pairing the ERC-20 token to the parachain token in the swap pallet and enable the token issuer rights. From 07409a16f66a72da5dd2a874db1fa805bb18a844 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Tue, 23 Jul 2024 12:43:36 +0200 Subject: [PATCH 06/22] Review Signed-off-by: Chris Chinchilla --- docs/develop/09_polarpath/01_overview.md | 25 +++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/docs/develop/09_polarpath/01_overview.md b/docs/develop/09_polarpath/01_overview.md index b24d39158..de472bfb4 100644 --- a/docs/develop/09_polarpath/01_overview.md +++ b/docs/develop/09_polarpath/01_overview.md @@ -3,11 +3,9 @@ id: what-is-polarpath title: Overview --- -Polar path consists of an `asset-swap` pallet for KILT chain runtimes and extrinisics that let parachain-based chain developers to make their native token accessible on the Ethereum network using [the Snowbridge bridge](https://docs.snowbridge.network) between Polkadot and Ethereum. +Polar path consists of an `asset-swap` pallet for parachain runtimes and extrinisics that let parachain developers make their native token accessible on the Ethereum network using [the Snowbridge bridge](https://docs.snowbridge.network) between Polkadot and Ethereum. -Polar path provides parachains with a solution for creating an ERC-20 wrapper around their native tokens, enabling a trustless conversion of any existing native parachain token (PARA) into a wrapped parachain token (wPARA) on Ethereum while maintaining the trustlessness guarantees Snowbridge provides. - -The pallet enables a configured conversion rate of parachain tokens on the origin chain to an ERC-20 wrapper token on Polkadot's AssetHub. +Polar path provides parachains with a solution for creating an ERC-20 wrapper around their native tokens, enabling a trustless, one to one conversion of any existing native parachain token (PARA) into a wrapped parachain token (wPARA) on Ethereum while maintaining the trustlessness guarantees Snowbridge provides. ## Setup @@ -15,9 +13,14 @@ The pallet enables a configured conversion rate of parachain tokens on the origi The Polkadot Relay Chain doesn't natively support assets apart from DOT. Instead, parachains support this functionality, and for Polkadot, this parachain is the [Asset Hub](https://wiki.polkadot.network/docs/build-integrate-assets). ::: -Making a Parachain Token to be usable on Ethereum requires the following steps: +Making a Parachain token usable on Ethereum requires the following steps: 1. Deploy an ERC-20 contract token to Ethereum with a fixed supply based on the parachain needs. + + :::tip Asset Hub + In most cases, the total supply should match the parachain max supply. + ::: + 2. [Disable the token issuer rights](https://ethereum.org/en/guides/how-to-revoke-token-access/) on the ERC-20 contract. 3. [Register the ERC-20 token on Asset Hub](https://wiki.polkadot.network/docs/learn-assets#creation-and-management). 4. The entity holding ERC-20 funds performs a one-time transfer of all tokens from their Ethereum account to the parachain's sovereign account on Asset Hub. @@ -41,15 +44,19 @@ Polar path uses Polkadot's [Cross-Consensus Message Format (XCM)](https://wiki.p ### Sending tokens from Ethereum to the parachain 1. Send wPARAs from the ERC-20 contract on Ethereum to Asset Hub via Snowbridge -2. Transmit wPARAs on Asset Hub to PARAs on the parachain via XCM +2. Send wPARAs on Asset Hub to PARAs on the parachain via XCM ## Extrinsics -Before performing a switch, you first need to create a switch pair between the parachain token and the ERC-20 token using the `setSwitchPair` extrinisc. Then you can use any of the other extriniscs with the switch pair, including performing the switch itself using the `switch` extrinisc. +Before performing a switch, the `origin` account first needs to create a switch pair between the parachain token and the ERC-20 token using the `setSwitchPair` extrinisc. Then you can use any of the other extriniscs with the switch pair, including performing the switch itself using the `switch` extrinisc. + +:::tip KILT example +The KILT parachain uses the `Root` origin account, so creating a switch pair requires a referendum to dispatch the extrinsic. +::: -:::tip Local and remote assets +:::info Local and remote assets A **local asset** is the identifier of the asset considered to be the parachain token. -This is a [Junction](https://wiki.polkadot.network/docs/learn/xcm/fundamentals/multilocation-junctions) type, refering where in the current hierachy to find the asset. +This is a [Junction](https://wiki.polkadot.network/docs/learn/xcm/fundamentals/multilocation-junctions) type, referring where in the current hierarchy to find the asset. A **remote asset** is the identifier of the asset considered to be the other side of the switch pair. For an ERC20 token, this is a [MultiLocation](https://wiki.polkadot.network/docs/learn/xcm/fundamentals/multilocation-summary) type (in XCM terms) pointing directly to an address on one of the many EVM-based deployments. From 8217630f3a06d3d37c54570ce6ae9d8f4b3118d7 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Tue, 23 Jul 2024 12:51:27 +0200 Subject: [PATCH 07/22] Add versions Signed-off-by: Chris Chinchilla --- docs/develop/09_polarpath/01_overview.md | 4 ++++ src/versions.js | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/develop/09_polarpath/01_overview.md b/docs/develop/09_polarpath/01_overview.md index 50ec1fe29..2e9ac50ae 100644 --- a/docs/develop/09_polarpath/01_overview.md +++ b/docs/develop/09_polarpath/01_overview.md @@ -3,6 +3,10 @@ id: what-is-polarpath title: Overview --- +:::version-label[polarPath] + +::: + Polar path consists of an `asset-swap` pallet for parachain runtimes and extrinisics that let parachain developers make their native token accessible on the Ethereum network using [the Snowbridge bridge](https://docs.snowbridge.network) between Polkadot and Ethereum. Polar path provides parachains with a solution for creating an ERC-20 wrapper around their native tokens, enabling a trustless, one to one conversion of any existing native parachain token (PARA) into a wrapped parachain token (wPARA) on Ethereum while maintaining the trustlessness guarantees Snowbridge provides. diff --git a/src/versions.js b/src/versions.js index d9386b7f8..57b0edde9 100644 --- a/src/versions.js +++ b/src/versions.js @@ -1,5 +1,12 @@ export const nodeVersions = { - '1.13.0':{ + '1.14.0':{ + name: 'Polar Path', + features: [ + { polarPath: "Spiritnet" }, + { polarPath: "Peregrine" }, + ], + }, + '1.13.0':{ name: 'Dippy Duck', features: [ { DIP: "Spiritnet" }, From d34179b9318fa205ea11ff25a1a17be4971d1538 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Tue, 23 Jul 2024 12:52:47 +0200 Subject: [PATCH 08/22] Fix malformed tag Signed-off-by: Chris Chinchilla --- docs/develop/09_polarpath/01_overview.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/develop/09_polarpath/01_overview.md b/docs/develop/09_polarpath/01_overview.md index 2e9ac50ae..c48ad2ced 100644 --- a/docs/develop/09_polarpath/01_overview.md +++ b/docs/develop/09_polarpath/01_overview.md @@ -72,28 +72,28 @@ Create a new switch pair between a parachain token and an ERC-20 token. Returns - `origin`: Polkadot [Junction](https://wiki.polkadot.network/docs/learn/xcm/fundamentals/multilocation-junctions) defining the - `reserve_location`: `MultiLocation` defining the location of the remote asset. -- `remote_asset_id`: Box -- `remote_fee`: Box -- `total_issuance`: A `u128` defining , -- `circulating_supply`: A `u128` defining, +- `remote_asset_id`: VersionedAssetId +- `remote_fee`: VersionedMultiAsset +- `total_issuance`: A `u128` defining +- `circulating_supply`: A `u128` defining ### `removeSwitchPair` Remove an existing switch pair. Returns a result and takes the following parameters: -- `remote_asset_id`: Box, +- `remote_asset_id`: VersionedAssetId ### `pauseSwitchPair` Pause an existing switch pair. Returns a result and takes the following parameters: -- `remote_asset_id`: Box, +- `remote_asset_id`: VersionedAssetId ### `resumeSwitchPair` Resume a paused an existing switch pair. Returns a result and takes the following parameters: -- `remote_asset_id`: Box, +- `remote_asset_id`: VersionedAssetId ### `switch` @@ -103,4 +103,4 @@ Returns a result and takes the following parameters: - `from`: T::AccountId - `to`: VersionedMultiLocation -- `amount`: LocalCurrencyBalanceOf +- `amount`: LocalCurrencyBalanceOf From 023d28904ad884fd296224d90aaaaa60e3e0a70b Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Tue, 23 Jul 2024 17:10:02 +0200 Subject: [PATCH 09/22] Draft Signed-off-by: Chris Chinchilla --- docs/develop/09_polarpath/01_overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/09_polarpath/01_overview.md b/docs/develop/09_polarpath/01_overview.md index c48ad2ced..03bf5f674 100644 --- a/docs/develop/09_polarpath/01_overview.md +++ b/docs/develop/09_polarpath/01_overview.md @@ -27,7 +27,7 @@ Making a Parachain token usable on Ethereum requires the following steps: 2. [Disable the token issuer rights](https://ethereum.org/en/guides/how-to-revoke-token-access/) on the ERC-20 contract. 3. [Register the ERC-20 token on Asset Hub](https://docs.snowbridge.network/applications/token-transfers#token-registration). -4. The entity holding ERC-20 funds performs a one-time transfer of all tokens from their Ethereum account to the parachain's sovereign account on Asset Hub. +4. The entity holding ERC-20 funds performs a one-time transfer of all tokens from their Ethereum account, minus the amount of tokens previously locked with the parachain, to the parachain's sovereign account on Asset Hub. 5. Parachain governance recognizes the wrapper around the ERC-20 token by pairing the ERC-20 token to the parachain token in the swap pallet and enable the token issuer rights. Holders of the token on the parachain can can now switch tokens between it and Ethereum. From 50cc0e7bd636a8fc85c6c8d6b26bbe6183fd9655 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Tue, 23 Jul 2024 17:13:49 +0200 Subject: [PATCH 10/22] Remove the variable Signed-off-by: Chris Chinchilla --- docs/develop/09_polarpath/01_overview.md | 27 ++++-------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/docs/develop/09_polarpath/01_overview.md b/docs/develop/09_polarpath/01_overview.md index 03bf5f674..348fcae22 100644 --- a/docs/develop/09_polarpath/01_overview.md +++ b/docs/develop/09_polarpath/01_overview.md @@ -68,39 +68,20 @@ For an ERC20 token, this is a [MultiLocation](https://wiki.polkadot.network/docs ### `setSwitchPair` -Create a new switch pair between a parachain token and an ERC-20 token. Returns a result and takes the following parameters: - -- `origin`: Polkadot [Junction](https://wiki.polkadot.network/docs/learn/xcm/fundamentals/multilocation-junctions) defining the -- `reserve_location`: `MultiLocation` defining the location of the remote asset. -- `remote_asset_id`: VersionedAssetId -- `remote_fee`: VersionedMultiAsset -- `total_issuance`: A `u128` defining -- `circulating_supply`: A `u128` defining +Create a new switch pair between a parachain token and an ERC-20 token. ### `removeSwitchPair` -Remove an existing switch pair. Returns a result and takes the following parameters: - -- `remote_asset_id`: VersionedAssetId +Remove an existing switch pair. ### `pauseSwitchPair` -Pause an existing switch pair. Returns a result and takes the following parameters: - -- `remote_asset_id`: VersionedAssetId +Pause an existing switch pair. ### `resumeSwitchPair` -Resume a paused an existing switch pair. Returns a result and takes the following parameters: - -- `remote_asset_id`: VersionedAssetId +Resume a paused an existing switch pair. ### `switch` Allow any user with enough parachain asset balance to send them to the [Asset Hub pool account](https://docs.rs/pallet-asset-conversion/latest/pallet_asset_conversion/pallet/struct.Pallet.html#method.create_pool) for a specific switch pair and receive a corresponding amount of remote asset from the parachain's sovereign account on the remote location, to a `MultiLocation` of their choice. - -Returns a result and takes the following parameters: - -- `from`: T::AccountId -- `to`: VersionedMultiLocation -- `amount`: LocalCurrencyBalanceOf From 4c345dfaf0f7e9f1557f22ae6e4982e4811c8aa4 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Thu, 25 Jul 2024 17:38:57 +0200 Subject: [PATCH 11/22] Rewrite paths to not be broken Signed-off-by: Chris Chinchilla --- docs/develop/09_polarpath/02_switch_pallet.md | 141 ++++++++++++++++++ docs/develop/09_polarpath/README.md | 11 -- docusaurus.config.js | 34 +++-- 3 files changed, 160 insertions(+), 26 deletions(-) create mode 100644 docs/develop/09_polarpath/02_switch_pallet.md delete mode 100644 docs/develop/09_polarpath/README.md diff --git a/docs/develop/09_polarpath/02_switch_pallet.md b/docs/develop/09_polarpath/02_switch_pallet.md new file mode 100644 index 000000000..aa9e17382 --- /dev/null +++ b/docs/develop/09_polarpath/02_switch_pallet.md @@ -0,0 +1,141 @@ +# Asset switch pallet + +The asset switch pallet allows for switching the chain local currency 1:1 with a remote asset at a remote destination, according to the provided configuration, and using XCM. + +This is possible by creating a *switch pair*, which contains information about the remote asset's identifier (e.g., its MultiLocation`), the remote location where the asset lives (and with which XCM communication takes place), the circulating supply of the remote asset, which can be switched back for the local currency, and additional information relevant for the XCM communication, which is explained more in-depth later on. + +## Summary + +The pallet lets users on the local chain lock `N` tokens of the chain's native currency into a switch pair-specific account to receive `N` remote assets on the configured remote location, which are transferred to them from the source chain's sovereign account on the remote chain. + +## Design choices + +The pallet aims to be generic enough for most parachains to be able to add one or more instances of the asset switch pallet into their runtime, after configuring it according to their needs. + +The pallet makes the following assumptions: + +* The local asset to switch is always the chain local currency, implementing the `fungible::Mutate` trait. +* The switch ratio is pre-defined to be 1:1, i.e., one unit of local currency for one unit of remote asset. +* The pallet only exposes calls to allow local -> remote switches. The reverse is assumed to happen via XCM reserve transfer from the configured remote location, for which the pallet crate provides all the XCM components that are dynamically configured based on the switch pair information stored within each instance of this pallet. +* The sovereign account of the source chain at destination owns the remote assets in the amount that is specified when the switch pair is created. The validation of this requirement is delegated to the source chain governance in the act leading to the creation of the switch pair, as the source chain itself has currently no means of doing that. +* Similarly, the pallet has currently no way to verify that a transfer of remote tokens from the chain sovereign account to the **specified** beneficiary has been completed successfully on the remote location, hence it takes an optimistic approach given that all the verifiable preconditions for the switch are verified on the source chain, i.e., the chain from which the switch originates. Any unexpected issues in the transfer on the remote location will most likely require intervention of the source chain governance to re-balance the state and make it consistent again. + +## Add the pallet to the runtime + +Add the following line to the runtime `Cargo.toml` dependencies section: + +```toml +pallet-asset-switch = {git = "https://github.com/KILTprotocol/kilt-node.git", branch = "release-1.13.0"} +``` + +The asset switch pallet is available in the KILT node release 1.13.0 and later. + +## Configure the pallet + +The pallet can be added one or more times to the runtime. + +For multiple deployments of the same pallet (e.g., to bridge the local currency to different remote assets), pass runtime configuration to the pallet's `Config` trait. + +```rust,ignore +pub type SwitchPool1 = pallet_asset_switch::Instance1; +impl pallet_asset_switch::Config for Runtime { + // Config +} + +pub type SwitchPool2 = pallet_asset_switch::Instance2; +impl pallet_asset_switch::Config for Runtime { + // Config +} +``` + +If a single instance is required, then use the default instance: + +```rust +impl pallet_asset_switch::Config for Runtime { + // Config +} +``` + +## The `Config` trait + +As the pallet is generic over the runtime specifics, the `Config` trait requires the following configuration parameters passed to it: + +- `type AccountIdConverter: TryConvert`: Because the `AccountId` type can be anything in the runtime, the converter is responsible for converting such a `AccountId` into a `Junction`, which is then used for some XCM processing. +- `type AssetTransactor: TransactAsset`: This component is used when charging the extrinsic submitter with the XCM fees that the chain will pay at the remote chain. For instance, if the transfer on the remote chain will cost 0.1 DOTs, the `AssetTransactor` might deduct 0.1 DOTs from the user's previously topped up balance on the source chain (more details below). +- `type FeeOrigin: EnsureOrigin`: The origin that can update the XCM fee to be paid for the transfer on the remote chain. +- `type LocalCurrency: MutateFungible`: The chain's local currency. +- `type PauseOrigin: EnsureOrigin`: The origin that can pause a switch pair, e.g., if a vulnerability is found. +- `type RuntimeEvent: From> + IsType<::RuntimeEvent>`: The aggregate `Event` type. +- `type SubmitterOrigin: EnsureOrigin`: The origin that can call the `switch` extrinsic and perform the switch. +- `type SwitchHooks: SwitchHooks`: Any additional runtime-specific logic that can be injected both before and after local tokens are exchanged for the remote assets, and before and after the remote assets are converted into local tokens. +- `type SwitchOrigin: EnsureOrigin`: The origin that can set, resume, and delete a switch pair. +- `type WeightInfo: WeightInfo`: The computed weights of the pallet after benchmarking it. +- `type XcmRouter: SendXcm`: The component responsible for routing XCM messages to the switch pair remote location to perform the remote asset transfer from the chain's sovereign account to the specified beneficiary. + +### Benchmark-only `Config` components + +- `type BenchmarkHelper: BenchmarkHelper`: Helper trait to allow the runtime to set the ground before the benchmark logic is executed. It allows the runtime to return any of the parameters that are used in the extrinsic benchmarks, or `None` if the runtime has no special conditions to fulfil. + +## Storage + +The pallet has a single `SwitchPair` storage value that contains a `Option`. +If unset, no switch pair is configured hence no switch can happen. +When set and its status is `Running`, switches are enabled in both directions. + +## Events + +The pallet generates the following events: + +- `SwitchPairCreated`: when a new switch pair is created by the required origin, e.g., governance. +- `SwitchPairRemoved`: when a switch pair is removed by the root origin. +- `SwitchPairResumed`: when a switch pair has (re-)enabled local to remote asset switches. +- `SwitchPairPaused`: when a switch pair has been paused. +- `SwitchPairFeeUpdated`: when the XCM fee for the switch transfer has been updated. +- `LocalToRemoteSwitchExecuted`: when a switch of some local tokens for the remote asset has taken place. +- `RemoteToLocalSwitchExecuted`: when a switch of some remote assets for the local tokens has taken place. + +## Calls + +1. `pub fn set_switch_pair(origin: OriginFor, remote_asset_total_supply: u128, remote_asset_id: Box, remote_asset_circulating_supply: u128, remote_reserve_location: Box, remote_asset_ed: u128, remote_xcm_fee: Box) -> DispatchResult`: Set a new switch pair between the local currency and the specified `remote_asset_id` on the `reserve_location`. The specified `total_issuance` includes both the `circulating_supply` (i.e., the remote asset amount that the chain does not control on the `reserve_location`) and the locked supply under the control of the chain's sovereign account on the `reserve_location`. For this reason, the value of `total_issuance` must be at least as large as `circulating_supply`. It is possible for `circulating_supply` to be `0`, in which case it means this chain controls all the `total_issuance` of the remote asset, which can be obtained by locking a corresponding amount of local tokens via the `switch` call below. + + Furthermore, the pallet calculates the account that will hold the local tokens locked in exchange for remote tokens. This account is based on the pallet runtime name as returned by the `PalletInfoAccess` trait and the value of `remote_asset_id`. The generated account must already have a balance of at least `circulating_supply`, ensuring enough local tokens are locked to satisfy all requests to exchange the remote asset for local tokens. The balance of such an account can be increased with a simple transfer after obtaining the to-be-created switch pair pool account by interacting with the [asset-switch runtime API][asset-switch-runtime-api]. + + This requirement can be bypassed with the `force_set_switch_pair` call. Only `SwitchOrigin` can call this, and in most cases it will most likely be a governance-based origin such as the one provided by referenda or collectives with high privileges. +2. `pub fn force_set_switch_pair(origin: OriginFor, reserve_location: Box, remote_asset_id: Box, remote_xcm_fee: Box, total_issuance: u128, circulating_supply: u128) -> DispatchResult`: The same as the `set_switch_pair`, but skips the check over the switch pair pool account balance, and requires the `root` origin for the call to be dispatched. +3. `pub fn force_unset_switch_pair(origin: OriginFor) -> DispatchResult`: Forcibly remove a previously-stored switch pair. This operation can only be called by the `root` origin. + + **Any intermediate state, such as local tokens locked in the switch pair pool or remote assets that are not switchable anymore for local tokens, must be taken care of with subsequent governance operations.** +4. `pub fn pause_switch_pair(origin: OriginFor) -> DispatchResult`: Allows the `PauseOrigin` to immediately pause switches in both directions. +5. `pub fn resume_switch_pair(origin: OriginFor) -> DispatchResult`: Allows the `SwitchOrigin` to resume switches in both directions. +6. `pub fn remote_xcm_fee(origin: OriginFor, new: Box) -> DispatchResult`: Allows the `FeeOrigin` to update the required XCM fee to execute the transfer of remote asset on the reserve location from the chain's sovereign account to the beneficiary specified in the `switch` operation. + + For example, if the cost of sending an XCM message containing a `TransferAsset` instruction from the source chain to AssetHub (reserve location) changes from 0.1 DOTs to 0.2 DOTs, the fee will need to be updated accordingly to avoid transfers failing on AssetHub, leaving the whole system in an inconsistent state. Since the pallet refunds any unused assets on the reserve location to the account initiating the switch on the source chain, it is not a big issue to overestimate this value here since no funds will be burnt or unfairly taken from the user during the switch process. +7. `pub fn switch(origin: OriginFor, local_asset_amount: LocalCurrencyBalanceOf, beneficiary: Box) -> DispatchResult`: Allows the `SubmitterOrigin` to perform a switch of some local tokens for the corresponding amount of remote assets on the configured `reserve_location`. The switch will fail on the source chain if any of the following preconditions are not met: + 1. The submitter does not have enough balance to pay for the tx fees on the source chain or to cover the amount of local tokens requested. Hence, the user's local balance must be greater than or equal to the amount of tokens requested in the switch + the cost of executing the extrinsic on the source chain. + 2. No switch pair is set or the switch pair is currently not allowing switches. + 3. There are not enough locked remote assets on the `reserve_location` to cover the switch request. e.g., if the chain sovereign account on the `reserve_location` only controls `10` remote assets, users can only switch up to `10` local tokens. Once the limit is reached, someone needs to perform the reverse operation (remote -> local switch) to free up some remote tokens. + 4. The switch pair `reserve_location` is not reachable from the source chain, because the configured `XcmRouter` returns an error (e.g., there is no XCM channel between the two chains). + 5. The configured `SwitchHooks` returns an error in either the `pre-` or the `post-` switch checks. + 6. The user does not have enough assets to pay for the required remote XCM fees as specified in the switch pair info and as returned by the configured `AssetTransactor`. + +## XCM components + +Because the switch functionality relies on XCM, the pallet provides a few XCM components that should be included in a runtime to enable the whole set of interactions between the source chain and the configured remote reserve location. + +* `AccountId32ToAccountId32JunctionConverter` in [xcm::convert][xcm-convert]: provides an implementation for the pallet's `AccountIdConverter` config component, that converts local `AccountId32`s into a `AccountId32` XCM `Junction`. This works only for chains that use `AccountId32` as their overarching `AccountId` type. +* `MatchesSwitchPairXcmFeeFungibleAsset` in [xcm::match][xcm-match]: provides an implementation of the `MatchesFungibles` that returns the input `MultiAsset` if its ID matches the XCM fee asset ID as configured in the switch pair, if present. If no switch pair is present or if the ID does not match, it returns a [XcmExecutorError::AssetNotHandled][XcmExecutorError::AssetNotHandled], which does not prevent other matchers after it to apply their matching logic. It can be used for the `AssetTransactor` property of the [XcmExecutor::Config][XcmExecutor::Config] and as the `AssetTransactor` component of this pallet in the runtime. +* `UsingComponentsForXcmFeeAsset` in [xcm::trade][xcm-trade]: provides an implementation of `WeightTrader` that allows buying weight using the XCM fee asset configured in the switch pair. That is, if the XCM fee asset is DOT, and users need to send DOTs to this chain in order to pay for XCM fees, this component lets them use those very same DOTs that are being sent to pay for the XCM fees on this chain. Any unused weight is burnt, since this chain's sovereign account already controls the whole amount on the reserve location due to the nature of reserve-based transfers. It can be used for the `Trader` property of the [XcmExecutor::Config][XcmExecutor::Config]. +* `UsingComponentsForSwitchPairRemoteAsset` in [xcm::trade][xcm-trade]: provides an implementation of `WeightTrader` that allows buying weight using the remote asset configured in the switch pair when sending it to this chain to be switched for local tokens. Any unused weight is transferred from the switch pair account to the configured `FeeDestinationAccount`, as those local tokens do not need to back any remote assets because they have been used to pay for XCM fees. It can be used for the `Trader` property of the [XcmExecutor::Config][XcmExecutor::Config]. +* `SwitchPairRemoteAssetTransactor` in [xcm::transact][xcm-transact]: provides an implementation of `TransactAsset::deposit_asset` that matches the asset to be deposited with the remote asset configured in the switch pair '(else it returns [Error::AssetNotFound][Error::AssetNotFound]) and moves as many local tokens from the switch pair account to the specified `who` destination. It also calls into the `SwitchHooks` pre- and post- checks, and generates a `RemoteToLocalSwitchExecuted` if everything is completed successfully. It can be used for the `AssetTransactor` property of the [XcmExecutor::Config][XcmExecutor::Config]. +* `IsSwitchPairXcmFeeAsset` in [xcm::transfer][xcm-transfer]: provides an implementation of `ContainsPair` that returns `true` if the given asset and sender match the stored switch pair XCM fee asset and reserve location respectively. It can be used for the `IsReserve` property of the [XcmExecutor::Config][XcmExecutor::Config]. +* `IsSwitchPairRemoteAsset` in [xcm::transfer][xcm-transfer]: provides an implementation of `ContainsPair` that returns `true` if the given asset and sender match the stored switch pair remote asset and reserve location respectively. It can be used for the `IsReserve` property of the [XcmExecutor::Config][XcmExecutor::Config]. + +[asset-switch-runtime-api]: https://github.com/KILTprotocol/kilt-node/tree/604a78397c20a396e50c19fb925c96b7c9c51635/runtime-api/asset-switch +[xcm-convert]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/604a78397c20a396e50c19fb925c96b7c9c51635/pallets/pallet-asset-switch/src/xcm/convert.rs +[xcm-match]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/604a78397c20a396e50c19fb925c96b7c9c51635/pallets/pallet-asset-switch/src/xcm/match.rs +[XcmExecutorError::AssetNotHandled]: https://github.com/paritytech/polkadot-sdk/blob/33324fe01c5b1f341687cef2aa6e767f6acf40f3/polkadot/xcm/xcm-executor/src/traits/token_matching.rs#L54 +[XcmExecutor::Config]: https://github.com/paritytech/polkadot-sdk/blob/33324fe01c5b1f341687cef2aa6e767f6acf40f3/polkadot/xcm/xcm-executor/src/config.rs#L31 +[xcm-trade]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/604a78397c20a396e50c19fb925c96b7c9c51635/pallets/pallet-asset-switch/src/xcm/trade.rs +[Error::AssetNotFound]: https://github.com/paritytech/polkadot-sdk/blob/e5791a56dcc35e308a80985cc3b6b7f2ed1eb6ec/polkadot/xcm/src/v3/traits.rs#L68 +[xcm-transact]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/604a78397c20a396e50c19fb925c96b7c9c51635/pallets/pallet-asset-switch/src/xcm/transact.rs +[xcm-transfer]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/604a78397c20a396e50c19fb925c96b7c9c51635/pallets/pallet-asset-switch/src/xcm/transfer.rs diff --git a/docs/develop/09_polarpath/README.md b/docs/develop/09_polarpath/README.md deleted file mode 100644 index 3dcaa4867..000000000 --- a/docs/develop/09_polarpath/README.md +++ /dev/null @@ -1,11 +0,0 @@ -WIP. - -# TODO - -Besides the TODOs in the code, the following points must be tackled (ordered by importance): -* [REQUIRED FOR V1] Allow for DOT transfers to KILT to be paid with those DOTs -* [REQUIRED FOR V1] Allow for eKILT transfers to KILT (to be swapped for KILTs) to be paid with those eKILTs -* [REQUIRED FOR V2] Add hook to check the swap parameters (restricting where remote assets can be sent to). -* [REQUIRED FOR V1] Add integrity tests to check invariant that total issuance - remote balance = local pool balance (circulating supply) -> especially useful when adding token ratios, to avoid rounding errors -* [OPTIONAL] Add configurable ratio for local/remote swaps. -* [OPTIONAL] Delegate XCM message composition to a trait Config as well, depending on the destination (choosing which asset to use for payments, what amount, etc). diff --git a/docusaurus.config.js b/docusaurus.config.js index 81151f6b6..f5b36cc44 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -291,25 +291,29 @@ module.exports = { 'docusaurus-plugin-remote-content', { // Pulls external files and adds them as files in the Docusaurus folder, rewriting the title and the file name - name: 'swap-pallet', + name: 'switch-pallet', // TODO: Temp URL sourceBaseUrl: - 'https://raw.githubusercontent.com/KILTprotocol/kilt-node/b23207e9782ea024cde8f4883cb4029eebb1735f/pallets/pallet-asset-swap/', + 'https://raw.githubusercontent.com/KILTprotocol/kilt-node/604a78397c20a396e50c19fb925c96b7c9c51635/pallets/pallet-asset-switch/', outDir: 'docs/develop/09_polarpath', documents: ['README.md'], - // modifyContent(filename, content) { - // if (filename.includes('README')) { - // var trimContent = content.replace( - // '# Decentralized Identity Provider (DIP) consumer pallet', - // '# Consumer pallet' - // ) - // return { - // filename: '03_consumer.md', - // content: trimContent, - // } - // } - // return undefined - // }, + modifyContent(filename, content) { + if (filename.includes('README')) { + var trimContent = content.replaceAll( + './src/xcm/', + 'https://raw.githubusercontent.com/KILTprotocol/kilt-node/604a78397c20a396e50c19fb925c96b7c9c51635/pallets/pallet-asset-switch/src/xcm/' + ) + var trimContent2 = trimContent.replace( + '../../runtime-api/asset-switch/', + 'https://github.com/KILTprotocol/kilt-node/tree/604a78397c20a396e50c19fb925c96b7c9c51635/runtime-api/asset-switch' + ) + return { + filename: '02_switch_pallet.md', + content: trimContent2, + } + } + return undefined + }, }, ], ], From c8d903b1579275878c1c5d76c15dda12266e4417 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Tue, 6 Aug 2024 10:02:07 +0200 Subject: [PATCH 12/22] Update paths for release Signed-off-by: Chris Chinchilla --- docusaurus.config.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docusaurus.config.js b/docusaurus.config.js index f5b36cc44..dad6a758d 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -294,18 +294,18 @@ module.exports = { name: 'switch-pallet', // TODO: Temp URL sourceBaseUrl: - 'https://raw.githubusercontent.com/KILTprotocol/kilt-node/604a78397c20a396e50c19fb925c96b7c9c51635/pallets/pallet-asset-switch/', + 'https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.0/pallets/pallet-asset-switch/', outDir: 'docs/develop/09_polarpath', documents: ['README.md'], modifyContent(filename, content) { if (filename.includes('README')) { var trimContent = content.replaceAll( './src/xcm/', - 'https://raw.githubusercontent.com/KILTprotocol/kilt-node/604a78397c20a396e50c19fb925c96b7c9c51635/pallets/pallet-asset-switch/src/xcm/' + 'https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.0/pallets/pallet-asset-switch/src/xcm/' ) var trimContent2 = trimContent.replace( '../../runtime-api/asset-switch/', - 'https://github.com/KILTprotocol/kilt-node/tree/604a78397c20a396e50c19fb925c96b7c9c51635/runtime-api/asset-switch' + 'https://github.com/KILTprotocol/kilt-node/tree/1.14.0/runtime-api/asset-switch' ) return { filename: '02_switch_pallet.md', From 7e76510594f362b2cb76daaa69ff5fea1d3d97c2 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Thu, 15 Aug 2024 11:57:11 +0200 Subject: [PATCH 13/22] Draft Signed-off-by: Chris Chinchilla --- docs/develop/09_polarpath/01_overview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/develop/09_polarpath/01_overview.md b/docs/develop/09_polarpath/01_overview.md index 348fcae22..c0bd44f9c 100644 --- a/docs/develop/09_polarpath/01_overview.md +++ b/docs/develop/09_polarpath/01_overview.md @@ -9,7 +9,7 @@ title: Overview Polar path consists of an `asset-swap` pallet for parachain runtimes and extrinisics that let parachain developers make their native token accessible on the Ethereum network using [the Snowbridge bridge](https://docs.snowbridge.network) between Polkadot and Ethereum. -Polar path provides parachains with a solution for creating an ERC-20 wrapper around their native tokens, enabling a trustless, one to one conversion of any existing native parachain token (PARA) into a wrapped parachain token (wPARA) on Ethereum while maintaining the trustlessness guarantees Snowbridge provides. +Polar path provides parachains with a solution for creating an ERC-20 wrapper around their native tokens, enabling a trustless, one to one conversion of any existing native parachain token (TOKEN) into a wrapped parachain token (wTOKEN) on Ethereum while maintaining the trustlessness guarantees Snowbridge provides. ## Setup @@ -22,7 +22,7 @@ Making a Parachain token usable on Ethereum requires the following steps: 1. Deploy an ERC-20 contract token to Ethereum with a fixed supply based on the parachain needs. :::tip Asset Hub - In most cases, the total supply should match the parachain max supply. + Usually, the total supply should match the parachain max supply. ::: 2. [Disable the token issuer rights](https://ethereum.org/en/guides/how-to-revoke-token-access/) on the ERC-20 contract. From b27a7f1b9a5777eb1ecfb031617009a69a760b57 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Thu, 22 Aug 2024 12:48:00 +0200 Subject: [PATCH 14/22] Changes from review Signed-off-by: Chris Chinchilla --- docs/develop/09_polarpath/01_overview.md | 25 ++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/docs/develop/09_polarpath/01_overview.md b/docs/develop/09_polarpath/01_overview.md index c0bd44f9c..73445cb77 100644 --- a/docs/develop/09_polarpath/01_overview.md +++ b/docs/develop/09_polarpath/01_overview.md @@ -9,7 +9,7 @@ title: Overview Polar path consists of an `asset-swap` pallet for parachain runtimes and extrinisics that let parachain developers make their native token accessible on the Ethereum network using [the Snowbridge bridge](https://docs.snowbridge.network) between Polkadot and Ethereum. -Polar path provides parachains with a solution for creating an ERC-20 wrapper around their native tokens, enabling a trustless, one to one conversion of any existing native parachain token (TOKEN) into a wrapped parachain token (wTOKEN) on Ethereum while maintaining the trustlessness guarantees Snowbridge provides. +Polar path provides parachains with a solution for creating an ERC-20 wrapper around their native tokens, enabling a trustless, one to one conversion of any existing native parachain token (TOKEN) into a wrapped parachain token (eTOKEN) on Ethereum while maintaining the trustlessness guarantees Snowbridge provides. The switch also sends a corresponding amount of the native token to the parachain's sovereign account on the Asset Hub (wTOKEN). ## Setup @@ -19,16 +19,21 @@ The Polkadot Relay Chain doesn't natively support assets apart from DOT. Instead Making a Parachain token usable on Ethereum requires the following steps: -1. Deploy an ERC-20 contract token to Ethereum with a fixed supply based on the parachain needs. +1. All involved accounts need enough balance of TOKEN and wTOKEN to cover the switch. This includes the amount of the switch, fees, and an existential deposit. +2. Deploy an ERC-20 contract token to Ethereum with a fixed supply based on the parachain needs. :::tip Asset Hub Usually, the total supply should match the parachain max supply. ::: -2. [Disable the token issuer rights](https://ethereum.org/en/guides/how-to-revoke-token-access/) on the ERC-20 contract. -3. [Register the ERC-20 token on Asset Hub](https://docs.snowbridge.network/applications/token-transfers#token-registration). -4. The entity holding ERC-20 funds performs a one-time transfer of all tokens from their Ethereum account, minus the amount of tokens previously locked with the parachain, to the parachain's sovereign account on Asset Hub. -5. Parachain governance recognizes the wrapper around the ERC-20 token by pairing the ERC-20 token to the parachain token in the swap pallet and enable the token issuer rights. +3. [Disable the token issuer rights](https://ethereum.org/en/guides/how-to-revoke-token-access/) on the ERC-20 contract. +4. [Register the ERC-20 token on Asset Hub](https://docs.snowbridge.network/applications/token-transfers#token-registration). +5. The parachain must have a representative asset on the state of the reserve XCM fees asset. + + For example, in the case of Asset Hub, the parachain should implement, `pallet-assets` to manage DOT on their chain. + +6. The entity holding ERC-20 funds performs a one-time transfer of all tokens from their Ethereum account, minus the amount of tokens previously locked with the parachain, to the parachain's sovereign account on Asset Hub. +7. Parachain governance recognizes the wrapper around the ERC-20 token by pairing the ERC-20 token to the parachain token in the swap pallet and enable the token issuer rights. Holders of the token on the parachain can can now switch tokens between it and Ethereum. @@ -42,13 +47,13 @@ Polar path uses Polkadot's [Cross-Consensus Message Format (XCM)](https://wiki.p ### Sending tokens from the parachain to Ethereum -1. Transmit custom parachain tokens, "PARA", from the parachain to wrapped tokens "wPARAs" on Asset Hub via XCM -2. Send wPARAs from Asset Hub to the ERC-20 contract on Ethereum via Snowbridge +1. Transmit custom parachain tokens, "TOKEN", from the parachain to tokens "eTOKEN" on Asset Hub via XCM +2. Send eTOKENs from Asset Hub to the ERC-20 contract on Ethereum via Snowbridge ### Sending tokens from Ethereum to the parachain -1. Send wPARAs from the ERC-20 contract on Ethereum to Asset Hub via Snowbridge -2. Send wPARAs on Asset Hub to PARAs on the parachain via XCM +1. Send eTOKENs from the ERC-20 contract on Ethereum to Asset Hub via Snowbridge +2. Send wTOKENs on Asset Hub to TOKENs on the parachain via XCM ## Extrinsics From 9c1d8f97f18e08819235cc273082b1162492b8ce Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Tue, 27 Aug 2024 16:36:42 +0200 Subject: [PATCH 15/22] Draft Signed-off-by: Chris Chinchilla --- docs/develop/09_polarpath/01_overview.md | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/docs/develop/09_polarpath/01_overview.md b/docs/develop/09_polarpath/01_overview.md index 73445cb77..0509d05a3 100644 --- a/docs/develop/09_polarpath/01_overview.md +++ b/docs/develop/09_polarpath/01_overview.md @@ -57,7 +57,9 @@ Polar path uses Polkadot's [Cross-Consensus Message Format (XCM)](https://wiki.p ## Extrinsics -Before performing a switch, the `origin` account first needs to create a switch pair between the parachain token and the ERC-20 token using the `setSwitchPair` extrinisc. Then you can use any of the other extriniscs with the switch pair, including performing the switch itself using the `switch` extrinisc. +Before performing a switch, the `origin` account first needs to create a switch pair between the parachain token and the ERC-20 token using the `setSwitchPair` extrinisc. Then you can use any of the other extriniscs with the switch pair, including pausing, resuming, and performing the switch itself using the `switch` extrinisc. + +Read [the `switch` pallet's documentation](./02_switch_pallet.md) for more information on the extriniscs. :::tip KILT example The KILT parachain uses the `Root` origin account, so creating a switch pair requires a referendum to dispatch the extrinsic. @@ -70,23 +72,3 @@ This is a [Junction](https://wiki.polkadot.network/docs/learn/xcm/fundamentals/m A **remote asset** is the identifier of the asset considered to be the other side of the switch pair. For an ERC20 token, this is a [MultiLocation](https://wiki.polkadot.network/docs/learn/xcm/fundamentals/multilocation-summary) type (in XCM terms) pointing directly to an address on one of the many EVM-based deployments. ::: - -### `setSwitchPair` - -Create a new switch pair between a parachain token and an ERC-20 token. - -### `removeSwitchPair` - -Remove an existing switch pair. - -### `pauseSwitchPair` - -Pause an existing switch pair. - -### `resumeSwitchPair` - -Resume a paused an existing switch pair. - -### `switch` - -Allow any user with enough parachain asset balance to send them to the [Asset Hub pool account](https://docs.rs/pallet-asset-conversion/latest/pallet_asset_conversion/pallet/struct.Pallet.html#method.create_pool) for a specific switch pair and receive a corresponding amount of remote asset from the parachain's sovereign account on the remote location, to a `MultiLocation` of their choice. From 03e49864c39d7a593fb50e06e079320d0d5ddc0f Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Thu, 29 Aug 2024 11:14:40 +0200 Subject: [PATCH 16/22] Remove broken links Signed-off-by: Chris Chinchilla --- docs/concepts/05_credentials/02_ctypes.md | 2 +- docs/concepts/07_dip/04_user_account_kilt.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/concepts/05_credentials/02_ctypes.md b/docs/concepts/05_credentials/02_ctypes.md index f902ba161..11aa11918 100644 --- a/docs/concepts/05_credentials/02_ctypes.md +++ b/docs/concepts/05_credentials/02_ctypes.md @@ -16,7 +16,7 @@ The schema defines which properties exist and what their type should be, e.g., a ## CType model JSON schema -The following are all required properties of the JSON schema for [CType models](https://github.com/KILTprotocol/sdk-js/blob/master/packages/core/src/ctype/CType.schemas.ts): +The following are all required properties of the JSON schema for CType models: - `$id`: An **identifier**: in the format `kilt:ctype:0x{cTypeHash}`. - `$schema`: A **reference to CType metaschema**: Describes what a valid CType must looks like. You can find the latest metaschema on IPFS at the following address [ipfs://bafybeiah66wbkhqbqn7idkostj2iqyan2tstc4tpqt65udlhimd7hcxjyq/](ipfs://bafybeiah66wbkhqbqn7idkostj2iqyan2tstc4tpqt65udlhimd7hcxjyq/). diff --git a/docs/concepts/07_dip/04_user_account_kilt.md b/docs/concepts/07_dip/04_user_account_kilt.md index 834c3d736..97c5fb035 100644 --- a/docs/concepts/07_dip/04_user_account_kilt.md +++ b/docs/concepts/07_dip/04_user_account_kilt.md @@ -50,7 +50,7 @@ The command requires the following variables: - `relayApi` The [`ApiPromise`](https://polkadot.js.org/docs/api/examples/promise/) instance for the parent relay chain. - `signer` The signing callback to sign the cross-chain transaction. - `submitterAddress` The address of the transaction submitter on the consumer chain. -- `keyRelationship` The [`VerificationKeyRelationship`](https://kiltprotocol.github.io/sdk-js/types/types_src.VerificationKeyRelationship.html) required for the DIP operation authorized on the relay chain. +- `keyRelationship` The `VerificationKeyRelationship` required for the DIP operation authorized on the relay chain. And the following optional environment variables: From c54c480a28527523deab633a1f00deda7cc3ecf8 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Mon, 30 Sep 2024 12:46:34 +0200 Subject: [PATCH 17/22] Change config Signed-off-by: Chris Chinchilla --- docusaurus.config.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docusaurus.config.js b/docusaurus.config.js index dad6a758d..bf8fc143b 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -292,20 +292,19 @@ module.exports = { { // Pulls external files and adds them as files in the Docusaurus folder, rewriting the title and the file name name: 'switch-pallet', - // TODO: Temp URL sourceBaseUrl: - 'https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.0/pallets/pallet-asset-switch/', + 'https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.3/pallets/pallet-asset-switch/', outDir: 'docs/develop/09_polarpath', documents: ['README.md'], modifyContent(filename, content) { if (filename.includes('README')) { var trimContent = content.replaceAll( './src/xcm/', - 'https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.0/pallets/pallet-asset-switch/src/xcm/' + 'https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.3/pallets/pallet-asset-switch/src/xcm/' ) var trimContent2 = trimContent.replace( '../../runtime-api/asset-switch/', - 'https://github.com/KILTprotocol/kilt-node/tree/1.14.0/runtime-api/asset-switch' + 'https://github.com/KILTprotocol/kilt-node/tree/1.14.3/runtime-api/asset-switch' ) return { filename: '02_switch_pallet.md', From 59ad35efe5ac2b7e27b62828291a55f94603bfbd Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Mon, 30 Sep 2024 12:51:25 +0200 Subject: [PATCH 18/22] Fix links Signed-off-by: Chris Chinchilla --- docs/develop/02_chain/04_fullnode.md | 2 +- .../01_staking/01_become_a_collator/03_setup_node.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/develop/02_chain/04_fullnode.md b/docs/develop/02_chain/04_fullnode.md index d056efcc4..80264abf7 100644 --- a/docs/develop/02_chain/04_fullnode.md +++ b/docs/develop/02_chain/04_fullnode.md @@ -41,7 +41,7 @@ This can either be `peregrine` or `spiritnet`. Hence, to start a full node for the Spiritnet network, the parameter would be `--chain=spiritnet`. Unfortunately, there is no hardcoded chain spec for the Peregrine network, so the full path of the chainspec file must be provided `--chain=/node/dev-specs/kilt-parachain/peregrine-kilt.json`. -Please refer to the [KILT node repository](https://github.com/KILTprotocol/kilt-node/blob/master/dev-specs/kilt-parachain/peregrine-kilt.json) or the [Docker image](https://hub.docker.com/r/kiltprotocol/kilt-node/tags) for more information. +Please refer to the [KILT node repository](https://github.com/KILTprotocol/kilt-node/blob/master/chainspecs/peregrine/peregrine-paseo.json) or the [Docker image](https://hub.docker.com/r/kiltprotocol/kilt-node/tags) for more information. ### Specify the Blockchain Storage Path diff --git a/docs/participate/01_staking/01_become_a_collator/03_setup_node.md b/docs/participate/01_staking/01_become_a_collator/03_setup_node.md index d7d47eff5..f029d5870 100644 --- a/docs/participate/01_staking/01_become_a_collator/03_setup_node.md +++ b/docs/participate/01_staking/01_become_a_collator/03_setup_node.md @@ -74,7 +74,7 @@ This can either be `peregrine` or `spiritnet`. Hence, to start a collator node for the Spiritnet network, the parameter would be `--chain=spiritnet`. Unfortunately, there is no hardcoded chain spec for the Peregrine network, so the full path of the chainspec file must be provided `--chain=/node/dev-specs/kilt-parachain/peregrine-kilt.json`. -Please refer to the [KILT node repository](https://github.com/KILTprotocol/kilt-node/blob/master/dev-specs/kilt-parachain/peregrine-kilt.json) or the [Docker image](https://hub.docker.com/r/kiltprotocol/kilt-node/tags) for more information. +Please refer to the [KILT node repository](https://github.com/KILTprotocol/kilt-node/blob/master/chainspecs/peregrine/peregrine-paseo.json) or the [Docker image](https://hub.docker.com/r/kiltprotocol/kilt-node/tags) for more information. ### Specify the Blockchain Storage Path From 0f4a277271f1e8e0908cdf65c434ff57e50914a2 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Mon, 30 Sep 2024 13:50:16 +0200 Subject: [PATCH 19/22] Add disclaimer Signed-off-by: Chris Chinchilla --- docs/develop/09_polarpath/01_overview.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/develop/09_polarpath/01_overview.md b/docs/develop/09_polarpath/01_overview.md index 0509d05a3..436af962c 100644 --- a/docs/develop/09_polarpath/01_overview.md +++ b/docs/develop/09_polarpath/01_overview.md @@ -19,7 +19,12 @@ The Polkadot Relay Chain doesn't natively support assets apart from DOT. Instead Making a Parachain token usable on Ethereum requires the following steps: -1. All involved accounts need enough balance of TOKEN and wTOKEN to cover the switch. This includes the amount of the switch, fees, and an existential deposit. +1. All involved accounts need enough balance of TOKEN and wTOKEN to cover the switch. This includes the amount of the switch, fees, and an existential deposit. The balance can be in DOT, KSM, ETH, or USDC. + + :::danger + If you don't have enough balance when you perform the switch, you will lock your funds, requiring someone from the KILT governance team to unlock them. + ::: + 2. Deploy an ERC-20 contract token to Ethereum with a fixed supply based on the parachain needs. :::tip Asset Hub From cb0f6c4d461b6eba489bb228386df89c4f11f626 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Mon, 30 Sep 2024 13:50:24 +0200 Subject: [PATCH 20/22] Update imported file Signed-off-by: Chris Chinchilla --- docs/develop/09_polarpath/02_switch_pallet.md | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/develop/09_polarpath/02_switch_pallet.md b/docs/develop/09_polarpath/02_switch_pallet.md index aa9e17382..58cbc0736 100644 --- a/docs/develop/09_polarpath/02_switch_pallet.md +++ b/docs/develop/09_polarpath/02_switch_pallet.md @@ -2,7 +2,7 @@ The asset switch pallet allows for switching the chain local currency 1:1 with a remote asset at a remote destination, according to the provided configuration, and using XCM. -This is possible by creating a *switch pair*, which contains information about the remote asset's identifier (e.g., its MultiLocation`), the remote location where the asset lives (and with which XCM communication takes place), the circulating supply of the remote asset, which can be switched back for the local currency, and additional information relevant for the XCM communication, which is explained more in-depth later on. +This is possible by creating a *switch pair*, which contains information about the remote asset's identifier (e.g., its `Location`), the remote location where the asset lives (and with which XCM communication takes place), the circulating supply of the remote asset, which can be switched back for the local currency, and additional information relevant for the XCM communication, which is explained more in-depth later on. ## Summary @@ -25,10 +25,10 @@ The pallet makes the following assumptions: Add the following line to the runtime `Cargo.toml` dependencies section: ```toml -pallet-asset-switch = {git = "https://github.com/KILTprotocol/kilt-node.git", branch = "release-1.13.0"} +pallet-asset-switch = {git = "https://github.com/KILTprotocol/kilt-node.git", branch = "release-1.14.0"} ``` -The asset switch pallet is available in the KILT node release 1.13.0 and later. +The asset switch pallet is available in the KILT node release 1.14.0 and later. ## Configure the pallet @@ -50,7 +50,7 @@ impl pallet_asset_switch::Config for Runtime { If a single instance is required, then use the default instance: -```rust +```rust,ignore impl pallet_asset_switch::Config for Runtime { // Config } @@ -96,21 +96,21 @@ The pallet generates the following events: ## Calls -1. `pub fn set_switch_pair(origin: OriginFor, remote_asset_total_supply: u128, remote_asset_id: Box, remote_asset_circulating_supply: u128, remote_reserve_location: Box, remote_asset_ed: u128, remote_xcm_fee: Box) -> DispatchResult`: Set a new switch pair between the local currency and the specified `remote_asset_id` on the `reserve_location`. The specified `total_issuance` includes both the `circulating_supply` (i.e., the remote asset amount that the chain does not control on the `reserve_location`) and the locked supply under the control of the chain's sovereign account on the `reserve_location`. For this reason, the value of `total_issuance` must be at least as large as `circulating_supply`. It is possible for `circulating_supply` to be `0`, in which case it means this chain controls all the `total_issuance` of the remote asset, which can be obtained by locking a corresponding amount of local tokens via the `switch` call below. +1. `pub fn set_switch_pair(origin: OriginFor, remote_asset_total_supply: u128, remote_asset_id: Box, remote_asset_circulating_supply: u128, remote_reserve_location: Box, remote_asset_ed: u128, remote_xcm_fee: Box) -> DispatchResult`: Set a new switch pair between the local currency and the specified `remote_asset_id` on the `reserve_location`. The specified `total_issuance` includes both the `circulating_supply` (i.e., the remote asset amount that the chain does not control on the `reserve_location`) and the locked supply under the control of the chain's sovereign account on the `reserve_location`. For this reason, the value of `total_issuance` must be at least as large as `circulating_supply`. It is possible for `circulating_supply` to be `0`, in which case it means this chain controls all the `total_issuance` of the remote asset, which can be obtained by locking a corresponding amount of local tokens via the `switch` call below. Furthermore, the pallet calculates the account that will hold the local tokens locked in exchange for remote tokens. This account is based on the pallet runtime name as returned by the `PalletInfoAccess` trait and the value of `remote_asset_id`. The generated account must already have a balance of at least `circulating_supply`, ensuring enough local tokens are locked to satisfy all requests to exchange the remote asset for local tokens. The balance of such an account can be increased with a simple transfer after obtaining the to-be-created switch pair pool account by interacting with the [asset-switch runtime API][asset-switch-runtime-api]. This requirement can be bypassed with the `force_set_switch_pair` call. Only `SwitchOrigin` can call this, and in most cases it will most likely be a governance-based origin such as the one provided by referenda or collectives with high privileges. -2. `pub fn force_set_switch_pair(origin: OriginFor, reserve_location: Box, remote_asset_id: Box, remote_xcm_fee: Box, total_issuance: u128, circulating_supply: u128) -> DispatchResult`: The same as the `set_switch_pair`, but skips the check over the switch pair pool account balance, and requires the `root` origin for the call to be dispatched. +2. `pub fn force_set_switch_pair(origin: OriginFor, remote_asset_total_supply: u128, remote_asset_id: Box, remote_asset_circulating_supply: u128, remote_reserve_location: Box, remote_asset_ed: u128, remote_xcm_fee: Box) -> DispatchResult`: The same as the `set_switch_pair`, but skips the check over the switch pair pool account balance, and requires the `root` origin for the call to be dispatched. 3. `pub fn force_unset_switch_pair(origin: OriginFor) -> DispatchResult`: Forcibly remove a previously-stored switch pair. This operation can only be called by the `root` origin. **Any intermediate state, such as local tokens locked in the switch pair pool or remote assets that are not switchable anymore for local tokens, must be taken care of with subsequent governance operations.** 4. `pub fn pause_switch_pair(origin: OriginFor) -> DispatchResult`: Allows the `PauseOrigin` to immediately pause switches in both directions. 5. `pub fn resume_switch_pair(origin: OriginFor) -> DispatchResult`: Allows the `SwitchOrigin` to resume switches in both directions. -6. `pub fn remote_xcm_fee(origin: OriginFor, new: Box) -> DispatchResult`: Allows the `FeeOrigin` to update the required XCM fee to execute the transfer of remote asset on the reserve location from the chain's sovereign account to the beneficiary specified in the `switch` operation. +6. `pub fn remote_xcm_fee(origin: OriginFor, new: Box) -> DispatchResult`: Allows the `FeeOrigin` to update the required XCM fee to execute the transfer of remote asset on the reserve location from the chain's sovereign account to the beneficiary specified in the `switch` operation. For example, if the cost of sending an XCM message containing a `TransferAsset` instruction from the source chain to AssetHub (reserve location) changes from 0.1 DOTs to 0.2 DOTs, the fee will need to be updated accordingly to avoid transfers failing on AssetHub, leaving the whole system in an inconsistent state. Since the pallet refunds any unused assets on the reserve location to the account initiating the switch on the source chain, it is not a big issue to overestimate this value here since no funds will be burnt or unfairly taken from the user during the switch process. -7. `pub fn switch(origin: OriginFor, local_asset_amount: LocalCurrencyBalanceOf, beneficiary: Box) -> DispatchResult`: Allows the `SubmitterOrigin` to perform a switch of some local tokens for the corresponding amount of remote assets on the configured `reserve_location`. The switch will fail on the source chain if any of the following preconditions are not met: +7. `pub fn switch(origin: OriginFor, local_asset_amount: LocalCurrencyBalanceOf, beneficiary: Box) -> DispatchResult`: Allows the `SubmitterOrigin` to perform a switch of some local tokens for the corresponding amount of remote assets on the configured `reserve_location`. The switch will fail on the source chain if any of the following preconditions are not met: 1. The submitter does not have enough balance to pay for the tx fees on the source chain or to cover the amount of local tokens requested. Hence, the user's local balance must be greater than or equal to the amount of tokens requested in the switch + the cost of executing the extrinsic on the source chain. 2. No switch pair is set or the switch pair is currently not allowing switches. 3. There are not enough locked remote assets on the `reserve_location` to cover the switch request. e.g., if the chain sovereign account on the `reserve_location` only controls `10` remote assets, users can only switch up to `10` local tokens. Once the limit is reached, someone needs to perform the reverse operation (remote -> local switch) to free up some remote tokens. @@ -123,19 +123,19 @@ The pallet generates the following events: Because the switch functionality relies on XCM, the pallet provides a few XCM components that should be included in a runtime to enable the whole set of interactions between the source chain and the configured remote reserve location. * `AccountId32ToAccountId32JunctionConverter` in [xcm::convert][xcm-convert]: provides an implementation for the pallet's `AccountIdConverter` config component, that converts local `AccountId32`s into a `AccountId32` XCM `Junction`. This works only for chains that use `AccountId32` as their overarching `AccountId` type. -* `MatchesSwitchPairXcmFeeFungibleAsset` in [xcm::match][xcm-match]: provides an implementation of the `MatchesFungibles` that returns the input `MultiAsset` if its ID matches the XCM fee asset ID as configured in the switch pair, if present. If no switch pair is present or if the ID does not match, it returns a [XcmExecutorError::AssetNotHandled][XcmExecutorError::AssetNotHandled], which does not prevent other matchers after it to apply their matching logic. It can be used for the `AssetTransactor` property of the [XcmExecutor::Config][XcmExecutor::Config] and as the `AssetTransactor` component of this pallet in the runtime. +* `MatchesSwitchPairXcmFeeFungibleAsset` in [xcm::match][xcm-match]: provides an implementation of the `MatchesFungibles` that returns the input `Asset` if its ID matches the XCM fee asset ID as configured in the switch pair, if present. If no switch pair is present or if the ID does not match, it returns a [XcmExecutorError::AssetNotHandled][XcmExecutorError::AssetNotHandled], which does not prevent other matchers after it to apply their matching logic. It can be used for the `AssetTransactor` property of the [XcmExecutor::Config][XcmExecutor::Config] and as the `AssetTransactor` component of this pallet in the runtime. * `UsingComponentsForXcmFeeAsset` in [xcm::trade][xcm-trade]: provides an implementation of `WeightTrader` that allows buying weight using the XCM fee asset configured in the switch pair. That is, if the XCM fee asset is DOT, and users need to send DOTs to this chain in order to pay for XCM fees, this component lets them use those very same DOTs that are being sent to pay for the XCM fees on this chain. Any unused weight is burnt, since this chain's sovereign account already controls the whole amount on the reserve location due to the nature of reserve-based transfers. It can be used for the `Trader` property of the [XcmExecutor::Config][XcmExecutor::Config]. * `UsingComponentsForSwitchPairRemoteAsset` in [xcm::trade][xcm-trade]: provides an implementation of `WeightTrader` that allows buying weight using the remote asset configured in the switch pair when sending it to this chain to be switched for local tokens. Any unused weight is transferred from the switch pair account to the configured `FeeDestinationAccount`, as those local tokens do not need to back any remote assets because they have been used to pay for XCM fees. It can be used for the `Trader` property of the [XcmExecutor::Config][XcmExecutor::Config]. * `SwitchPairRemoteAssetTransactor` in [xcm::transact][xcm-transact]: provides an implementation of `TransactAsset::deposit_asset` that matches the asset to be deposited with the remote asset configured in the switch pair '(else it returns [Error::AssetNotFound][Error::AssetNotFound]) and moves as many local tokens from the switch pair account to the specified `who` destination. It also calls into the `SwitchHooks` pre- and post- checks, and generates a `RemoteToLocalSwitchExecuted` if everything is completed successfully. It can be used for the `AssetTransactor` property of the [XcmExecutor::Config][XcmExecutor::Config]. -* `IsSwitchPairXcmFeeAsset` in [xcm::transfer][xcm-transfer]: provides an implementation of `ContainsPair` that returns `true` if the given asset and sender match the stored switch pair XCM fee asset and reserve location respectively. It can be used for the `IsReserve` property of the [XcmExecutor::Config][XcmExecutor::Config]. -* `IsSwitchPairRemoteAsset` in [xcm::transfer][xcm-transfer]: provides an implementation of `ContainsPair` that returns `true` if the given asset and sender match the stored switch pair remote asset and reserve location respectively. It can be used for the `IsReserve` property of the [XcmExecutor::Config][XcmExecutor::Config]. +* `IsSwitchPairXcmFeeAsset` in [xcm::transfer][xcm-transfer]: provides an implementation of `ContainsPair` that returns `true` if the given asset and sender match the stored switch pair XCM fee asset and reserve location respectively. It can be used for the `IsReserve` property of the [XcmExecutor::Config][XcmExecutor::Config]. +* `IsSwitchPairRemoteAsset` in [xcm::transfer][xcm-transfer]: provides an implementation of `ContainsPair` that returns `true` if the given asset and sender match the stored switch pair remote asset and reserve location respectively. It can be used for the `IsReserve` property of the [XcmExecutor::Config][XcmExecutor::Config]. -[asset-switch-runtime-api]: https://github.com/KILTprotocol/kilt-node/tree/604a78397c20a396e50c19fb925c96b7c9c51635/runtime-api/asset-switch -[xcm-convert]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/604a78397c20a396e50c19fb925c96b7c9c51635/pallets/pallet-asset-switch/src/xcm/convert.rs -[xcm-match]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/604a78397c20a396e50c19fb925c96b7c9c51635/pallets/pallet-asset-switch/src/xcm/match.rs +[asset-switch-runtime-api]: https://github.com/KILTprotocol/kilt-node/tree/1.14.3/runtime-api/asset-switch +[xcm-convert]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.3/pallets/pallet-asset-switch/src/xcm/convert.rs +[xcm-match]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.3/pallets/pallet-asset-switch/src/xcm/match.rs [XcmExecutorError::AssetNotHandled]: https://github.com/paritytech/polkadot-sdk/blob/33324fe01c5b1f341687cef2aa6e767f6acf40f3/polkadot/xcm/xcm-executor/src/traits/token_matching.rs#L54 [XcmExecutor::Config]: https://github.com/paritytech/polkadot-sdk/blob/33324fe01c5b1f341687cef2aa6e767f6acf40f3/polkadot/xcm/xcm-executor/src/config.rs#L31 -[xcm-trade]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/604a78397c20a396e50c19fb925c96b7c9c51635/pallets/pallet-asset-switch/src/xcm/trade.rs +[xcm-trade]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.3/pallets/pallet-asset-switch/src/xcm/trade.rs [Error::AssetNotFound]: https://github.com/paritytech/polkadot-sdk/blob/e5791a56dcc35e308a80985cc3b6b7f2ed1eb6ec/polkadot/xcm/src/v3/traits.rs#L68 -[xcm-transact]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/604a78397c20a396e50c19fb925c96b7c9c51635/pallets/pallet-asset-switch/src/xcm/transact.rs -[xcm-transfer]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/604a78397c20a396e50c19fb925c96b7c9c51635/pallets/pallet-asset-switch/src/xcm/transfer.rs +[xcm-transact]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.3/pallets/pallet-asset-switch/src/xcm/transact.rs +[xcm-transfer]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.3/pallets/pallet-asset-switch/src/xcm/transfer.rs From 2f4b570176d53111417edb9f71536976e27a8d0e Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Mon, 30 Sep 2024 17:58:16 +0200 Subject: [PATCH 21/22] Clarify Signed-off-by: Chris Chinchilla --- docs/develop/09_polarpath/01_overview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/develop/09_polarpath/01_overview.md b/docs/develop/09_polarpath/01_overview.md index 436af962c..e4e212740 100644 --- a/docs/develop/09_polarpath/01_overview.md +++ b/docs/develop/09_polarpath/01_overview.md @@ -19,10 +19,10 @@ The Polkadot Relay Chain doesn't natively support assets apart from DOT. Instead Making a Parachain token usable on Ethereum requires the following steps: -1. All involved accounts need enough balance of TOKEN and wTOKEN to cover the switch. This includes the amount of the switch, fees, and an existential deposit. The balance can be in DOT, KSM, ETH, or USDC. +1. The involved AssetHub account need enough balance of wTOKEN to cover the switch. This includes the amount of the switch, fees, and an existential deposit. The balance can be in DOT, KSM, ETH, or USDC. :::danger - If you don't have enough balance when you perform the switch, you will lock your funds, requiring someone from the KILT governance team to unlock them. + If you don't have enough balance when you perform the switch, you will lock your funds, requiring a public KILT governance referendum to unlock them. ::: 2. Deploy an ERC-20 contract token to Ethereum with a fixed supply based on the parachain needs. From 2524a17f2ff21f9551cee519c67da03005e7667b Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Tue, 15 Oct 2024 12:38:53 +0200 Subject: [PATCH 22/22] Fix broken pallet paths Signed-off-by: Chris Chinchilla --- docs/develop/09_polarpath/02_switch_pallet.md | 26 ++++++++++++++----- docusaurus.config.js | 9 ++++--- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/docs/develop/09_polarpath/02_switch_pallet.md b/docs/develop/09_polarpath/02_switch_pallet.md index 58cbc0736..78693d165 100644 --- a/docs/develop/09_polarpath/02_switch_pallet.md +++ b/docs/develop/09_polarpath/02_switch_pallet.md @@ -18,7 +18,7 @@ The pallet makes the following assumptions: * The switch ratio is pre-defined to be 1:1, i.e., one unit of local currency for one unit of remote asset. * The pallet only exposes calls to allow local -> remote switches. The reverse is assumed to happen via XCM reserve transfer from the configured remote location, for which the pallet crate provides all the XCM components that are dynamically configured based on the switch pair information stored within each instance of this pallet. * The sovereign account of the source chain at destination owns the remote assets in the amount that is specified when the switch pair is created. The validation of this requirement is delegated to the source chain governance in the act leading to the creation of the switch pair, as the source chain itself has currently no means of doing that. -* Similarly, the pallet has currently no way to verify that a transfer of remote tokens from the chain sovereign account to the **specified** beneficiary has been completed successfully on the remote location, hence it takes an optimistic approach given that all the verifiable preconditions for the switch are verified on the source chain, i.e., the chain from which the switch originates. Any unexpected issues in the transfer on the remote location will most likely require intervention of the source chain governance to re-balance the state and make it consistent again. +* To account for failure on the remote destination, the pallet stores unconfirmed operations in a storage map. The remote chain then sends `Report` messages back to either confirm or revert a transfer. In the meanwhile, the source chain (where this pallet is deployed) assumes the transfer will be successful and updates all related counters tracking the destination state, to then revert them in case of failures. ## Add the pallet to the runtime @@ -69,6 +69,7 @@ As the pallet is generic over the runtime specifics, the `Config` trait requires - `type SubmitterOrigin: EnsureOrigin`: The origin that can call the `switch` extrinsic and perform the switch. - `type SwitchHooks: SwitchHooks`: Any additional runtime-specific logic that can be injected both before and after local tokens are exchanged for the remote assets, and before and after the remote assets are converted into local tokens. - `type SwitchOrigin: EnsureOrigin`: The origin that can set, resume, and delete a switch pair. +- `type UniversalLocation: Get`: The location of the parachain relative to the global consensus space. - `type WeightInfo: WeightInfo`: The computed weights of the pallet after benchmarking it. - `type XcmRouter: SendXcm`: The component responsible for routing XCM messages to the switch pair remote location to perform the remote asset transfer from the chain's sovereign account to the specified beneficiary. @@ -82,6 +83,11 @@ The pallet has a single `SwitchPair` storage value that contains a `Option` that returns `true` if the given asset and sender match the stored switch pair XCM fee asset and reserve location respectively. It can be used for the `IsReserve` property of the [XcmExecutor::Config][XcmExecutor::Config]. * `IsSwitchPairRemoteAsset` in [xcm::transfer][xcm-transfer]: provides an implementation of `ContainsPair` that returns `true` if the given asset and sender match the stored switch pair remote asset and reserve location respectively. It can be used for the `IsReserve` property of the [XcmExecutor::Config][XcmExecutor::Config]. -[asset-switch-runtime-api]: https://github.com/KILTprotocol/kilt-node/tree/1.14.3/runtime-api/asset-switch -[xcm-convert]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.3/pallets/pallet-asset-switch/src/xcm/convert.rs -[xcm-match]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.3/pallets/pallet-asset-switch/src/xcm/match.rs +The pallet itself implements the [OnResponse trait][on-response-trait], that must be added to runtimes that deploy this pallet to allow for the error-recovery process to take place. +The trait implementation validates the received query response message based on the state of the switch pair, and then performs the required action on the pending transfer info accordingly. + +[asset-switch-runtime-api]: https://github.com/KILTprotocol/kilt-node/tree/develop/runtime-api/asset-switch +[xcm-convert]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/develop/pallets/pallet-asset-switch/src/xcm/convert/mod.rs +[xcm-match]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/develop/pallets/pallet-asset-switch/src/xcm/match/mod.rs [XcmExecutorError::AssetNotHandled]: https://github.com/paritytech/polkadot-sdk/blob/33324fe01c5b1f341687cef2aa6e767f6acf40f3/polkadot/xcm/xcm-executor/src/traits/token_matching.rs#L54 [XcmExecutor::Config]: https://github.com/paritytech/polkadot-sdk/blob/33324fe01c5b1f341687cef2aa6e767f6acf40f3/polkadot/xcm/xcm-executor/src/config.rs#L31 -[xcm-trade]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.3/pallets/pallet-asset-switch/src/xcm/trade.rs +[xcm-trade]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/develop/pallets/pallet-asset-switch/src/xcm/trade/mod.rs [Error::AssetNotFound]: https://github.com/paritytech/polkadot-sdk/blob/e5791a56dcc35e308a80985cc3b6b7f2ed1eb6ec/polkadot/xcm/src/v3/traits.rs#L68 -[xcm-transact]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.3/pallets/pallet-asset-switch/src/xcm/transact.rs -[xcm-transfer]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.3/pallets/pallet-asset-switch/src/xcm/transfer.rs +[xcm-transact]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/develop/pallets/pallet-asset-switch/src/xcm/transact/mod.rs +[xcm-transfer]: https://raw.githubusercontent.com/KILTprotocol/kilt-node/develop/pallets/pallet-asset-switch/src/xcm/transfer/mod.rs +[on-response-trait]: https://github.com/paritytech/polkadot-sdk/blob/33324fe01c5b1f341687cef2aa6e767f6acf40f3/polkadot/xcm/xcm-executor/src/traits/on_response.rs#L29 diff --git a/docusaurus.config.js b/docusaurus.config.js index bf8fc143b..c18d33462 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -293,18 +293,19 @@ module.exports = { // Pulls external files and adds them as files in the Docusaurus folder, rewriting the title and the file name name: 'switch-pallet', sourceBaseUrl: - 'https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.3/pallets/pallet-asset-switch/', + 'https://raw.githubusercontent.com/KILTprotocol/kilt-node/develop/pallets/pallet-asset-switch/', outDir: 'docs/develop/09_polarpath', documents: ['README.md'], modifyContent(filename, content) { if (filename.includes('README')) { + const regex = /\.\/[^\/]+\/[^\/]+\/([^\/]+\/mod\.rs)/g var trimContent = content.replaceAll( - './src/xcm/', - 'https://raw.githubusercontent.com/KILTprotocol/kilt-node/1.14.3/pallets/pallet-asset-switch/src/xcm/' + regex, + 'https://raw.githubusercontent.com/KILTprotocol/kilt-node/develop/pallets/pallet-asset-switch/src/xcm/$1' ) var trimContent2 = trimContent.replace( '../../runtime-api/asset-switch/', - 'https://github.com/KILTprotocol/kilt-node/tree/1.14.3/runtime-api/asset-switch' + 'https://github.com/KILTprotocol/kilt-node/tree/develop/runtime-api/asset-switch' ) return { filename: '02_switch_pallet.md',