0

I have a function inside an arbitrage bot that is supposed to use getAmountsIn to determine the profitability of the trade. However, due to the current implementation, every single trade results in a high predicted loss. Below, you'll find the relevant code, a printout displaying the heavy loss prediction, and my own math that seems to contradict the finding of getAmountsIn

Where is this implementation going wrong?

The code:

        const determineProfitability = async (_routerPath, _token0Contract, _token0, _token1, uPairValue, sPairValue) => {

            let reserves, exchangeToBuy, exchangeToSell, reserve0, reserve1

            if (_routerPath[0]._address == uRouter._address) {
                reserves = await getReserves(sPairValue)
                otherReserves = await getReserves(uPairValue)
                exchangeToBuy = 'Uniswap'
                exchangeToSell = 'Sushiswap'

            } else {
                reserves = await getReserves(uPairValue)
                otherReserves  = await getReserves(sPairValue)
                exchangeToBuy = 'Sushiswap'
                exchangeToSell = 'Uniswap'
            }

            try { 

                // v-- This is where the calculation seems to go wrong --v

                let result = await _routerPath[0].methods.getAmountsIn(reserves[0], [_token1.address, _token0.address]).call()

                const token0In = result[0]
                const token1In = result[1] 

                result = await _routerPath[1].methods.getAmountsOut(token1In, [_token1.address, _token0.address]).call()

                const { amountIn, amountOut } = await getEstimatedReturn(token0In, _routerPath, _token0, _token1)
  
                const gasPrice = await web3.eth.getGasPrice();
                const gasCalc = (gasPrice * 21000).toString();
                const estimatedGasCost = web3.utils.fromWei(gasCalc, 'ether')                

                let ethBalanceBefore = await web3.eth.getBalance(account) 
                ethBalanceBefore = web3.utils.fromWei(ethBalanceBefore, 'ether')
                const ethBalanceAfter = ethBalanceBefore - estimatedGasCost

                const amountDifference = amountOut - amountIn
                let wethBalanceBefore = await _token0Contract.methods.balanceOf(account).call() 
                wethBalanceBefore = web3.utils.fromWei(wethBalanceBefore, 'ether')

                const wethBalanceAfter = amountDifference + Number(wethBalanceBefore)
                const wethBalanceDifference = wethBalanceAfter - Number(wethBalanceBefore)

                const totalGained = wethBalanceDifference - Number(estimatedGasCost)

                if (totalGained < 0 || amountOut < amountIn) {
                    return false
                }

                amount = token0In
                return true

            } catch (error) {      
                console.log(error)
                return false
            }

        }

Here's the printout:

Swap Initiated on Sushiswap, Checking Price...

Current Block: 16587119
-----------------------------------------
UNISWAP   | WETH/FXS     | 142
SUSHISWAP | WETH/FXS     | 143

Percentage Difference: -0.70%

Determining Direction...

Potential Arbitrage Direction:

Buy  -->     Sushiswap
Sell     -->     Uniswap

Determining Profitability...

uPair Address: 0xecBa967D84fCF0405F6b32Bc45F4d36BfDBB2E81
sPair Address: 0x61eB53ee427aB4E007d78A9134AaCb3101A2DC23

Reserves on Uniswap (0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D)
WETH: 94.71862096607386039
FXS: 13480.822150599881758659

Reserves on Sushiswap (0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F)
OtherWETH: 1263.203664453649794659
OtherFXS: 180432.001225073992589556

token0In: 102.30694284028118994
token1In: 13480.822150599881758659
result[0]: 13480.822150599881758659
result[1]: 47.288164798785998402

Estimated amount of WETH needed to buy enough FXS on Sushiswap      | 102.30694284028118994
Estimated amount of WETH returned after swapping FXS on Uniswap | 47.288164798785998402

┌─────────────────────┬────────────────────────┐
│       (index)       │         Values         │
├─────────────────────┼────────────────────────┤
│ ETH Balance Before  │ '0.011059137636702474' │
│  ETH Balance After  │  0.010474034995509474  │
│   ETH Spent (gas)   │  '0.000585102641193'   │
│          -          │                        │
│ WETH Balance BEFORE │      '0.00003675'      │
│ WETH Balance AFTER  │  -55.018741291495196   │
│  WETH Gained/Lost   │  -55.018778041495196   │
│  Total Gained/Lost  │   -55.01936314413639   │
└─────────────────────┴────────────────────────┘
No Arbitrage Currently Available

Here's my math on this:

WETH reserves on UniSwap were 94.7186209660738
At a price of 1 WETH / 143 FXS on Sushiswap, the output from using all that WETH would be 13544.7627981486000 FXS
Selling that amount of FXS of Uniswap at a price of 1 WETH / 142 FXS would provide a return in WETH of 95.38565351
Gas was 0.0005851026412 ETH for this transaction
There are also .3% transaction fees to account for on Uniswap and Sushiswap

So here's the calculation: 
95.38565351 - (95.38565351 * .003) - 0.0005851026412 - 94.7186209660738 - (94.7186209660738 *.003) = 0.0981357135770 ETH

Now, just for fun, what if we change the transaction fee to 30% for each?

Then the total becomes -56.1647251402709 ETH ... very close to the -55.01936314413639 ETH final calculation spurred on by getAmountsIn.  

I don't know if that last bit is a false equivalency or not, but I've seen it when doing the math on 10-20 or more swaps like this. In any case, there should have been a gain of nearly .1 ETH on this transaction. So why is getAmountsIn giving me such a drastically different number?

1 Answer 1

0

I ended up just not using getAmountsIn or getAmountsOut at all and opting for a simple math equation. Seems like one of those situations where the library just made life harder.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.