diff --git a/xcm/src/v3/multiasset.rs b/xcm/src/v3/multiasset.rs index 0dd6b55826c8..602c9722f753 100644 --- a/xcm/src/v3/multiasset.rs +++ b/xcm/src/v3/multiasset.rs @@ -235,7 +235,7 @@ impl TryFrom for u128 { } /// Classification of whether an asset is fungible or not, along with a mandatory amount or instance. -#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)] +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub enum Fungibility { /// A fungible asset; we record a number of units, as a `u128` in the inner item. @@ -245,6 +245,23 @@ pub enum Fungibility { NonFungible(AssetInstance), } +#[derive(Decode)] +enum UncheckedFungibility { + Fungible(#[codec(compact)] u128), + NonFungible(AssetInstance), +} + +impl Decode for Fungibility { + fn decode(input: &mut I) -> Result { + match UncheckedFungibility::decode(input)? { + UncheckedFungibility::Fungible(a) if a != 0 => Ok(Self::Fungible(a)), + UncheckedFungibility::NonFungible(i) => Ok(Self::NonFungible(i)), + UncheckedFungibility::Fungible(_) => + Err("Fungible asset of zero amount is not allowed".into()), + } + } +} + impl Fungibility { pub fn is_kind(&self, w: WildFungibility) -> bool { use Fungibility::*;