2021-11-30T08:56:45.285696+00:00 app[arbitrage.1]: at WebSocketConnection.emit (events.js:400:28)
2021-11-30T08:56:45.285696+00:00 app[arbitrage.1]: at WebSocketConnection.handleSocketClose (/app/node_modules/websocket/lib/WebSocketConnection.js:389:14)
2021-11-30T08:56:45.285697+00:00 app[arbitrage.1]: at TLSSocket.emit (events.js:412:35)
2021-11-30T08:56:45.285697+00:00 app[arbitrage.1]: at net.js:686:12
2021-11-30T08:56:45.285698+00:00 app[arbitrage.1]: at TCP.done (_tls_wrap.js:564:7) {
2021-11-30T08:56:45.285698+00:00 app[arbitrage.1]: code: 4040,
2021-11-30T08:56:45.285698+00:00 app[arbitrage.1]: reason: 'Draining connection'
2021-11-30T08:56:45.285699+00:00 app[arbitrage.1]: }
2021-11-30T08:56:45.498389+00:00 heroku[arbitrage.1]: Process exited with status 0
2021-11-30T08:56:45.571632+00:00 heroku[arbitrage.1]: State changed from up to crashed
2021-11-30T10:11:35.303205+00:00 heroku[arbitrage.1]: State changed from crashed to starting
2021-11-30T10:11:39.218702+00:00 heroku[arbitrage.1]: Starting process with command `node bscFlashArb1.js`
2021-11-30T10:11:39.788533+00:00 heroku[arbitrage.1]: State changed from starting to up
2021-11-30T10:16:37.187777+00:00 heroku[arbitrage.1]: Process exited with status 0
2021-11-30T10:16:37.289534+00:00 heroku[arbitrage.1]: State changed from up to crashed
2021-11-30T10:16:37.018779+00:00 app[arbitrage.1]: Error: CONNECTION ERROR: The connection got closed with the close code `4040` and the following reason string `Draining connection`
2021-11-30T10:16:37.018791+00:00 app[arbitrage.1]: at Object.ConnectionError (/app/node_modules/web3-core-helpers/lib/errors.js:66:23)
2021-11-30T10:16:37.018791+00:00 app[arbitrage.1]: at Object.ConnectionCloseError (/app/node_modules/web3-core-helpers/lib/errors.js:53:25)
2021-11-30T10:16:37.018792+00:00 app[arbitrage.1]: at /app/node_modules/web3-core-requestmanager/lib/index.js:119:50
2021-11-30T10:16:37.018792+00:00 app[arbitrage.1]: at Map.forEach (<anonymous>)
2021-11-30T10:16:37.018793+00:00 app[arbitrage.1]: at WebsocketProvider.disconnect (/app/node_modules/web3-core-requestmanager/lib/index.js:118:37)
2021-11-30T10:16:37.018793+00:00 app[arbitrage.1]: at WebsocketProvider.emit (/app/node_modules/eventemitter3/index.js:181:35)
2021-11-30T10:16:37.018793+00:00 app[arbitrage.1]: at WebsocketProvider._onClose (/app/node_modules/web3-providers-ws/lib/index.js:152:10)
2021-11-30T10:16:37.018794+00:00 app[arbitrage.1]: at W3CWebSocket._dispatchEvent [as dispatchEvent] (/app/node_modules/yaeti/lib/EventTarget.js:115:12)
2021-11-30T10:16:37.018794+00:00 app[arbitrage.1]: at W3CWebSocket.onClose (/app/node_modules/websocket/lib/W3CWebSocket.js:228:10)
2021-11-30T10:16:37.018794+00:00 app[arbitrage.1]: at WebSocketConnection.<anonymous> (/app/node_modules/websocket/lib/W3CWebSocket.js:201:17)
2021-11-30T10:16:37.018795+00:00 app[arbitrage.1]: at WebSocketConnection.emit (events.js:400:28)
2021-11-30T10:16:37.018795+00:00 app[arbitrage.1]: at WebSocketConnection.handleSocketClose (/app/node_modules/websocket/lib/WebSocketConnection.js:389:14)
2021-11-30T10:16:37.018795+00:00 app[arbitrage.1]: at TLSSocket.emit (events.js:412:35)
2021-11-30T10:16:37.018795+00:00 app[arbitrage.1]: at net.js:686:12
2021-11-30T10:16:37.018796+00:00 app[arbitrage.1]: at TCP.done (_tls_wrap.js:564:7) {
2021-11-30T10:16:37.018796+00:00 app[arbitrage.1]: code: 4040,
2021-11-30T10:16:37.018797+00:00 app[arbitrage.1]: reason: 'Draining connection'
2021-11-30T10:16:37.018797+00:00 app[arbitrage.1]: }
2021-11-30T10:16:37.024479+00:00 app[arbitrage.1]: Error: CONNECTION ERROR: Couldn't connect to node on WS.
2021-11-30T10:16:37.024480+00:00 app[arbitrage.1]: at Object.ConnectionError (/app/node_modules/web3-core-helpers/lib/errors.js:66:23)
2021-11-30T10:16:37.024480+00:00 app[arbitrage.1]: at Object.InvalidConnection (/app/node_modules/web3-core-helpers/lib/errors.js:36:21)
2021-11-30T10:16:37.024481+00:00 app[arbitrage.1]: at /app/node_modules/web3-providers-ws/lib/index.js:161:37
2021-11-30T10:16:37.024481+00:00 app[arbitrage.1]: at Map.forEach (<anonymous>)
2021-11-30T10:16:37.024481+00:00 app[arbitrage.1]: at WebsocketProvider._onClose (/app/node_modules/web3-providers-ws/lib/index.js:160:28)
2021-11-30T10:16:37.024482+00:00 app[arbitrage.1]: at W3CWebSocket._dispatchEvent [as dispatchEvent] (/app/node_modules/yaeti/lib/EventTarget.js:115:12)
2021-11-30T10:16:37.024483+00:00 app[arbitrage.1]: at W3CWebSocket.onClose (/app/node_modules/websocket/lib/W3CWebSocket.js:228:10)
2021-11-30T10:16:37.024483+00:00 app[arbitrage.1]: at WebSocketConnection.<anonymous> (/app/node_modules/websocket/lib/W3CWebSocket.js:201:17)
2021-11-30T10:16:37.024483+00:00 app[arbitrage.1]: at WebSocketConnection.emit (events.js:400:28)
2021-11-30T10:16:37.024484+00:00 app[arbitrage.1]: at WebSocketConnection.handleSocketClose (/app/node_modules/websocket/lib/WebSocketConnection.js:389:14)
2021-11-30T10:16:37.024484+00:00 app[arbitrage.1]: at TLSSocket.emit (events.js:412:35)
2021-11-30T10:16:37.024485+00:00 app[arbitrage.1]: at net.js:686:12
2021-11-30T10:16:37.024486+00:00 app[arbitrage.1]: at TCP.done (_tls_wrap.js:564:7) {
2021-11-30T10:16:37.024486+00:00 app[arbitrage.1]: code: 4040,
2021-11-30T10:16:37.024487+00:00 app[arbitrage.1]: reason: 'Draining connection'
2021-11-30T10:16:37.024487+00:00 app[arbitrage.1]: }
Disconnected from log stream. There may be events happening that you do not see here! Attempting to reconnect...
2021-11-30T10:16:37.024483+00:00 app[arbitrage.1]: at WebSocketConnection.emit (events.js:400:28)
2021-11-30T10:16:37.024484+00:00 app[arbitrage.1]: at WebSocketConnection.handleSocketClose (/app/node_modules/websocket/lib/WebSocketConnection.js:389:14)
2021-11-30T10:16:37.024484+00:00 app[arbitrage.1]: at TLSSocket.emit (events.js:412:35)
2021-11-30T10:16:37.024485+00:00 app[arbitrage.1]: at net.js:686:12
2021-11-30T10:16:37.024486+00:00 app[arbitrage.1]: at TCP.done (_tls_wrap.js:564:7) {
2021-11-30T10:16:37.024486+00:00 app[arbitrage.1]: code: 4040,
2021-11-30T10:16:37.024487+00:00 app[arbitrage.1]: reason: 'Draining connection'
2021-11-30T10:16:37.024487+00:00 app[arbitrage.1]: }
2021-11-30T10:16:37.187777+00:00 heroku[arbitrage.1]: Process exited with status 0
2021-11-30T10:16:37.289534+00:00 heroku[arbitrage.1]: State changed from up to crashed
2021-11-30T10:50:55.859675+00:00 heroku[arbitrage.1]: State changed from crashed to starting
2021-11-30T10:50:58.714643+00:00 heroku[arbitrage.1]: Starting process with command `node bscFlashArb1.js`
2021-11-30T10:50:59.312175+00:00 heroku[arbitrage.1]: State changed from starting to up
I created a flashloan bot for arbitrage (on bsc) and deployed it to heroku. The bot keeps crashing with the same error (draining connection error 400).
Here is the hole script:
require('dotenv').config();
const Web3 = require('web3');
const abis = require('./abis');
const { mainnet: addresses } = require('./addresses');
const web3 = new Web3(
new Web3.providers.WebsocketProvider(process.env.MORALIS_WSS_URL)
);
// const web3 = new Web3(
// new Web3.providers.WebsocketProvider(process.env.BSC_WSS_URL)
// );
const { address: admin } = web3.eth.accounts.wallet.add(process.env.PRIVATE_KEY);
const AMOUNT_DAI_WEI = web3.utils.toBN(web3.utils.toWei('THE_AMOUNT_YOU_WANT_TO_BORROW'));
const init = async () => {
const BscFlashArb1 = new web3.eth.Contract(
abis.bscFlashArb1.abi,
addresses.bscFlashArb1.addr
);
const PancakeSwap = new web3.eth.Contract(
abis.pancakeSwap.router,
addresses.pancakeSwap.router
);
const BakerySwap = new web3.eth.Contract(
abis.bakerySwap.router,
addresses.bakerySwap.router
);
web3.eth.subscribe('newBlockHeaders')
.on('data', async block => {
try {
// borrow DAI from pancakeswap and sell it on
// bakeryswap. Repay in WBNB. Keep the profit in WBNB
const [amountsIn1, amountsOut1] = await Promise.all([
PancakeSwap.methods
.getAmountsIn(
AMOUNT_DAI_WEI,
[addresses.tokens.WBNB, addresses.tokens.DAI]
).call(),
BakerySwap.methods
.getAmountsOut(
AMOUNT_DAI_WEI,
[addresses.tokens.DAI, addresses.tokens.WBNB]
).call()
]);
const profit_in_WBNB = web3.utils.toBN(amountsOut1[1]).sub(web3.utils.toBN(amountsIn1[0]));
// borrow WBNB from pancakeswap and sell it on
// bakeryswap. Repay in DAI. Keep the profit in DAI
const AMOUNT_WBNB_WEI = await PancakeSwap
.methods
.getAmountsOut(
AMOUNT_DAI_WEI,
[addresses.tokens.DAI, addresses.tokens.WBNB]
).call();
const [amountsIn2, amountsOut2] = await Promise.all([
PancakeSwap
.methods
.getAmountsIn(
AMOUNT_WBNB_WEI[1],
[addresses.tokens.DAI, addresses.tokens.WBNB]
).call(),
BakerySwap
.methods
.getAmountsOut(
AMOUNT_WBNB_WEI[1],
[addresses.tokens.WBNB, addresses.tokens.DAI]
).call()
]);
const profit_in_DAI = web3.utils.toBN(amountsOut2[1]).sub(web3.utils.toBN(amountsIn2[0]));
// arbitrage borrowing DAI
if (profit_in_WBNB > 0) {
const tx = BscFlashArb1.methods.startArbitrage(
addresses.tokens.DAI,
addresses.tokens.WBNB,
AMOUNT_DAI_WEI,
0
);
const [gasPrice, gasCost] = await Promise.all([
web3.eth.getGasPrice(),
tx.estimateGas({from: admin})
]);
const gas = web3.utils.toBN(gasCost).add(
web3.utils.toBN(gasCost).div(web3.utils.toBN('20'))
);
const txCost = gas.mul(web3.utils.toBN(gasPrice));
const profit = profit_in_WBNB.sub(txCost);
if(profit.gte(txCost)) {
console.log('Arb opportunity found. Borrow DAI. Repay in WBNB!');
console.log(`Expected profit: ${web3.utils.fromWei(profit)} Dai`);
const data = tx.encodeABI();
const txData = {
from: admin,
to: addresses.bscFlashArb1.addr,
data,
gas,
gasPrice
};
const receipt = await web3.eth.sendTransaction(txData);
console.log(`Transaction hash: ${receipt.transactionHash}`);
}
}
// arbitrage borrowing WBNB
if (profit_in_DAI > 0) {
const tx = BscFlashArb1.methods.startArbitrage(
addresses.tokens.DAI,
addresses.tokens.WBNB,
0,
AMOUNT_WBNB_WEI
);
const [gasPrice, gasCost] = await Promise.all([
web3.eth.getGasPrice(),
tx.estimateGas({from: admin})
]);
const gas = web3.utils.toBN(gasCost).add(
web3.utils.toBN(gasCost).div(web3.utils.toBN('20'))
);
const txCost = gas.mul(web3.utils.toBN(gasPrice));
const txCost_in_Dai = web3.utils.toBN(amountsOut2[1]).mul(txCost).div(AMOUNT_WBNB_WEI[1]);
const profit = profit_in_DAI.sub(txCost_in_Dai);
if(profit.gte(web3.utils.toBN('0'))) {
console.log('Arb opportunity found. Borrow WBNB. Repay in DAI!');
console.log(`Expected profit: ${web3.utils.fromWei(profit)} Dai`);
const data = tx.encodeABI();
const txData = {
from: admin,
to: addresses.bscFlashArb1.addr,
data,
gas,
gasPrice
};
const receipt = await web3.eth.sendTransaction(txData);
console.log(`Transaction hash: ${receipt.transactionHash}`);
}
}
// console.log('running...')
} catch (error) {
console.error(error);
}
})
.on('error', error => {
console.log(error);
});
}
init();
I noticed that most of time the app runs well. It crashes only when there is an arbitrage opportunity (when the code in one of the main if statments runs). I can’t figure out why It happens.
I made some research about draining connections. AWS uses it a lot. If the moralis servers are hosted on AWS, maybe this errore comes frome AWS servers configurations.