Web3js – How to Use getReserves() in a forEach Loop

javascripttruffleuniswapweb3js

How can I use getReserves inside a forEach loop to call the reserves relative to each array object (the array objects are token addresses)? Details below:

I have an array of addresses being monitored inside a forEach loop like so:

const arbFor = process.env.ARB_FOR 
const arbAgainst = ["address1","address2","address3"]
let i = 0;

arbAgainst.forEach(()=>{

  const main = async () => {
    const { token0Contract, token1Contract, token0, token1 } = await getTokenAndContract(arbFor, arbAgainst[i])
    var uPair = await getPairContract(uFactory, token0.address, token1.address)
    uniPair = Object.freeze(uPair);
    var sPair = await getPairContract(sFactory, token0.address, token1.address)
    sushiPair = Object.freeze(sPair);
    
    // Do some stuff

  // Other async functions

  const determineProfitability = async (_routerPath, _token0Contract, _token0, _token1,  exchange, token0, token1) => {
    console.log(`Determining Profitability...\n`)

    let reserves, exchangeToBuy, exchangeToSell

    if (_routerPath[0]._address == uRouter._address) {
        reserves = await getReserves(sushiPair)
        exchangeToBuy = 'Uniswap'
        exchangeToSell = 'Sushiswap'
    } else {
        reserves = await getReserves(uniPair)
        exchangeToBuy = 'Sushiswap'
        exchangeToSell = 'Uniswap'
    }

    console.log(`Reserves on ${_routerPath[1]._address}\n`)
    console.log(`Token 1: ${web3.utils.fromWei(reserves[0].toString(), 'ether')}`)
    console.log(`Token 0: ${web3.utils.fromWei(reserves[1].toString(), 'ether')}\n`)
}

As you can see, I've been attempting to use Object.freeze to work with a specific object for that iteration of the forEach loop. However, when I run this, it seems to only freeze one time and attempt to iterate over that same object each time. So clearly it doesn't freeze anew for each array object.

However, if I simply use uPair and sPair inside getReserves() I get the following error stack:

  const reserves = await _pairContract.methods.getReserves().call()
                                         ^

TypeError: Cannot read properties of undefined (reading 'methods')
    at getReserves (/Users/Me/trading_bot_V2/helpers/helpers.js:54:42)
    at calculatePrice (/Users/Me/trading_bot_V2/helpers/helpers.js:59:40)
    at checkPrice (/Users/Me/trading_bot_V2/bot.js:105:34)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Subscription.callback (/Users/Me/trading_bot_V2/bot.js:40:45)

Any thoughts?

**Update – I removed var from in front of uPair and sPair. Now they're behaving exactly like uniPair and sushiPair did. Which is to say they're only looping through a single reserves router path. And I think it's also worth noting that path doesn't change ever regardless of which swap I identify first (say USDT/WETH or DAI/WETH)

Edit – I realized it may be beneficial to see the getReserves() function, as it is used differently in this case. Here are the relevant functions:

async function getPairAddress(_V2Factory, _token0, _token1) {
    const pairAddress = await _V2Factory.methods.getPair(_token0, _token1).call()
    return pairAddress
}

async function getPairContract(_V2Factory, _token0, _token1) {
    const pairAddress = await getPairAddress(_V2Factory, _token0, _token1)
    const pairContract = new web3.eth.Contract(IUniswapV2Pair.abi, pairAddress)
    return pairContract
}

async function getReserves(_pairContract) {
    const reserves = await _pairContract.methods.getReserves().call()
    return [reserves.reserve0, reserves.reserve1]

***Update 2: I've JUST noticed that when I call console.log(`Reserves on ${_routerPath[1]._address}\n`) it's actually printing the router address for sushiswap or uniswap rather than pulling reserves. Might have something to do with it. Still open to suggestions.

Best Answer

I would have an array with the addresses of all pairs and would do something like this:


for(let i = 0; i < allPairs.length; i++){
  const pair = new ethers.Contract(allPairs[i], UniswapV2Pair.abi, provider)
const reserves = await pair.getReserves()

pairWithReserves.push({pair: allPair[i], reserve0: reserves.token0, reserve1: reserves.token1})

This would be enough. It's just a glimpse on how you can solve this easily.

BROTIP: If it's for arbitrage, you should be looking for kLast() insteed of getReserves()

Related Topic