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?