This document is meant to help service providers (exchanges, custodians, etc.), understand the implications of XCM when it comes to monitoring for user deposits of the DOT token sent with a "[Reserve-backed transfer](https://wiki.polkadot.network/docs/learn-assets#cross-chain-accounting)". This document also assumes that the service provider has set their system up in a way that each user has a unique deposit address and no additional information (ex. memo) is required. An example and tutorial on such a set-up could be found here: [Building a Hot Wallet With Substrate Primitives](https://www.parity.io/blog/building-a-hot-wallet-with-substrate-primitives/). It is also worth mentioning that XCM messages can cost more computational power, and thus the transaction fees are likely to be higher. XCM also allows for transaction fees to be paid in other assets besides DOT, so it would be prudent to provide some advanced warnings to users so that they are aware that they should make sure they understand what they are doing prior to using XCM to deposit funds on your platform. ## Problem In its initial form, all DOT tokens existed on the Polkadot Relay Chain, and any movement of tokens from one account to another typically resulted in a `balances.transfer` event being emitted. So monitoring for user deposits only required listening for those events and then checking to see if it pertained to an address in the service providers system. Now with the introduction of XCM, DOT tokens can exist across a growing number of blockchains. So in addition to monitoring for "local DOT transfers" (transfers between accounts on the same chain), the provider will also need to monitor for cross-chain transfers. ## Solution When a user submits a cross-chain transfer from a parachain to the Relay Chain, it will first be verified by the parachain's runtime, and if valid, it gets packaged up along with the block proof that is sent to the Relay Chain to be processed and finalized. During this process, the XCM messages are added to a message queue. Then the Relay Chain will begin executing the instructions contained in each message one at a time. Unlike local transfers that handle the withdrawal of the asset from one account and the deposit of the asset into another account all in one step resulting in a `balances.transfer` event, XCM transfers handle the withdrawal and deposit as two seperate steps, resulting in multiple events. The event most relevant for service providers monitoring for user deposits is the `balances.deposited` event. So the solution to problem described above is to begin listening for `balances.deposit` events as well as `balances.transfer` events. The service provider will need to query every new block that is created, loop through the events array, filter for any `balances.deposit` AND `balances.transfer` and apply the appropriate business logic. #### Examples: `balances.deposit` - Captures XCM (reserve-backed) transfers: ![](https://hackmd.io/_uploads/HJz_-QO93.png) **Logic**: If `who` is an address that belongs to the service provider's client, then increment the user's balance by `amount` in the service provider's accounting system. <br/> `balances.transfer` - Captures local transfers ![](https://hackmd.io/_uploads/HyvtGm_qn.png) **Logic**: If `to` is an address that belongs to the service provider's client, then increment the user's balance by `amount` in the service provider's accounting system. ### Manually Verifying The above solution will be sufficient to ensure that DOT has arrived in a given account either through a reserve-backed or local transfer. However, if a user ever claims that they have submitted a successful reserve-backed transfer but the funds haven't arrived, the service provider can investigate the claim as follows: 1. Get message ID (also called message hash), Parachain (ID), and block number for the XCM message in question - Request that the user provide these 3 pieces of information, which they can find using a block explorer such as [Subscan](https://www.subscan.io/). 2. Query the parachain `at` the block height provided - Using a tool like [Substrate API Sidecar](https://github.com/paritytech/substrate-api-sidecar) you can get all the events that were emmitted in the given block 3. Filter for the provided Message ID - Once you have all the events for the given block, you can then loop through and filter for a `parachainsystem.upwardMessageSent` event that has a `message_hash` value equal to the message ID provided by the user. If you find the event and message hash, then you have just verified that the user has in fact sent an XCM message from the parachain they claimed. Next we will see that that message was processed by the Relay Chain in the same block that the `balances.deposit` event was emitted. 4. Query the Relay Chain `at` the block the `balances.deposit` event was emitted - Again using a querying tool like Substrate API Sidecar, you can query for and loop through the other events in that block and filter for a `ump.executedUpward` event that has a `messageId` equal to the one provided. This event is the last event that gets emitted when all the instructions from an XCM message have been executed. That means that you should be able to find the `balances.deposit` event as well as all the other events that got emmitted based on the message instructions immediately before the `ump.executedUpward` event. If so, then you have successfully traced the users XCM message from start to finish. 5. sss ***NOTE: It is important to note here that XCM message IDs (message hashes) are NOT unique. In the same way that transaction hashes are [NOT a unique identifier](https://wiki.polkadot.network/docs/build-protocol-info#unique-identifiers-for-extrinsics), XCM messages with the same paramaters will produce identical message IDs.*** ### Additional Considerations #### Asset-Hub Currently, the Polkadot Relay Chain uses an instance of the Balances pallet in order to manage which addresses contain the DOT token. In the future though, DOT balances will be managed by a system level parachain called Asset-Hub-Polkadot (originally Statemint). As a step toward that goal, today, users are able to "Teleport" DOT from the Relay Chain to Asset-Hub-Polkadot, and once there DOT can be transferred to other parachains using the "Reserve-backed transfer" functionality of the XCM protocol. As the name suggests, the Asset-Hub parachain is meant to be used as accounting layer when tracking where tokens are across the entire Polkadot ecosystem. With this architecture, service providers will only need to integrate with a single parachain and then utilize XCM to move funds across any parachains they wish. With these changes on the horizon, service providers may want to consider having there services use the Asset-Hub as their accounting layer as opposed to the Relay Chain. #### Asset Transfer API Regardless of whether you are using Asset-Hub or the Relay Chain, service providers should also consider using the [Asset Transfer API](https://github.com/paritytech/asset-transfer-api) to help them construct the XCM messages they need. This API exposes a set of methods that simplify the transfer of assets locally as well as across blockchains using the XCM standard. #### XCM UI Lastly, as a service provider you may want to create a web app for your users to connect their non-custodial wallet to. This app would aid the user in creating the XCM call that will transfer DOT on a parachain to the correct address in the service provider's system. This UI could then easily be used to facilitate instances where your user wishes to withdraw funds to a chain where that token is not a native asset, but is still a valid "foreign asset" (ex. Withdrawing DOT to Moonbeam). The Asset Transfer API would also be the best tool to power this UI.