Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
rouzwelt committed Jan 22, 2025
1 parent 434a92a commit 768e1a3
Show file tree
Hide file tree
Showing 16 changed files with 269 additions and 323 deletions.
4 changes: 2 additions & 2 deletions scripts/sweep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { routeProcessor3Abi } from "../src/abis";
import { setWatchedTokens } from "../src/account";
import { Native, Token, WNATIVE } from "sushi/currency";
import { ROUTE_PROCESSOR_4_ADDRESS } from "sushi/config";
import { createViemClient, getDataFetcher } from "../src/config";
import { getRpSwap, PoolBlackList, processLps, sleep } from "../src/utils";
import { getRpSwap, PoolBlackList, sleep } from "../src/utils";
import { createViemClient, getDataFetcher, processLps } from "../src/config";
import { HDAccount, mnemonicToAccount, PrivateKeyAccount } from "viem/accounts";

/**
Expand Down
1 change: 1 addition & 0 deletions src/abis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export const DefaultArbEvaluable = {
export const TakeOrderV2EventAbi = parseAbi([orderbookAbi[13]]);
export const OrderbookQuoteAbi = parseAbi([orderbookAbi[14]]);
export const VaultBalanceAbi = parseAbi([orderbookAbi[3]]);
export const AfterClearAbi = parseAbi([orderbookAbi[2]]);
export const DeployerAbi = parseAbi(deployerAbi);
export const MulticallAbi = parseAbi(multicall3Abi);

Expand Down
41 changes: 37 additions & 4 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getSgOrderbooks } from "./sg";
import { sendTransaction } from "./tx";
// import { sendTransaction } from "./tx";
import { WNATIVE } from "sushi/currency";
import { ChainId, ChainKey } from "sushi/chain";
import { DataFetcher, LiquidityProviders } from "sushi/router";
Expand Down Expand Up @@ -31,6 +31,15 @@ import {
ROUTE_PROCESSOR_3_2_ADDRESS,
} from "sushi/config";

/**
* List of liquidity provider that are excluded
*/
export const ExcludedLiquidityProviders = [
LiquidityProviders.CurveSwap,
LiquidityProviders.Camelot,
LiquidityProviders.Trident,
] as const;

/**
* Get the chain config for a given chain id
* @param chainId - The chain id
Expand Down Expand Up @@ -127,9 +136,9 @@ export async function createViemClient(

// set injected properties
client.BUSY = false;
client.sendTx = async (tx) => {
return await sendTransaction(client, tx);
};
// client.sendTx = async (tx) => {
// return await sendTransaction(client, tx);
// };

return client;
}
Expand Down Expand Up @@ -262,6 +271,30 @@ export async function getMetaInfo(config: BotConfig, sg: string[]): Promise<Reco
}
}

/**
* Resolves an array of case-insensitive names to LiquidityProviders, ignores the ones that are not valid
* @param liquidityProviders - List of liquidity providers
*/
export function processLps(liquidityProviders?: string[]): LiquidityProviders[] {
const LP = Object.values(LiquidityProviders);
if (
!liquidityProviders ||
!Array.isArray(liquidityProviders) ||
!liquidityProviders.length ||
!liquidityProviders.every((v) => typeof v === "string")
) {
return LP.filter((v) => !ExcludedLiquidityProviders.includes(v as any));
}
const lps: LiquidityProviders[] = [];
for (let i = 0; i < liquidityProviders.length; i++) {
const index = LP.findIndex(
(v) => v.toLowerCase() === liquidityProviders[i].toLowerCase().trim(),
);
if (index > -1 && !lps.includes(LP[index])) lps.push(LP[index]);
}
return lps.length ? lps : LP.filter((v) => !ExcludedLiquidityProviders.includes(v as any));
}

