Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor create base class #54

Merged
merged 9 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ Usage: venus release-funds [options]

Options:
--simulate Simulate transactions (default: false)
--verbose Verbose logging (default: false)
--accrue-interest Accrue Interest (default: false)
--no-reduce-reserves Reduce BNB Reserves
-d, --debug Add debug logging (default: false)
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@venusprotocol/cli",
"version": "1.5.0-dev.1",
"version": "1.5.0-dev.2",
"license": "MIT",
"bin": {
"venus": "dist/venus.js"
Expand Down
132 changes: 57 additions & 75 deletions packages/cli/source/commands/convert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { option } from "pastel";
import { Box, Spacer, Text, useApp, useStderr } from "ink";
import zod from "zod";
import { parseUnits } from "viem";
import { TokenConverter, PancakeSwapProvider, UniswapProvider, BalanceResult } from "@venusprotocol/keeper-bots";
import { TokenConverter, PancakeSwapProvider, UniswapProvider } from "@venusprotocol/keeper-bots";
import { stringifyBigInt, getConverterConfigId } from "../utils/index.js";
import { Options, Title, BorderBox } from "../components/index.js";
import { reducer, defaultState } from "../state/convert.js";
Expand Down Expand Up @@ -152,10 +152,7 @@ export default function Convert({ options }: Props) {
const tokenConverter = new TokenConverter({
subscriber: dispatch,
simulate: !!simulate,
verbose: debug,
swapProvider: network?.includes("bsc")
? new PancakeSwapProvider({ subscriber: dispatch })
: new UniswapProvider({ subscriber: dispatch }),
swapProvider: network?.includes("bsc") ? PancakeSwapProvider : UniswapProvider,
});

do {
Expand All @@ -173,84 +170,69 @@ export default function Convert({ options }: Props) {
// @todo check if we need to release funds or if there are already enough funds to make our trade
await tokenConverter.releaseFundsForConversions(potentialConversions);
}
await Promise.allSettled(
potentialConversions.map(async (t: BalanceResult) => {
let amountOut = t.assetOut.balance;

const vTokenAddress = t.assetOutVTokens.core || t.assetOutVTokens.isolated![0]![1];
const { underlyingPriceUsd, underlyingUsdValue, underlyingDecimals } = await tokenConverter.getUsdValue(
t.assetOut.address,
vTokenAddress,
amountOut,
);
for (const t of potentialConversions) {
let amountOut = t.assetOut.balance;

if (+underlyingUsdValue > minTradeUsd) {
if (+underlyingUsdValue > maxTradeUsd) {
amountOut = parseUnits((maxTradeUsd / +underlyingPriceUsd.toString()).toString(), underlyingDecimals);
}
const vTokenAddress = t.assetOutVTokens.core || t.assetOutVTokens.isolated![0]![1];
const { underlyingPriceUsd, underlyingUsdValue, underlyingDecimals } = await tokenConverter.getUsdValue(
t.assetOut.address,
vTokenAddress,
amountOut,
);

const arbitrageArgs = await tokenConverter.prepareConversion(
t.tokenConverter,
t.assetOut.address,
t.assetIn.address,
amountOut,
);
if (+underlyingUsdValue > minTradeUsd) {
if (+underlyingUsdValue > maxTradeUsd) {
amountOut = parseUnits((maxTradeUsd / +underlyingPriceUsd.toString()).toString(), underlyingDecimals);
}

const { trade, amount, minIncome } = arbitrageArgs || {
trade: undefined,
amount: 0n,
minIncome: 0n,
};
const arbitrageArgs = await tokenConverter.prepareConversion(
t.tokenConverter,
t.assetOut.address,
t.assetIn.address,
amountOut,
);

const maxMinIncome = ((amount * BigInt(10000 + minIncomeBp)) / 10000n - amount) * -1n;
const { trade, amount, minIncome } = arbitrageArgs || {
trade: undefined,
amount: 0n,
minIncome: 0n,
};

if (trade && ((profitable && minIncome > 0n) || !profitable)) {
dispatch({
type: "ExecuteTrade",
context: {
converter: t.tokenConverter,
tokenToReceiveFromConverter: t.assetOut.address,
tokenToSendToConverter: t.assetIn.address,
amount,
minIncome,
percentage: Number((minIncome * 10000000n) / amount) / 10000000,
maxMinIncome,
},
});
const maxMinIncome = ((amount * BigInt(10000 + minIncomeBp)) / 10000n - amount) * -1n;

await tokenConverter.arbitrage(t.tokenConverter, trade, amount, minIncome);
} else if (t.accountBalanceAssetOut < minIncome * -1n) {
dispatch({
type: "ExecuteTrade",
error: "Insufficient wallet balance to pay min income",
context: {
converter: t.tokenConverter,
tokenToReceiveFromConverter: t.assetOut.address,
tokenToSendToConverter: t.assetIn.address,
amount,
minIncome,
percentage: Number((minIncome * 10000000n) / amount) / 10000000,
maxMinIncome,
},
});
} else if (minIncome < 1 && minIncome * -1n > maxMinIncome * -1n) {
dispatch({
type: "ExecuteTrade",
error: "Min income too high",
context: {
converter: t.tokenConverter,
tokenToReceiveFromConverter: t.assetOut.address,
tokenToSendToConverter: t.assetIn.address,
amount,
minIncome,
percentage: Number((minIncome * 10000000n) / amount) / 10000000,
maxMinIncome,
},
});
}
const context = {
converter: t.tokenConverter,
tokenToReceiveFromConverter: t.assetOut.address,
tokenToSendToConverter: t.assetIn.address,
amount,
minIncome,
percentage: Number(minIncome) && Number(amount) && Number((minIncome * 10000000n) / amount) / 10000000,
maxMinIncome,
};
if (profitable && minIncome < 0) {
dispatch({
error: "Conversion is not profitable",
type: "ExecuteTrade",
context,
});
} else if (minIncome < 1 && minIncome * -1n > maxMinIncome * -1n) {
dispatch({
type: "ExecuteTrade",
error: "Min income too high",
context,
});
} else if (t.accountBalanceAssetOut < minIncome * -1n && !profitable) {
dispatch({
error: "Insufficient wallet balance to pay min income",
type: "ExecuteTrade",
context,
});
} else if (trade) {
await tokenConverter.arbitrage(t.tokenConverter, trade, amount, minIncome);
}
}),
);
}
}
} while (loop);
};
if (converter || assetIn || assetOut) {
Expand Down
15 changes: 1 addition & 14 deletions packages/cli/source/commands/releaseFunds.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,6 @@ export const options = zod.object({
}),
)
.optional(),
verbose: zod
.boolean()
.default(false)
.describe(
option({
description: "Verbose logging",
alias: "v",
}),
)
.optional(),
accrueInterest: zod
.boolean()
.default(false)
Expand Down Expand Up @@ -136,10 +126,7 @@ function ReleaseFunds({ options = {} }: Props) {
const tokenConverter = new TokenConverter({
subscriber: dispatch,
simulate: !!simulate,
verbose: false,
swapProvider: network?.includes("bsc")
? new PancakeSwapProvider({ subscriber: dispatch, verbose: false })
: new UniswapProvider({ subscriber: dispatch, verbose: false }),
swapProvider: network?.includes("bsc") ? PancakeSwapProvider : UniswapProvider,
});
const corePoolMarkets = await getCoreMarkets();
const isolatedPoolsMarkets = await getIsolatedMarkets();
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/source/state/convert.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Address } from "viem";
import {
Message,
ConverterBotMessage,
GetBestTradeMessage,
ArbitrageMessage,
PotentialConversionsMessage,
Expand Down Expand Up @@ -43,7 +43,7 @@ export const defaultState = {
messages: [],
};

export const reducer = (state: State, action: Message | ExecuteTradeMessage): State => {
export const reducer = (state: State, action: ConverterBotMessage | ExecuteTradeMessage): State => {
switch (action.type) {
case "PotentialConversions":
case "GetBestTrade":
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/source/state/releaseFunds.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Message } from "@venusprotocol/keeper-bots";
import { ConverterBotMessage } from "@venusprotocol/keeper-bots";

interface State {
releasedFunds: {
trx: string | undefined;
error: string | undefined;
error: string | string[] | undefined;
context: [`0x${string}`, readonly `0x${string}`[]];
}[];
}
Expand All @@ -12,7 +12,7 @@ export const defaultState = {
releasedFunds: [],
};

export const reducer = (state: State, action: Message): State => {
export const reducer = (state: State, action: ConverterBotMessage): State => {
switch (action.type) {
case "ReleaseFunds": {
const releasedFunds = [...state.releasedFunds];
Expand Down
1 change: 1 addition & 0 deletions packages/keeper-bots/.env.test
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ PRIVATE_KEY_bscmainnet=0x0000000000000000000000000000000000000000000000000000000
RPC_bsctestnet=https://bsc-testnet.nodereal.io/v1/apiKey
RPC_bscmainnet=https://bsc-mainnet.nodereal.io/v1/apiKey
THE_GRAPH_STUDIO_API_KEY=1234567890
TESTNET_GRAPH_ID=
5 changes: 2 additions & 3 deletions packages/keeper-bots/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@venusprotocol/keeper-bots",
"version": "1.0.0-dev.1",
"version": "1.0.0-dev.2",
"description": "",
"scripts": {
"dev": "tsc --watch",
Expand Down Expand Up @@ -42,8 +42,7 @@
"hardhat": "^2.19.5",
"jsbi": "^3.2.5",
"urql": "^3.0.3",
"viem": "^2.7.1",
"winston": "^3.11.0"
"viem": "^2.7.1"
},
"devDependencies": {
"@typechain/hardhat": "^6.1.2",
Expand Down
47 changes: 47 additions & 0 deletions packages/keeper-bots/src/bot-base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import getConfig from "./config";
import type { SUPPORTED_CHAINS } from "./config/chains";
import publicClient from "./config/clients/publicClient";
import walletClient from "./config/clients/walletClient";
import { ConverterBotMessage } from "./converter-bot/types";
import { SwapProvider } from "./providers";

const config = getConfig();

class BotBase {
protected chainName: SUPPORTED_CHAINS;
protected subscriber: undefined | ((msg: ConverterBotMessage) => void);
protected simulate: boolean;
protected swapProvider: SwapProvider;
public publicClient: typeof publicClient;
public walletClient: typeof walletClient;

constructor({
subscriber,
swapProvider,
simulate,
}: {
subscriber?: (msg: ConverterBotMessage) => void;
swapProvider: typeof SwapProvider;
simulate: boolean;
}) {
this.subscriber = subscriber;
this.swapProvider = new swapProvider({ subscriber });
this.publicClient = publicClient;
this.walletClient = walletClient;
this.simulate = simulate;
this.chainName = config.network.name;
}
protected sendMessage({
type,
trx = undefined,
error = undefined,
context = undefined,
blockNumber = undefined,
}: Partial<ConverterBotMessage>) {
if (this.subscriber) {
this.subscriber({ type, trx, error, context, blockNumber } as ConverterBotMessage);
}
}
}

export default BotBase;
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const getPublicClientMock = () => ({
const publicClientMock = {
simulateContract: jest.fn(),
readContract: jest.fn(),
multicall: jest.fn(),
getBlock: jest.fn(),
getBlockNumber: jest.fn(),
waitForTransactionReceipt: jest.fn(),
estimateContractGas: jest.fn(),
});
};

export default getPublicClientMock;
export default publicClientMock;
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const getWalletClientMock = () => ({
const walletClientMock = {
account: {
address: "0x4CCeBa2d7D2B4fdcE4304d3e09a1fea9fbEb1528",
},
writeContract: jest.fn(() => "0xtransactionHash"),
});
};

export default getWalletClientMock;
export default walletClientMock;
2 changes: 1 addition & 1 deletion packages/keeper-bots/src/config/clients/publicClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ const getPublicClient = () => {
});
};

export default getPublicClient;
export default getPublicClient();
2 changes: 1 addition & 1 deletion packages/keeper-bots/src/config/clients/walletClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ const getWalletClient = () => {
});
};

export default getWalletClient;
export default getWalletClient();
Loading
Loading