js,js-legacy: Match on-chain semantics in amountToUiAmount helpers - #1345
Open
plutohan wants to merge 2 commits into
Open
js,js-legacy: Match on-chain semantics in amountToUiAmount helpers#1345plutohan wants to merge 2 commits into
plutohan wants to merge 2 commits into
Conversation
The conversion helpers in both clients diverged from the program: plain-mint paths lost precision above 2^53 and accepted malformed or out-of-range input, extension paths truncated at base-unit precision so multipliers below one rendered nonzero amounts as "0", and the interest-bearing ui-amount path truncated where the program rounds. Plain-mint conversions now use exact bigint string arithmetic ported from the program. Extension paths scale with the total multiplier like the program, format with an exact round-half-even formatter, validate input, range-check against u64 and saturate like the program's cast.
The cjs tsconfig targets ES2016 where bigint literals are a syntax error. Use the BigInt constructor instead; behavior is unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #1340, for the client side of the same problem. The
amountToUiAmount/uiAmountToAmounthelpers in both JS clients diverged from the program in several ways:NumberandparseFloat, losing precision above 2^53 (u64::MAXprinted as18446744073.709553) and silently accepting malformed input ("1.5oops"parsed as1,"1e30"returned a value aboveu64::MAX)."0", and small amounts printed in scientific notation ("1e-10") which the program never emits.Plain-mint conversions now use exact bigint string arithmetic ported from
amount_to_ui_amount_string_trimmedandtry_ui_amount_into_amount. Extension paths mirror the fixed on-chain behavior: scale by the total multiplier, format to the mint's decimals with an exact round-half-even formatter (matching Rust's float formatting, wheretoFixedrounds half up), validate input like anf64parse, range-check against u64 and saturate the way the program's cast does.Existing test expectations that asserted the old behavior were updated to the values the program produces (verified against the interface crate), e.g.
"1e-10"is now"0.0000000001","Infinity"is now"inf", and the interest-bearing round-trip returns the rounded principal. New tests cover sub-unit multipliers, u64-range exactness, malformed input rejection and round-trips.Fixes #1325