/**
* Chain specific fallback data
*/
Expand Down
7 changes: 2 additions & 5 deletions src/gas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ChainId } from "sushi";
import { BigNumber } from "ethers";
import { getQuoteConfig } from "./utils";
import { publicActionsL2 } from "viem/op-stack";
import { encodeFunctionData, multicall3Abi, toHex } from "viem";
import { encodeFunctionData, multicall3Abi } from "viem";
import { BotConfig, BundledOrders, OperationState, RawTx, ViemClient } from "./types";
import { ArbitrumNodeInterfaceAbi, ArbitrumNodeInterfaceAddress, OrderbookQuoteAbi } from "./abis";

Expand Down Expand Up @@ -103,10 +103,7 @@ export async function getQuoteGas(
): Promise<bigint> {
if (config.chain.id === ChainId.ARBITRUM) {
// build the calldata of a quote call
const quoteConfig = getQuoteConfig(orderDetails.takeOrders[0]) as any;
quoteConfig.inputIOIndex = BigInt(quoteConfig.inputIOIndex);
quoteConfig.outputIOIndex = BigInt(quoteConfig.outputIOIndex);
quoteConfig.order.evaluable.bytecode = toHex(quoteConfig.order.evaluable.bytecode);
const quoteConfig = getQuoteConfig(orderDetails.takeOrders[0]);
const multicallConfig = {
target: orderDetails.orderbook as `0x${string}`,
allowFailure: true,
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { ethers } from "ethers";
import { ChainId } from "sushi";
import { versions } from "process";
import { PublicClient } from "viem";
import { processLps } from "./utils";
import { DeployerAbi } from "./abis";
import { initAccounts } from "./account";
import { processOrders } from "./processOrders";
Expand All @@ -21,6 +20,7 @@ import {
OperationState,
} from "./types";
import {
processLps,
getChainConfig,
getDataFetcher,
onFetchRequest,
Expand Down
3 changes: 2 additions & 1 deletion src/modes/interOrderbook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
extendSpanAttributes,
} from "../utils";

const obInterface = new ethers.utils.Interface(orderbookAbi);

/**
* Executes a extimateGas call for an inter-orderbook arb() tx, to determine if the tx is successfull ot not
*/
Expand Down Expand Up @@ -65,7 +67,6 @@ export async function dryrun({
);

// encode takeOrders2()
const obInterface = new ethers.utils.Interface(orderbookAbi);
const encodedFN = obInterface.encodeFunctionData("takeOrders2", [
{
minimumInput: ethers.constants.One,
Expand Down
3 changes: 2 additions & 1 deletion src/modes/intraOrderbook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
TakeOrderDetails,
} from "../types";

const obInterface = new ethers.utils.Interface(orderbookAbi);

/**
* Executes a extimateGas call for an intra-orderbook tx (clear2()), to determine if the tx is successfull ot not
*/
Expand Down Expand Up @@ -51,7 +53,6 @@ export async function dryrun({

const inputBountyVaultId = "1";
const outputBountyVaultId = "1";
const obInterface = new ethers.utils.Interface(orderbookAbi);
const task = {
evaluable: {
interpreter: config.dispair.interpreter,
Expand Down
5 changes: 2 additions & 3 deletions src/modes/routeProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -541,12 +541,11 @@ export async function findOppWithRetries({
if (allPromises.some((v) => v.status === "fulfilled")) {
let choice;
for (let i = 0; i < allPromises.length; i++) {
// from retries, choose the one that can clear the most
// ie its maxInput is the greatest
// from retries, choose the one that has the highest profit
const prom = allPromises[i];
if (prom.status === "fulfilled") {
if (!choice || choice.estimatedProfit.lt(prom.value.value!.estimatedProfit)) {
// record the attributes of the choosing one
// record the attributes
for (const attrKey in prom.value.spanAttributes) {
spanAttributes[attrKey] = prom.value.spanAttributes[attrKey];
}
Expand Down
71 changes: 34 additions & 37 deletions src/order.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { ethers } from "ethers";
import { SgOrder } from "./query";
import { Span } from "@opentelemetry/api";
import { OrderV3, VaultBalanceAbi } from "./abis";
import { decodeAbiParameters, erc20Abi, parseAbiParameters } from "viem";
import { doQuoteTargets, QuoteTarget } from "@rainlanguage/orderbook/quote";
import { OrderbookQuoteAbi, OrderV3, VaultBalanceAbi } from "./abis";
import { shuffleArray, sleep, addWatchedToken, getQuoteConfig } from "./utils";
import {
erc20Abi,
encodeFunctionData,
parseAbiParameters,
decodeAbiParameters,
decodeFunctionResult,
} from "viem";
import {
Pair,
Order,
Expand Down Expand Up @@ -648,47 +653,39 @@ export function getOrdersTokens(ordersDetails: SgOrder[]): TokenDetails[] {
/**
* Quotes a single order
* @param orderDetails - Order details to quote
* @param rpcs - RPC urls
* @param viemClient - Viem client
* @param blockNumber - Optional block number
* @param multicallAddressOverride - Optional multicall address
* @param gas - Optional read gas
*/
export async function quoteSingleOrder(
orderDetails: BundledOrders,
rpcs: string[],
viemClient: ViemClient,
blockNumber?: bigint,
gas?: bigint,
multicallAddressOverride?: string,
) {
for (let i = 0; i < rpcs.length; i++) {
const rpc = rpcs[i];
try {
const quoteResult = (
await doQuoteTargets(
[
{
orderbook: orderDetails.orderbook,
quoteConfig: getQuoteConfig(orderDetails.takeOrders[0]),
},
] as any as QuoteTarget[],
rpc,
blockNumber,
gas,
multicallAddressOverride,
)
)[0];
if (typeof quoteResult !== "string") {
orderDetails.takeOrders[0].quote = {
maxOutput: ethers.BigNumber.from(quoteResult.maxOutput),
ratio: ethers.BigNumber.from(quoteResult.ratio),
};
return;
} else {
return Promise.reject(`failed to quote order, reason: ${quoteResult}`);
}
} catch (e) {
// throw only after every available rpc has been tried and failed
if (i === rpcs.length - 1) throw (e as Error)?.message;
}
const { data } = await viemClient.call({
to: orderDetails.orderbook as `0x${string}`,
data: encodeFunctionData({
abi: OrderbookQuoteAbi,
functionName: "quote",
args: [getQuoteConfig(orderDetails.takeOrders[0])],
}),
blockNumber,
gas,
});
if (typeof data !== "undefined") {
const quoteResult = decodeFunctionResult({
abi: OrderbookQuoteAbi,
functionName: "quote",
data,
});
orderDetails.takeOrders[0].quote = {
maxOutput: ethers.BigNumber.from(quoteResult[1]),
ratio: ethers.BigNumber.from(quoteResult[2]),
};
return;
} else {
return Promise.reject(`Failed to quote order, reason: reqtured no data`);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/processOrders.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { ChainId } from "sushi";
import { findOpp } from "./modes";
import { getGasPrice, getQuoteGas } from "./gas";
import { PublicClient } from "viem";
import { Token } from "sushi/currency";
import { quoteSingleOrder } from "./order";
import { createViemClient } from "./config";
import { arbAbis, orderbookAbi } from "./abis";
import { getGasPrice, getQuoteGas } from "./gas";
import { getSigner, handleTransaction } from "./tx";
import { privateKeyToAccount } from "viem/accounts";
import { BigNumber, Contract, ethers } from "ethers";
Expand Down Expand Up @@ -441,7 +441,7 @@ export async function processPair(args: {
try {
await quoteSingleOrder(
orderPairObject,
isE2eTest ? (config as any).quoteRpc : config.rpc,
viemClient as any as ViemClient,
undefined,
isE2eTest ? config.quoteGas : await getQuoteGas(config, orderPairObject),
);
Expand Down
Loading

0 comments on commit 768e1a3

Please sign in to comment.