3

Ran into an issue transferring a statemine token (ex: USDt) on a local testnet with rococo-local and statemine-local. I'm trying to transfer USDt to a sibling parachain, but it fails on the statemine side, with Account cannot be created. It seems to come from this part of the code in pallet-assets. For convenience, can_inc_consumer

This call works if USDt is made to be isSufficient on statemine-local, however that is not the case for production, or other assets.

There are native UNITS in the sovereign account of the parachain I am trying to transfer to. system_parachain_sovereign_account_info

I tried to mirror the USDt deployed on Statemine, although minted a whole bunch of it: local USDt token

I am using a limitedReserveTransferAssets call, encoded data: 0x1f0801010100951f0100010100d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0104000002043205011f000700e87648170000000000

Statemine is on 9290. There is a (bug?) which results in UnweighableMessage if using the normal reserveTransferAssets as described here, which is the reason behind limitedReserveTransferAssets

Logs of the XCM Execution:

2022-11-23 19:41:12.091 TRACE tokio-runtime-worker xcm::weight: [Parachain] WeightInfoBounds message: Xcm([TransferReserveAsset { assets: MultiAssets([MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X2(PalletInstance(50), GeneralIndex(1984)) }), fun: Fungible(100000000) }]), dest: MultiLocation { parents: 1, interior: X1(Parachain(2021)) }, xcm: Xcm([]) }])    
2022-11-23 19:41:12.091 TRACE tokio-runtime-worker xcm::weight: [Parachain] WeightInfoBounds message: Xcm([TransferReserveAsset { assets: MultiAssets([MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X2(PalletInstance(50), GeneralIndex(1984)) }), fun: Fungible(100000000) }]), dest: MultiLocation { parents: 1, interior: X1(Parachain(2021)) }, xcm: Xcm([BuyExecution { fees: MultiAsset { id: Concrete(MultiLocation { parents: 1, interior: X3(Parachain(1000), PalletInstance(50), GeneralIndex(1984)) }), fun: Fungible(100000000) }, weight_limit: Unlimited }, DepositAsset { assets: Wild(All), max_assets: 1, beneficiary: MultiLocation { parents: 0, interior: X1(AccountId32 { network: Any, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] }) } }]) }])    
2022-11-23 19:41:12.091 TRACE tokio-runtime-worker xcm::execute_xcm_in_credit: [Parachain] origin: MultiLocation { parents: 0, interior: X1(AccountId32 { network: Polkadot, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] }) }, message: Xcm([TransferReserveAsset { assets: MultiAssets([MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X2(PalletInstance(50), GeneralIndex(1984)) }), fun: Fungible(100000000) }]), dest: MultiLocation { parents: 1, interior: X1(Parachain(2021)) }, xcm: Xcm([BuyExecution { fees: MultiAsset { id: Concrete(MultiLocation { parents: 1, interior: X3(Parachain(1000), PalletInstance(50), GeneralIndex(1984)) }), fun: Fungible(100000000) }, weight_limit: Unlimited }, DepositAsset { assets: Wild(All), max_assets: 1, beneficiary: MultiLocation { parents: 0, interior: X1(AccountId32 { network: Any, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] }) } }]) }]), weight_limit: 654404000, weight_credit: 654404000    
2022-11-23 19:41:12.091 TRACE tokio-runtime-worker xcm::weight: [Parachain] WeightInfoBounds message: Xcm([TransferReserveAsset { assets: MultiAssets([MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X2(PalletInstance(50), GeneralIndex(1984)) }), fun: Fungible(100000000) }]), dest: MultiLocation { parents: 1, interior: X1(Parachain(2021)) }, xcm: Xcm([BuyExecution { fees: MultiAsset { id: Concrete(MultiLocation { parents: 1, interior: X3(Parachain(1000), PalletInstance(50), GeneralIndex(1984)) }), fun: Fungible(100000000) }, weight_limit: Unlimited }, DepositAsset { assets: Wild(All), max_assets: 1, beneficiary: MultiLocation { parents: 0, interior: X1(AccountId32 { network: Any, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] }) } }]) }])    
2022-11-23 19:41:12.091 TRACE tokio-runtime-worker xcm::barriers: [Parachain] TakeWeightCredit origin: MultiLocation { parents: 0, interior: X1(AccountId32 { network: Polkadot, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] }) }, message: Xcm([TransferReserveAsset { assets: MultiAssets([MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X2(PalletInstance(50), GeneralIndex(1984)) }), fun: Fungible(100000000) }]), dest: MultiLocation { parents: 1, interior: X1(Parachain(2021)) }, xcm: Xcm([BuyExecution { fees: MultiAsset { id: Concrete(MultiLocation { parents: 1, interior: X3(Parachain(1000), PalletInstance(50), GeneralIndex(1984)) }), fun: Fungible(100000000) }, weight_limit: Unlimited }, DepositAsset { assets: Wild(All), max_assets: 1, beneficiary: MultiLocation { parents: 0, interior: X1(AccountId32 { network: Any, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] }) } }]) }]), max_weight: 654404000, weight_credit: 654404000    
2022-11-23 19:41:12.091 TRACE tokio-runtime-worker xcm::execute: [Parachain] origin: Some(MultiLocation { parents: 0, interior: X1(AccountId32 { network: Polkadot, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] }) }), total_surplus/refunded: 0/0, error_handler_weight: 0    
2022-11-23 19:41:12.091 TRACE tokio-runtime-worker xcm::currency_adapter: [Parachain] internal_transfer_asset asset: MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X2(PalletInstance(50), GeneralIndex(1984)) }), fun: Fungible(100000000) }, from: MultiLocation { parents: 0, interior: X1(AccountId32 { network: Polkadot, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] }) }, to: MultiLocation { parents: 1, interior: X1(Parachain(2021)) }    
2022-11-23 19:41:12.091 TRACE tokio-runtime-worker xcm::fungibles_adapter: [Parachain] internal_transfer_asset what: MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X2(PalletInstance(50), GeneralIndex(1984)) }), fun: Fungible(100000000) }, from: MultiLocation { parents: 0, interior: X1(AccountId32 { network: Polkadot, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] }) }, to: MultiLocation { parents: 1, interior: X1(Parachain(2021)) }    
2022-11-23 19:41:12.091 TRACE tokio-runtime-worker xcm::execute_xcm_in_credit: [Parachain] result: Err(ExecutorError { index: 0, xcm_error: FailedToTransactAsset("Account cannot be created"), weight: 0 })    
2022-11-23 19:41:12.091 DEBUG tokio-runtime-worker xcm::execute_xcm_in_credit: [Parachain] Execution errored at 0: FailedToTransactAsset("Account cannot be created") (original_origin: MultiLocation { parents: 0, interior: X1(AccountId32 { network: Polkadot, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] }) })    
2022-11-23 19:41:12.091 DEBUG tokio-runtime-worker sc_basic_authorship::basic_authorship: [Parachain] [0xd6ea01cd2d378517b78a7ad42da163a0a559c3384c6745582e6451f1b9915c42] Pushed to the block.    

