-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
150 lines (123 loc) · 3.9 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
require('dotenv').config();
const { ethers, BigNumber } = require('ethers');
const { strategies, provider } = require('./strategies');
const { getGasPrice } = require('./gas');
const Sentry = require('@sentry/node');
const { METHODS_TO_EXECUTE } = require('./constants');
// Call cost in wei, zero for now while it's subsidized by Tesseract.fi
const callCost = BigInt(0);
const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
async function harvestTrigger(strategy, callCostInWei) {
return await strategy.harvestTrigger(callCostInWei);
}
async function tendTrigger(strategy, callCostInWei) {
return await strategy.tendTrigger(callCostInWei);
}
/**
* @param contract Strategy contract instance
* @param method ENUM which method to execute from METHODS_TO_EXECUTE
* */
async function execute(contract, method) {
const strategy = await contract.connect(signer);
const isMethodHarvest = method === METHODS_TO_EXECUTE.harvest;
const sentryTransaction = Sentry.startTransaction({
op: 'pre-' + method,
name: 'Catch if ' + method + ' would fail',
});
try {
if (isMethodHarvest) {
await strategy.callStatic.harvest();
} else {
await strategy.callStatic.tend();
}
} catch (error) {
Sentry.captureException(error);
console.error('Error occured, check Sentry for details');
return;
}
// estimate the gas of transaction
let estimatedGas = 0;
if (isMethodHarvest) {
estimatedGas = await strategy.estimateGas.harvest()
} else {
estimatedGas = await strategy.estimateGas.tend()
}
// mutliple that value with 1.3
const gasLimit = estimatedGas.add(
estimatedGas.mul(BigNumber.from(3)).div(BigNumber.from(10))
);
const gasPrice = await getGasPrice();
sentryTransaction.finish();
const nonce = await signer.getTransactionCount();
const txParams = {
gasLimit: gasLimit,
gasPrice: gasPrice,
nonce: nonce
}
let transaction;
if (isMethodHarvest) {
transaction = await strategy.harvest(txParams);
} else {
transaction = await strategy.tend(txParams);
}
console.log(`Tx Hash: ${transaction.hash}`);
console.log(`Waiting for the transaction to be mined...`);
await transaction.wait();
console.log(`Transaction confirmed!\n`);
}
async function main(method) {
const isMethodHarvest = method === METHODS_TO_EXECUTE.harvest;
const sentryTransaction = Sentry.startTransaction({
op: method,
name: 'Catch ' + method + ' failed transactions',
});
console.log('Check for ' + method + ' started...\n');
for (const [name, contract] of strategies.entries()) {
console.log(`Checking: ${name}`);
let shouldExecute = false;
if (isMethodHarvest) {
shouldExecute = await harvestTrigger(contract, callCost);
} else {
shouldExecute = await tendTrigger(contract, callCost);
}
if (shouldExecute) {
console.log('Trying to ' + method + '...');
try {
await execute(contract, method)
} catch (error) {
Sentry.captureException(error);
console.error('Error occured, check Sentry for details');
}
} else {
console.log('Strategy doesn\'t need ' + method + '\n');
}
}
sentryTransaction.finish();
}
function exec(method, interval) {
const sentryTransaction = Sentry.startTransaction({
op: 'general',
name: 'Catch general errors',
});
main(method)
.then(() =>
console.log(
`Harvest check done, next in ${interval} miliseconds\n`
)
)
.catch((error) => {
Sentry.captureException(error);
console.error('Error occured, check Sentry for details');
})
.finally(() => sentryTransaction.finish());
}
Sentry.init({
dsn: process.env.SENTRY_DSN,
tracesSampleRate: 1.0,
});
console.log('🚀 Keeper bot script is up & running\n');
const harvestInterval = process.env.HARVEST_CHECK_INTERVAL;
const tendInterval = process.env.TEND_CHECK_INTERVAL;
exec(METHODS_TO_EXECUTE.harvest, harvestInterval);
setInterval(() => exec(METHODS_TO_EXECUTE.harvest, harvestInterval), harvestInterval);
setInterval(() => exec(METHODS_TO_EXECUTE.tend, tendInterval), tendInterval);