many changes sorry.

This commit is contained in:
Moon 2021-02-16 17:56:55 -07:00
parent 4fd993ad30
commit 0c07810d06
2 changed files with 160 additions and 44 deletions

201
index.js
View File

@ -1,4 +1,4 @@
// SPHRc Liquidity Harvester Pro 2000
// Ubiq Token Liquidity Harvester Pro 2000
// License: Public Domain
/**
@ -16,8 +16,14 @@
* the terminal.
*/
const account_number = 1; // Sparrow acct num, STARTS AT ZERO, CAN'T USE TREZOR
const loop_delay = 7200 * 1000; // 2 hours
// Sparrow acct num, STARTS AT ZERO, CAN'T USE TREZOR/LEDGER.
// Defaults to second account ("1"), or pass a number as the first parameter
// on the command line.
const account_number = process.argv.length >= 3 ? parseInt(process.argv[2]) : 1;
// Time between runs in milliseconds, or pass a number of hours as second
// argument on command line.
const loop_delay = ( process.argv.length >= 4 ? (parseFloat(process.argv[3]) * 3600) : 7200 ) * 1000;
const router_address = '0xf3ce4655a44146c8eefbf45651f6479f9d67a77a';
@ -30,6 +36,12 @@ const ubiq_sphr_pool_address = '0x5130bc430Ed7cD252a18B724fBa40cd1078F8C75';
const ricks_sphr_pool_address = '0xB934A32F065a9db4B2Df565b901276c88dc31F3E';
const sphrc_sphr_pool_address = '0x93CdC7AF7fa7CfA9E603Cf4406acD81171A7Cfaa';
const tengrans_token_address = '0x0826180A4c981d5095Cb5c48BB2A098A44cf6f73';
const tengrans_ubiq_slpt_token_address = '0x6321C294f34C2CDAF61012Ac4f3588a527F4D990';
const tengrans_pool_address = '0x9969A0123c7e7553dac5390221e321C05630d102';
const wubq_token_address = '0x1FA6A37c64804C0D797bA6bC1955E50068FbF362';
const pool_addresses = [
grans_sphr_pool_address,
ubiq_sphr_pool_address,
@ -40,6 +52,8 @@ const pool_addresses = [
const deadline_seconds = 600;
slippage_pct = .995;
const one_eth = '1000000000000000000';
const HDWalletProvider = require('@truffle/hdwallet-provider');
const Web3 = require("web3");
const Contract = require('web3-eth-contract');
@ -48,6 +62,14 @@ BigNumber.set({ DECIMAL_PLACES: 18, ROUNDING_MODE: BigNumber.ROUND_FLOOR })
const mnemonic = process.env.MNEMONIC;
if (mnemonic) {
console.log("Mnemonic found.");
}
else {
console.error("No mnemonic found, remember to do ' export MNEMONIC=\"your seed phrase\"' before running.");
process.exit(1);
}
const provider = new HDWalletProvider({
mnemonic: {
phrase: mnemonic
@ -59,8 +81,10 @@ Contract.setProvider(provider);
let web3 = new Web3(provider);
const erc20_abi = require('./IERC20.json').abi;
const pair_abi = require('./IUniswapV2Pair.json').abi;
const router_abi = require('./IUniswapV2Router02.json').abi;
const factory_abi = require('./IUniswapV2Factory.json').abi;
const router = new Contract(router_abi, router_address);
console.log("Starting loop");
@ -71,80 +95,97 @@ console.log("Starting loop");
const factory_address = await router.methods.factory().call();
console.log(`factory address: ${factory_address}`);
const factory_abi = require('./IUniswapV2Factory.json').abi;
const factory = new Contract(factory_abi, factory_address);
const pool_abi = require('./ShinobiPool.json').abi;
while (true) {
const reward_promises = [];
for (const pool_address of pool_addresses) {
reward_promises.push(
new Promise(resolve => {
const pool = new Contract(pool_abi, pool_address);
console.log(`Calling harvest for ${pool_address}`);
pool.methods.getReward().send({ from: account }).then(() => {
console.log(`Harvested rewards for ${pool_address}`);
resolve();
})
pool.methods.earned(account).call().then(earned => {
if (earned === '0') {
console.log(`No rewards for ${pool_address}`);
resolve();
}
else {
console.log(`Calling harvest for ${pool_address}`);
pool.methods.getReward().send({ from: account }).then(() => {
console.log(`Harvested rewards for ${pool_address}`);
resolve();
});
}
});
})
);
}
console.log(`There are ${reward_promises.length} pools to harvest.`);
console.log("Getting rewards from all pools.")
await Promise.all(reward_promises);
console.log("Done harvesting.")
console.log(`There are ${reward_promises.length} SPHR pools to harvest.`);
console.log("Getting rewards from all SPHR pools.")
if (reward_promises.length) await Promise.all(reward_promises);
console.log("Done harvesting SPHRc.")
const sphr = new Contract(erc20_abi, sphr_token_address);
const sphr_balance = await sphr.methods.balanceOf(account).call();
const sphr_balance_pretty = new BigNumber(sphr_balance).div('1e+8');
console.log(`sphere balance: ${sphr_balance_pretty}`);
const sphr_balance = new BigNumber(await sphr.methods.balanceOf(account).call());
console.log(`sphere balance: ${sphr_balance.div('1e+8')}`);
const sphrc = new Contract(erc20_abi, sphrc_token_address);
const sphrc_balance = await sphrc.methods.balanceOf(account).call();
const sphrc_balance_pretty = new BigNumber(sphrc_balance).div('1e+18');
console.log(`spherec balance: ${sphrc_balance_pretty}`);
const sphrc_balance = new BigNumber(await sphrc.methods.balanceOf(account).call());
console.log(`spherec balance: ${sphrc_balance.div('1e+18')}`);
if (new BigNumber(sphr_balance).isZero() || new BigNumber(sphrc_balance).lt('1000000000000000000')) {
if (sphr_balance.isZero() || sphrc_balance.lt(one_eth)) {
console.log("sphere or spherec balance too low, skipping this step.")
}
else {
const pair_address = await factory.methods.getPair(sphr_token_address, sphrc_token_address).call();
const pair_abi = require('./IUniswapV2Pair.json').abi;
const pair = new Contract(pair_abi, pair_address);
const reserves = await pair.methods.getReserves().call();
console.log(`reserve0: ${reserves.reserve0}, reserve1: ${reserves.reserve1}`);
// console.log(`reserve0: ${reserves.reserve0}, reserve1: ${reserves.reserve1}`);
const sphr_sphrc_ratio = new BigNumber(reserves.reserve0).div(reserves.reserve1);
console.log(`ratio of sphr to sphrc: ${sphr_sphrc_ratio}`);
const needed_sphr = new BigNumber(sphrc_balance).times(sphr_sphrc_ratio).integerValue().toString();
console.log(`needed sphere: ${new BigNumber(needed_sphr).div('1e+8')}`);
const needed_sphr = sphrc_balance.times(sphr_sphrc_ratio).integerValue();
// console.log(`needed sphere: ${needed_sphr.div('1e+8')}`);
if (new BigNumber(needed_sphr).gt(sphr_balance)) {
console.log("Not enough sphr, skipping this step.");
if (sphrc_balance.isZero() || sphr_balance.isZero()) {
console.log("Not enough SPHR/SPHRc, skipping this step.");
}
else {
let usedSphr;
let usedSphrc;
const use_full_sphr_balance = needed_sphr.lte(sphr_balance);
if (use_full_sphr_balance) {
usedSphr = needed_sphr;
usedSphrc = sphrc_balance;
}
else {
usedSphr = sphr_balance;
usedSphrc = sphr_balance.div(sphr_sphrc_ratio).integerValue();
}
console.log(`Will use ${usedSphr.div('1e+8')} SPHR, ${usedSphrc.div('1e+18')} SPHRc.`);
// account for slippage
const sphr_min_desired = new BigNumber(needed_sphr).times(slippage_pct).integerValue().toString();
const sphrc_min_desired = new BigNumber(sphrc_balance).times(slippage_pct).integerValue().toString()
console.log(`desired: ${new BigNumber(sphr_min_desired).div('1e+8')} ${new BigNumber(sphrc_min_desired).div('1e+18')}`);
const sphr_min_desired = usedSphr.times(slippage_pct).integerValue().toString();
const sphrc_min_desired = usedSphrc.times(slippage_pct).integerValue().toString();
// make sure both tokens are approved for the amounts
const approval_promises = [];
const sphr_allowance = await sphr.methods.allowance(account, router_address).call();
if (new BigNumber(sphr_allowance).lt(needed_sphr)) {
console.log("Sphere allowance isn't big enough, approving now.");
approval_promises.push( sphr.methods.approve(router_address, needed_sphr).send({ from: account }) );
const sphr_allowance = new BigNumber(await sphr.methods.allowance(account, router_address).call());
if (sphr_allowance.lt(usedSphr)) {
console.log("SPHR allowance isn't big enough, approving now.");
approval_promises.push( sphr.methods.approve(router_address, usedSphr.toString()).send({ from: account }) );
}
const sphrc_allowance = await sphrc.methods.allowance(account, router_address).call()
if (new BigNumber(sphrc_allowance).lt(sphrc_balance)) {
console.log("Sphere Cubed allowance isn't big enough, approving now.");
approval_promises.push( sphrc.methods.approve(router_address, sphrc_balance).send({ from: account }) );
const sphrc_allowance = new BigNumber(await sphrc.methods.allowance(account, router_address).call());
if (sphrc_allowance.lt(usedSphrc)) {
console.log("SPHRc allowance isn't big enough, approving now.");
approval_promises.push( sphrc.methods.approve(router_address, usedSphrc.toString()).send({ from: account }) );
}
if (approval_promises.length) {
@ -153,12 +194,12 @@ console.log("Starting loop");
const deadline = Math.floor(Date.now() / 1000) + deadline_seconds;
console.log('Adding liquidity to Shinobi.');
console.log('Adding SPHR/SPHRc liquidity to Shinobi in exchange for SLPT tokens.');
await router.methods.addLiquidity(
sphr_token_address,
sphrc_token_address,
needed_sphr,
sphrc_balance,
usedSphr.toString(),
usedSphrc.toString(),
sphr_min_desired,
sphrc_min_desired,
account,
@ -171,7 +212,7 @@ console.log("Starting loop");
const slpt_balance = await slpt.methods.balanceOf(account).call();
if ( new BigNumber(slpt_balance).isZero() ) {
console.log("No new SLPT to stake.")
console.log("No new SPHR/SPHRc SLPT to stake.")
}
else {
console.log(`SLPT balance: ${new BigNumber(slpt_balance).div('1e+18')}`);
@ -188,6 +229,80 @@ console.log("Starting loop");
await sphr_sphrc_pool.methods.stake(slpt_balance).send({ from: account });
}
const tengrans = new Contract(erc20_abi, tengrans_token_address);
const tengrans_pool = new Contract(pool_abi, tengrans_pool_address);
console.log("Harvesting 10grans rewards");
await tengrans_pool.methods.getReward().send({ from: account });
const tengrans_balance = new BigNumber(await tengrans.methods.balanceOf(account).call());
const ubiq_balance = new BigNumber(await web3.eth.getBalance(account));
console.log(`10grans balance: ${tengrans_balance.div('1e+18')}`);
if (tengrans_balance.lt('1000000000000000')) {
console.log("Not enough 10grans to stake, skipping.");
}
else if (ubiq_balance.lt(one_eth)) {
console.log("Not enough ubiq to stake, skipping.")
}
else {
const pair_address = await factory.methods.getPair(tengrans_token_address, wubq_token_address).call();
const pair = new Contract(pair_abi, pair_address);
const reserves = await pair.methods.getReserves().call();
console.log(`reserve0: ${reserves.reserve0}, reserve1: ${reserves.reserve1}`);
const grans_ubiq_ratio = new BigNumber(reserves.reserve1).div(reserves.reserve0);
console.log(`10grans/ubiq reserves ratio: ${grans_ubiq_ratio}`);
const needed_ubiq = new BigNumber(tengrans_balance).times(grans_ubiq_ratio).integerValue();
console.log(`needed ubiq: ${needed_ubiq.div('1e+18')}`);
if (ubiq_balance.lt(needed_ubiq)) {
console.log("Not enough ubiq to stake 10grans, skipping.")
}
else {
// account for slippage
const grans_min_desired = tengrans_balance.times(slippage_pct).integerValue().toString();
const ubiq_min_desired = needed_ubiq.times(slippage_pct).integerValue().toString()
const grans_allowance = new BigNumber(await tengrans.methods.allowance(account, router_address).call());
console.log(`10grans allowance: ${grans_allowance.div('1e+18')}`);
if (grans_allowance.lt(tengrans_balance)) {
console.log("10grans allowance for Shinobi isn't big enough, approving now.");
await tengrans.methods.approve(router_address, tengrans_balance.toString()).send({from: account});
}
const deadline = Math.floor(Date.now() / 1000) + deadline_seconds;
console.log("Adding liquidity to Shinobi.");
await router.methods.addLiquidityETH(
tengrans_token_address,
tengrans_balance.toString(),
grans_min_desired,
ubiq_min_desired,
account,
deadline
).send({ from: account, value: needed_ubiq.toString() });
}
}
const grans_slpt = new Contract(erc20_abi, tengrans_ubiq_slpt_token_address);
const grans_slpt_balance = new BigNumber(await grans_slpt.methods.balanceOf(account).call());
console.log(`SLPT balance: ${grans_slpt_balance.div('1e+18')}`);
if (grans_slpt_balance.isZero()) {
console.log("No 10grans/Ubiq SLPT to stake.");
}
else {
const grans_slpt_allowance = new BigNumber(await grans_slpt.methods.allowance(account, tengrans_pool_address).call());
if (grans_slpt_allowance.lt(grans_slpt_balance)) {
console.log("10grans staking pool allowance isn't big enough, approving now.");
await grans_slpt.methods.approve(tengrans_pool_address, grans_slpt_balance.toString()).send({ from: account });
}
console.log("Staking SLPT tokens.");
await tengrans_pool.methods.stake(grans_slpt_balance.toString()).send({ from: account });
}
console.log("Waiting for a while...");
await new Promise(resolve => setTimeout(resolve, loop_delay));
console.log("Done waiting, resuming.");

View File

@ -1,6 +1,7 @@
#!/bin/bash
# defaults to account 0, two hour wait
while :
do
node index.js || continue
node index.js "${1:-0}" "${2:-2}" || continue
sleep 5
done