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

improve: simulate relay gas fees for messages #862

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c9dc866
chore: add vercel as dev dep
james-a-morris Oct 5, 2023
403499e
improve: simulate relay gas fees
james-a-morris Oct 5, 2023
b3efc79
chore: revert for another PR
james-a-morris Oct 5, 2023
80cb76f
improve: throw error if recipient is not a contract
james-a-morris Oct 10, 2023
bb5925e
improve: change constructor imports
james-a-morris Oct 20, 2023
2ae0db4
chore: bump sdk
james-a-morris Oct 20, 2023
1abe39e
improve: ready for changes
james-a-morris Oct 20, 2023
8ab4e64
chore: wrap error
james-a-morris Oct 20, 2023
856bf67
chore: resolve check for hex string at first
james-a-morris Oct 23, 2023
e0ca8d2
improve: doc representation
james-a-morris Oct 23, 2023
a8e7c84
improve: error message
james-a-morris Oct 23, 2023
703312b
improve: add token caching
james-a-morris Oct 23, 2023
1d77eb5
chore: merge branch
james-a-morris Oct 24, 2023
bc6c8f7
chore: remove blockTag
james-a-morris Oct 24, 2023
6821268
improve: use dummy address
james-a-morris Oct 24, 2023
fef8c7a
improve: remove blocktag reference. Always "latest"
james-a-morris Oct 25, 2023
5b79022
chore: fix bug
james-a-morris Oct 25, 2023
351f102
improve: remove account balance
james-a-morris Oct 25, 2023
aba05f7
improve: use recipient ZERO_ADDRESS
james-a-morris Oct 25, 2023
ac085a4
chore: change out comment
james-a-morris Oct 25, 2023
fd5dc96
improve: modify UI call
james-a-morris Oct 25, 2023
1d6d0e6
chore: target block lag
james-a-morris Oct 25, 2023
b16d52d
chore: revise item
james-a-morris Oct 25, 2023
572ce1e
improve: use optional param
james-a-morris Oct 25, 2023
70bea1d
chore: revert optional params
james-a-morris Oct 25, 2023
11c8552
fix: invalid signature call
james-a-morris Oct 25, 2023
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
6 changes: 6 additions & 0 deletions api/_types/utility.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,9 @@ export type PoolStateResult = {
exchangeRateCurrent: string;
totalPoolSize: string;
};

export type MessagePayload = {
message: string;
recipientAddress: string;
relayerAddress?: string;
};
51 changes: 31 additions & 20 deletions api/_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import {
maxRelayFeePct,
relayerFeeCapitalCostConfig,
} from "./_constants";
import { PoolStateResult } from "./_types";
import { MessagePayload, PoolStateResult } from "./_types";

type LoggingUtility = sdk.relayFeeCalculator.Logger;

