Skip to content

fix(nextjs): parse the unshield amount in confidential decimals - #54

Open
Dusk1e wants to merge 1 commit into
FhenixProtocol:masterfrom
Dusk1e:fix/unshield-input-decimals
Open

fix(nextjs): parse the unshield amount in confidential decimals#54
Dusk1e wants to merge 1 commit into
FhenixProtocol:masterfrom
Dusk1e:fix/unshield-input-decimals

Conversation

@Dusk1e

@Dusk1e Dusk1e commented Aug 13, 2026

Copy link
Copy Markdown

The unshield amount is parsed with the wrong decimals. useUpdateEncryptDecryptValue always does parseUnits(sanitized, pair.publicToken.decimals), but in the decrypt direction that value goes straight into unshield(from, to, uint64 amount), which takes the amount in the confidential token's own decimals, and the FHERC20 wrapper caps those at 6. The call site in MainTokenSwapping already passes tokenDecimals: pair.confidentialToken.decimals for that same value, so only the parse disagreed.

For the ETH pair (public 18, confidential 6) typing 1 gives 1e18 where the contract wants 1e6. You mostly can't get that far though, because useEncryptDecryptValueError compares the input against the decrypted confidential balance, which is in 6 decimals. Holding 1 eETH that comparison is 1000000000000000000 against 1000000, so anything you type comes back as insufficient balance. The percent buttons show the same split from the other end: they already store the right raw value, but useEncryptDecryptInputValue renders it with public decimals, so 50% of 1 eETH appears in the box as 0.0000000000005 instead of 0.5.

useUpdateEncryptDecryptValueByPercent was already choosing decimals by direction, so I lifted that expression into a small inputDecimals(pair, isEncrypt) helper and used it in all three places. Shield is untouched, shield(to, uint256 amount) really does take underlying units and that call site already passes publicToken.decimals.

Worth noting why this went unseen: the token list only ships USDC and EURC, both 6 decimals, so public and confidential coincide and nothing looks wrong. ETH is the pair that breaks and it has its own branch in the selector.

There is no test runner in packages/nextjs, so I could not add a test. check-types passes, lint reports no errors (the prettier warnings it prints are pre-existing, all in the generated lib/abis.ts), and prettier --check passes on the changed file.

`useUpdateEncryptDecryptValue` parsed the input with `pair.publicToken.decimals`
in both directions. In the decrypt direction that value goes straight into
`unshield(from, to, uint64 amount)`, which takes the amount in the confidential
token's own decimals — the FHERC20 wrapper caps those at 6. The call site in
MainTokenSwapping already labels it as such (`tokenDecimals:
pair.confidentialToken.decimals`), so only the parse was wrong.

For the ETH pair (public 18, confidential 6) typing 1 produced 1e18 where the
contract expects 1e6. In practice the form blocked first:
`useEncryptDecryptValueError` compares the input against the decrypted
confidential balance, which is in 6 decimals, so with 1 eETH held the comparison
was 1000000000000000000 > 1000000 and every amount read as insufficient balance.

The percent buttons showed the same split from the other side. They stored the
correct raw value but `useEncryptDecryptInputValue` rendered it with public
decimals, so 50% of 1 eETH appeared as 0.0000000000005 instead of 0.5.

`useUpdateEncryptDecryptValueByPercent` already selected decimals by direction,
so that expression is now an `inputDecimals(pair, isEncrypt)` helper used by all
three. Shield is unchanged: `shield(to, uint256 amount)` does take underlying
units and that call site already passes `publicToken.decimals`.

Only USDC and EURC ship in the token list and both are 6 decimals, so public and
confidential coincide and nothing looks wrong there.
@vercel

vercel Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

@Dusk1e is attempting to deploy a commit to the Fhenix Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant