Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

connectors: Wrapped token lookup #1393

Merged
merged 28 commits into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
17c2853
asset-registry: Add `transferability` property
NunoAlexandre May 1, 2023
a172a75
Merge branch 'main' into feat/connectors-metadata
NunoAlexandre Jun 7, 2023
64bb64a
wip: Move xcm metadata to Transferability::Xcm and All
NunoAlexandre Jun 7, 2023
5ccc7d3
fixup
NunoAlexandre Jun 7, 2023
cf627d6
Add CrossChainTransferability::None and set as default
NunoAlexandre Jun 7, 2023
85175ed
fmt
NunoAlexandre Jun 7, 2023
5ed78f0
Fix e2e tests
NunoAlexandre Jun 7, 2023
1c2e548
altair: Add CrossChainTransferabilityMigration
NunoAlexandre Jun 7, 2023
8a70101
Merge branch 'main' into feat/connectors-metadata
NunoAlexandre Jun 7, 2023
bda728e
Merge branch 'main' into feat/connectors-metadata
NunoAlexandre Jun 8, 2023
cf56bff
Merge branch 'main' into feat/connectors-metadata
NunoAlexandre Jun 8, 2023
36bc975
cfg-traits: Add AssetLocator trait
NunoAlexandre Jun 8, 2023
fafee80
cfg-types: Move `EVMChainId` to crate root
NunoAlexandre Jun 8, 2023
34f7453
cfg-types: Add AssetLocation enum type
NunoAlexandre Jun 8, 2023
c7481bb
Add ConnectorsWrappedToken and test conversion identity
NunoAlexandre Jun 8, 2023
f42a6e6
Drop old approach ✨ 🧹
NunoAlexandre Jun 8, 2023
0f2088b
clippy
NunoAlexandre Jun 9, 2023
e88c7ee
wip: ConnectorsWrappedTokenConvert
NunoAlexandre Jun 12, 2023
8d94947
Impl Token to MultiLocation conversion
NunoAlexandre Jun 12, 2023
0d116d4
fmt
NunoAlexandre Jun 12, 2023
5dc6889
Test ConnectorsWrappedToken conversions
NunoAlexandre Jun 12, 2023
850de3b
fmt
NunoAlexandre Jun 12, 2023
82b9737
Add mod test
NunoAlexandre Jun 12, 2023
8f71ff2
Self review
NunoAlexandre Jun 12, 2023
cedf48b
Fix cargo doc
NunoAlexandre Jun 13, 2023
104d82d
fmt
NunoAlexandre Jun 13, 2023
3c466ff
Merge remote-tracking branch 'origin/main' into evm-token-lookup
NunoAlexandre Jun 13, 2023
a464b1e
Doc review comment
NunoAlexandre Jun 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion libs/traits/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ pub trait TransferAllowance<AccountId> {
type CurrencyId;
type Location: Member + Debug + Eq + PartialEq + TypeInfo + Encode + Decode + MaxEncodedLen;
/// Determines whether the `send` account is allowed to make a transfer to
/// the `recieve` loocation with `currency` type currency. Returns result
/// the `receive` location with `currency` type currency. Returns result
/// wrapped bool for whether allowance is allowed.
fn allowance(
send: AccountId,
Expand Down
4 changes: 1 addition & 3 deletions libs/types/src/domain_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ use codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_core::TypeId;

/// The EVM Chain ID
/// The type should accomodate all chain ids listed on https://chainlist.org/.
type EVMChainId = u64;
use crate::EVMChainId;

/// A Domain is a chain or network we can send a Connectors message to.
/// The domain indices need to match those used in the EVM contracts and these
Expand Down
4 changes: 4 additions & 0 deletions libs/types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,7 @@ pub mod permissions;
pub mod time;
pub mod tokens;
pub mod xcm;

/// The EVM Chain ID
/// The type should accomodate all chain ids listed on https://chainlist.org/.
type EVMChainId = u64;
146 changes: 142 additions & 4 deletions libs/types/src/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@ use scale_info::TypeInfo;
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
use sp_runtime::{traits::Get, DispatchError, TokenError};
use xcm::{
latest::{MultiLocation, NetworkId},
prelude::{AccountKey20, GlobalConsensus, X2},
};

use crate::xcm::XcmMetadata;
use crate::{xcm::XcmMetadata, EVMChainId};

#[derive(
Clone,
Expand Down Expand Up @@ -66,7 +70,7 @@ pub enum CurrencyId {
)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum StakingCurrency {
/// An emulated internal, non-transferrable currency
/// An emulated internal, non-transferable currency
/// Its issuance and holding is handled inherently
BlockRewards,
}
Expand Down Expand Up @@ -194,8 +198,8 @@ impl TrancheCurrencyT<PoolId, TrancheId> for TrancheCurrency {
MaxEncodedLen,
)]
pub struct CustomMetadata {
/// XCM-related metadata.
pub xcm: XcmMetadata,
/// The ways, if any, this token is cross-chain transferable
pub transferability: CrossChainTransferability,

/// Whether an asset can be minted.
/// When `true`, the right permissions will checked in the permissions
Expand All @@ -212,6 +216,107 @@ pub struct CustomMetadata {
pub pool_currency: bool,
}

/// The Cross Chain Transferability property of an asset describes the way(s),
/// if any, that said asset is cross-chain transferable. It may currently be
/// transferable through Xcm, Centrifuge Connectors, or All .
///
/// NOTE: Once set to `All`, the asset is automatically transferable through any
/// eventual new option added at a later stage. A migration might be required if
/// that's undesirable for any registered asset.
#[derive(
Clone,
Copy,
Default,
PartialOrd,
Ord,
PartialEq,
Eq,
Debug,
Encode,
Decode,
TypeInfo,
MaxEncodedLen,
)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum CrossChainTransferability {
/// The asset is not transferable cross-chain
#[default]
None,

/// The asset is only transferable through XCM
Xcm(XcmMetadata),

/// The asset is only transferable through Centrifuge Connectors
Connectors,

/// The asset is transferable through all available options
All(XcmMetadata),
}

impl CrossChainTransferability {
pub fn includes_xcm(self) -> bool {
self != Self::None && matches!(self, Self::Xcm(..) | Self::All(..))
}
}

/// Connectors wrapped tokens
///
/// Currently, Connectors are only deployed on EVM-based chains and therefore
/// the only supported type of connectors-wrapped tokens are Evm tokens. In the
/// far future, we might support wrapped tokens from other chains, such as
/// Cosmos, Avalanche, etc.
#[derive(
Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen,
)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum ConnectorsWrappedToken {
NunoAlexandre marked this conversation as resolved.
Show resolved Hide resolved
/// An EVM-native token
EVM {
/// The EVM chain id where the token is deployed
chain_id: EVMChainId,
/// The token contract address
address: [u8; 20],
},
}

