-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
169 lines (147 loc) · 6.15 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
require('dotenv').config();
const Web3 = require('web3');
const BigNumber = require('bignumber.js');
const abis = require('./abis');
const { mainnet: addresses } = require('./addresses');
const Flashswap = require('./build/contracts/Flashswap.json');
const web3 = new Web3(
new Web3.providers.WebsocketProvider(process.env.BSC_WSS)
);
const { address: admin } = web3.eth.accounts.wallet.add(process.env.PRIVATE_KEY)
// we need pancakeSwap
const pancakeFactory = new web3.eth.Contract(
abis.pancakeFactory.pancakeFactory,
addresses.pancake.factory
);
const pancakeRouter = new web3.eth.Contract(
abis.pancakeRouter.pancakeRouter,
addresses.pancake.router
);
// we need bakerySwap
const bakeryFactory = new web3.eth.Contract(
abis.bakeryFactory.bakeryFactory,
addresses.bakery.factory
);
const bakeryRouter = new web3.eth.Contract(
abis.bakeryRouter.bakeryRouter,
addresses.bakery.router
);
const WBNB = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c';
const fromTokens = ['WBNB'];
const fromToken = [
'0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c' // WBNB
];
const fromTokenDecimals = [18];
const toTokens = ['BUSD'];
const toToken = [
'0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56' // BUSD
];
const toTokenDecimals = [18];
const amount = process.env.BNB_AMOUNT;
const init = async () => {
const networkId = await web3.eth.net.getId();
const flashswap = new web3.eth.Contract(
Flashswap.abi,
Flashswap.networks[networkId].address
);
let subscription = web3.eth.subscribe('newBlockHeaders', (error, result) => {
if (!error) {
// console.log(result);
return;
}
console.error(error);
})
.on("connected", subscriptionId => {
console.log(`You are connected on ${subscriptionId}`);
})
.on('data', async block => {
console.log('-------------------------------------------------------------');
console.log(`New block received. Block # ${block.number}`);
console.log(`GasLimit: ${block.gasLimit} and Timestamp: ${block.timestamp}`);
for (let i = 0; i < fromTokens.length; i++) {
for (let j = 0; j < toTokens.length; j++) {
console.log(`Trading ${toTokens[j]}/${fromTokens[i]} ...`);
const pairAddress = await pancakeFactory.methods.getPair(fromToken[i], toToken[j]).call();
console.log(`pairAddress ${toTokens[j]}/${fromTokens[i]} is ${pairAddress}`);
const unit0 = await new BigNumber(amount);
const amount0 = await new BigNumber(unit0).shiftedBy(fromTokenDecimals[i]);
console.log(`Input amount of ${fromTokens[i]}: ${amount0.toString()}`);
// The quote currency needs to be WBNB
let tokenIn, tokenOut;
if (fromToken[i] === WBNB) {
tokenIn = fromToken[i];
tokenOut = toToken[j];
}
if (toToken[j] === WBNB) {
tokenIn = toToken[j];
tokenOut = fromToken[i];
}
// The quote currency is not WBNB
if (typeof tokenIn === 'undefined') {
return;
}
// call getAmountsOut in PancakeSwap
const amounts = await pancakeRouter.methods.getAmountsOut(amount0, [tokenIn, tokenOut]).call();
const unit1 = await new BigNumber(amounts[1]).shiftedBy(-toTokenDecimals[j]);
const amount1 = await new BigNumber(amounts[1]);
console.log(`
Buying token at PancakeSwap DEX
=================
tokenIn: ${unit0.toString()} ${tokenIn}
tokenOut: ${unit1.toString()} ${tokenOut}
`);
// call getAmountsOut in BakerySwap
const amounts2 = await bakeryRouter.methods.getAmountsOut(amount1, [tokenOut, tokenIn]).call();
const unit2 = await new BigNumber(amounts2[1]).shiftedBy(-fromTokenDecimals[i]);
const amount2 = await new BigNumber(amounts2[1]);
console.log(`
Buying back token at BakerySwap DEX
=================
tokenOut: ${unit1.toString()} ${tokenOut}
tokenIn: ${unit2.toString()} ${tokenIn}
`);
let profit = await new BigNumber(amount2).minus(amount0);
console.log(`Profit: ${profit.toString()}`);
if (profit > 0) {
const tx = flashswap.methods.startArbitrage(
tokenIn,
tokenOut,
0,
amount1
);
const [gasPrice, gasCost] = await Promise.all([
web3.eth.getGasPrice(),
tx.estimateGas({from: admin}),
]);
const txCost = web3.utils.toBN(gasCost) * web3.utils.toBN(gasPrice);
profit = await new BigNumber(profit).minus(txCost);
if (profit > 0) {
console.log(`
Block # ${block.number}: Arbitrage opportunity found!
Expected profit: ${profit}
`);
const data = tx.encodeABI();
const txData = {
from: admin,
to: flashswap.options.address,
data,
gas: gasCost,
gasPrice
};
const receipt = await web3.eth.sendTransaction(txData);
console.log(`Transaction hash: ${receipt.transactionHash}`);
}
} else {
console.log(`
Block # ${block.number}: Arbitrage opportunity not found!
Expected profit: ${profit}
`);
}
}
}
})
.on('error', error => {
console.log(error);
});
}
init();