Skip to content

Commit

Permalink
improve(RelayFeeCalc): Add gas cost component getters (#826)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholaspai authored Jan 12, 2025
1 parent c29e90f commit b37a0f3
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 8 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@across-protocol/sdk",
"author": "UMA Team",
"version": "3.4.9",
"version": "3.4.10",
"license": "AGPL-3.0",
"homepage": "https://docs.across.to/reference/sdk",
"files": [
Expand Down
64 changes: 57 additions & 7 deletions src/relayFeeCalculator/chain-queries/baseQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export class QueryBase implements QueryInterface {
transport,
} = options;

const tx = await populateV3Relay(this.spokePool, deposit, relayer);
const tx = await this.getUnsignedTxFromDeposit(deposit, relayer);
const {
nativeGasCost,
tokenGasCost,
Expand All @@ -114,6 +114,59 @@ export class QueryBase implements QueryInterface {
};
}

/**
* @notice Return ethers.PopulatedTransaction for a fill based on input deposit args
* @param deposit
* @param relayer Sender of PopulatedTransaction
* @returns PopulatedTransaction
*/
getUnsignedTxFromDeposit(
deposit: Deposit,
relayer = DEFAULT_SIMULATED_RELAYER_ADDRESS
): Promise<PopulatedTransaction> {
return populateV3Relay(this.spokePool, deposit, relayer);
}

/**
* @notice Return the gas cost of a simulated transaction
* @param deposit
* @param relayer Sender of PopulatedTransaction
* @returns Estimated gas cost based on ethers.VoidSigner's gas estimation
*/
async getNativeGasCost(deposit: Deposit, relayer = DEFAULT_SIMULATED_RELAYER_ADDRESS): Promise<BigNumber> {
const unsignedTx = await this.getUnsignedTxFromDeposit(deposit, relayer);
const voidSigner = new VoidSigner(relayer, this.provider);
return voidSigner.estimateGas(unsignedTx);
}

/**
* @notice Return L1 data fee for OP stack L2 transaction, which is based on L2 calldata.
* @dev https://docs.optimism.io/stack/transactions/fees#l1-data-fee
* @param unsignedTx L2 transaction that you want L1 data fee for
* @param relayer Sender of unsignedTx
* @param options Specify gas units to avoid additional gas estimation call and multiplier for L1 data fee
* @returns BigNumber L1 data fee in gas units
*/
async getOpStackL1DataFee(
unsignedTx: PopulatedTransaction,
relayer = DEFAULT_SIMULATED_RELAYER_ADDRESS,
options: Partial<{
opStackL2GasUnits: BigNumberish;
opStackL1DataFeeMultiplier: BigNumber;
}>
): Promise<BigNumber> {
const { opStackL2GasUnits, opStackL1DataFeeMultiplier = toBNWei("1") } = options || {};
const { chainId } = await this.provider.getNetwork();
assert(isOptimismL2Provider(this.provider), `Unexpected provider for chain ID ${chainId}.`);
const voidSigner = new VoidSigner(relayer, this.provider);
const populatedTransaction = await voidSigner.populateTransaction({
...unsignedTx,
gasLimit: opStackL2GasUnits, // prevents additional gas estimation call
});
const l1DataFee = await (this.provider as L2Provider<providers.Provider>).estimateL1GasCost(populatedTransaction);
return l1DataFee.mul(opStackL1DataFeeMultiplier).div(fixedPointAdjustment);
}

/**
* Estimates the total gas cost required to submit an unsigned (populated) transaction on-chain.
* @param unsignedTx The unsigned transaction that this function will estimate.
Expand Down Expand Up @@ -164,13 +217,10 @@ export class QueryBase implements QueryInterface {
// OP stack is a special case; gas cost is computed by the SDK, without having to query price.
let opStackL1GasCost: BigNumber | undefined;
if (chainIsOPStack(chainId)) {
assert(isOptimismL2Provider(provider), `Unexpected provider for chain ID ${chainId}.`);
const populatedTransaction = await voidSigner.populateTransaction({
...unsignedTx,
gasLimit: nativeGasCost, // prevents additional gas estimation call
opStackL1GasCost = await this.getOpStackL1DataFee(unsignedTx, senderAddress, {
opStackL2GasUnits: nativeGasCost,
opStackL1DataFeeMultiplier: opStackL1GasCostMultiplier,
});
const l1GasCost = await (provider as L2Provider<providers.Provider>).estimateL1GasCost(populatedTransaction);
opStackL1GasCost = l1GasCost.mul(opStackL1GasCostMultiplier).div(fixedPointAdjustment);
const l2GasCost = nativeGasCost.mul(gasPrice);
tokenGasCost = opStackL1GasCost.add(l2GasCost);
} else {
Expand Down

0 comments on commit b37a0f3

Please sign in to comment.