-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrun-arbitrage.js
133 lines (119 loc) · 5.34 KB
/
run-arbitrage.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
require('dotenv').config();
const Web3 = require('web3');
const { ChainId, Token, TokenAmount, Fetcher } = require('@uniswap/sdk');
const abis = require('./abis');
const {mainnet: addresses } = require('./addresses');
const Flashloan = require('./build/contracts/Flashloan.json');
const web3 = new Web3(
new Web3.providers.WebsocketProvider(process.env.INFURA_URL)
);
const {address: admin} = web3.eth.accounts.wallet.add(process.env.INFURA_URL);
const kyber = new web3.eth.Contract(
abis.kyber.kyberNetworkProxy,
addresses.kyber.kyberNetworkProxy
);
const AMOUNT_ETH = 100;
const RECENT_ETH_PRICE = 1521;
const AMOUNT_ETH_WEI = web3.utils.toWei(AMOUNT_ETH.toString());
const AMOUNT_DAI_WEI = web3.utils.toWei((AMOUNT_ETH * RECENT_ETH_PRICE).toString());
const DIRECTION = {KYBER_TO_UNISWAP: 0, UNISWAP_TO_KYBER: 1};
const init = async () => {
const networkId = await web3.eyh.net.getId();
const flashloan = new web3.eth.Contract(Flashloan.abi, Flashloan.networks[networkId].address);
const [dai, weth] = await Promise.all(
[addresses.tokens.dai, addresses.tokens.weth].map(tokenAddress => (
Fetcher.fetchTokenData(
ChainId.MAINNET,
tokenAddress
)
)));
const daiWeth = await Fetcher.fetchPairData(
dai,
weth
);
web3.eth.subscribe('newBlockHeaders')
.on('data', async block => {
console.log(`New block received. Block # ${block.number}`);
const kyberResults = await Promise.all([
kyber.methods.getExpectedRate(
addresses.tokens.dai,
'0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
AMOUNT_DAI_WEI
).call(),
kyber.methods.getExpectedRate(
'0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
addresses.tokens.dai,
AMOUNT_ETH_WEI
).call()
]);
const kyberRates = {
buy: parseFloat(1 / (kyberResults[0].expectedRate / (10 ** 18))),
sell: parseFloat(kyberResults[1].expectedRate / (10 ** 18))
};
console.log('Kyber ETH/DAI');
console.log(kyberRates);
const uniswapResults = await Promise.all([
daiWeth.getOutputAmount(new TokenAmount(dai, AMOUNT_DAI_WEI)),
daiWeth.getOutputAmount(new TokenAmount(weth, AMOUNT_ETH_WEI)),
]);
const uniswapRates = {
buy: parseFloat(AMOUNT_DAI_WEI / (uniswapResults[0][0].toExact() * 10 ** 18)),
sell: parseFloat(uniswapResults[1][0].toExact() / AMOUNT_ETH)
};
console.log('Uniswap ETH/DAI');
console.log(uniswapRates);
const [tx1, tx2] = Object.keys(DIRECTION).map(direction => flashloan.methods.initiateFlashloan)(
(
addresses.dydx.solo,
addresses.tokens.dai,
AMOUNT_DAI_WEI,
DIRECTION[direction]
));
const [gasPrice, gasCost1, gasCost2] = await Promise.all([
web3.eth.getGasPrice(),
tx1.estimateGas({from: admin }),
tx2.estimateGas({from: admin })
]);
const txCost1 = parseInt(gasCost1) * parseInt(gasPrice);
const txCost2 = parseInt(gasCost2) * parseInt(gasPrice);
const currentEthPrice = (uniswapRates.buy + uniswapRates.sell) / 2;
const profit1 = (parseInt(AMOUNT_ETH_WEI) / 10 ** 18) * (uniswapRates.sell - kyberRates.buy) - (txCost1 / 10 ** 18) * currentEthPrice;
const profit2 = (parseInt(AMOUNT_ETH_WEI) / 10 ** 18) * (kyberRates.sell - uniswapRates.buy) - (txCost2 / 10 ** 18) * currentEthPrice;
if (profit1 > 0){
console.log('Arb opportunity found!');
console.log(`Buy ETH on Kyber at ${kyberRates.buy} dai`);
console.log(`Sell ETH on Uniswap at ${uniswapRates.sell} dai`);
console.log(`Expected profit ${profit1} dai`);
const data = tx1.encodeABI();
const txData = {
from: admin,
to: flashloan.options.address,
data,
gas: gasCost1,
gasPrice
};
const receipt = await web3.eth.sendTransaction(txData);
console.log(`Transaction hash: ${receipt.transactionHash}`);
}
else if(profit2 > 0){
console.log('Arb opportunity found!');
console.log(`Buy ETH on Uniswap at ${uniswapRates.buy} dai`);
console.log(`Sell ETH on Kyber at ${kyberRates.sell} dai`);
console.log(`Expected profit ${profit2} dai`);
const data = tx2.encodeABI();
const txData = {
from: admin,
to: flashloan.options.address,
data,
gas: gasCost2,
gasPrice
};
const receipt = await web3.eth.sendTransaction(txData);
console.log(`Transaction hash: ${receipt.transactionHash}`);
}
})
.on('error', error => {
console.log(error);
});
}
init();