Expand Down Expand Up @@ -333,7 +333,6 @@ export const queries: Record<
undefined,
undefined,
undefined,
undefined,
REACT_APP_COINGECKO_PRO_API_KEY,
getLogger(),
getGasMarkup(CHAIN_IDs.MAINNET)
Expand All @@ -344,7 +343,6 @@ export const queries: Record<
undefined,
undefined,
undefined,
undefined,
REACT_APP_COINGECKO_PRO_API_KEY,
getLogger(),
getGasMarkup(CHAIN_IDs.OPTIMISM)
Expand All @@ -355,7 +353,6 @@ export const queries: Record<
undefined,
undefined,
undefined,
undefined,
REACT_APP_COINGECKO_PRO_API_KEY,
getLogger(),
getGasMarkup(CHAIN_IDs.POLYGON)
Expand All @@ -366,7 +363,6 @@ export const queries: Record<
undefined,
undefined,
undefined,
undefined,
REACT_APP_COINGECKO_PRO_API_KEY,
getLogger(),
getGasMarkup(CHAIN_IDs.ARBITRUM)
Expand All @@ -377,7 +373,6 @@ export const queries: Record<
undefined,
undefined,
undefined,
undefined,
REACT_APP_COINGECKO_PRO_API_KEY,
getLogger(),
getGasMarkup(CHAIN_IDs.ZK_SYNC)
Expand All @@ -388,7 +383,6 @@ export const queries: Record<
undefined,
undefined,
undefined,
undefined,
REACT_APP_COINGECKO_PRO_API_KEY,
getLogger(),
getGasMarkup(CHAIN_IDs.BASE)
Expand All @@ -400,7 +394,6 @@ export const queries: Record<
undefined,
undefined,
undefined,
undefined,
REACT_APP_COINGECKO_PRO_API_KEY,
getLogger(),
getGasMarkup(CHAIN_IDs.GOERLI)
Expand All @@ -411,7 +404,6 @@ export const queries: Record<
undefined,
undefined,
undefined,
undefined,
REACT_APP_COINGECKO_PRO_API_KEY,
getLogger(),
getGasMarkup(CHAIN_IDs.ARBITRUM_GOERLI)
Expand All @@ -422,7 +414,6 @@ export const queries: Record<
undefined,
undefined,
undefined,
undefined,
REACT_APP_COINGECKO_PRO_API_KEY,
getLogger(),
getGasMarkup(CHAIN_IDs.ZK_SYNC_GOERLI)
Expand All @@ -433,7 +424,6 @@ export const queries: Record<
undefined,
undefined,
undefined,
undefined,
REACT_APP_COINGECKO_PRO_API_KEY,
getLogger(),
getGasMarkup(CHAIN_IDs.BASE_GOERLI)
Expand Down Expand Up @@ -492,22 +482,43 @@ export const getTokenSymbol = (tokenAddress: string): string => {
* @param tokenPrice An optional overred price to prevent the SDK from creating its own call
* @returns The a promise to the relayer fee for the given `amount` of transferring `l1Token` to `destinationChainId`
*/
export const getRelayerFeeDetails = (
export const getRelayerFeeDetails = async (
l1Token: string,
amount: sdk.utils.BigNumberish,
originChainId: number,
destinationChainId: number,
tokenPrice?: number
tokenPrice?: number,
messagePayload?: MessagePayload
): Promise<sdk.relayFeeCalculator.RelayerFeeDetails> => {
const tokenSymbol = getTokenSymbol(l1Token);
const relayFeeCalculator = getRelayerFeeCalculator(destinationChainId);
return relayFeeCalculator.relayerFeeDetails(
amount,
tokenSymbol,
tokenPrice,
originChainId.toString(),
destinationChainId.toString()
);
try {
return await relayFeeCalculator.relayerFeeDetails(
amount,
tokenSymbol,
String(originChainId),
String(destinationChainId),
messagePayload,
tokenPrice
);
} catch (_e: unknown) {
const e = _e as Error;
// If the error is due to a specific number of erroneous inputs,
// we can propagate the error to the user as a 4xx.
if (e.message.includes("Could not simulate message fill.")) {
throw new InputError(e.message);
} else {
// Otherwise, we throw a 500.
throw new Error(
`Could not process relayer fee details.
${
sdk.utils.isDefined(messagePayload)
? " The likely cause is related to message payload."
: ""
}`
);
james-a-morris marked this conversation as resolved.
Show resolved Hide resolved
}
}
};

/**
Expand Down
36 changes: 34 additions & 2 deletions api/suggested-fees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as sdk from "@across-protocol/sdk-v2";
import { BlockFinder } from "@uma/sdk";
import { VercelResponse } from "@vercel/node";
import { ethers } from "ethers";
import { type, assert, Infer, optional } from "superstruct";
import { type, assert, Infer, optional, string } from "superstruct";
import { disabledL1Tokens, DEFAULT_QUOTE_TIMESTAMP_BUFFER } from "./_constants";
import { TypedVercelRequest } from "./_types";
import {
Expand Down Expand Up @@ -33,6 +33,9 @@ const SuggestedFeesQueryParamsSchema = type({
originChainId: optional(positiveIntStr()),
timestamp: optional(positiveIntStr()),
skipAmountLimit: optional(boolStr()),
message: optional(string()),
recipientAddress: optional(validAddress()),
relayerAddress: optional(validAddress()),
});

type SuggestedFeesQueryParams = Infer<typeof SuggestedFeesQueryParamsSchema>;
Expand Down Expand Up @@ -64,6 +67,9 @@ const handler = async (
originChainId,
timestamp,
skipAmountLimit,
recipientAddress,
relayerAddress,
message,
} = query;

if (originChainId === destinationChainId) {
Expand All @@ -78,6 +84,31 @@ const handler = async (
]);
const { l1Token, hubPool, chainId: computedOriginChainId } = tokenDetails;

if (
sdk.utils.isDefined(message) &&
!sdk.utils.isDefined(recipientAddress)
) {
throw new InputError(
"Recipient address is required when message is provided"
);
}
if (
sdk.utils.isDefined(message) &&
// Our message encoding is a hex string, so we need to check that the length is even.
message.length % 2 !== 0
) {
throw new InputError("Message must be an even hex string");
}

const messagePayload =
sdk.utils.isDefined(message) && sdk.utils.isDefined(recipientAddress)
? {
message,
recipientAddress,
relayerAddress,
}
: undefined;
james-a-morris marked this conversation as resolved.
Show resolved Hide resolved

// Note: Add a buffer to "latest" timestamp so that it corresponds to a block older than HEAD.
// This is to improve relayer UX who have heightened risk of sending inadvertent invalid fills
// for quote times right at HEAD (or worst, in the future of HEAD). If timestamp is supplied as
Expand Down Expand Up @@ -151,7 +182,8 @@ const handler = async (
amount,
computedOriginChainId,
Number(destinationChainId),
tokenPrice
tokenPrice,
messagePayload
);

const skipAmountLimitEnabled = skipAmountLimit === "true";
Expand Down