# Prerequisite
In order to make ReserveAssetTransfer at least three chains need to be involved:
- Relay chain
- Asset Hub
- Penpal or any other parachain which is not a reserve for the asset that we are going to transfer
# Goal
The goal is to transfer USDT asset from Asset Hub to Penpal (routing happens through the relay).
## Asset related pallets
Asset Hub has two pallets which are responsible for asset handling: pallet Balances and pallet Assets. Pallet Balances is used to handle native token (e.g. DOT or KMS), pallet Asset is used for other assets.
There is also Foreign Assets pallet which is responsible for ... #TODO
# Withdrawing asset
Here is the initial version of Westend Asset Hub config:
```yaml=
endpoint: wss://asset-hub-westend-rpc.dwellir.com
mock-signature-host: true
#block: ${env.WESTEND_ASSET_HUB_BLOCK_NUMBER}
db: ./db.sqlite
runtime-log-level: 5
wasm-override: wasms/asset_hub_westend_runtime.compact.compressed.wasm
import-storage:
PolkadotXcm:
SafeXcmVersion: 5
System:
Account:
[
[[5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY], { providers: 1, data: { free: 1000000000000000 } }], # Alice
[[5Eg2fntQqFi3EvFWAf71G66Ecjjah26bmFzoANAeHFgj9Lia], { providers: 1, data: { free: 1000000000000000 } }],
[[5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty], { providers: 1, data: { free: 1000000000000000 } }], # Bob
[[5HcCnKwHkdR8ho25XV5B29CfMs1rGxwUyVpbo4Mxzrvqcc7w], { providers: 1, data: { free: 1000000000000000 } }], # Bob on Penpal
]
Assets:
Account:
- [[1984, 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY], { balance: 1000000000 }]
```
By analogy to `System/Account` I created `Asset/Account` set-up for Alice and assigned 10^9 USDT to her address.
However, when I tried to execute a simple XCM withdraw:
```typescript
XcmV4Instruction.WithdrawAsset([
{
id: {
parents: 0,
interior: XcmV3Junctions.X2([
XcmV3Junction.PalletInstance(50),
XcmV3Junction.GeneralIndex(1984n)]),
},
fun: XcmV3MultiassetFungibility.Fungible(3_000_000n),
},
]),
```
it was failing with:
`xcm::pallet_xcm::execute ERROR: XCM execution failed with error error=FailedToTransactAsset("Funds are unavailable")`
I tried the same command on Polkadot network and it executed successfully. I started adding runtime logs to understand what went wrong.
The error was coming from [burn_from](https://github.com/paritytech/polkadot-sdk/blob/7ecf3f757a5d6f622309cea7f788e8a547a5dce8/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs#L304) function, specifically from [reducible_balance](https://github.com/paritytech/polkadot-sdk/blob/7ecf3f757a5d6f622309cea7f788e8a547a5dce8/substrate/frame/support/src/traits/tokens/fungibles/regular.rs#L290) which showed `0`.
I logged a few extra functions calls to see what was going on:
`Self::total_issuance(asset.clone());` - outputs 0,
`Self::balance(asset.clone(), who);` - outputs the value that I've put in the config or `10^9`
`Self::reducible_balance(asset.clone(), who, preservation, force);` - outputs 0.
I looked at the Network/Asset tab in both Polkadot and Westend Asset Hub and, in fact, Polkadot had issuance set to non-zero value while Westend had `0` as test-tether supply.


I went ahead and picked an asset with non-zero issuance on Westend to verify my hypothesis. I changed Asset that I was withdrawing from `GeneralIndex(1984)` to `GeneralIndex(1994)` (together with the config) and `withdraw` succeeded.
Fast-forward to the proper `Assets` pallet config with supply included:
```yaml=
Assets:
Account:
- [[1984, 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY], { balance: 1000000000 }]
Asset:
[
[[1984], { supply: 4000000000 }],
]
```
# TransferReserveAsset
Once the supply was fixed it allowed me to proceed further to `TransferReserveAsset` instruction itself.
Now XCM program looks like:
```typescript=
XcmV4Instruction.WithdrawAsset([
{
id: {
parents: 1,
interior: XcmV3Junctions.Here(),
},
fun: XcmV3MultiassetFungibility.Fungible(3_000_000_000_000n),
},
]),
Enum('PayFees', {
asset: {
id: {
parents: 1,
interior: XcmV3Junctions.Here(),
},
fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n),
}
}),
XcmV4Instruction.TransferReserveAsset({
assets: [
{
id: {
parents: 0,
interior: XcmV3Junctions.X2([
XcmV3Junction.PalletInstance(50),
XcmV3Junction.GeneralIndex(1984n)]),
},
fun: XcmV3MultiassetFungibility.Fungible(100_000_000n),
},
{
id: {
parents: 1,
interior: XcmV3Junctions.Here(),
},
fun: XcmV3MultiassetFungibility.Fungible(2_000_000_000_000n),
},
],
dest: {
parents: 1,
interior: XcmV3Junctions.X1(
XcmV3Junction.Parachain(2042),
),
},
xcm: [
Enum('PayFees', {
asset: {
id: {
parents: 1,
interior: XcmV3Junctions.Here(),
},
fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n),
}
}),
],
})
```
This led to a new error, namely:
`xcm::execute TRACE: !!! ERROR: FailedToTransactAsset("Account cannot receive the assets")`
This problem was related to the fact that sovereign account of Penpal on Asset Hub did not have enough funds.
In Polkusama blockchain, your address balance should always stay above or equal to a minimum value (i.e. existential deposit). Or else your balance will be completely erased by the blockchain.
## How to find a Sovereign Account?
There is a dedicated Runtime API to convert location into account.
Connect to Asset Hub, go to `Runtime calls` tab, select `LocationToAccountApi` and `convert_location` method then. The example below demonstrates how to get Penpal's sovereign account.
> Note: You can apply this method not only to parachain's but to accounts itself.

## Top up corresponding SA
Here is an updated config:
```yaml
Assets:
Account:
- [[1984, 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY], { balance: 1000000000 }]
- [[1984, 5Eg2fntSSE9VPsfxjgvpoZCoPo2uquZaYwmNDDV91bxUxEt7], { balance: 1000000000 }] # SA of Penpal chain
Asset:
[
[[1984], { supply: 4000000000 }],
]
```
After that the above XCM program started passing.
# Depositing reserve asset
Right now the XCM nested within `TransferReserveAsset` contains a single instruction -- `PayFees`. It needs `PayFees` to pass all the barriers on AssetHub side.
Let's add `DepositAsset` instruction and see what happens:
```typescript
xcm: [
Enum('PayFees', {
asset: {
id: {
parents: 1,
interior: XcmV3Junctions.Here(),
},
fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n),
}
}),
XcmV4Instruction.DepositAsset({
assets: XcmV4AssetAssetFilter.Definite([{
id: {
parents: 1,
interior: XcmV3Junctions.X3([
XcmV3Junction.Parachain(1000),
XcmV3Junction.PalletInstance(50),
XcmV3Junction.GeneralIndex(1984n)]),
},
fun: XcmV3MultiassetFungibility.Fungible(100_000_000n),
}]),
beneficiary: {
parents: 0,
interior: XcmV3Junctions.X1(XcmV3Junction.AccountId32({
network: undefined,
id: Binary.fromBytes(hdkdKeyPairAlice.publicKey),
})),
},
}),
],
```
No matter which asset I try to depsit (even if both), I receive an error:
`xcm::execute TRACE: !!! ERROR: FailedToTransactAsset("The asset in question is unknown")`
[UnknownAsset](https://github.com/paritytech/polkadot-sdk/blob/c5444f381fdba68aa9cb73b39cc63f34604da156/substrate/primitives/runtime/src/lib.rs#L659) is error's type in Substrate realm.
# Reproducing error on Westend Asset Hub
I tried to reproduce the error on Westend Asset Hub but it failed with `LocalExecutionIncomplete` which does not give any useful information about the error that hapenned during runtime execution.
Here is the encoded XCM program to reproduce the failure:
`0x1f03040c000401000007b186ba47171301000007b12e734f0900050401000007b1f68af70d010100e91f041301000007b1127fa30b000700e40b540202093d00`