Skip to content

Commit

Permalink
Merge pull request #40 from yuichiroaoki/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
yuichiroaoki authored Feb 4, 2022
2 parents 97dffa5 + dfb1d89 commit 50088ba
Show file tree
Hide file tree
Showing 14 changed files with 209 additions and 163 deletions.
46 changes: 46 additions & 0 deletions src/consoleUI/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Table } from "console-table-printer";
import { baseTokens, tradingTokens } from "../config";
const readline = require("readline");

export const initPriceTable = (p: Table, idx: number) => {
baseTokens.forEach(async (baseToken) => {
tradingTokens.forEach(async (tradingToken) => {
if (baseToken.address > tradingToken.address) {
p.addRow({
index: idx,

fromToken: (baseToken === tradingToken
? ""
: baseToken.symbol
).padEnd(6),
toToken: (baseToken === tradingToken
? ""
: tradingToken.symbol
).padEnd(6),

fromAmount: "".padStart(7),
toAmount: "".padStart(7),

difference: "".padStart(7),
percentage: "".padStart(5),

time: "".padStart(6),
timestamp: "".padStart(24),
});

idx++;
}
});
});
};

export const renderTables = (p: Table, pp: Table) => {
// console.clear();
readline.cursorTo(process.stdout, 0, 0);

p.printTable();

if (pp.table.rows.length > 0) {
pp.printTable();
}
};
59 changes: 59 additions & 0 deletions src/consoleUI/table.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Table } from "console-table-printer";

export const priceTable = (maxX: number) =>
new Table({
// title: "Quotes",
columns: [
{ name: "index", title: "#", alignment: "right" },

{ name: "fromToken", title: "From", alignment: "left" },
{ name: "fromAmount", title: "Amount", alignment: "right" },

{ name: "toToken", title: "To", alignment: "left" },
{ name: "toAmount", title: "Amount", alignment: "right" },

{ name: "difference", title: "±", alignment: "right" },
{ name: "percentage", title: "%", alignment: "right" },

{ name: "log", title: "Log", alignment: "left", maxLen: maxX - 101 },

{ name: "time", title: "Time", alignment: "right" },
{ name: "timestamp", title: "Timestamp", alignment: "right" },
],
});

export const flashloanTable = (maxX: number) =>
new Table({
title: "Flash Loans",
columns: [
{ name: "baseToken", title: "From", alignment: "left" },
{ name: "tradingToken", title: "To", alignment: "left" },

{ name: "amount", title: "Amount", alignment: "right" },

{ name: "difference", title: "±", alignment: "right" },
{ name: "percentage", title: "%", alignment: "right" },

{
name: "firstRoutes",
title: "First Routes",
alignment: "left",
maxLen: maxX / 2 - 78,
},
{
name: "secondRoutes",
title: "Second Routes",
alignment: "left",
maxLen: maxX / 2 - 79,
},

{
name: "txHash",
title: "Transaction Hash",
alignment: "left",
},

{ name: "time", title: "Time", alignment: "right" },
{ name: "timestamp", title: "Timestamp", alignment: "right" },
],
});
3 changes: 1 addition & 2 deletions src/constants/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,7 @@ export const dodoV2Pool: PoolMap = {
USDT_DAI: "0xDa43a4aAB20D313Ab3AA07d8E09f3521F32a3D83",
WETH_USDC: "0x5333Eb1E32522F1893B7C9feA3c263807A02d561",
WMATIC_USDC: "0x10Dd6d8A29D489BEDE472CC1b22dc695c144c5c7",
WMATIC_WETH: "0xC877D7BbCB5b40C3F3d7e7E0d0DA6220BEE027a1",
USDC_USDT: "0x56FF5E27d40FBF746ADaa3DA820ADb2056F225E7",
USDC_USDT: "0xA0020444b98f67B77a3d6dE6E66aF11c87da086e",
WBTC_USDC: "0xe020008465cD72301A18b97d33D73bF44858A4b7",
};

