Assistance Requested: Subaccount Calculation Issue

Hello everyone, We’re the ICPSwap team,

We’ve encountered an issue involving a user on our platform who is experiencing difficulties with subaccount calculations.

The user used the Plug wallet to connect to ICPSwap. During a Swap operation, the front-end utilizes this method use Principal and Subaccount to calculate the Account Identifier. And transfer ICP to SwapPool.

Under normal case, this method runs well. However, this user has encountered a problem. Here are the specific details:

User’s Principal: idbjp-7cvie-zfmuk-rphe5-sic4b-is6i5-edoui-by4kc-pemjv-lsgyg-gqe

SwapPool Principal: 3ejs3-eaaaa-aaaag-qbl2a-cai

Account = AccountIdentifier.fromPrincpal({ principal: Principal.fromText(“3ejs3-eaaaa-aaaag-qbl2a-cai”), subAccount: SubAccount.fromPrincpal(“idbjp-7cvie-zfmuk-rphe5-sic4b-is6i5-edoui-by4kc-pemjv-lsgyg-gqe”) }).toHex()

The calculated result should have been: a2150c24e80aab5b73b6fda67072c7e4003e361cf6754cdc8b880acd26b72b81.

However, this user’s side calculation has a different result: 227494b464772a7cac2d2d14ba8009d931e5e10d671a2f74fd19c644bc73eb74.

Our development team performed the same calculation locally using the same parameters and received the correct result. Upon our debugging, it appears that the user’s computer is generating an incorrect result when computing sha224.

This predicament has left the user unable to withdraw tokens. We kindly request assistance to address this issue. Your help would be immensely appreciated.


It’s been raised recently, use @noble/hashes/sha256 to replace js-sha256

also tagging @peterparker to upgrade ic-js


Thanks for tagging me @neeboo.

@ICPSwap what version of @dfinity/nns library are you using?

I actually merged the PR to replace js-sha256 by @noble/hashes in ic-js yesterday (PR #405). If that would be the root cause of the issue, we can publish a new release of the libraries asap.

Give me 5min
Awaiting small PR reviews to release


ic-js which replaces js-sha256 by @noble/hashes has been published.

CHANGELOG :point_right:

@ICPSwap can you bump your depencies and let me know if it solve the issue?

Note: have run a small test locally using this new version to ensure that the example you provided in your post matches the expected calculated hex account, and I can confirm it worked. I got a2150c24e80aab5b73b6fda67072c7e4003e361cf6754cdc8b880acd26b72b81 too.


Fixing the library won’t solve the issue, right?
The issue is that this user’s money is now stuck in a different subaccount.
Isn’t the question how to create a transaction to recover the money from that subaccount?

Edit: To be clear, I don’t know if this is possible or if it is, how to do it, so I’m hoping someone else can help with that.


Thank you so much for your assistance!

1 Like

Hello @peterparker Thank you so much for your assistance. Our devs are currently making updates, and we need to get in touch with the user who encountered the issue. We require the user’s cooperation in conducting tests to confirm if the problem has been resolved.


Hello @dskloet Yes, the user lost 530 ICP as the tokens were mistakenly sent to another address. We’ve tried numerous approaches but have been unable to recover tokens. Is there any way you can assist us in recovering the user’s tokens? We are very thankful for your assistance!


Hi, if you manage to find which subaccount was used it might be possible to recover the user’s funds. Do you know which subaccount was used? Also, do you know which wallet was used?


I believe the problem is not the wrong subaccount, but incorrect hash computation on the user’s computer. I’d say there is no chance of recovery in this case.


It’s related to some specific chrome version



Yes, we have carried out debug tracking and discovered that when using sha224 to calculate the hash, the user is using the same parameters as us, but the result they obtain differs from ours.

Thank you! this is very helpful!

Calculating subaccount identifiers in the client is (as we’ve unfortunately found out) quite dangerous.
Fortunately there is an ICRC-1 interface to the ICP ledger canister where you specify the subaccount explicitly.
I recommend migrating to it.

September 10th Update:

We would like to express our heartfelt gratitude to @neeboo, @peterparker, @dskloet, @0rions and @roman-kashitsyn for your invaluable assistance, suggestions, and solutions.

ICPSwap has successfully implemented a system upgrade, and has resolved the issue.

During the computation of the Account Identifier, a calculation error was identified. This error was attributed to the utilization of the SHA256 encryption library, particularly in specific circumstances (which may be associated with certain versions of Chrome). Unfortunately, this led to the transfer of 530 ICP from the user’s Swap transaction to an unknown account (Account: 227494b464772a7c - ICP Dashboard

Regrettably, it seems that these ICP cannot be recovered at this time. In light of this, the ICPSwap team is committed to compensating this user for the lost 530.04 ICP.

Furthermore, as a token of appreciation for the user’s collaboration and support during the recent testing and system upgrade process, the ICPSwap team will reward the user with a portion of ICS tokens (to be distributed after the SNS).


It is extremely valuable that a dex that is so committed supports its users, in our opinion, the user in question could not experience such support in any other chain.

We do not have programming knowledge professionally, but in user experience we would like to share a topic and maybe this can help readers…

  1. Suppose our plug-in wallet is installed on the browser as an extension…
  2. Our plug-in wallet plugin consists of several wallets inside it
  3. We connect to ICP Swap with wallet 1
  4. During the execution of the transaction, we change the wallet number and confirm the transaction with a wallet other than wallet number 1.

This can cause ICP tokens to decrease and mislead users. But in fact, the lost ICPs remain and there is a possibility of this with the help of the right wallet that has the amount in it and the Unreceived tokens after swap? option. Reclaim here in the swap section can find the amounts.

We stated this issue only to convey the user experience, because they may not follow up on small funds to find small amounts and never be able to find tokens and publish their negative experience.

1 Like

The issue of going through a dapp ↔ wallet flow where the wallet account changes in the middle of the flow is already covered in the (draft) ICRC-25 Wallet Interaction standard.

Whenever a dapp asks the wallet to make a transaction, the dapp also tells the wallet what account (defined in spec as sender) should be used to make that transaction. So the wallet can check if this is indeed the current account, if not the wallet can ask the user for example to switch to the correct account. This prevents the scenario you described above.

As for the issue in this topic, the target address of funds is calculated based on hashing a user principal and subaccount. The hashing library was faulty in Chrome 115 and above, causing this calculated address to be incorrect. With the ICRC-1 standard, this issue would have been avoided since the hashing step isn’t required, the principal and subaccount are both sent “as is” within the transaction request instead.


Thank you for the useful and comprehensive information you provided.

1 Like