I get this error or another error err: insufficient funds for gas * price + value
, which has been exhaustively discussed, but no real solution has worked for me here.
I saw the suggestion made here, but I don't see where I'm using the same method
I am running a bot that operates a swap between crytocurrencies on two exchanges. Here is the relevant code:
The bot is running against a live contract on etherscan here.
reserve0 = reserves.reserve0;
reserve0toNumber = BigInt(reserve0)
let maxUint256 = BigInt("115792089237316195423570985008687907853269984665640564039457584007913129639935")
if (reserve0toNumber < maxUint256) {
reserve0Final = reserve0toNumber
} else {
reserve0Final = maxUint256
}
reserve1 = reserves.reserve1
console.log(`Reserves on ${_routerPath[1]._address}`)
console.log(`Token 1: ${reserve0}`)
console.log(`Token 0: ${reserve1}\n`)
try {
*** //This is where the ds-math-sub-underflow error occurs
let result = await _routerPath[0].methods.getAmountsIn(reserve0Final, [_token0.address, _token1.address]).call()
const token0In = result[0]
const token1In = result[1]
result = await _routerPath[1].methods.getAmountsOut(token1In, [_token1.address, _token0.address]).call()
console.log(`Estimated amount of Token 0 needed to buy enough Token 1 on ${exchangeToBuy}\t\t| ${web3.utils.fromWei(token0In, 'ether')}`)
console.log(`Estimated amount of Token 0 returned after swapping Token 1 on ${exchangeToSell}\t| ${web3.utils.fromWei(result[1], 'ether')}\n`)
const { amountIn, amountOut } = await getEstimatedReturn(token0In, _routerPath, _token0, _token1)
console.log([amountIn,amountOut])
// const block = web3.eth.getBlock("latest")
// const gas = web3.eth.getBlock("latest").gasLimit
*** //This is where the insufficient funds for gas * price + value error occurs
const estimatedGasCost = await _routerPath[0].methods.swapExactTokensForTokens(result[1], web3.utils.toWei('1', 'ether'), [_token1.address, _token0.address],account, Math.floor(Date.now() / 1000) + 60*60).estimateGas({from: account, value: web3.utils.toWei(result[1], 'ether')});
Here is the error stack for ds-math-sub-underflow
Error: Returned error: execution reverted: ds-math-sub-underflow
at Object.ErrorResponse (/Users/TrentKennelly/trading_bot_V2/node_modules/web3-core-helpers/lib/errors.js:28:19)
at Object.callback (/Users/TrentKennelly/trading_bot_V2/node_modules/web3-core-requestmanager/lib/index.js:300:36)
at /Users/TrentKennelly/trading_bot_V2/node_modules/web3-providers-ws/lib/index.js:114:45
at Array.forEach (<anonymous>)
at WebsocketProvider._onMessage (/Users/TrentKennelly/trading_bot_V2/node_modules/web3-providers-ws/lib/index.js:102:69)
at W3CWebSocket._dispatchEvent [as dispatchEvent] (/Users/TrentKennelly/trading_bot_V2/node_modules/yaeti/lib/EventTarget.js:115:12)
at W3CWebSocket.onMessage (/Users/TrentKennelly/trading_bot_V2/node_modules/websocket/lib/W3CWebSocket.js:234:14)
at WebSocketConnection.<anonymous> (/Users/TrentKennelly/trading_bot_V2/node_modules/websocket/lib/W3CWebSocket.js:205:19)
at WebSocketConnection.emit (node:events:513:28)
at WebSocketConnection.processFrame (/Users/TrentKennelly/trading_bot_V2/node_modules/websocket/lib/WebSocketConnection.js:554:26)
at /Users/TrentKennelly/trading_bot_V2/node_modules/websocket/lib/WebSocketConnection.js:323:40
at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
data: //this is a hash - is it safe to provide?
}
Here is the error stack for err: insufficient funds for gas * price + value
Estimated amount of Token 0 needed to buy enough Token 1 on Sushiswap | 0.000000000000000022
Estimated amount of Token 0 returned after swapping Token 1 on Uniswap | 0.000000000000000012
Error: Returned error: err: insufficient funds for gas * price + value: address 0xdf58cA0a02bf9b43CE13b8AB5969E4b60f22c0a3 have 11059137636702474 want 12000000000000000000 (supplied gas 15010499)
at Object.ErrorResponse (/Users/TrentKennelly/trading_bot_V2/node_modules/web3-core-helpers/lib/errors.js:28:19)
at Object.callback (/Users/TrentKennelly/trading_bot_V2/node_modules/web3-core-requestmanager/lib/index.js:300:36)
at /Users/TrentKennelly/trading_bot_V2/node_modules/web3-providers-ws/lib/index.js:114:45
at Array.forEach (<anonymous>)
at WebsocketProvider._onMessage (/Users/TrentKennelly/trading_bot_V2/node_modules/web3-providers-ws/lib/index.js:102:69)
at W3CWebSocket._dispatchEvent [as dispatchEvent] (/Users/TrentKennelly/trading_bot_V2/node_modules/yaeti/lib/EventTarget.js:115:12)
at W3CWebSocket.onMessage (/Users/TrentKennelly/trading_bot_V2/node_modules/websocket/lib/W3CWebSocket.js:234:14)
at WebSocketConnection.<anonymous> (/Users/TrentKennelly/trading_bot_V2/node_modules/websocket/lib/W3CWebSocket.js:205:19)
at WebSocketConnection.emit (node:events:513:28)
at WebSocketConnection.processFrame (/Users/TrentKennelly/trading_bot_V2/node_modules/websocket/lib/WebSocketConnection.js:554:26)
at /Users/TrentKennelly/trading_bot_V2/node_modules/websocket/lib/WebSocketConnection.js:323:40
at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
data: null
}
I can't see a reason why this would be failing other than maybe a math problem? Any thoughts?
UPDATE I have been printing out different parts of the code I provided and I'm fairly comfortable that there is indeed a math problem, I'm just not totally sure how to fix it.
Here's the updated code:
reserve0 = reserves.reserve0;
reserve1 = reserves.reserve1
console.log(`Reserves on ${_routerPath[1]._address}`)
console.log(`Token 1: ${reserve0}`)
console.log(`Token 0: ${reserve1}\n`)
try {
//***This is where the ds-math-sub-underflow error occurs
let result = await _routerPath[0].methods.getAmountsIn(reserve0, [_token0.address, _token1.address]).call()
console.log(`result: ${result}`)
const token0In = result[0]
const token1In = result[1]
result = await _routerPath[1].methods.getAmountsOut(token1In, [_token1.address, _token0.address]).call()
console.log(`result V2: ${result}`)
console.log(`Estimated amount of Token 0 needed to buy enough Token 1 on ${exchangeToBuy}\t\t| ${web3.utils.fromWei(token0In, 'ether')}`)
console.log(`Estimated amount of Token 0 returned after swapping Token 1 on ${exchangeToSell}\t| ${web3.utils.fromWei(result[1], 'ether')}\n`)
const { amountIn, amountOut } = await getEstimatedReturn(token0In, _routerPath, _token0, _token1)
console.log(`amountIn: ${amountIn}`)
console.log(`amountOut: ${amountOut}`)
// ***This is where the insufficient funds for gas * price + value error occurs
const estimatedGasCost = await _routerPath[0].methods.swapExactTokensForTokens(result[1], web3.utils.toWei('1', 'ether'), [_token1.address, _token0.address],account, Math.floor(Date.now() / 1000) + 60*60).estimateGas({from: account, value: web3.utils.toWei(result[1], 'ether')});
Here's an example with result
and resultV2
printed out:
Swap Initiated on Sushiswap, Checking Price...
Current Block: 16490588
-----------------------------------------
UNISWAP | WETH/SYN | 1669
SUSHISWAP | SYN/WETH | 1817
Percentage Difference: -8.15%
Determining Direction...
Potential Arbitrage Direction:
Buy --> Sushiswap
Sell --> Uniswap
Determining Profitability...
Reserves on 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
Token 1: 41732
Token 0: 25
result: 24,41732
result V2: 41732,41706
Estimated amount of Token 0 needed to buy enough Token 1 on Sushiswap | 0.000000000000000024
Estimated amount of Token 0 returned after swapping Token 1 on Uniswap | 0.000000000000041706
amountIn: 2.4e-17
amountOut: 1.2e-17
Error: Returned error: err: insufficient funds for gas * price + value: address 0xdf58cA0a02bf9b43CE13b8AB5969E4b60f22c0a3 have 11059137636702474 want 41706000000000000000000 (supplied gas 15010499)
at Object.ErrorResponse (/Users/TrentKennelly/trading_bot_V2/node_modules/web3-core-helpers/lib/errors.js:28:19)
at Object.callback (/Users/TrentKennelly/trading_bot_V2/node_modules/web3-core-requestmanager/lib/index.js:300:36)
at /Users/TrentKennelly/trading_bot_V2/node_modules/web3-providers-ws/lib/index.js:114:45
at Array.forEach (<anonymous>)
at WebsocketProvider._onMessage (/Users/TrentKennelly/trading_bot_V2/node_modules/web3-providers-ws/lib/index.js:102:69)
at W3CWebSocket._dispatchEvent [as dispatchEvent] (/Users/TrentKennelly/trading_bot_V2/node_modules/yaeti/lib/EventTarget.js:115:12)
at W3CWebSocket.onMessage (/Users/TrentKennelly/trading_bot_V2/node_modules/websocket/lib/W3CWebSocket.js:234:14)
at WebSocketConnection.<anonymous> (/Users/TrentKennelly/trading_bot_V2/node_modules/websocket/lib/W3CWebSocket.js:205:19)
at WebSocketConnection.emit (node:events:513:28)
at WebSocketConnection.processFrame (/Users/TrentKennelly/trading_bot_V2/node_modules/websocket/lib/WebSocketConnection.js:554:26)
at /Users/TrentKennelly/trading_bot_V2/node_modules/websocket/lib/WebSocketConnection.js:323:40
at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
data: null
}
Seems like the amountsIn
result is greater than the amountsOut
result every time.
Final note - this update is demonstrating the gas * price + value
error, but I THINK the ds-math-sub-underflow
error happens in the same spot, it just errors out at the try
in its entirety
Update 2 It's possible that the math problem is originating from the estimateGas
function call. It seems that function may require that I provide a wallet address with enough ether to cover the entirety of the trade amount, even though the contract this is using has arbitrage components to it (though, at this point in the code, because I haven't called the contract at all it doesn't know that). How can I estimate the gas in a "theoretical" way without it deciding I'm too poor to run the trade and refusing to continue?
Update 3 I've discovered that reserve0
in the line let result = await _routerPath[0].methods.getAmountsIn(reserve0, [_token0.address, _token1.address]).call()
is being passed as a string when it should be a uint. However, even with this change the same error is occurring. Could really use some help here if anybody has any to give.