-
Notifications
You must be signed in to change notification settings - Fork 43
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(API): Apply gas mark up to base fee rather than gas cost #1339
base: master
Are you sure you want to change the base?
Changes from all commits
1a21394
eaf7fd8
ed22e76
00a4557
cb6b690
cdde913
396d62b
8cf8072
99b5da2
eb77db9
ea0a94d
ed05490
769296d
6a524ac
0113ac5
3044ca9
099d72b
18c3641
c9a3481
75254f6
6f2bcf3
051be80
7f4f2a8
bbfbe1b
5fb79b9
6948d14
752704c
868d76b
7d91801
47fa488
5f6a1c5
2ffb6a6
f10a8e9
fc08217
9fe1b31
24c2bbd
207397d
ca704ea
e48b4f9
894c141
0f3d4f2
cd4dd7e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,139 @@ | ||
import { VercelResponse } from "@vercel/node"; | ||
import { | ||
buildDepositForSimulation, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This file has a lot of changes but its an API endpoint we don't depend on in production as its mostly here to compare against the current existing API to compare the expected gas total changes. The main changes are:
|
||
getGasMarkup, | ||
getLogger, | ||
getMaxFeePerGas, | ||
getRelayerFeeCalculatorQueries, | ||
handleErrorCondition, | ||
latestGasPriceCache, | ||
sendResponse, | ||
} from "./_utils"; | ||
import { TypedVercelRequest } from "./_types"; | ||
import { ethers, providers, VoidSigner } from "ethers"; | ||
import * as sdk from "@across-protocol/sdk"; | ||
import { L2Provider } from "@eth-optimism/sdk/dist/interfaces/l2-provider"; | ||
|
||
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) | ||
); | ||
// getMaxFeePerGas will return the gas price after including the baseFeeMultiplier. | ||
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( | ||
async ([chainId, tokenAddress], i) => { | ||
// This is a dummy deposit used to pass into buildDepositForSimulation() to build a fill transaction | ||
// that we can simulate without reversion. The only parameter that matters is that the destinationChainId | ||
// is set to the spoke pool's chain ID we'll be simulating the fill call on. | ||
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 deposit = buildDepositForSimulation(depositArgs); | ||
const relayerFeeCalculatorQueries = getRelayerFeeCalculatorQueries( | ||
Number(chainId) | ||
); | ||
const { nativeGasCost, tokenGasCost } = | ||
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, | ||
} | ||
); | ||
// 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); | ||
} | ||
return { | ||
nativeGasCost, | ||
tokenGasCost, | ||
opStackL1GasCost, | ||
}; | ||
} | ||
) | ||
); | ||
const responseJson = { | ||
tokenSymbol, | ||
...Object.fromEntries( | ||
Object.keys(chainIdsWithToken).map((chainId, i) => [ | ||
chainId, | ||
{ | ||
gasPrice: gasPrices[i].maxFeePerGas.toString(), | ||
gasPriceComponents: { | ||
maxFeePerGas: gasPrices[i].maxFeePerGas | ||
.sub(gasPrices[i].maxPriorityFeePerGas) | ||
.toString(), | ||
priorityFeePerGas: gasPrices[i].maxPriorityFeePerGas.toString(), | ||
baseFeeMultiplier: ethers.utils.formatEther( | ||
getGasMarkup(chainId) | ||
), | ||
}, | ||
nativeGasCost: gasCosts[i].nativeGasCost.toString(), | ||
tokenGasCost: gasCosts[i].tokenGasCost.toString(), | ||
opStackL1GasCost: gasCosts[i]?.opStackL1GasCost?.toString(), | ||
}, | ||
]) | ||
), | ||
}; | ||
|
||
logger.debug({ | ||
at: "GasPrices", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -194,6 +194,8 @@ const handler = async ( | |
tokenPriceNative, | ||
relayer, | ||
gasUnits, | ||
// !!gas price should be defined and passed into getRelayerFeeDetails so we don't recompute using default | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think its important to highlight the importance of not letting gasPrice be undefined here, otherwise the effects of the |
||
// settings in the GasPriceOracle | ||
gasPrice | ||
), | ||
callViaMulticall3(provider, multiCalls, { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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/[email protected]", | ||
"@across-protocol/sdk": "^3.3.27", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This SDK change has two important changes that will materially impact the
|
||
"@across-protocol/sdk": "^3.4.3", | ||
"@amplitude/analytics-browser": "^2.3.5", | ||
"@balancer-labs/sdk": "1.1.6-beta.16", | ||
"@emotion/react": "^11.13.0", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,10 +16,10 @@ | |
"@uma/common" "^2.17.0" | ||
hardhat "^2.9.3" | ||
|
||
"@across-protocol/constants@^3.1.24": | ||
version "3.1.24" | ||
resolved "https://registry.yarnpkg.com/@across-protocol/constants/-/constants-3.1.24.tgz#01fe49330bb467dd01813387ddbac741bc74a035" | ||
integrity sha512-guKtvIbif//vsmSZbwGubTWVtfkWiyWenr2sVyo63U/68GOW89ceJRLu4efLjeLVGiSrNAJtFUCv9dTwrrosWA== | ||
"@across-protocol/constants@^3.1.24", "@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" | ||
|
@@ -83,13 +83,13 @@ | |
yargs "^17.7.2" | ||
zksync-web3 "^0.14.3" | ||
|
||
"@across-protocol/sdk@^3.3.27": | ||
version "3.3.27" | ||
resolved "https://registry.yarnpkg.com/@across-protocol/sdk/-/sdk-3.3.27.tgz#ca58012c30e7d489ba5493981447c8cf2b82ef58" | ||
integrity sha512-TebERt9Z0CF3NzD4dkurrgEqHn7gqidgoUrvk0kMUy2HzrlZilYj3oKgn+Kevn4XqomPfdWOkuAyiWDV5uNYew== | ||
"@across-protocol/sdk@^3.4.3": | ||
version "3.4.3" | ||
resolved "https://registry.yarnpkg.com/@across-protocol/sdk/-/sdk-3.4.3.tgz#4b57028b0a04ceb2387a45d950e689d43ed3e587" | ||
integrity sha512-1BFL5W1USZYGMGVnrFdXBVNTJQu2wdvGI2hB73J8bvO03jFzY3EcWEEGDSp0Bq29V1WuX1vrjBNIczSGTAbrdw== | ||
dependencies: | ||
"@across-protocol/across-token" "^1.0.0" | ||
"@across-protocol/constants" "^3.1.24" | ||
"@across-protocol/constants" "^3.1.25" | ||
"@across-protocol/contracts" "^3.0.19" | ||
"@eth-optimism/sdk" "^3.3.1" | ||
"@ethersproject/bignumber" "^5.7.0" | ||
|
@@ -22961,7 +22961,7 @@ string-length@^4.0.1: | |
char-regex "^1.0.2" | ||
strip-ansi "^6.0.0" | ||
|
||
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: | ||
"string-width-cjs@npm:string-width@^4.2.0": | ||
version "4.2.3" | ||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" | ||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== | ||
|
@@ -22996,6 +22996,15 @@ string-width@^3.0.0, string-width@^3.1.0: | |
is-fullwidth-code-point "^2.0.0" | ||
strip-ansi "^5.1.0" | ||
|
||
string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: | ||
version "4.2.3" | ||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" | ||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== | ||
dependencies: | ||
emoji-regex "^8.0.0" | ||
is-fullwidth-code-point "^3.0.0" | ||
strip-ansi "^6.0.1" | ||
|
||
string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2: | ||
version "5.1.2" | ||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" | ||
|
@@ -23070,7 +23079,7 @@ string_decoder@~1.1.1: | |
dependencies: | ||
safe-buffer "~5.1.0" | ||
|
||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: | ||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1": | ||
version "6.0.1" | ||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" | ||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== | ||
|
@@ -23098,6 +23107,13 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: | |
dependencies: | ||
ansi-regex "^4.1.0" | ||
|
||
strip-ansi@^6.0.0, strip-ansi@^6.0.1: | ||
version "6.0.1" | ||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" | ||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== | ||
dependencies: | ||
ansi-regex "^5.0.1" | ||
|
||
strip-ansi@^7.0.1: | ||
version "7.0.1" | ||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" | ||
|
@@ -25814,7 +25830,7 @@ [email protected]: | |
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" | ||
integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== | ||
|
||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: | ||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": | ||
version "7.0.0" | ||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" | ||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== | ||
|
@@ -25849,6 +25865,15 @@ wrap-ansi@^6.2.0: | |
string-width "^4.1.0" | ||
strip-ansi "^6.0.0" | ||
|
||
wrap-ansi@^7.0.0: | ||
version "7.0.0" | ||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" | ||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== | ||
dependencies: | ||
ansi-styles "^4.0.0" | ||
string-width "^4.1.0" | ||
strip-ansi "^6.0.0" | ||
|
||
wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: | ||
version "8.1.0" | ||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Important LOC we're removing. We should use gas price oracle for all estimates since it handles OP stack now