wevm / viem

TypeScript Interface for Ethereum
https://viem.sh
Other
2.44k stars 729 forks source link

IntegerOutOfRangeError when encoding transaction data with large token approval amounts #2524

Closed ArielGueta closed 1 month ago

ArielGueta commented 1 month ago

Check existing issues

Viem Version

^2.13.2

Current Behavior

When interacting with dApps such as Uniswap, large token approval amounts are often used. For example, the approval amount might be:

115792089237316195423570985008687907853269984665640564039457584007913129.639936

Using the parseUnits(amount, decimals) function converts this to:

115792089237316195423570985008687907853269984665640564039457584007913129639936n

However, when trying to encode this amount for a transaction, the following code snippet:

const calldata = encodeFunctionData(tokenApprovalSig, [
  spender,
  parseUnits(amount, decimals)
]);

results in an IntegerOutOfRangeError.

Expected Behavior

The encodeTxData function should handle large integers without throwing an IntegerOutOfRangeError.

Steps To Reproduce

Use the parseUnits function with a large token approval amount:

const amount = "115792089237316195423570985008687907853269984665640564039457584007913129.639936";
const decimals = 6;
const parsedAmount = parseUnits(amount, decimals);

Attempt to encode the transaction data with the parsed amount:

const calldata = encodeTxData('function approve(address spender, uint256 amount)', [
  spender,
  parsedAmount
]);

Link to Minimal Reproducible Example

No response

Anything else?

No response

jxom commented 1 month ago

parseUnits('115792089237316195423570985008687907853269984665640564039457584007913129.639936', 6) is greater than the maximum uint256 value (2 ** 256 - 1) so this is expected.

ArielGueta commented 1 month ago

How it works for uniswap? any suggestion, please?

jxom commented 1 month ago

What do you need a suggestion for? Just don’t exceed the max uint256 range I guess.

ArielGueta commented 1 month ago

@jxom The value 115792089237316195423570985008687907853269984665640564039457584007913129639935 is exactly the maximum value for a uint256. So why the code throws?

ArielGueta commented 1 month ago

Ok, I see that there is some rounding issue.

115792089237316195423570985008687907853269984665640564039457584007913129639935 becomes 115792089237316195423570985008687907853269984665640564039457584007913129639936n

ArielGueta commented 1 month ago

Ok, the issue solved, thanks

github-actions[bot] commented 1 month ago

This issue has been locked since it has been closed for more than 14 days.

If you found a concrete bug or regression related to it, please open a new bug report with a reproduction against the latest Viem version. If you have any questions or comments you can create a new discussion thread.