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

Test: Add gas costs to /gas-prices endpoint #1349

Closed
wants to merge 14 commits into from
2 changes: 1 addition & 1 deletion api/_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ export const getRelayerFeeCalculator = (
);
};

const getRelayerFeeCalculatorQueries = (
export const getRelayerFeeCalculatorQueries = (
destinationChainId: number,
overrides: Partial<{
spokePoolAddress: string;
Expand Down
76 changes: 70 additions & 6 deletions api/gas-prices.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,95 @@
import { VercelResponse } from "@vercel/node";
import {
buildDepositForSimulation,
getLogger,
getMaxFeePerGas,
getRelayerFeeCalculatorQueries,
handleErrorCondition,
latestGasPriceCache,
sendResponse,
} from "./_utils";
import { TypedVercelRequest } from "./_types";
import { ethers } from "ethers";
import * as sdk from "@across-protocol/sdk";

import mainnetChains from "../src/data/chains_1.json";
import {
DEFAULT_SIMULATED_RECIPIENT_ADDRESS,
TOKEN_SYMBOLS_MAP,
} from "./_constants";
import { assert, Infer, object, optional, string } from "superstruct";

const chains = mainnetChains;

const QueryParamsSchema = object({
symbol: optional(string()),
});
type QueryParams = Infer<typeof QueryParamsSchema>;

const handler = async (
_: TypedVercelRequest<Record<string, never>>,
{ query }: TypedVercelRequest<QueryParams>,
response: VercelResponse
) => {
const logger = getLogger();
assert(query, QueryParamsSchema);
const tokenSymbol = query.symbol ?? "WETH";

try {
const chainIdsWithToken: { [chainId: string]: string } = Object.fromEntries(
chains
.map(({ chainId }) => {
const tokenAddress =
TOKEN_SYMBOLS_MAP?.[tokenSymbol as keyof typeof TOKEN_SYMBOLS_MAP]
?.addresses[chainId];
return [chainId, tokenAddress];
})
.filter(([, tokenAddress]) => tokenAddress !== undefined)
);
const gasPrices = await Promise.all(
chains.map(({ chainId }) => {
return latestGasPriceCache(chainId).get();
Object.keys(chainIdsWithToken).map((chainId) => {
return getMaxFeePerGas(Number(chainId));
})
);
const responseJson = Object.fromEntries(
chains.map(({ chainId }, i) => [chainId, gasPrices[i].toString()])
const gasCosts = await Promise.all(
Object.entries(chainIdsWithToken).map(([chainId, tokenAddress], i) => {
const depositArgs = {
amount: ethers.BigNumber.from(100),
inputToken: sdk.constants.ZERO_ADDRESS,
outputToken: tokenAddress,
recipientAddress: DEFAULT_SIMULATED_RECIPIENT_ADDRESS,
originChainId: 0, // Shouldn't matter for simulation
destinationChainId: Number(chainId),
};
const relayerFeeCalculatorQueries = getRelayerFeeCalculatorQueries(
Number(chainId)
);
return relayerFeeCalculatorQueries.getGasCosts(
buildDepositForSimulation(depositArgs),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should parallel how the /iimits endpoint computes the gasFeePercent today:

  • Passes the gasPrice computed using getMaxFeePerGas and the gasUnits passed from a getGasCosts() call with omitMarkup = true into getRelayerFeeDetails which ultimately calls the SDK's getGasCosts function

undefined,
{
gasPrice: gasPrices[i],
}
);
})
);
const responseJson = {
tokenSymbol,
...Object.fromEntries(
Object.entries(chainIdsWithToken).map(([chainId], i) => [
chainId,
{
gasPrice: gasPrices[i].toString(),
nativeGasCost: gasCosts[i].nativeGasCost.toString(),
tokenGasCost: gasCosts[i].tokenGasCost.toString(),
gasCostMultiplier:
(
getRelayerFeeCalculatorQueries(
Number(chainId)
) as sdk.relayFeeCalculator.QueryBase
).gasMarkup + 1,
},
])
),
};

logger.debug({
at: "GasPrices",
Expand Down
Loading