raydium-io / raydium-sdk-V2

Open-source Typescript SDK for Raydium
GNU General Public License v3.0
79 stars 47 forks source link

Error: Number can only safely store up to 53 bits from computeAmountOut #21

Closed mcfriend99 closed 3 months ago

mcfriend99 commented 4 months ago

Hi,

I have the code below which should compute amount out from given pool. It works sometimes, but half the time I keep getting the error Number can only safely store up to 53 bits.

Here's the code:

const out = raydium.liquidity.computeAmountOut({
    poolInfo: {
      ...poolInfo,
      baseReserve,
      quoteReserve,
      status,
      version: 4,
    },
    amountIn: new BN(amountIn),
    mintIn: mintIn.address,
    mintOut: mintOut.address,
    slippage: 0.01, // range: 1 ~ 0.0001, means 100% ~ 0.01%
  })

The amount is fixed at 100k lamports for all transactions so that should not be outside the range of big numbers (53 bits).

My code is based on https://github.com/raydium-io/raydium-sdk-V2-demo/blob/master/src/amm/swap.ts with the variables renamed but no other difference whatsoever.

cruzshia commented 4 months ago

could you share the full code? which pool and amountIn...etc. also you can try print logs to see is there any data exceed 53 bits.

cruzshia commented 4 months ago

I guess if you are swapping for a pair like 100K sol to a meme coin with value like 0.000000001 usd, and the out.minAmountOut might overflow, so you should check the value of out.minAmountOut to prevent error

mcfriend99 commented 4 months ago

I already pointed to the source verbatim in the post. Since the error happens on the function that should return the minAmountOut, I can't log it because that's exactly the function raising an exception.

cruzshia commented 4 months ago

could you share more info? which pool and amountIn...etc. it's hard to debug with limited infomation and also print input params like

poolInfo: {
      ...poolInfo,
      baseReserve,
      quoteReserve,
      status,
      version: 4,
    },

to see whether the data is valid.

mcfriend99 commented 4 months ago

This is the complete error message:

Error: Number can only safely store up to 53 bits
    at assert (/home/ubuntu/MyProject/node_modules/bn.js/lib/bn.js:6:21)
    at BN.toNumber (/home/ubuntu/MyProject/node_modules/bn.js/lib/bn.js:547:7)
    at Pr.computeAmountOut (/home/ubuntu/MyProject/node_modules/@raydium-io/raydium-sdk-v2/lib/index.js:1:259520)
    at raydiumSwap (/home/ubuntu/MyProject/raydium-swap.js:405:55)

I think the library should use parseFloat(bn.toString()) instead of bn.toNumber(). I've found the later to fail a lot of times in this age of memecoins.

mcfriend99 commented 4 months ago

The pool is 3rjdW2acpqdyf8qapEHwMoAzQUsfGjPbG3hjmJWaC6vN and the amount is 100k lamports as said in the original post.

cruzshia commented 4 months ago

I didn't get any error even give 100 * 10 ** 9 input amount,

image
cruzshia commented 4 months ago

also you can check we didn't use any parseFloat or toNumber in calculation here https://github.com/raydium-io/raydium-sdk-V2/blob/master/src/raydium/liquidity/liquidity.ts#L723, which I pass fixed pool version: 4 to raydium.liquidity.computeAmountOut, so all xxx.toNumber won't be reached.