diff --git a/api/_constants.ts b/api/_constants.ts index ee5cc58a5..8f1b20d4d 100644 --- a/api/_constants.ts +++ b/api/_constants.ts @@ -202,3 +202,5 @@ export const DOMAIN_CALLDATA_DELIMITER = "0x1dc0de"; export const DEFAULT_LITE_CHAIN_USD_MAX_BALANCE = "250000"; export const DEFAULT_LITE_CHAIN_USD_MAX_DEPOSIT = "25000"; + +export const DEFAULT_FILL_DEADLINE_BUFFER_SECONDS = 2.5 * 60 * 60; // 2.5 hours diff --git a/api/_fill-deadline.ts b/api/_fill-deadline.ts new file mode 100644 index 000000000..2016e28b4 --- /dev/null +++ b/api/_fill-deadline.ts @@ -0,0 +1,19 @@ +import { DEFAULT_FILL_DEADLINE_BUFFER_SECONDS } from "./_constants"; +import { getSpokePool } from "./_utils"; + +function getFillDeadlineBuffer(chainId: number) { + const bufferFromEnv = ( + JSON.parse(process.env.FILL_DEADLINE_BUFFER_SECONDS || "{}") as Record< + string, + string + > + )?.[chainId.toString()]; + return Number(bufferFromEnv ?? DEFAULT_FILL_DEADLINE_BUFFER_SECONDS); +} + +export async function getFillDeadline(chainId: number): Promise { + const fillDeadlineBuffer = getFillDeadlineBuffer(chainId); + const spokePool = getSpokePool(chainId); + const currentTime = await spokePool.callStatic.getCurrentTime(); + return Number(currentTime) + fillDeadlineBuffer; +} diff --git a/api/_utils.ts b/api/_utils.ts index 69851b2de..4b94d2296 100644 --- a/api/_utils.ts +++ b/api/_utils.ts @@ -85,7 +85,6 @@ const { REACT_APP_HUBPOOL_CHAINID, REACT_APP_PUBLIC_INFURA_ID, REACT_APP_COINGECKO_PRO_API_KEY, - GAS_MARKUP, // To be deprecated and replaced by BASE_FEE_MARKUP and PRIORITY_FEE_MARKUP BASE_FEE_MARKUP, PRIORITY_FEE_MARKUP, VERCEL_ENV, @@ -94,7 +93,7 @@ const { export const baseFeeMarkup: { [chainId: string]: number; -} = JSON.parse(BASE_FEE_MARKUP || GAS_MARKUP || "{}"); +} = JSON.parse(BASE_FEE_MARKUP || "{}"); export const priorityFeeMarkup: { [chainId: string]: number; } = JSON.parse(PRIORITY_FEE_MARKUP || "{}"); diff --git a/api/suggested-fees.ts b/api/suggested-fees.ts index a1ad89a28..35a9ebdf4 100644 --- a/api/suggested-fees.ts +++ b/api/suggested-fees.ts @@ -39,6 +39,7 @@ import { AmountTooHighError, AmountTooLowError, } from "./_errors"; +import { getFillDeadline } from "./_fill-deadline"; const { BigNumber } = ethers; @@ -187,6 +188,7 @@ const handler = async ( [currentUt, nextUt, _quoteTimestamp, rawL1TokenConfig], tokenPriceUsd, limits, + fillDeadline, ] = await Promise.all([ callViaMulticall3(provider, multiCalls, { blockTag: quoteBlockNumber }), getCachedTokenPrice(l1Token.address, "usd"), @@ -203,6 +205,7 @@ const handler = async ( depositWithMessage ? relayer : undefined, depositWithMessage ? message : undefined ), + getFillDeadline(destinationChainId), ]); const { maxDeposit, maxDepositInstant, minDeposit, relayerFeeDetails } = limits; @@ -341,6 +344,7 @@ const handler = async ( maxDepositShortDelay: limits.maxDepositShortDelay, recommendedDepositInstant: limits.recommendedDepositInstant, }, + fillDeadline: fillDeadline.toString(), }; logger.debug({ diff --git a/package.json b/package.json index 67a167b89..6ec93dc78 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "@across-protocol/constants": "^3.1.24", "@across-protocol/contracts": "^3.0.19", "@across-protocol/contracts-v3.0.6": "npm:@across-protocol/contracts@3.0.6", - "@across-protocol/sdk": "^3.4.5", + "@across-protocol/sdk": "^3.4.7", "@amplitude/analytics-browser": "^2.3.5", "@balancer-labs/sdk": "1.1.6-beta.16", "@emotion/react": "^11.13.0", diff --git a/src/utils/bridge.ts b/src/utils/bridge.ts index c2b5acd7b..d60e15127 100644 --- a/src/utils/bridge.ts +++ b/src/utils/bridge.ts @@ -1,7 +1,6 @@ import { ethers, BigNumber } from "ethers"; import { ChainId, - DEFAULT_FILL_DEADLINE_BUFFER_SECONDS, fixedPointAdjustment, referrerDelimiterHex, } from "./constants"; @@ -32,6 +31,7 @@ export type BridgeFees = { estimatedFillTimeSec: number; exclusiveRelayer: string; exclusivityDeadline: number; + fillDeadline: number; }; type GetBridgeFeesArgs = { @@ -77,6 +77,7 @@ export async function getBridgeFees({ estimatedFillTimeSec, exclusiveRelayer, exclusivityDeadline, + fillDeadline, } = await getApiEndpoint().suggestedFees( amount, getConfig().getTokenInfoBySymbol(fromChainId, inputTokenSymbol).address, @@ -103,6 +104,7 @@ export async function getBridgeFees({ estimatedFillTimeSec, exclusiveRelayer, exclusivityDeadline, + fillDeadline, }; } @@ -150,7 +152,7 @@ export type AcrossDepositArgs = { export type AcrossDepositV3Args = AcrossDepositArgs & { inputTokenAddress: string; outputTokenAddress: string; - fillDeadline?: number; + fillDeadline: number; exclusivityDeadline?: number; exclusiveRelayer?: string; }; @@ -236,7 +238,6 @@ export async function sendDepositV3Tx( const outputAmount = inputAmount.sub( inputAmount.mul(relayerFeePct).div(fixedPointAdjustment) ); - fillDeadline ??= await getFillDeadline(spokePool); const useExclusiveRelayer = exclusiveRelayer !== ethers.constants.AddressZero && @@ -350,7 +351,6 @@ export async function sendSwapAndBridgeTx( const outputAmount = inputAmount.sub( inputAmount.mul(relayerFeePct).div(fixedPointAdjustment) ); - fillDeadline ??= await getFillDeadline(spokePool); const tx = await swapAndBridge.populateTransaction.swapAndBridge( swapQuote.routerCalldata, @@ -424,15 +424,6 @@ export async function getSpokePoolAndVerifier({ }; } -async function getFillDeadline(spokePool: SpokePool): Promise { - const fillDeadlineBuffer = Number( - process.env.FILL_DEADLINE_BUFFER_SECONDS ?? - DEFAULT_FILL_DEADLINE_BUFFER_SECONDS - ); - const currentTime = await spokePool.callStatic.getCurrentTime(); - return Number(currentTime) + fillDeadlineBuffer; -} - async function _tagRefAndSignTx( tx: ethers.PopulatedTransaction, referrer: string, diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 76d61c00d..49508b541 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -551,5 +551,3 @@ export const defaultSwapSlippage = Number( export const indexerApiBaseUrl = process.env.REACT_APP_INDEXER_BASE_URL || undefined; - -export const DEFAULT_FILL_DEADLINE_BUFFER_SECONDS = 2.5 * 60 * 60; // 2.5 hours diff --git a/src/utils/serverless-api/mocked/suggested-fees.mocked.ts b/src/utils/serverless-api/mocked/suggested-fees.mocked.ts index 4477ebf10..b02d76bfe 100644 --- a/src/utils/serverless-api/mocked/suggested-fees.mocked.ts +++ b/src/utils/serverless-api/mocked/suggested-fees.mocked.ts @@ -51,5 +51,6 @@ export async function suggestedFeesMockedApiCall( }, exclusiveRelayer: ethers.constants.AddressZero, exclusivityDeadline: 0, + fillDeadline: Date.now(), }; } diff --git a/src/utils/serverless-api/prod/suggested-fees.prod.ts b/src/utils/serverless-api/prod/suggested-fees.prod.ts index 7481cee24..3e5ea2bf5 100644 --- a/src/utils/serverless-api/prod/suggested-fees.prod.ts +++ b/src/utils/serverless-api/prod/suggested-fees.prod.ts @@ -89,5 +89,6 @@ export async function suggestedFeesApiCall( estimatedFillTimeSec, exclusiveRelayer, exclusivityDeadline, + fillDeadline: result.fillDeadline, }; } diff --git a/src/utils/serverless-api/types.ts b/src/utils/serverless-api/types.ts index 488b9afab..c85d4b2d5 100644 --- a/src/utils/serverless-api/types.ts +++ b/src/utils/serverless-api/types.ts @@ -58,6 +58,7 @@ export type SuggestedApiFeeReturnType = { estimatedFillTimeSec: number; exclusiveRelayer: string; exclusivityDeadline: number; + fillDeadline: number; }; export type SuggestedApiFeeType = ( diff --git a/src/views/Bridge/hooks/useBridgeAction.ts b/src/views/Bridge/hooks/useBridgeAction.ts index 891363bc8..a47b3eb8a 100644 --- a/src/views/Bridge/hooks/useBridgeAction.ts +++ b/src/views/Bridge/hooks/useBridgeAction.ts @@ -238,6 +238,7 @@ export function useBridgeAction( // Disabling until we update the contract. exclusiveRelayer: constants.AddressZero, exclusivityDeadline: 0, + fillDeadline: frozenFeeQuote.fillDeadline, }, networkMismatchHandler ); @@ -266,6 +267,7 @@ export function useBridgeAction( toAddress: externalProjectIsHyperLiquid ? "0x924a9f036260DdD5808007E1AA95f08eD08aA569" // Default multicall handler : frozenDepositArgs.toAddress, + fillDeadline: frozenFeeQuote.fillDeadline, }, spokePool, networkMismatchHandler diff --git a/yarn.lock b/yarn.lock index 1b7066726..9b06bf5bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21,11 +21,6 @@ resolved "https://registry.yarnpkg.com/@across-protocol/constants/-/constants-3.1.25.tgz#60d6d9814582ff91faf2b6d9f51d6dccb447b4ce" integrity sha512-GpZoYn7hETYL2BPMM2GqXAer6+l/xuhder+pvpb00HJcb/sqCjF7vaaeKxjKJ3jKtyeulYmdu0NDkeNm5KbNWA== -"@across-protocol/constants@^3.1.25": - version "3.1.25" - resolved "https://registry.yarnpkg.com/@across-protocol/constants/-/constants-3.1.25.tgz#60d6d9814582ff91faf2b6d9f51d6dccb447b4ce" - integrity sha512-GpZoYn7hETYL2BPMM2GqXAer6+l/xuhder+pvpb00HJcb/sqCjF7vaaeKxjKJ3jKtyeulYmdu0NDkeNm5KbNWA== - "@across-protocol/constants@^3.1.9": version "3.1.13" resolved "https://registry.yarnpkg.com/@across-protocol/constants/-/constants-3.1.13.tgz#b4caf494e9d9fe50290cca91b7883ea408fdb90a" @@ -88,10 +83,10 @@ yargs "^17.7.2" zksync-web3 "^0.14.3" -"@across-protocol/sdk@^3.4.5": - version "3.4.5" - resolved "https://registry.yarnpkg.com/@across-protocol/sdk/-/sdk-3.4.5.tgz#343f53be92e92afd2fd4dbea16f180533093ea26" - integrity sha512-o1DovRfSriL0GTa304rd2KcBDwWYbK2SHT8mElyCLg6beX5RnJKT0YiMUMuCMfZ7MZJscdGzV023e5BhbyeP5A== +"@across-protocol/sdk@^3.4.7": + version "3.4.7" + resolved "https://registry.yarnpkg.com/@across-protocol/sdk/-/sdk-3.4.7.tgz#6ddf9698f918d7b7e0216327d60b54b37fe14f22" + integrity sha512-GeyzDG8EzlN8oddmjXASqND+usZPkWDLpzbdWfAfBfHT3pjIMatntZqZghfCfjy+ICf+rlYrAb8I24H4jlct8Q== dependencies: "@across-protocol/across-token" "^1.0.0" "@across-protocol/constants" "^3.1.25"