raydium-io / raydium-sdk-V2-demo

Open-source Typescript SDK demos
48 stars 31 forks source link

Incorrect calculation at raydium.liquidity.computeAmountOut fn #46

Closed dexweb3 closed 3 months ago

dexweb3 commented 3 months ago

raydium.liquidity.computeAmountOut Hi, looks like I found an issue when for some tokens it calculates incorrect amountOut (I have last sdk version)

I'll attach 2 examples:

  1. SUCCES CASE: Around michi token (5mbK36SZ7J19An8jFochhQS4of8g6BwUjbeCSxBSoWdp)

PARAMS: {"poolInfo":{"type":"Standard","programId":"675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8","id":"GH8Ers4yzKR3UKDvgVu8cqJfGzU4cU62mTeg9bcJ7ug6","mintA":{"chainId":101,"address":"So11111111111111111111111111111111111111112","programId":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","logoURI":"https://img-v1.raydium.io/icon/So11111111111111111111111111111111111111112.png","symbol":"WSOL","name":"Wrapped SOL","decimals":9,"tags":[],"extensions":{}},"mintB":{"chainId":101,"address":"5mbK36SZ7J19An8jFochhQS4of8g6BwUjbeCSxBSoWdp","programId":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","logoURI":"https://img-v1.raydium.io/icon/5mbK36SZ7J19An8jFochhQS4of8g6BwUjbeCSxBSoWdp.png","symbol":"$michi","name":"michi","decimals":6,"tags":[],"extensions":{}},"price":1086.7353136120869,"mintAmountA":9473.278486682,"mintAmountB":10294946.267159,"feeRate":0.0025,"openTime":"0","tvl":2603956.06,"day":{"volume":3911208.461379176,"volumeQuote":29410027.565738827,"volumeFee":9778.021153447942,"apr":137.06,"feeApr":137.06,"priceMin":833.3333333333334,"priceMax":1149.9553106726048,"rewardApr":[]},"week":{"volume":30115226.99600453,"volumeQuote":201900927.171002,"volumeFee":75288.06749001132,"apr":86.74,"feeApr":86.74,"priceMin":734.7821656307822,"priceMax":1456.8985846335192,"rewardApr":[]},"month":{"volume":173058530.49210197,"volumeQuote":769371616.7229099,"volumeFee":432646.3262302549,"apr":199.38,"feeApr":199.38,"priceMin":453.75164745,"priceMax":1456.8985846335192,"rewardApr":[]},"pooltype":["OpenBookMarket"],"rewardDefaultInfos":[],"farmUpcomingCount":0,"farmOngoingCount":0,"farmFinishedCount":0,"marketId":"C5RUxJuZz5YC7s9zKiLrXePs9WxWNyJPY7jRhBe76fiJ","lpMint":{"chainId":101,"address":"8WAtGHTrvrhx8Vc1Z8zSz41ZuYKkrDgQ5Q5ptoPYCEYY","programId":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","logoURI":"","symbol":"","name":"","decimals":9,"tags":[],"extensions":{}},"lpPrice":640.8244825214848,"lpAmount":4063.446591663,"baseReserve":"089bf5d3f2ca","quoteReserve":"095ee52c80c1","status":6,"version":4},"amountIn":"0bebc200","mintIn":"So11111111111111111111111111111111111111112","mintOut":"5mbK36SZ7J19An8jFochhQS4of8g6BwUjbeCSxBSoWdp","slippage":0.1}

RESULT: out.amountOut.toString() 217140715

image

It's correct value and almost same with UI on Raydium

I made a trx and swap done succes

  1. ERROR CASE: Around ANALOS token (7iT1GRYYhEop2nV1dyCwK2MGyLmPHq47WhPGSwiqcUg5)

PARAMS: {"poolInfo":{"type":"Standard","programId":"675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8","id":"69grLw4PcSypZnn3xpsozCJFT8vs8WA5817VUVnzNGTh","mintA":{"chainId":101,"address":"7iT1GRYYhEop2nV1dyCwK2MGyLmPHq47WhPGSwiqcUg5","programId":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","logoURI":"https://img-v1.raydium.io/icon/7iT1GRYYhEop2nV1dyCwK2MGyLmPHq47WhPGSwiqcUg5.png","symbol":"ANALOS","name":"ANALOS","decimals":8,"tags":[],"extensions":{}},"mintB":{"chainId":101,"address":"So11111111111111111111111111111111111111112","programId":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","logoURI":"https://img-v1.raydium.io/icon/So11111111111111111111111111111111111111112.png","symbol":"WSOL","name":"Wrapped SOL","decimals":9,"tags":[],"extensions":{}},"price":4.1865137663277175e-7,"mintAmountA":4678778357.910858,"mintAmountB":1958.777000499,"feeRate":0.0025,"openTime":"1703037625","tvl":538416.48,"day":{"volume":28158.6785576279,"volumeQuote":203.84366711348707,"volumeFee":70.39669639406974,"apr":4.77,"feeApr":4.77,"priceMin":4.102763370594576e-7,"priceMax":4.4213751854765853e-7,"rewardApr":[]},"week":{"volume":246099.47400114112,"volumeQuote":1732.530235560141,"volumeFee":615.2486850028528,"apr":3.43,"feeApr":3.43,"priceMin":3.920840459675289e-7,"priceMax":4.720146010253016e-7,"rewardApr":[]},"month":{"volume":1940350.1843614827,"volumeQuote":11954.359182971002,"volumeFee":4850.875460903706,"apr":10.81,"feeApr":10.81,"priceMin":3.920840459675289e-7,"priceMax":7.493835438716984e-7,"rewardApr":[]},"pooltype":["OpenBookMarket"],"rewardDefaultInfos":[],"farmUpcomingCount":0,"farmOngoingCount":0,"farmFinishedCount":0,"marketId":"3sJVHtBTjpHmTgArbtTz5cDr6umJZUTjx8yZfyoGAhZm","lpMint":{"chainId":101,"address":"6fhwfgUNqwX1YVGvArwyi3AVSkn8nxByvU81ynHHbpcz","programId":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","logoURI":"","symbol":"","name":"","decimals":8,"tags":[],"extensions":{}},"lpPrice":0.12151735532991034,"lpAmount":4430778.44060063,"baseReserve":"067e3c69a89b30e0","quoteReserve":"01c810351233","status":6,"version":4},"amountIn":"0bebc200","mintIn":"7iT1GRYYhEop2nV1dyCwK2MGyLmPHq47WhPGSwiqcUg5","mintOut":"So11111111111111111111111111111111111111112","slippage":0.1}

RESULT: out.amountOut.toString() 835

image

For some reason for that token it provide absolutely wrong amountOut and for sure trx fail at the network (Program Error: "Instruction #5 Failed - insufficient funds)


I just noticed that the difference in these tokens is in the decimals value, perhaps there is some kind of bug in the calculations related to this

cruzshia commented 3 months ago

just tried poolId: 69grLw4PcSypZnn3xpsozCJFT8vs8WA5817VUVnzNGTh and cuz is not base In, so in computeAmountOut method mintIn and mintOut should pass reverse value

 mintIn: poolInfo.mintB.address, // swap mintB -> mintA, use: poolInfo.mintB.address
 mintOut: poolInfo.mintA.address, // swap mintB -> mintA, use: poolInfo.mintA.address

and it's output value is correct, you can check out you input mint

cruzshia commented 3 months ago

here's the sample code

const raydium = await initSdk()
  const amountIn = 200000000
  const poolId = '69grLw4PcSypZnn3xpsozCJFT8vs8WA5817VUVnzNGTh'

  // RAY-USDC pool
  // note: api doesn't support get devnet pool info
  const data = (await raydium.api.fetchPoolById({ ids: poolId })) as any
  const poolInfo = data[0] as ApiV3PoolInfoStandardItem

  if (!isValidAmm(poolInfo.programId)) throw new Error('target pool is not AMM pool')
  const poolKeys = await raydium.liquidity.getAmmPoolKeys(poolId)

  const res = await fetchMultipleInfo({
    connection: raydium.connection,
    poolKeysList: [poolKeys],
    config: undefined,
  })
  const pool = res[0]

  await raydium.liquidity.initLayout()
  const out = raydium.liquidity.computeAmountOut({
    poolInfo: {
      ...poolInfo,
      baseReserve: pool.baseReserve,
      quoteReserve: pool.quoteReserve,
      status: pool.status.toNumber(),
      version: 4,
    },
    amountIn: new BN(amountIn),
    // mintIn: poolInfo.mintA.address, // swap mintB -> mintA, use: poolInfo.mintB.address
    mintIn: poolInfo.mintB.address, // swap mintB -> mintA, use: poolInfo.mintB.address
    mintOut: poolInfo.mintA.address, // swap mintB -> mintA, use: poolInfo.mintA.address
    // mintOut: poolInfo.mintB.address, // swap mintB -> mintA, use: poolInfo.mintA.address
    slippage: 0.01, // range: 1 ~ 0.0001, means 100% ~ 0.01%
  })

  console.log({
    amountOut: out.amountOut.toNumber() / 10 ** poolInfo.mintA.decimals,
    minAmountOut: out.minAmountOut.toNumber() / 10 ** poolInfo.mintA.decimals,
  })
image