Recover user funds lost due to failed XCM transfer
TL;DR
The proposal aims to recover 317.001366 USDT lost in a failed XCM transfer. Bifrost Kusama part of transfer was successful with USDT burnt on Bifrost Kusama. However, AssetHub dropped message execution since it hasn't passed one of the xcm barriers. The proposal suggests performing recovery by issuing USDT tokens on Bifrost Kusama to the user account that has originated the abovementioned xcm transfer.
Context
Two months ago user tried to transfer 317.001366 USDT from the Bifrost Kusama chain to AssetHub (Kusama) chain. They were successfully burnt on the Bifrost Kusama side. By burning we mean that total issuance of USDT decreases whenTokens::Wihtdrawn
event is issued.
On the AssetHub side, however, the message hasn't passed a barrier. In particular, it failed due toAllowTopLevelPaidExecutionFrom
barrier which rejected the message due to zero proof_size
in WeightLimit.Limited
argument. Previously it was not a problem since proof_size
was not accounted for when checking weights. However, after a certain runtime upgrade, it started being accounted which caused the barrier to reject the message.
Given the above, this proposal aims to recover USDT on the Bifrost Kusama side.
Are we sure the tokens are gone?
Tokens not arriving at a user account on AssetHub doesn't necessarily mean they haven't been recorded by AssetHub. In particular, when message execution fails in XCMVM, tokens get recorded into AssetTrap
.
However, in discussed case, message execution hasn't even started - barriers checks are performed before executing message & even before initializing XCMVM. Moreover, when assets are trapped, runtime emits AssetsTrapped
event, which is not present in our case.
Given that, we can conclude, that tokens haven't been recorded by AssetHub in any way, thus creating an imbalance between AssetHub reserves and Bifrost Kusama derivatives of USDT.
Confirming USDT imbalance between AssetHub and Bifrost Kusama
We can only issue USDT on Bifrost if we are sure it won't end up with more USDT on Bifrost than there are on AssetHub.
AssetHub currently (at the time of writing) holds 26,837.133 USDT on Bifrost Kusama sovereign account.
On the other hand, Bifrost Kusama have 26,512.064781 USDT
This means AssetHub has 325.068219 USDT more in reserves than Bifrost Kusama has derivatives.
Proposed recovery solution
Bifrost Kusama doesn't have issue
or mint
calls for tokens
that might be called with privileged origin. Given that, the proposed recovery solution is to perform two calls wrapped in batch_all
:
tokens.setBalance
for some inaccessible account(e.g. with 0x00..00 public key)
tokens.forceTransfer
from abovementioned account to the user's account (fa4zqK6a2sSd59UFJLuCz4D1fFTHEpnjqNFuUvtZR2JMfz1
)
The first step is needed since we cannot safely call update_balance
since it would require accounting for existing user balance which might change while the referendum passes on-chain. Thus, we update the balance of some inaccessible accounts instead.
I agree with the proposal, it will set a precedent for the technical forces to recover user's fund when incident occurred thus will prove the highest security of XCM transfers