3 Answers 3

3

There's an referendum open for make USDT sufficient in statemint: https://polkadot.polkassembly.io/referendum/80

The referendum passed, there's 28 days delay to the change be applied

1

USDT is sufficient in Statemine. If you want your test to work on your local you will have to make USDT sufficient as well.

As Lohann pointed, it will be soon also sufficient in Statemint.

Here you have a test to achieve exactly what you are trying to do. The tests are run with the parachains-integration-tests tool. Bear in mind that to run those tests you'll need a relay chain runtime with sudo in it. In case you want to test with Kusama/Polkadot instead of Rococo, you can find a v0.9.29 version here.

1
  • I was already able to transfer with is_sufficient true, and if in fact USDt will be is_sufficient than this is a non-issue for the actual transfer. However, I'm wondering how other parachains already have USDt transfers enabled if is_sufficient is required. The way I see it, the original transfer should go through because consumers & providers meet the requirements of can_inc_consumer. Even if is_sufficient is being provided for USDt, this does not apply to other assets on statemint, so what if I want to transfer something else?
    – insipx
    Nov 24, 2022 at 17:39
1

thanks for the responses

The reason this transfer was not working in this case, is because the sibling parachain account was not created. I had mistakenly assumed that the parachain relay sovereign account is the same on siblings and the relay chain. However, on sibling chains, the MultiLocation for the sovereign parachain account is:

{ parents: 1, X1(Parachain(SiblingID) }

and on the relay:

{ parents: 0, X1(Parachain(SiblingId) }

So when these are converted to AccountID32, they are different accounts.

The PolkadotJS UI does not recognize this "Sibling Parachain account" as the sovereign account of the parachain, instead it labels the relay sovereign account as the sovereign account. So I had assumed I had the right account when I did not.

Therefore, transferring DOT to the sibling Parachain account, or using assets.touch(1984) (@Lohann DM'ed me this solution too) for Sibling Account (which I tried, got a decode error, and it is easier to just transfer tokens) "created" the account, and the transfer went through successfully with the XCM call I posted earlier. That would be the missing piece to transferring assets with assets not labeled as sufficient.

This should work for USDt when it is not sufficient and other not sufficient assets.

Admittedly, this would have been difficult to gather from the original stackexchange post, as i did not screenshot the AccountID data, I did not believe it to be necessary at the time

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.