diff --git a/bridges/snowbridge/pallets/system/src/lib.rs b/bridges/snowbridge/pallets/system/src/lib.rs index 30aba4588ba5..46a94782666c 100644 --- a/bridges/snowbridge/pallets/system/src/lib.rs +++ b/bridges/snowbridge/pallets/system/src/lib.rs @@ -35,8 +35,15 @@ //! //! Typically, Polkadot governance will use the `force_transfer_native_from_agent` and //! `force_update_channel` and extrinsics to manage agents and channels for system parachains. +//! +//! ## Polkadot-native tokens on Ethereum +//! +//! Tokens deposited on AssetHub pallet can be bridged to Ethereum as wrapped ERC20 tokens. As a prerequisite, +//! the token should be registered first. +//! +//! * [`Call:register_token`]: Register a token location as a wrapped ERC20 contract on Ethereum. +//! #![cfg_attr(not(feature = "std"), no_std)] - #[cfg(test)] mod mock; @@ -214,7 +221,7 @@ pub mod pallet { PricingParametersChanged { params: PricingParametersOf, }, - /// Register token + /// Register Polkadot-native token as a wrapped ERC20 token on Ethereum RegisterToken { asset_id: VersionedLocation, token_id: H256, @@ -252,14 +259,16 @@ pub mod pallet { pub type PricingParameters = StorageValue<_, PricingParametersOf, ValueQuery, T::DefaultPricingParameters>; + /// Lookup table for foreign to native token ID #[pallet::storage] #[pallet::getter(fn tokens)] - pub type Tokens = + pub type ForeignToNativeId = StorageMap<_, Twox64Concat, TokenId, xcm::v4::Location, OptionQuery>; + /// Lookup table for native to foreign token ID #[pallet::storage] #[pallet::getter(fn location_tokens)] - pub type LocationToToken = + pub type NativeToForeignId = StorageMap<_, Twox64Concat, xcm::v4::Location, TokenId, OptionQuery>; #[pallet::genesis_config] @@ -594,10 +603,9 @@ pub mod pallet { Ok(()) } - /// Sends a message to the Gateway contract to register a new - /// token that represents `asset`. + /// Registers a Polkadot-native token as a wrapped ERC20 token on Ethereum. /// - /// - `origin`: Must be `MultiLocation` from sibling parachain + /// - `origin`: Must be root #[pallet::call_index(10)] #[pallet::weight(T::WeightInfo::register_token())] pub fn register_token( @@ -607,12 +615,12 @@ pub mod pallet { ) -> DispatchResult { ensure_root(origin)?; - let asset_loc: Location = + let location: Location = (*location).try_into().map_err(|_| Error::::UnsupportedLocationVersion)?; let pays_fee = PaysFee::::No; - Self::do_register_token(asset_loc, metadata, pays_fee)?; + Self::do_register_token(location, metadata, pays_fee)?; Ok(()) } @@ -707,15 +715,16 @@ pub mod pallet { } pub(crate) fn do_register_token( - asset_loc: Location, + location: Location, metadata: AssetMetadata, pays_fee: PaysFee, ) -> Result<(), DispatchError> { // Record the token id or fail if it has already been created - let token_id = TokenIdOf::convert_location(&asset_loc) + let token_id = TokenIdOf::convert_location(&location) .ok_or(Error::::LocationConversionFailed)?; - Tokens::::insert(token_id, asset_loc.clone()); - LocationToToken::::insert(asset_loc.clone(), token_id); + + ForeignToNativeId::::insert(token_id, location.clone()); + NativeToForeignId::::insert(location.clone(), token_id); let command = Command::RegisterForeignToken { token_id, @@ -725,7 +734,7 @@ pub mod pallet { }; Self::send(SECONDARY_GOVERNANCE_CHANNEL, command, pays_fee)?; - Self::deposit_event(Event::::RegisterToken { asset_id: asset_loc.into(), token_id }); + Self::deposit_event(Event::::RegisterToken { asset_id: location.into(), token_id }); Ok(()) } @@ -752,11 +761,11 @@ pub mod pallet { } impl MaybeEquivalence for Pallet { - fn convert(id: &TokenId) -> Option { - Tokens::::get(id) + fn convert(foreign_id: &TokenId) -> Option { + ForeignToNativeId::::get(id) } - fn convert_back(loc: &Location) -> Option { - LocationToToken::::get(loc) + fn convert_back(location: &Location) -> Option { + NativeToForeignId::::get(location) } } } diff --git a/bridges/snowbridge/primitives/core/src/lib.rs b/bridges/snowbridge/primitives/core/src/lib.rs index b4e9c9b3c857..0afba79fd765 100644 --- a/bridges/snowbridge/primitives/core/src/lib.rs +++ b/bridges/snowbridge/primitives/core/src/lib.rs @@ -168,7 +168,7 @@ impl DescribeLocation for DescribeHere { pub type AgentIdOf = HashedDescription)>; -#[derive(Clone, Default, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, TypeInfo)] +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] pub struct AssetMetadata { pub name: BoundedVec>, pub symbol: BoundedVec>,