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

Add Unlimited weight to Xtokens precompile #2307

Merged
merged 1 commit into from
May 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 12 additions & 6 deletions precompiles/xtokens/Xtokens.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ interface Xtokens {
/// @param currencyAddress The ERC20 address of the currency we want to transfer
/// @param amount The amount of tokens we want to transfer
/// @param destination The Multilocation to which we want to send the tokens
/// @param destination The weight we want to buy in the destination chain
/// @param weight The weight we want to buy in the destination chain
/// (uint64::MAX means Unlimited weight)
/// @custom:selector b9f813ff
function transfer(
address currencyAddress,
Expand All @@ -51,7 +52,8 @@ interface Xtokens {
/// @param currencyAddress The ERC20 address of the currency we want to transfer
/// @param amount The amount of tokens we want to transfer
/// @param destination The Multilocation to which we want to send the tokens
/// @param destination The weight we want to buy in the destination chain
/// @param weight The weight we want to buy in the destination chain
/// (uint64::MAX means Unlimited weight)
/// @custom:selector 3e506ef0
function transferWithFee(
address currencyAddress,
Expand All @@ -68,7 +70,8 @@ interface Xtokens {
/// Currently only Concrete Fungible assets
/// @param amount The amount of tokens we want to transfer
/// @param destination The Multilocation to which we want to send the tokens
/// @param destination The weight we want to buy in the destination chain
/// @param weight The weight we want to buy in the destination chain
/// (uint64::MAX means Unlimited weight)
/// @custom:selector b4f76f96
function transferMultiasset(
Multilocation memory asset,
Expand All @@ -84,7 +87,8 @@ interface Xtokens {
/// Currently only Concrete Fungible assets
/// @param amount The amount of tokens we want to transfer
/// @param destination The Multilocation to which we want to send the tokens
/// @param destination The weight we want to buy in the destination chain
/// @param weight The weight we want to buy in the destination chain
/// (uint64::MAX means Unlimited weight)
/// @custom:selector 150c016a
function transferMultiassetWithFee(
Multilocation memory asset,
Expand All @@ -100,7 +104,8 @@ interface Xtokens {
/// @param currencies The currencies we want to transfer, defined by their address and amount.
/// @param feeItem Which of the currencies to be used as fee
/// @param destination The Multilocation to which we want to send the tokens
/// @param weight The weight we want to buy in the destination chain
/// @param weight The weight we want to buy in the destination chain
/// (uint64::MAX means Unlimited weight)
/// @custom:selector ab946323
function transferMultiCurrencies(
Currency[] memory currencies,
Expand All @@ -115,7 +120,8 @@ interface Xtokens {
/// @param assets The assets we want to transfer, defined by their location and amount.
/// @param feeItem Which of the currencies to be used as fee
/// @param destination The Multilocation to which we want to send the tokens
/// @param weight The weight we want to buy in the destination chain
/// @param weight The weight we want to buy in the destination chain
/// (uint64::MAX means Unlimited weight)
/// @custom:selector 797b45fd
function transferMultiAssets(
MultiAsset[] memory assets,
Expand Down
48 changes: 42 additions & 6 deletions precompiles/xtokens/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,17 @@ where
.try_into()
.map_err(|_| RevertReason::value_is_too_large("balance type").in_field("amount"))?;

let dest_weight_limit = if weight == u64::MAX {
WeightLimit::Unlimited
} else {
WeightLimit::Limited(Weight::from_parts(weight, DEFAULT_PROOF_SIZE))
};

let call = orml_xtokens::Call::<Runtime>::transfer {
currency_id,
amount,
dest: Box::new(VersionedMultiLocation::V3(destination)),
dest_weight_limit: WeightLimit::Limited(Weight::from_parts(weight, DEFAULT_PROOF_SIZE)),
dest_weight_limit,
};

RuntimeHelper::<Runtime>::try_dispatch(handle, Some(origin).into(), call)?;
Expand Down Expand Up @@ -137,12 +143,18 @@ where
.try_into()
.map_err(|_| RevertReason::value_is_too_large("balance type").in_field("fee"))?;

let dest_weight_limit = if weight == u64::MAX {
WeightLimit::Unlimited
} else {
WeightLimit::Limited(Weight::from_parts(weight, DEFAULT_PROOF_SIZE))
};

let call = orml_xtokens::Call::<Runtime>::transfer_with_fee {
currency_id,
amount,
fee,
dest: Box::new(VersionedMultiLocation::V3(destination)),
dest_weight_limit: WeightLimit::Limited(Weight::from_parts(weight, DEFAULT_PROOF_SIZE)),
dest_weight_limit,
};

RuntimeHelper::<Runtime>::try_dispatch(handle, Some(origin).into(), call)?;
Expand All @@ -164,13 +176,19 @@ where
.try_into()
.map_err(|_| RevertReason::value_is_too_large("balance type").in_field("amount"))?;

let dest_weight_limit = if weight == u64::MAX {
WeightLimit::Unlimited
} else {
WeightLimit::Limited(Weight::from_parts(weight, DEFAULT_PROOF_SIZE))
};

let call = orml_xtokens::Call::<Runtime>::transfer_multiasset {
asset: Box::new(VersionedMultiAsset::V3(MultiAsset {
id: AssetId::Concrete(asset),
fun: Fungibility::Fungible(to_balance),
})),
dest: Box::new(VersionedMultiLocation::V3(destination)),
dest_weight_limit: WeightLimit::Limited(Weight::from_parts(weight, DEFAULT_PROOF_SIZE)),
dest_weight_limit,
};

RuntimeHelper::<Runtime>::try_dispatch(handle, Some(origin).into(), call)?;
Expand Down Expand Up @@ -200,6 +218,12 @@ where
.try_into()
.map_err(|_| RevertReason::value_is_too_large("balance type").in_field("fee"))?;

let dest_weight_limit = if weight == u64::MAX {
WeightLimit::Unlimited
} else {
WeightLimit::Limited(Weight::from_parts(weight, DEFAULT_PROOF_SIZE))
};

let call = orml_xtokens::Call::<Runtime>::transfer_multiasset_with_fee {
asset: Box::new(VersionedMultiAsset::V3(MultiAsset {
id: AssetId::Concrete(asset.clone()),
Expand All @@ -210,7 +234,7 @@ where
fun: Fungibility::Fungible(fee),
})),
dest: Box::new(VersionedMultiLocation::V3(destination)),
dest_weight_limit: WeightLimit::Limited(Weight::from_parts(weight, DEFAULT_PROOF_SIZE)),
dest_weight_limit,
};

RuntimeHelper::<Runtime>::try_dispatch(handle, Some(origin).into(), call)?;
Expand Down Expand Up @@ -260,11 +284,17 @@ where
})
.collect::<EvmResult<_>>()?;

let dest_weight_limit = if weight == u64::MAX {
WeightLimit::Unlimited
} else {
WeightLimit::Limited(Weight::from_parts(weight, DEFAULT_PROOF_SIZE))
};

let call = orml_xtokens::Call::<Runtime>::transfer_multicurrencies {
currencies,
fee_item,
dest: Box::new(VersionedMultiLocation::V3(destination)),
dest_weight_limit: WeightLimit::Limited(Weight::from_parts(weight, DEFAULT_PROOF_SIZE)),
dest_weight_limit,
};

RuntimeHelper::<Runtime>::try_dispatch(handle, Some(origin).into(), call)?;
Expand Down Expand Up @@ -309,11 +339,17 @@ where
.in_field("assets")
})?;

let dest_weight_limit = if weight == u64::MAX {
WeightLimit::Unlimited
} else {
WeightLimit::Limited(Weight::from_parts(weight, DEFAULT_PROOF_SIZE))
};

let call = orml_xtokens::Call::<Runtime>::transfer_multiassets {
assets: Box::new(VersionedMultiAssets::V3(multiassets)),
fee_item,
dest: Box::new(VersionedMultiLocation::V3(destination)),
dest_weight_limit: WeightLimit::Limited(Weight::from_parts(weight, DEFAULT_PROOF_SIZE)),
dest_weight_limit,
};

RuntimeHelper::<Runtime>::try_dispatch(handle, Some(origin).into(), call)?;
Expand Down
47 changes: 47 additions & 0 deletions precompiles/xtokens/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,53 @@ fn transfer_to_reserve_works() {
});
}

#[test]
fn transfer_to_reserve_with_unlimited_weight_works() {
ExtBuilder::default()
.with_balances(vec![(Alice.into(), 1000)])
.build()
.execute_with(|| {
let destination = MultiLocation::new(
1,
Junctions::X1(Junction::AccountId32 {
network: None,
id: [1u8; 32],
}),
);
// We are transferring asset 0, which we have instructed to be the relay asset
precompiles()
.prepare_test(
Alice,
Precompile1,
PCall::transfer {
currency_address: Address(AssetAccount(0u128).into()),
amount: 500.into(),
destination: destination.clone(),
weight: u64::MAX,
},
)
.expect_cost(3000)
.expect_no_logs()
.execute_returns(());

let expected_asset: MultiAsset = MultiAsset {
id: AssetId::Concrete(
CurrencyIdToMultiLocation::convert(CurrencyId::OtherReserve(0u128)).unwrap(),
),
fun: Fungibility::Fungible(500),
};
let expected: crate::mock::RuntimeEvent = XtokensEvent::TransferredMultiAssets {
sender: Alice.into(),
assets: vec![expected_asset.clone()].into(),
fee: expected_asset,
dest: destination,
}
.into();
// Assert that the events vector contains the one expected
assert!(events().contains(&expected));
});
}

#[test]
fn transfer_to_reserve_with_fee_works() {
ExtBuilder::default()
Expand Down