impl TryFrom<MultiLocation> for ConnectorsWrappedToken {
type Error = ();

fn try_from(location: MultiLocation) -> Result<Self, Self::Error> {
match location {
MultiLocation {
parents: 0,
interior:
X2(
NunoAlexandre marked this conversation as resolved.
Show resolved Hide resolved
GlobalConsensus(NetworkId::Ethereum { chain_id }),
AccountKey20 {
network: None,
key: address,
},
),
} => Ok(Self::EVM { chain_id, address }),
_ => Err(()),
}
}
}

impl Into<MultiLocation> for ConnectorsWrappedToken {
mustermeiszer marked this conversation as resolved.
Show resolved Hide resolved
fn into(self) -> MultiLocation {
match self {
Self::EVM { chain_id, address } => MultiLocation {
parents: 0,
interior: X2(
GlobalConsensus(NetworkId::Ethereum { chain_id }),
AccountKey20 {
network: None,
key: address,
},
),
},
}
}
}

#[cfg(test)]
mod tests {
use frame_support::parameter_types;
Expand Down Expand Up @@ -273,4 +378,37 @@ mod tests {
.is_err()
);
}

#[test]
/// Verify that converting a ConnectorsWrappedToken to MultiLocation and
/// back results in the same original value.
fn connectors_wrapped_token_location_conversion_identity() {
const CHAIN_ID: EVMChainId = 123;
const ADDRESS: [u8; 20] = [9; 20];

let wrapped_token = ConnectorsWrappedToken::EVM {
chain_id: CHAIN_ID,
address: ADDRESS,
};
let as_location: MultiLocation = wrapped_token.into();

assert_eq!(
as_location,
MultiLocation {
parents: 0,
interior: X2(
GlobalConsensus(NetworkId::Ethereum { chain_id: CHAIN_ID }),
AccountKey20 {
network: None,
key: ADDRESS
},
),
}
);

assert_eq!(
ConnectorsWrappedToken::try_from(as_location),
Ok(wrapped_token)
);
}
}
6 changes: 2 additions & 4 deletions pallets/pool-system/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use cfg_traits::{PoolMutate, TrancheCurrency as TrancheCurrencyT};
use cfg_types::{
epoch::EpochState,
fixed_point::Rate,
tokens::{CurrencyId, CustomMetadata, TrancheCurrency},
tokens::{CrossChainTransferability, CurrencyId, CustomMetadata, TrancheCurrency},
xcm::XcmMetadata,
};
use frame_support::{assert_err, assert_noop, assert_ok};
Expand Down Expand Up @@ -2319,9 +2319,7 @@ fn create_tranche_token_metadata() {
mintable: false,
permissioned: true,
pool_currency: false,
xcm: XcmMetadata {
fee_per_second: None,
},
transferability: CrossChainTransferability::Connectors,
},
}
);
Expand Down
6 changes: 2 additions & 4 deletions pallets/pool-system/src/tranches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ use cfg_traits::{
ops::{EnsureAdd, EnsureFixedPointNumber, EnsureInto},
TrancheCurrency as TrancheCurrencyT,
};
use cfg_types::tokens::{CrossChainTransferability, CustomMetadata};
#[cfg(test)]
use cfg_types::{fixed_point::Rate, tokens::TrancheCurrency};
use cfg_types::{tokens::CustomMetadata, xcm::XcmMetadata};
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::{
dispatch::DispatchResult,
Expand Down Expand Up @@ -248,9 +248,7 @@ where
mintable: false,
permissioned: true,
pool_currency: false,
xcm: XcmMetadata {
fee_per_second: None,
},
transferability: CrossChainTransferability::Connectors,
},
}
}
Expand Down
10 changes: 5 additions & 5 deletions runtime/altair/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ use orml_traits::{currency::MutationHooks, parameter_type_with_key};
use pallet_anchors::AnchorData;
pub use pallet_balances::Call as BalancesCall;
use pallet_collective::{EnsureMember, EnsureProportionMoreThan};
use pallet_ethereum::{Transaction as EthereumTransaction, TransactionAction};
use pallet_ethereum::Transaction as EthereumTransaction;
use pallet_evm::{Account as EVMAccount, FeeCalculator, Runner};
use pallet_investments::OrderType;
use pallet_pool_system::{
Expand All @@ -72,11 +72,8 @@ pub use pallet_timestamp::Call as TimestampCall;
pub use pallet_transaction_payment::{CurrencyAdapter, Multiplier, TargetedFeeAdjustment};
use pallet_transaction_payment_rpc_runtime_api::{FeeDetails, RuntimeDispatchInfo};
use polkadot_runtime_common::{prod_or_fast, BlockHashCount, SlowAdjustingFeeUpdate};
use runtime_common::fees::{DealWithFees, WeightToFee};
pub use runtime_common::*;
use runtime_common::{
evm::GetTransactionAction,
fees::{DealWithFees, WeightToFee},
};
use scale_info::TypeInfo;
use sp_api::impl_runtime_apis;
use sp_core::{OpaqueMetadata, H160, H256, U256};
Expand Down Expand Up @@ -1676,6 +1673,9 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall {

#[cfg(not(feature = "testnet-runtime"))]
fn check_self_contained(&self) -> Option<Result<Self::SignedInfo, TransactionValidityError>> {
use pallet_ethereum::TransactionAction;
use runtime_common::evm::GetTransactionAction;

match self {
RuntimeCall::Ethereum(call) => match call {
pallet_ethereum::Call::transact { transaction }
Expand Down