Expand Down
8 changes: 4 additions & 4 deletions src/expect.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { BigNumber, ethers } from "ethers";
import { Hop, IFlashloanRoute, Swap } from "./interfaces/main";
import { getPriceOnUniV2 } from "./uniswap/v2/getPrice";
import { getUniswapV3PoolFee } from "./uniswap/v3/fee";
import { getPriceOnUniV3 } from "./uniswap/v3/getPrice";
import { getPriceOnUniV2 } from "./price/uniswap/v2/getPrice";
import { getUniswapV3PoolFee } from "./price/uniswap/v3/fee";
import { getPriceOnUniV3 } from "./price/uniswap/v3/getPrice";
import { findRouterFromProtocol, getBigNumber } from "./utils";
import { splitLoanAmount } from "./utils/split";

Expand Down Expand Up @@ -52,7 +52,7 @@ const getSwapsAmountOut = async (
return amountOut;
};

const expectPriceOnDex = async (
export const expectPriceOnDex = async (
protocol: number,
amountIn: BigNumber,
tokenIn: string,
Expand Down
115 changes: 10 additions & 105 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { config as dotEnvConfig } from "dotenv";
dotEnvConfig();
import { checkArbitrage } from "./inchPrice";
import { checkArbitrage } from "./price/1inch";
import {
baseTokens,
interval,
Expand All @@ -10,14 +10,12 @@ import {
diffAmount,
} from "./config";
import { createRoutes, flashloan } from "./flashloan";
import chalk = require("chalk");
import { expectAmountOut } from "./expect";
import { getBigNumber } from "./utils";
import { ethers } from "ethers";
import { chalkDifference, chalkPercentage, chalkTime } from "./utils/chalk";

const readline = require("readline");
const { Table } = require("console-table-printer");
import { flashloanTable, priceTable } from "./consoleUI/table";
import { initPriceTable, renderTables } from "./consoleUI";

export const main = async () => {
console.clear();
Expand All @@ -26,111 +24,18 @@ export const main = async () => {

const [maxX, _] = process.stdout.getWindowSize();

const p = new Table({
// title: "Quotes",
columns: [
{ name: "index", title: "#", alignment: "right" },

{ name: "fromToken", title: "From", alignment: "left" },
{ name: "fromAmount", title: "Amount", alignment: "right" },

{ name: "toToken", title: "To", alignment: "left" },
{ name: "toAmount", title: "Amount", alignment: "right" },

{ name: "difference", title: "±", alignment: "right" },
{ name: "percentage", title: "%", alignment: "right" },

{ name: "log", title: "Log", alignment: "left", maxLen: maxX - 101 },

{ name: "time", title: "Time", alignment: "right" },
{ name: "timestamp", title: "Timestamp", alignment: "right" },
],
});

const pp = new Table({
title: "Flash Loans",
columns: [
{ name: "baseToken", title: "From", alignment: "left" },
{ name: "tradingToken", title: "To", alignment: "left" },

{ name: "amount", title: "Amount", alignment: "right" },

{ name: "difference", title: "±", alignment: "right" },
{ name: "percentage", title: "%", alignment: "right" },

{
name: "firstRoutes",
title: "First Routes",
alignment: "left",
maxLen: maxX / 2 - 78,
},
{
name: "secondRoutes",
title: "Second Routes",
alignment: "left",
maxLen: maxX / 2 - 79,
},

{
name: "txHash",
title: "Transaction Hash",
alignment: "left",
},

{ name: "time", title: "Time", alignment: "right" },
{ name: "timestamp", title: "Timestamp", alignment: "right" },
],
});
const p = priceTable(maxX);
const pp = flashloanTable(maxX);

let idx = 0;
baseTokens.forEach(async (baseToken) => {
tradingTokens.forEach(async (tradingToken) => {
if (baseToken.address > tradingToken.address) {
p.addRow({
index: idx,

fromToken: (baseToken === tradingToken
? ""
: baseToken.symbol
).padEnd(6),
toToken: (baseToken === tradingToken
? ""
: tradingToken.symbol
).padEnd(6),

fromAmount: "".padStart(7),
toAmount: "".padStart(7),

difference: "".padStart(7),
percentage: "".padStart(5),

time: "".padStart(6),
timestamp: "".padStart(24),
});

idx++;
}
});
});
initPriceTable(p, idx);

idx = 0;
const renderTables = () => {
// console.clear();
readline.cursorTo(process.stdout, 0, 0);

p.printTable();

if (pp.table.rows.length > 0) {
pp.printTable();
}
};

renderTables();

renderTables(p, pp);
// const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))

setInterval(() => {
renderTables();
renderTables(p, pp);
}, renderInterval);

baseTokens.forEach(async (baseToken) => {
Expand Down Expand Up @@ -162,7 +67,7 @@ export const main = async () => {
const [isProfitable, firstProtocols, secondProtocols] =
await checkArbitrage(baseToken, tradingToken, updateRow);

renderTables();
renderTables(p, pp);

if (isProfitable && !isFlashLoaning) {
if (firstProtocols && secondProtocols) {
Expand Down Expand Up @@ -238,7 +143,7 @@ export const main = async () => {

isFlashLoaning = false;

renderTables();
renderTables(p, pp);
}
}
}
Expand Down
46 changes: 8 additions & 38 deletions src/inchPrice.ts → src/price/1inch/index.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,14 @@
import { config as dotEnvConfig } from "dotenv";
dotEnvConfig();
import { BigNumber, ethers } from "ethers";
import { chainId, protocols, diffAmount, loanAmount } from "./config";
import { IRoute } from "./interfaces/main";
import { ERC20Token, IToken } from "./constants/addresses";
import { replaceTokenAddress } from "./utils";
import { IProtocol } from "./interfaces/inch";
import { sendRequest } from "./utils/request";
import { chalkDifference, chalkPercentage } from "./utils/chalk";

/**
* Will get the 1inch API call URL for a trade
* @param chainId chain id of the network
* @param fromTokenAddress token address of the token you want to sell
* @param toTokenAddress token address of the token you want to buy
* @param amount amount of the token you want to sell
* @returns call URL for 1inch API
*/
function get1inchQuoteCallUrl(
chainId: number,
fromTokenAddress: string,
toTokenAddress: string,
amount: BigNumber
): string {
const callURL =
"https://api.1inch.exchange/v4.0/" +
chainId +
"/quote?" +
"fromTokenAddress=" +
fromTokenAddress +
"&toTokenAddress=" +
toTokenAddress +
"&amount=" +
amount.toString() +
"&mainRouteParts=50" +
"&protocols=" +
protocols;

return callURL;
}
import { chainId, protocols, diffAmount, loanAmount } from "../../config";
import { IRoute } from "../../interfaces/main";
import { ERC20Token, IToken } from "../../constants/addresses";
import { replaceTokenAddress } from "../../utils";
import { IProtocol } from "../../interfaces/inch";
import { sendRequest } from "../../utils/request";
import { chalkDifference, chalkPercentage } from "../../utils/chalk";
import { get1inchQuoteCallUrl } from "./url";

/**
* Will check if there's an arbitrage opportunity using the 1inch API
Expand Down
28 changes: 28 additions & 0 deletions src/price/1inch/url.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { BigNumber } from "ethers";
import { protocols } from "../../config";

/**
* Will get the 1inch API call URL for a trade
* @param chainId chain id of the network
* @param fromTokenAddress token address of the token you want to sell
* @param toTokenAddress token address of the token you want to buy
* @param amount amount of the token you want to sell
* @returns call URL for 1inch API
*/
export function get1inchQuoteCallUrl(
chainId: number,
fromTokenAddress: string,
toTokenAddress: string,
amount: BigNumber
): string {
const params = {
fromTokenAddress: fromTokenAddress,
toTokenAddress: toTokenAddress,
amount: amount.toString(),
protocols: protocols,
};
const apiURL = "https://api.1inch.exchange/v4.0/";
const searchString = new URLSearchParams(params);
const callURL = `${apiURL}${chainId}/quote?${searchString}`;
return callURL;
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { config as dotEnvConfig } from "dotenv";
import { BigNumber, ethers } from "ethers";
dotEnvConfig();
import * as UniswapV2Router from "../../abis/IUniswapV2Router02.json";
import { getBigNumber } from "../../utils";
import * as UniswapV2Router from "../../../abis/IUniswapV2Router02.json";
import { getBigNumber } from "../../../utils";

const maticProvider = new ethers.providers.JsonRpcProvider(
process.env.ALCHEMY_POLYGON_RPC_URL
Expand Down
2 changes: 1 addition & 1 deletion src/uniswap/v3/fee.ts → src/price/uniswap/v3/fee.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { findToken } from "../../utils";
import { findToken } from "../../../utils";

type FeeMap = {
[pair: string]: {
Expand Down
Loading

0 comments on commit 50088ba

Please sign in to comment.