Update package to version 3.0.0:
- Simplify getGasParams function by including additional L1 fee in gasLimit - Make calculateRefund functions non-async by providing gas price (its ok, because refund needs to be calculated only on user side, where gas price is known) - Allow passing to calculateWithdrawalFeeViaRelayer function predefined gas price and gas limit to not refetch/recalculate those values - Pass arguments as objects to functions with many optional parameters
This commit is contained in:
parent
ae9b15b7ed
commit
be7f911a17
@ -35,7 +35,7 @@ const tx: TransactionData = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const feeOracle = new TornadoFeeOracleV5(1, 'https://eth.llamarpc.com'); // First parameter - chain ID
|
const feeOracle = new TornadoFeeOracleV5(1, 'https://eth.llamarpc.com'); // First parameter - chain ID
|
||||||
const withdrawalGas = await feeOracle.getGas(tx, 'relayer_withdrawal');
|
const withdrawalGas = await feeOracle.getGas({tx, txType: 'relayer_withdrawal'});
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Estimate gas price and gas limit to send transaction
|
##### Estimate gas price and gas limit to send transaction
|
||||||
@ -51,10 +51,9 @@ const incompleteTx: TransactionData = {
|
|||||||
|
|
||||||
const feeOracle = new TornadoFeeOracleV5(1, 'https://eth.llamarpc.com');
|
const feeOracle = new TornadoFeeOracleV5(1, 'https://eth.llamarpc.com');
|
||||||
const transactionType: TxType = 'relayer_withdrawal';
|
const transactionType: TxType = 'relayer_withdrawal';
|
||||||
const gasPrice = await feeOracle.getGasPrice(transactionType);
|
const { gasPrice, gasLimit } = await feeOracle.getGasParams({tx: incompleteTx, txType: transactionType});
|
||||||
const gasLimit = await feeOracle.getGasLimit(incompleteTx, transactionType);
|
|
||||||
|
|
||||||
const tx: TransactionData = Object.assign({ gasPrice, gasLimit }, incompleteTx);
|
const tx: TransactionData = {...incompleteTx, gasPrice, gasLimit}
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Get token prices (rate to ETH) for tokens that used in Tornado
|
##### Get token prices (rate to ETH) for tokens that used in Tornado
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@tornado/tornado-oracles",
|
"name": "@tornado/tornado-oracles",
|
||||||
"version": "2.1.0",
|
"version": "3.0.0",
|
||||||
"description": "Gas oracle for Tornado-specific transactions",
|
"description": "Oracles for Tornado-specific transactions & actions",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
198
src/feeOracle.ts
198
src/feeOracle.ts
@ -1,5 +1,6 @@
|
|||||||
import { GasPriceOracle } from '@tornado/gas-price-oracle';
|
import { GasPriceOracle } from '@tornado/gas-price-oracle';
|
||||||
import { BigNumber, BigNumberish, ethers } from 'ethers';
|
import { BigNumber, BigNumberish, ethers } from 'ethers';
|
||||||
|
import BigNumberFloat from 'bignumber.js';
|
||||||
import { parseUnits } from 'ethers/lib/utils';
|
import { parseUnits } from 'ethers/lib/utils';
|
||||||
import {
|
import {
|
||||||
TransactionData,
|
TransactionData,
|
||||||
@ -9,12 +10,14 @@ import {
|
|||||||
GasPriceParams,
|
GasPriceParams,
|
||||||
GetGasParamsRes,
|
GetGasParamsRes,
|
||||||
HexadecimalStringifiedNumber,
|
HexadecimalStringifiedNumber,
|
||||||
|
GetGasInput,
|
||||||
|
GetGasParamsInput,
|
||||||
} from './types';
|
} from './types';
|
||||||
import { JsonRpcProvider } from '@ethersproject/providers';
|
import { JsonRpcProvider } from '@ethersproject/providers';
|
||||||
import { ChainId, defaultGasPrices, defaultInstanceTokensGasLimit, InstanceTokenSymbol } from './config';
|
import { ChainId, defaultGasPrices, defaultInstanceTokensGasLimit, InstanceTokenSymbol } from './config';
|
||||||
import { bump, calculateGasPriceInWei, convertETHToToken, fromGweiToWeiHex, serializeTx } from './utils';
|
import { bump, calculateGasPriceInWei, convertETHToToken, fromGweiToWeiHex, serializeTx } from './utils';
|
||||||
import { getOptimismL1FeeOracle } from './contracts/factories';
|
import { getOptimismL1FeeOracle } from './contracts/factories';
|
||||||
import { AvailableTokenSymbols } from '@tornado/tornado-config';
|
import { GetWithdrawalFeeViaRelayerInput } from './types';
|
||||||
|
|
||||||
export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
||||||
protected provider: JsonRpcProvider;
|
protected provider: JsonRpcProvider;
|
||||||
@ -44,55 +47,71 @@ export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Estimate gas price, gas limit and l1Fee for sidechain (if exists)
|
* Estimate gas price, gas limit and l1Fee for sidechain (if exists)
|
||||||
* @param {TransactionData} [tx] Transaction data in web3 / ethers format
|
* @param {GetGasParamsInput} params Function input arguments object
|
||||||
* @param {TxType} [txType=other] Tornado transaction type: withdrawal by user, withdrawal by relayer or 'other'
|
* @param {TransactionData} [params.tx] Transaction data in web3 / ethers format
|
||||||
* @param {number} [bumpGasLimitPercent] Gas limit bump percent to prioritize transaction (recenlty used)
|
* @param {TxType} [params.txType=other] Tornado transaction type: withdrawal by user, withdrawal by relayer or 'other'
|
||||||
* @param {number} [bumpGasPricePercent] Gas price bump percent to prioritize transaction (rarely used)
|
* @param {number} [params.predefinedGasLimit] Predefined gas limit, if already calculated (no refetching)
|
||||||
* @param {LegacyGasPriceKey} [speed] Preferred transaction speed, if uses legacy gas (before EIP-1559)
|
* @param {number} [params.predefinedGasPrice] Predefined gas price, if already calculated (no refetching)
|
||||||
* @returns {Promise<GetGasParamsRes>} Object with fields 'gasPrice', 'gasLimit' and 'l1Fee'
|
* @param {number} [params.bumpGasLimitPercent] Gas limit bump percent to prioritize transaction (if gas limit not predefined, recenlty used)
|
||||||
|
* @param {number} [params.bumpGasPricePercent] Gas price bump percent to prioritize transaction (if gas limit not predefined, rarely used)
|
||||||
|
* @param {LegacyGasPriceKey} [params.speed] Preferred transaction speed, if uses legacy gas (before EIP-1559)
|
||||||
|
* @param {boolean} [params.includeL1FeeToGasLimit=true] Include L1 additional fee on Optimism to gas limit (get fee and divide by gas price)
|
||||||
|
* @returns {Promise<GetGasParamsRes>} Object with fields 'gasPrice' and 'gasLimit', L1 fee, if exists, included in gasLimit
|
||||||
*/
|
*/
|
||||||
async getGasParams(
|
async getGasParams(params: GetGasParamsInput = {}): Promise<GetGasParamsRes> {
|
||||||
tx?: TransactionData,
|
let {
|
||||||
txType: TxType = 'other',
|
tx,
|
||||||
bumpGasLimitPercent?: number,
|
txType = 'other',
|
||||||
bumpGasPricePercent?: number,
|
bumpGasLimitPercent,
|
||||||
speed?: LegacyGasPriceKey,
|
bumpGasPricePercent,
|
||||||
): Promise<GetGasParamsRes> {
|
predefinedGasLimit: gasLimit,
|
||||||
const [gasPrice, gasLimit, l1Fee] = await Promise.all([
|
predefinedGasPrice: gasPrice,
|
||||||
this.getGasPrice(speed, bumpGasPricePercent),
|
speed,
|
||||||
this.getGasLimit(tx, txType, bumpGasLimitPercent),
|
includeL1FeeToGasLimit = true,
|
||||||
this.fetchL1OptimismFee(tx),
|
} = params;
|
||||||
]);
|
|
||||||
|
|
||||||
return { gasLimit, gasPrice, l1Fee };
|
let l1Fee: string = '0';
|
||||||
|
if (!gasLimit && !gasPrice) {
|
||||||
|
[gasPrice, gasLimit, l1Fee] = await Promise.all([
|
||||||
|
this.getGasPrice(speed, bumpGasPricePercent),
|
||||||
|
this.getGasLimit(tx, txType, bumpGasLimitPercent),
|
||||||
|
this.fetchL1OptimismFee(tx),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (!gasLimit) {
|
||||||
|
[gasLimit, l1Fee] = await Promise.all([
|
||||||
|
this.getGasLimit(tx, txType, bumpGasLimitPercent),
|
||||||
|
this.fetchL1OptimismFee(tx),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (!gasPrice) gasPrice = await this.getGasPrice(speed, bumpGasPricePercent);
|
||||||
|
|
||||||
|
if (includeL1FeeToGasLimit)
|
||||||
|
// Include L1 fee in gas limit (divide by gas price before), if l1 fee is 0, gas limit wont change
|
||||||
|
gasLimit = BigNumberFloat(gasLimit)
|
||||||
|
.plus(BigNumberFloat(l1Fee).div(BigNumberFloat(gasPrice)))
|
||||||
|
.decimalPlaces(0, 1)
|
||||||
|
.toNumber();
|
||||||
|
|
||||||
|
return { gasLimit, gasPrice };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Estimates next block gas for signed, unsigned or incomplete Tornado transaction
|
* Estimates next block gas for signed, unsigned or incomplete Tornado transaction
|
||||||
* @param {TransactionData} [tx] Transaction data in web3 / ethers format
|
* @param {GetGasInput} params Function input arguments object
|
||||||
* @param {TxType} [txType=other] Tornado transaction type: withdrawal by user, withdrawal by relayer or 'other'
|
* @param {TransactionData} [params.tx] Transaction data in web3 / ethers format
|
||||||
* @param {number} [bumpGasLimitPercent] Gas limit bump percent to prioritize transaction (recenlty used)
|
* @param {TxType} [params.txType] Tornado transaction type: withdrawal by user, withdrawal by relayer or 'other'
|
||||||
* @param {number} [bumpGasPricePercent] Gas price bump percent to prioritize transaction (rarely used)
|
* @param {number} [params.predefinedGasLimit] Predefined gas limit, if already calculated (no refetching)
|
||||||
* @param {LegacyGasPriceKey} [speed] Preferred transaction speed, if uses legacy gas (before EIP-1559)
|
* @param {number} [params.predefinedGasPrice] Predefined gas price, if already calculated (no refetching)
|
||||||
|
* @param {number} [params.bumpGasLimitPercent] Gas limit bump percent to prioritize transaction (if gas limit not predefined, recenlty used)
|
||||||
|
* @param {number} [params.bumpGasPricePercent] Gas price bump percent to prioritize transaction (if gas price not predefined, rarely used)
|
||||||
|
* @param {LegacyGasPriceKey} [params.speed] Preferred transaction speed, if uses legacy gas (before EIP-1559)
|
||||||
* @returns {Promise<HexadecimalStringifiedNumber>} Gas value in WEI (hex-format)
|
* @returns {Promise<HexadecimalStringifiedNumber>} Gas value in WEI (hex-format)
|
||||||
*/
|
*/
|
||||||
async getGas(
|
async getGas(params: GetGasInput = {}): Promise<HexadecimalStringifiedNumber> {
|
||||||
tx?: TransactionData,
|
const { gasPrice, gasLimit } = await this.getGasParams({ ...params, includeL1FeeToGasLimit: true });
|
||||||
txType: TxType = 'other',
|
|
||||||
bumpGasLimitPercent?: number,
|
|
||||||
bumpGasPricePercent?: number,
|
|
||||||
speed?: LegacyGasPriceKey,
|
|
||||||
): Promise<HexadecimalStringifiedNumber> {
|
|
||||||
const { gasPrice, gasLimit, l1Fee } = await this.getGasParams(
|
|
||||||
tx,
|
|
||||||
txType,
|
|
||||||
bumpGasLimitPercent,
|
|
||||||
bumpGasPricePercent,
|
|
||||||
speed,
|
|
||||||
);
|
|
||||||
const gas = BigNumber.from(gasPrice).mul(gasLimit).add(l1Fee);
|
|
||||||
|
|
||||||
return gas.toHexString();
|
return BigNumber.from(gasPrice).mul(gasLimit).toHexString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,61 +157,98 @@ export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
|||||||
* and if the relayer pays a commission and the transfer of tokens fails, this commission will remain to the relayer.
|
* and if the relayer pays a commission and the transfer of tokens fails, this commission will remain to the relayer.
|
||||||
*
|
*
|
||||||
* Refund needed that recipient can use tokens after withdrawal (covers gas fee for send/swap)
|
* Refund needed that recipient can use tokens after withdrawal (covers gas fee for send/swap)
|
||||||
|
* @param {BigNumberish} gasPrice Actual gas price
|
||||||
* @param {InstanceTokenSymbol} tokenSymbol Withdrawal token (currency) symbol - for example, 'dai'
|
* @param {InstanceTokenSymbol} tokenSymbol Withdrawal token (currency) symbol - for example, 'dai'
|
||||||
* @returns {Promise<HexadecimalStringifiedNumber>} Refund amount in WEI (in hex format)
|
* @returns {HexadecimalStringifiedNumber} Refund amount in WEI (in hex format)
|
||||||
*/
|
*/
|
||||||
async calculateRefundInETH(tokenSymbol: InstanceTokenSymbol): Promise<HexadecimalStringifiedNumber> {
|
calculateRefundInETH(gasPrice: BigNumberish, tokenSymbol: InstanceTokenSymbol): HexadecimalStringifiedNumber {
|
||||||
// In Tornado we need to calculate refund only on user side, relayer get refund value in proof
|
// In Tornado we need to calculate refund only on user side, relayer get refund value in proof
|
||||||
const gasPrice = await this.getGasPrice();
|
|
||||||
const gasLimit = defaultInstanceTokensGasLimit[tokenSymbol];
|
const gasLimit = defaultInstanceTokensGasLimit[tokenSymbol];
|
||||||
return BigNumber.from(gasPrice).mul(gasLimit).mul(2).toHexString();
|
return BigNumber.from(gasPrice).mul(gasLimit).mul(2).toHexString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetched actual gas price and calculates refund amount
|
||||||
|
* @param {InstanceTokenSymbol} tokenSymbol Withdrawal token (currency) symbol - for example, 'dai'
|
||||||
|
* @returns {Promise<HexadecimalStringifiedNumber>} Refund amount in WEI (in hex format)
|
||||||
|
*/
|
||||||
|
async fetchRefundInETH(tokenSymbol: InstanceTokenSymbol): Promise<HexadecimalStringifiedNumber> {
|
||||||
|
const gasPrice = await this.getGasPrice();
|
||||||
|
return this.calculateRefundInETH(gasPrice, tokenSymbol);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get refund amount on ETH or Goerli in non-native token
|
* Get refund amount on ETH or Goerli in non-native token
|
||||||
* @param {BigNumberish} tokenPriceInEth Token price in WEI in native currency
|
* @param {BigNumberish} gasPrice Actual gas price in ETH
|
||||||
|
* @param {BigNumberish} tokenPriceInEth Token price in WEI in ETH
|
||||||
* @param {HexadecimalStringifiedNumber | number} tokenDecimals Token (currency) decimals
|
* @param {HexadecimalStringifiedNumber | number} tokenDecimals Token (currency) decimals
|
||||||
* @param {InstanceTokenSymbol} tokenSymbol Withdrawal token (currency) symbol - for example, 'dai'
|
* @param {InstanceTokenSymbol} tokenSymbol Withdrawal token (currency) symbol - for example, 'dai'
|
||||||
* @returns {Promise<HexadecimalStringifiedNumber>} Refund amount in WEI in selected token (hexed number)
|
* @returns {HexadecimalStringifiedNumber} Refund amount in WEI in selected token (hexed number)
|
||||||
*/
|
*/
|
||||||
async calculateRefundInToken(
|
calculateRefundInToken(
|
||||||
|
gasPrice: BigNumberish,
|
||||||
tokenPriceInEth: BigNumberish,
|
tokenPriceInEth: BigNumberish,
|
||||||
tokenDecimals: HexadecimalStringifiedNumber | number,
|
tokenDecimals: HexadecimalStringifiedNumber | number,
|
||||||
tokenSymbol: InstanceTokenSymbol,
|
tokenSymbol: InstanceTokenSymbol,
|
||||||
): Promise<HexadecimalStringifiedNumber> {
|
): HexadecimalStringifiedNumber {
|
||||||
const refundInEth = await this.calculateRefundInETH(tokenSymbol);
|
const refundInEth = this.calculateRefundInETH(gasPrice, tokenSymbol);
|
||||||
return convertETHToToken(refundInEth, tokenDecimals, tokenPriceInEth).toHexString();
|
return convertETHToToken(refundInEth, tokenDecimals, tokenPriceInEth).toHexString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates relayer fee in selected currency (ETH, DAI, BNB etc) in WEI
|
||||||
|
* @param {number | string} relayerFeePercent Relayer percent (0.4 for ETH Mainnet, for example)
|
||||||
|
* @param {HexadecimalStringifiedNumber | number} amount Amount in selected currency (10 for 10 ETH, 1000 for 1000 DAI)
|
||||||
|
* @param {string | number} decimals Decimal places in selected token (currency)
|
||||||
|
* @returns {HexadecimalStringifiedNumber} Fee in WEI (hexed stingified number)
|
||||||
|
*/
|
||||||
|
calculateRelayerFeeInWei(
|
||||||
|
relayerFeePercent: number | string,
|
||||||
|
amount: HexadecimalStringifiedNumber | number,
|
||||||
|
decimals: string | number,
|
||||||
|
): HexadecimalStringifiedNumber {
|
||||||
|
return parseUnits(amount.toString(), decimals)
|
||||||
|
.mul(`${Math.floor(Number(relayerFeePercent) * 1e10)}`)
|
||||||
|
.div(`${100 * 1e10}`)
|
||||||
|
.toHexString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Estimates fee for withdrawal via relayer depending on type: gas bump percent is bigger, if it calculates by user,
|
* Estimates fee for withdrawal via relayer depending on type: gas bump percent is bigger, if it calculates by user,
|
||||||
* so that the real commission from the relayer side is a little less,
|
* so that the real commission from the relayer side is a little less,
|
||||||
* in order to the relayer can send a transaction without fear that he will go into the red
|
* in order to the relayer can send a transaction without fear that he will go into the red
|
||||||
* @param {TxType} type Tornado transaction type: withdrawal costs calculation from user side or from relayer side
|
* @param {GetWithdrawalFeeViaRelayerInput} params Function input arguments object
|
||||||
* @param {TransactionData} tx Transaction data (object in web3 / ethers format)
|
* @param {TxType} params.type Tornado transaction type: withdrawal costs calculation from user side or from relayer side
|
||||||
* @param {number} relayerFeePercent Relayer fee percent from the transaction amount (for example, 0.15 for BNB or 0.4 for ETH Mainnet)
|
* @param {TransactionData} [params.tx] Transaction data (object in web3 / ethers format)
|
||||||
* @param {AvailableTokenSymbols | Uppercase<AvailableTokenSymbols>} currency Currency symbol
|
* @param {number} params.relayerFeePercent Relayer fee percent from the transaction amount (for example, 0.15 for BNB or 0.4 for ETH Mainnet)
|
||||||
* @param {number | HexadecimalStringifiedNumber } amount Withdrawal amount in selected currency
|
* @param {AvailableTokenSymbols | Uppercase<AvailableTokenSymbols>} params.currency Currency symbol
|
||||||
* @param {number | HexadecimalStringifiedNumber } decimals Token (currency) decimals
|
* @param {number | HexadecimalStringifiedNumber } params.amount Withdrawal amount in selected currency
|
||||||
* @param {BigNumberish} [refundInEth=0] Refund in ETH, if withdrawed other tokens on Mainnet (not ETH)
|
* @param {number | HexadecimalStringifiedNumber } params.decimals Token (currency) decimals
|
||||||
* @param {BigNumberish} [tokenPriceInEth] If withdrawing other token on Mainnet or Goerli, need to provide token price in ETH (in WEI)
|
* @param {BigNumberish} [params.refundInEth=0] Refund in ETH, if withdrawed other tokens on Mainnet (not ETH)
|
||||||
|
* @param {BigNumberish} [params.tokenPriceInEth] If withdrawing other token on Mainnet or Goerli, need to provide token price in ETH (in WEI)
|
||||||
|
* @param {number} [params.gasLimit] Predefined gas limit, if already calculated (no refetching)
|
||||||
|
* @param {number} [params.gasPrice] Predefined gas price, if already calculated (no refetching)
|
||||||
|
*
|
||||||
* @returns {Promise<HexadecimalStringifiedNumber>} Fee in WEI (hexed string)
|
* @returns {Promise<HexadecimalStringifiedNumber>} Fee in WEI (hexed string)
|
||||||
*/
|
*/
|
||||||
async calculateWithdrawalFeeViaRelayer(
|
async calculateWithdrawalFeeViaRelayer(
|
||||||
type: TxType,
|
params: GetWithdrawalFeeViaRelayerInput,
|
||||||
tx: TransactionData,
|
|
||||||
relayerFeePercent: number,
|
|
||||||
currency: AvailableTokenSymbols | Uppercase<AvailableTokenSymbols>,
|
|
||||||
amount: HexadecimalStringifiedNumber | number,
|
|
||||||
decimals: HexadecimalStringifiedNumber | number,
|
|
||||||
refundInEth: BigNumberish = 0,
|
|
||||||
tokenPriceInEth?: BigNumberish,
|
|
||||||
): Promise<HexadecimalStringifiedNumber> {
|
): Promise<HexadecimalStringifiedNumber> {
|
||||||
const gasCosts = BigNumber.from(await this.getGas(tx, type));
|
let {
|
||||||
|
tx,
|
||||||
|
txType,
|
||||||
|
relayerFeePercent,
|
||||||
|
currency,
|
||||||
|
amount,
|
||||||
|
decimals,
|
||||||
|
refundInEth = 0,
|
||||||
|
tokenPriceInEth,
|
||||||
|
gasLimit,
|
||||||
|
gasPrice,
|
||||||
|
} = params;
|
||||||
|
|
||||||
const relayerFee = parseUnits(amount.toString(), decimals)
|
const relayerFee = this.calculateRelayerFeeInWei(relayerFeePercent, amount, decimals);
|
||||||
.mul(`${Math.floor(relayerFeePercent * 1e10)}`)
|
const gasCosts = await this.getGas({ tx, txType, predefinedGasLimit: gasLimit, predefinedGasPrice: gasPrice });
|
||||||
.div(`${100 * 1e10}`);
|
|
||||||
|
|
||||||
if ((this.chainId === ChainId.MAINNET || this.chainId === ChainId.GOERLI) && currency.toLowerCase() != 'eth') {
|
if ((this.chainId === ChainId.MAINNET || this.chainId === ChainId.GOERLI) && currency.toLowerCase() != 'eth') {
|
||||||
if (!tokenPriceInEth) {
|
if (!tokenPriceInEth) {
|
||||||
@ -200,10 +256,10 @@ export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
|||||||
return '0';
|
return '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
const feeInEth = gasCosts.add(refundInEth);
|
const feeInEth = BigNumber.from(gasCosts).add(refundInEth);
|
||||||
return convertETHToToken(feeInEth, decimals, tokenPriceInEth).add(relayerFee).toHexString();
|
return convertETHToToken(feeInEth, decimals, tokenPriceInEth).add(relayerFee).toHexString();
|
||||||
}
|
}
|
||||||
|
|
||||||
return gasCosts.add(relayerFee).toHexString();
|
return BigNumber.from(gasCosts).add(relayerFee).toHexString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ export class TornadoFeeOracleV4 extends TornadoFeeOracle implements ITornadoFeeO
|
|||||||
// For compatibility reasons, when wee check user-provided fee for V4 withdrawal transaction, we need dump gas limit
|
// For compatibility reasons, when wee check user-provided fee for V4 withdrawal transaction, we need dump gas limit
|
||||||
// for about 20 percent,so that the transaction will be sent, even if it results in some loss for the relayer
|
// for about 20 percent,so that the transaction will be sent, even if it results in some loss for the relayer
|
||||||
if (type === 'relayer_withdrawal_check_v4') return bump(defaultWithdrawalGasLimit[this.chainId], -25).toNumber();
|
if (type === 'relayer_withdrawal_check_v4') return bump(defaultWithdrawalGasLimit[this.chainId], -25).toNumber();
|
||||||
if (!tx || Object.keys(tx).length === 0) return bump(21_000, bumpPercent).toNumber();
|
if (!tx || Object.keys(tx).length === 0) return bump(23_000, bumpPercent).toNumber();
|
||||||
|
|
||||||
return bump(await this.provider.estimateGas(tx), bumpPercent).toNumber();
|
return bump(await this.provider.estimateGas(tx), bumpPercent).toNumber();
|
||||||
}
|
}
|
||||||
|
68
src/types.ts
68
src/types.ts
@ -18,7 +18,8 @@ export type LegacyGasPrices = {
|
|||||||
- 'relayer_withdrawal_check_v4' - Fee calculation on relayer side, when V4 relayer checks user-provided fee. For compatibility reasons
|
- 'relayer_withdrawal_check_v4' - Fee calculation on relayer side, when V4 relayer checks user-provided fee. For compatibility reasons
|
||||||
- 'other' - Any other non-specific transaction
|
- 'other' - Any other non-specific transaction
|
||||||
*/
|
*/
|
||||||
export type TxType = 'user_withdrawal' | 'relayer_withdrawal' | 'relayer_withdrawal_check_v4' | 'other';
|
export type WithdrawalTxType = 'user_withdrawal' | 'relayer_withdrawal' | 'relayer_withdrawal_check_v4';
|
||||||
|
export type TxType = WithdrawalTxType | 'other';
|
||||||
|
|
||||||
export interface TransactionData {
|
export interface TransactionData {
|
||||||
to: string;
|
to: string;
|
||||||
@ -35,40 +36,21 @@ export interface TransactionData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ITornadoFeeOracle {
|
export interface ITornadoFeeOracle {
|
||||||
getGasParams: (
|
getGasParams: (params?: GetGasParamsInput) => Promise<GetGasParamsRes>;
|
||||||
tx?: TransactionData,
|
getGas: (params?: GetGasInput) => Promise<HexadecimalStringifiedNumber>;
|
||||||
txType?: TxType,
|
|
||||||
bumpGasLimitPercent?: number,
|
|
||||||
bumpGasPricePercent?: number,
|
|
||||||
speed?: LegacyGasPriceKey,
|
|
||||||
) => Promise<GetGasParamsRes>;
|
|
||||||
getGas: (
|
|
||||||
tx?: TransactionData,
|
|
||||||
type?: TxType,
|
|
||||||
bumpGasLimitPercent?: number,
|
|
||||||
bumpGasPricePercent?: number,
|
|
||||||
speed?: LegacyGasPriceKey,
|
|
||||||
) => Promise<HexadecimalStringifiedNumber>;
|
|
||||||
getGasPriceParams: (speed?: LegacyGasPriceKey, bumpPercent?: number) => Promise<GasPriceParams>;
|
getGasPriceParams: (speed?: LegacyGasPriceKey, bumpPercent?: number) => Promise<GasPriceParams>;
|
||||||
getGasPrice: (speed?: LegacyGasPriceKey, bumpPercent?: number) => Promise<HexadecimalStringifiedNumber>;
|
getGasPrice: (speed?: LegacyGasPriceKey, bumpPercent?: number) => Promise<HexadecimalStringifiedNumber>;
|
||||||
getGasLimit: (tx?: TransactionData, type?: TxType, bumpPercent?: number) => Promise<number>;
|
getGasLimit: (tx?: TransactionData, type?: TxType, bumpPercent?: number) => Promise<number>;
|
||||||
fetchL1OptimismFee: (tx?: TransactionData) => Promise<HexadecimalStringifiedNumber>;
|
fetchL1OptimismFee: (tx?: TransactionData) => Promise<HexadecimalStringifiedNumber>;
|
||||||
calculateRefundInETH: (tokenSymbol: InstanceTokenSymbol) => Promise<HexadecimalStringifiedNumber>;
|
calculateRefundInETH: (gasPrice: BigNumberish, tokenSymbol: InstanceTokenSymbol) => HexadecimalStringifiedNumber;
|
||||||
|
fetchRefundInETH: (tokenSymbol: InstanceTokenSymbol) => Promise<HexadecimalStringifiedNumber>;
|
||||||
calculateRefundInToken: (
|
calculateRefundInToken: (
|
||||||
|
gasPrice: BigNumberish,
|
||||||
tokenPriceInEth: BigNumberish,
|
tokenPriceInEth: BigNumberish,
|
||||||
tokenDecimals: HexadecimalStringifiedNumber | number,
|
tokenDecimals: HexadecimalStringifiedNumber | number,
|
||||||
tokenSymbol: InstanceTokenSymbol,
|
tokenSymbol: InstanceTokenSymbol,
|
||||||
) => Promise<HexadecimalStringifiedNumber>;
|
) => HexadecimalStringifiedNumber;
|
||||||
calculateWithdrawalFeeViaRelayer: (
|
calculateWithdrawalFeeViaRelayer: (params: GetWithdrawalFeeViaRelayerInput) => Promise<HexadecimalStringifiedNumber>;
|
||||||
type: TxType,
|
|
||||||
tx: TransactionData,
|
|
||||||
relayerFeePercent: number,
|
|
||||||
currency: AvailableTokenSymbols,
|
|
||||||
amount: HexadecimalStringifiedNumber | number,
|
|
||||||
decimals: number,
|
|
||||||
refundInEth: BigNumberish,
|
|
||||||
tokenPriceInEth?: BigNumberish,
|
|
||||||
) => Promise<HexadecimalStringifiedNumber>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITornadoPriceOracle {
|
export interface ITornadoPriceOracle {
|
||||||
@ -99,6 +81,34 @@ export type TokenPrices = { [tokenSymbol in TokenSymbol]?: BigNumberish };
|
|||||||
// Reponse type for getGasParams function of fee oracle
|
// Reponse type for getGasParams function of fee oracle
|
||||||
export type GetGasParamsRes = {
|
export type GetGasParamsRes = {
|
||||||
gasLimit: number;
|
gasLimit: number;
|
||||||
gasPrice: HexadecimalStringifiedNumber;
|
gasPrice: HexadecimalStringifiedNumber; // Gas price in native currency
|
||||||
l1Fee: HexadecimalStringifiedNumber;
|
};
|
||||||
|
|
||||||
|
export type GetGasInput = {
|
||||||
|
// Transaction type: user-side calculation, relayer-side calculation or
|
||||||
|
// relayer calculation to check user-provided fee in old V4 relayer (for backwards compatibility)
|
||||||
|
txType?: TxType;
|
||||||
|
tx?: TransactionData; // Transaction data in ethers format
|
||||||
|
predefinedGasPrice?: HexadecimalStringifiedNumber; // Predefined gas price for withdrawal tx (wont be calculated again in function)
|
||||||
|
predefinedGasLimit?: number; // Predefined gas limit for withdrawal tx (wont be calculated again in function)
|
||||||
|
bumpGasLimitPercent?: number; // Gas limit bump percent to prioritize transaction (recenlty used)
|
||||||
|
bumpGasPricePercent?: number; // Gas price bump percent to prioritize transaction (rarely used)
|
||||||
|
speed?: LegacyGasPriceKey; // Preferred transaction speed, if uses legacy gas (before EIP-1559)
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GetGasParamsInput = GetGasInput & { includeL1FeeToGasLimit?: boolean };
|
||||||
|
|
||||||
|
export type GetWithdrawalFeeViaRelayerInput = {
|
||||||
|
// Transaction type: user-side calculation, relayer-side calculation or
|
||||||
|
// relayer calculation to check user-provided fee in old V4 relayer (for backwards compatibility)
|
||||||
|
txType: WithdrawalTxType;
|
||||||
|
tx?: TransactionData; // Transaction data in ethers format
|
||||||
|
relayerFeePercent: number | string; // Relayer fee percent from withdrawal amount (for example, 0.15 for BNB or 0.4 for ETH Mainnet)
|
||||||
|
currency: AvailableTokenSymbols | Uppercase<AvailableTokenSymbols>; // Currency (token) symbol
|
||||||
|
amount: string | number; // Withdrawal amount in selected currency (10 for 10 ETH, 10000 for 10000 DAI)
|
||||||
|
decimals: string | number; // Token (currency) decimal places
|
||||||
|
refundInEth?: HexadecimalStringifiedNumber; // Refund amount in ETH, if withdrawing non-native currency on ETH Mainnet or Goerli
|
||||||
|
tokenPriceInEth?: HexadecimalStringifiedNumber | string; // Token (currency) price in ETH wei, if withdrawing non-native currency
|
||||||
|
gasPrice?: HexadecimalStringifiedNumber; // Predefined gas price for withdrawal tx (wont be calculated again in function)
|
||||||
|
gasLimit?: number; // Predefined gas limit for withdrawal tx (wont be calculated again in function)
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user