Skip to content

fix: preserve decimal integer precision in viem arguments - #258

Open
snuff12 wants to merge 1 commit into
VeloraDEX:masterfrom
snuff12:fix/viem-decimal-integer-precision
Open

snuff12 wants to merge 1 commit into
VeloraDEX:masterfrom
snuff12:fix/viem-decimal-integer-precision

Conversation

@snuff12

@snuff12 snuff12 commented Nov 3, 2026 •

Copy link
Copy Markdown

Fixes #257

A viem-backed SDK can round a decimal integer approval amount before ABI encoding. For example, approving 1000.01 tokens with 18 decimals authorizes 65,536 base units less than requested, and decimal maxUint256 rounds out of range and is rejected.

Parse plain decimal integer strings directly with BigInt before the existing numeric fallback. This preserves the requested amount, including signs, leading zeros, and surrounding whitespace. Other numeric formats keep their existing behavior; this change does not attempt to fix exponent or decimal-point notation.

Add offline tests through the public SDK and the real viem encoder for swap/Delta/OTC approvals, unsafe integer boundaries, maxUint256, signed arguments, and compatibility cases.

Validation:

  • New regression suite: 17 passed; the same suite on the base commit has 10 failures and 7 passes.
  • New and existing offline suites (viemIntegerArgs, auctionAmounts, limitAmount, builderCode): 109 passed.
  • Build, lint, and type checks passed.
  • Local ERC20 approval/spend checks passed, including maxUint256; all 100 selected amounts from 1000.00 through 1000.99 are now approved exactly.
  • Additional independent runtime checks passed with viem 2.21.0 and 2.56.1, including local allowance/transfer checks and minimum-version type checking.

The local contract checks isolate approval and token spending. A live Velora-router swap and the external-RPC integration suite were not run.


Note

Medium Risk
Changes argument encoding for every viem transaction write, including token approvals where wrong amounts are user-visible and funds-related; behavior is localized and heavily regression-tested.

Overview
Fixes incorrect approval and contract-call amounts when the viem provider encodes string arguments: values above Number.MAX_SAFE_INTEGER (and full maxUint256 decimal strings) were routed through Number before BigInt, which rounded or broke encoding.

argsToViemArgs now recognizes plain decimal integer strings (optional sign, surrounding whitespace) and converts them with BigInt(arg) before the existing Number fallback. Hex-prefixed strings, scientific notation, and decimal-point forms still use the prior path; non-numeric strings, bytes, and bigint args are unchanged.

Adds an offline regression suite (viemIntegerArgs.test.ts) that exercises swap, Delta, and OTC approval flows plus signed int256 calls through the real viem encoder.

Reviewed by Cursor Bugbot for commit af75146. Bugbot is set up for automated code reviews on this repo. Configure here.

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.

Viem approvals round decimal integer amounts and reject max uint256

1 participant