Skip to content

Commit

Permalink
Merge branch 'master' into gerhard/acx-3081-update-frontend-dapp-lens…
Browse files Browse the repository at this point in the history
…-testnet
  • Loading branch information
gsteenkamp89 committed Jan 10, 2025
2 parents 7cadc8a + 44a2298 commit 3c0a5ed
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 62 deletions.
5 changes: 4 additions & 1 deletion api/_cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ export function buildCacheKey(
}

export function buildInternalCacheKey(...args: (string | number)[]): string {
return buildCacheKey("QUOTES_API", ...args);
return buildCacheKey(
`${process.env.CACHE_PREFIX ? process.env.CACHE_PREFIX + "-" : ""}QUOTES_API`,
...args
);
}

export async function getCachedValue<T>(
Expand Down
46 changes: 38 additions & 8 deletions api/_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ const {
REACT_APP_COINGECKO_PRO_API_KEY,
BASE_FEE_MARKUP,
PRIORITY_FEE_MARKUP,
OP_STACK_L1_DATA_FEE_MARKUP,
VERCEL_ENV,
LOG_LEVEL,
} = process.env;
Expand All @@ -97,6 +98,9 @@ export const baseFeeMarkup: {
export const priorityFeeMarkup: {
[chainId: string]: number;
} = JSON.parse(PRIORITY_FEE_MARKUP || "{}");
export const opStackL1DataFeeMarkup: {
[chainId: string]: number;
} = JSON.parse(OP_STACK_L1_DATA_FEE_MARKUP || "{}");
// Default to no markup.
export const DEFAULT_GAS_MARKUP = 0;

Expand Down Expand Up @@ -594,9 +598,14 @@ export const getHubPoolClient = () => {

export const getGasMarkup = (
chainId: string | number
): { baseFeeMarkup: BigNumber; priorityFeeMarkup: BigNumber } => {
): {
baseFeeMarkup: BigNumber;
priorityFeeMarkup: BigNumber;
opStackL1DataFeeMarkup: BigNumber;
} => {
let _baseFeeMarkup: BigNumber | undefined;
let _priorityFeeMarkup: BigNumber | undefined;
let _opStackL1DataFeeMarkup: BigNumber | undefined;
if (typeof baseFeeMarkup[chainId] === "number") {
_baseFeeMarkup = utils.parseEther((1 + baseFeeMarkup[chainId]).toString());
}
Expand All @@ -605,6 +614,11 @@ export const getGasMarkup = (
(1 + priorityFeeMarkup[chainId]).toString()
);
}
if (typeof opStackL1DataFeeMarkup[chainId] === "number") {
_opStackL1DataFeeMarkup = utils.parseEther(
(1 + opStackL1DataFeeMarkup[chainId]).toString()
);
}

// Otherwise, use default gas markup (or optimism's for OP stack).
if (_baseFeeMarkup === undefined) {
Expand All @@ -627,11 +641,21 @@ export const getGasMarkup = (
).toString()
);
}
if (_opStackL1DataFeeMarkup === undefined) {
_opStackL1DataFeeMarkup = utils.parseEther(
(
1 +
(sdk.utils.chainIsOPStack(Number(chainId))
? opStackL1DataFeeMarkup[CHAIN_IDs.OPTIMISM] ?? DEFAULT_GAS_MARKUP
: DEFAULT_GAS_MARKUP)
).toString()
);
}

// Otherwise, use default gas markup (or optimism's for OP stack).
return {
baseFeeMarkup: _baseFeeMarkup,
priorityFeeMarkup: _priorityFeeMarkup,
opStackL1DataFeeMarkup: _opStackL1DataFeeMarkup,
};
};

Expand Down Expand Up @@ -709,7 +733,7 @@ export const getRelayerFeeDetails = async (
},
tokenPrice: number,
relayerAddress: string,
gasPrice: sdk.utils.BigNumberish,
gasPrice?: sdk.utils.BigNumberish,
gasUnits?: sdk.utils.BigNumberish,
tokenGasCost?: sdk.utils.BigNumberish
): Promise<sdk.relayFeeCalculator.RelayerFeeDetails> => {
Expand Down Expand Up @@ -1948,8 +1972,8 @@ export function isContractCache(chainId: number, address: string) {

export function getCachedFillGasUsage(
deposit: Parameters<typeof buildDepositForSimulation>[0],
gasPrice?: BigNumber,
overrides?: Partial<{
spokePoolAddress: string;
relayerAddress: string;
}>
) {
Expand All @@ -1971,14 +1995,20 @@ export function getCachedFillGasUsage(
);
// We don't care about the gas token price or the token gas price, only the raw gas units. In the API
// we'll compute the gas price separately.
const markups = getGasMarkup(deposit.destinationChainId);
const gasCosts = await relayerFeeCalculatorQueries.getGasCosts(
buildDepositForSimulation(deposit),
overrides?.relayerAddress,
{
// Scale the op stack L1 gas cost component by the base fee multiplier.
// Consider adding a new environment variable OP_STACK_L1_GAS_COST_MARKUP if we want finer-grained control.
opStackL1GasCostMultiplier: getGasMarkup(deposit.destinationChainId)
.baseFeeMarkup,
gasPrice,
// We want the fee multipliers if the gasPrice is undefined:
baseFeeMultiplier: markups.baseFeeMarkup,
priorityFeeMultiplier: markups.priorityFeeMarkup,
opStackL1GasCostMultiplier: sdk.utils.chainIsOPStack(
deposit.destinationChainId
)
? getGasMarkup(deposit.destinationChainId).opStackL1DataFeeMarkup
: undefined,
}
);
return {
Expand Down
70 changes: 33 additions & 37 deletions api/gas-prices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { L2Provider } from "@eth-optimism/sdk/dist/interfaces/l2-provider";

import mainnetChains from "../src/data/chains_1.json";
import {
CHAIN_IDs,
DEFAULT_SIMULATED_RECIPIENT_ADDRESS,
TOKEN_SYMBOLS_MAP,
} from "./_constants";
Expand Down Expand Up @@ -70,50 +71,32 @@ const handler = async (
const relayerFeeCalculatorQueries = getRelayerFeeCalculatorQueries(
Number(chainId)
);
const opStackL1GasCostMultiplier = getGasMarkup(
Number(chainId)
).baseFeeMarkup;
const { nativeGasCost, tokenGasCost } =
const { baseFeeMarkup, priorityFeeMarkup, opStackL1DataFeeMarkup } =
getGasMarkup(Number(chainId));
const { nativeGasCost, tokenGasCost, opStackL1GasCost, gasPrice } =
await relayerFeeCalculatorQueries.getGasCosts(
deposit,
relayerFeeCalculatorQueries.simulatedRelayerAddress,
{
// Pass in the already-computed gasPrice into this query so that the tokenGasCost includes
// the scaled gas price,
// e.g. tokenGasCost = nativeGasCost * (baseFee * baseFeeMultiplier + priorityFee).
gasPrice: gasPrices[i].maxFeePerGas,
opStackL1GasCostMultiplier,
// Except for Linea, where the gas price is dependent on the unsignedTx produced from the deposit,
// so let the SDK compute its gas price here.
gasPrice:
Number(chainId) === CHAIN_IDs.LINEA
? undefined
: gasPrices[i].maxFeePerGas,
opStackL1GasCostMultiplier: opStackL1DataFeeMarkup,
baseFeeMultiplier: baseFeeMarkup,
priorityFeeMultiplier: priorityFeeMarkup,
}
);
// OPStack chains factor in the L1 gas cost of including the L2 transaction in an L1 rollup batch
// into the total gas cost of the L2 transaction.
let opStackL1GasCost: ethers.BigNumber | undefined = undefined;
if (sdk.utils.chainIsOPStack(Number(chainId))) {
const provider = relayerFeeCalculatorQueries.provider;
const _unsignedTx = await sdk.utils.populateV3Relay(
relayerFeeCalculatorQueries.spokePool,
deposit,
relayerFeeCalculatorQueries.simulatedRelayerAddress
);
const voidSigner = new VoidSigner(
relayerFeeCalculatorQueries.simulatedRelayerAddress,
relayerFeeCalculatorQueries.provider
);
const unsignedTx = await voidSigner.populateTransaction({
..._unsignedTx,
gasLimit: nativeGasCost, // prevents additional gas estimation call
});
opStackL1GasCost = await (
provider as L2Provider<providers.Provider>
).estimateL1GasCost(unsignedTx);
opStackL1GasCost = opStackL1GasCostMultiplier
.mul(opStackL1GasCost)
.div(sdk.utils.fixedPointAdjustment);
}
return {
nativeGasCost,
tokenGasCost,
opStackL1GasCost,
gasPrice,
};
}
)
Expand All @@ -124,12 +107,23 @@ const handler = async (
Object.keys(chainIdsWithToken).map((chainId, i) => [
chainId,
{
gasPrice: gasPrices[i].maxFeePerGas.toString(),
gasPrice:
Number(chainId) === CHAIN_IDs.LINEA
? gasCosts[i].gasPrice.toString()
: gasPrices[i].maxFeePerGas.toString(),
gasPriceComponents: {
maxFeePerGas: gasPrices[i].maxFeePerGas
.sub(gasPrices[i].maxPriorityFeePerGas)
.toString(),
priorityFeePerGas: gasPrices[i].maxPriorityFeePerGas.toString(),
// Linea hardcodes base fee at 7 wei so we can always back it out fromthe gasPrice returned by the
// getGasCosts method.
maxFeePerGas:
Number(chainId) === CHAIN_IDs.LINEA
? gasCosts[i].gasPrice.sub(7).toString()
: gasPrices[i].maxFeePerGas
.sub(gasPrices[i].maxPriorityFeePerGas)
.toString(),
priorityFeePerGas:
Number(chainId) === CHAIN_IDs.LINEA
? "7"
: gasPrices[i].maxPriorityFeePerGas.toString(),
baseFeeMultiplier: ethers.utils.formatEther(
getGasMarkup(chainId).baseFeeMarkup
),
Expand All @@ -139,7 +133,9 @@ const handler = async (
opStackL1GasCostMultiplier: sdk.utils.chainIsOPStack(
Number(chainId)
)
? ethers.utils.formatEther(getGasMarkup(chainId).baseFeeMarkup)
? ethers.utils.formatEther(
getGasMarkup(chainId).opStackL1DataFeeMarkup
)
: undefined,
},
nativeGasCost: gasCosts[i].nativeGasCost.toString(),
Expand Down
37 changes: 21 additions & 16 deletions api/limits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,39 +164,34 @@ const handler = async (
message,
};

const [tokenPriceNative, _tokenPriceUsd, latestBlock, gasCosts, gasPrice] =
const [tokenPriceNative, _tokenPriceUsd, latestBlock, gasPrice] =
await Promise.all([
getCachedTokenPrice(
l1Token.address,
sdk.utils.getNativeTokenSymbol(destinationChainId).toLowerCase()
),
getCachedTokenPrice(l1Token.address, "usd"),
getCachedLatestBlock(HUB_POOL_CHAIN_ID),
// Only use cached gas units if message is not defined, i.e. standard for standard bridges
isMessageDefined
// If Linea, then we will defer gas price estimation to the SDK in getCachedFillGasUsage because
// the priority fee depends upon the fill transaction calldata.
destinationChainId === CHAIN_IDs.LINEA
? undefined
: getCachedFillGasUsage(depositArgs, {
relayerAddress: relayer,
}),
latestGasPriceCache(destinationChainId).get(),
: latestGasPriceCache(destinationChainId).get(),
]);
const tokenPriceUsd = ethers.utils.parseUnits(_tokenPriceUsd.toString());

const [
relayerFeeDetails,
gasCosts,
multicallOutput,
fullRelayerBalances,
transferRestrictedBalances,
fullRelayerMainnetBalances,
] = await Promise.all([
getRelayerFeeDetails(
depositArgs,
tokenPriceNative,
relayer,
gasPrice,
gasCosts?.nativeGasCost,
gasCosts?.tokenGasCost
),
isMessageDefined
? undefined // Only use cached gas units if message is not defined, i.e. standard for standard bridges
: getCachedFillGasUsage(depositArgs, gasPrice, {
relayerAddress: relayer,
}),
callViaMulticall3(provider, multiCalls, {
blockTag: latestBlock.number,
}),
Expand Down Expand Up @@ -226,6 +221,16 @@ const handler = async (
)
),
]);
// This call should not make any additional RPC queries if gasCosts is defined--for any deposit
// with an empty message.
const relayerFeeDetails = await getRelayerFeeDetails(
depositArgs,
tokenPriceNative,
relayer,
gasPrice,
gasCosts?.nativeGasCost,
gasCosts?.tokenGasCost
);
logger.debug({
at: "Limits",
message: "Relayer fee details from SDK",
Expand Down

0 comments on commit 3c0a5ed

Please sign in to comment.