Compare commits
2 Commits
0aa15627f4
...
3c1352ea41
Author | SHA1 | Date | |
---|---|---|---|
3c1352ea41 | |||
1ace796f8a |
@ -1 +1,8 @@
|
|||||||
|
abis
|
||||||
lib
|
lib
|
||||||
|
README.md
|
||||||
|
src/contracts
|
||||||
|
node_modules
|
||||||
|
.prettierrc
|
||||||
|
tsconfig.*
|
||||||
|
package.json
|
@ -51,7 +51,7 @@ 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.getGasPriceInHex(transactionType);
|
const gasPrice = await feeOracle.getGasPrice(transactionType);
|
||||||
const gasLimit = await feeOracle.getGasLimit(incompleteTx, transactionType);
|
const gasLimit = await feeOracle.getGasLimit(incompleteTx, transactionType);
|
||||||
|
|
||||||
const tx: TransactionData = Object.assign({ gasPrice, gasLimit }, incompleteTx);
|
const tx: TransactionData = Object.assign({ gasPrice, gasLimit }, incompleteTx);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@tornado/tornado-oracles",
|
"name": "@tornado/tornado-oracles",
|
||||||
"version": "0.3.0",
|
"version": "1.0.0",
|
||||||
"description": "Gas oracle for Tornado-specific transactions",
|
"description": "Gas oracle for Tornado-specific transactions",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
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 { parseUnits } from 'ethers/lib/utils';
|
import { parseUnits } from 'ethers/lib/utils';
|
||||||
import { TransactionData, TxType, ITornadoFeeOracle, GasPrice, LegacyGasPriceKey } from './types';
|
import { TransactionData, TxType, ITornadoFeeOracle, LegacyGasPriceKey, GasPriceParams } from './types';
|
||||||
import { JsonRpcProvider } from '@ethersproject/providers';
|
import { JsonRpcProvider } from '@ethersproject/providers';
|
||||||
import { ChainId, defaultGasPrices } from './config';
|
import { ChainId, defaultGasPrices } from './config';
|
||||||
import { bump, calculateGasPriceInWei, convertETHToToken, fromGweiToWeiHex, serializeTx } from './utils';
|
import { bump, calculateGasPriceInWei, convertETHToToken, fromGweiToWeiHex, serializeTx } from './utils';
|
||||||
@ -36,23 +36,23 @@ export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
|||||||
/**
|
/**
|
||||||
* 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 {TransactionData} tx Transaction data in web3 / ethers format
|
||||||
* @param {TxType} type Tornado transaction type: withdrawal by user, withdrawal by relayer or 'other'
|
* @param {TxType} txType Tornado transaction type: withdrawal by user, withdrawal by relayer or 'other'
|
||||||
* @param {LegacyGasPriceKey} speed Preferred transaction speed, if uses legacy gas (before EIP-1559)
|
* @param {LegacyGasPriceKey} speed Preferred transaction speed, if uses legacy gas (before EIP-1559)
|
||||||
* @returns {Promise<string>} Gas value in WEI (hex-format)
|
* @returns {Promise<string>} Gas value in WEI (hex-format)
|
||||||
*/
|
*/
|
||||||
public async getGas(
|
public async getGas(
|
||||||
tx?: TransactionData,
|
tx?: TransactionData,
|
||||||
type: TxType = 'other',
|
txType: TxType = 'other',
|
||||||
speed: LegacyGasPriceKey = 'fast',
|
speed: LegacyGasPriceKey = 'fast',
|
||||||
): Promise<BigNumber> {
|
): Promise<string> {
|
||||||
const gasPrice = await this.getGasPriceInHex(type, speed);
|
const gasPrice = await this.getGasPrice(txType, speed);
|
||||||
let gas = BigNumber.from(0);
|
let gas = BigNumber.from(0);
|
||||||
gas = gas.add(gasPrice);
|
gas = gas.add(gasPrice);
|
||||||
if (tx) tx = Object.assign(tx, { gasPrice });
|
if (tx) tx = Object.assign(tx, { gasPrice });
|
||||||
gas = gas.mul(await this.getGasLimit(tx, type));
|
gas = gas.mul(await this.getGasLimit(tx, txType));
|
||||||
if (this.chainId === ChainId.OPTIMISM) gas = gas.add(await this.fetchL1OptimismFee(tx));
|
if (this.chainId === ChainId.OPTIMISM) gas = gas.add(await this.fetchL1OptimismFee(tx));
|
||||||
|
|
||||||
return gas;
|
return gas.toHexString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,18 +60,18 @@ export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
|||||||
* @param {TxType} type Tornado transaction type (to select correct default bump percent)
|
* @param {TxType} type Tornado transaction type (to select correct default bump percent)
|
||||||
* @param {LegacyGasPriceKey} speed Preferred transaction speed, if uses legacy gas (before EIP-1559)
|
* @param {LegacyGasPriceKey} speed Preferred transaction speed, if uses legacy gas (before EIP-1559)
|
||||||
* @param {number} bumpPercent Gas bump percent to prioritize transaction
|
* @param {number} bumpPercent Gas bump percent to prioritize transaction
|
||||||
* @returns {Promise<GasPrice>} Estimated gas price info in WEI (hexed) - legacy object with gasPrice property or EIP-1559 object with maxFeePerGas
|
* @returns {Promise<GasPriceParams>} Estimated gas price info in WEI (hexed) - legacy object with gasPrice property or
|
||||||
* and maxPriorityFeePerGas properties
|
* EIP-1559 object with maxFeePerGas and maxPriorityFeePerGas properties
|
||||||
*/
|
*/
|
||||||
async getGasPrice(
|
async getGasPriceParams(
|
||||||
type: TxType = 'other',
|
type: TxType = 'other',
|
||||||
speed: LegacyGasPriceKey = 'fast',
|
speed: LegacyGasPriceKey = 'fast',
|
||||||
bumpPercent: number = 0,
|
bumpPercent: number = 0,
|
||||||
): Promise<GasPrice> {
|
): Promise<GasPriceParams> {
|
||||||
try {
|
try {
|
||||||
return await this.oracle.getTxGasParams({ legacySpeed: speed, bumpPercent });
|
return await this.oracle.getTxGasParams({ legacySpeed: speed, bumpPercent });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return { gasPrice: bump(fromGweiToWeiHex(defaultGasPrices[this.chainId][speed]), bumpPercent) };
|
return { gasPrice: bump(fromGweiToWeiHex(defaultGasPrices[this.chainId][speed]), bumpPercent).toHexString() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,22 +82,22 @@ export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
|||||||
* @param {number} bumpPercent Gas bump percent to prioritize transaction
|
* @param {number} bumpPercent Gas bump percent to prioritize transaction
|
||||||
* @returns {Promise<string>} Gas price in WEI (hex string)
|
* @returns {Promise<string>} Gas price in WEI (hex string)
|
||||||
*/
|
*/
|
||||||
async getGasPriceInHex(
|
async getGasPrice(
|
||||||
type: TxType = 'other',
|
type: TxType = 'other',
|
||||||
speed: LegacyGasPriceKey = 'fast',
|
speed: LegacyGasPriceKey = 'fast',
|
||||||
bumpPercent: number = 0,
|
bumpPercent: number = 0,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const gasPrice = await this.getGasPrice(type, speed, bumpPercent);
|
const gasPriceParams = await this.getGasPriceParams(type, speed, bumpPercent);
|
||||||
return calculateGasPriceInWei(gasPrice).toHexString();
|
return calculateGasPriceInWei(gasPriceParams).toHexString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Estimates gas limit for transaction (or basic gas limit, if no tx data provided)
|
* Estimates gas limit for transaction (or basic gas limit, if no tx data provided)
|
||||||
* @param {TransactionData} tx Transaction data (object in web3 / ethers format)
|
* @param {TransactionData} tx Transaction data (object in web3 / ethers format)
|
||||||
* @param {TxType} type Tornado transaction type: withdrawal by user, withdrawal by relayer, relayer fee check or 'other'
|
* @param {TxType} type Tornado transaction type: withdrawal by user, withdrawal by relayer, relayer fee check or 'other'
|
||||||
* @returns {Promise<BigNumber>} Gas limit
|
* @returns {Promise<number>} Gas limit
|
||||||
*/
|
*/
|
||||||
abstract getGasLimit(tx?: TransactionData, type?: TxType): Promise<BigNumber>;
|
abstract getGasLimit(tx?: TransactionData, type?: TxType): Promise<number>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If user withdraw non-native tokens on ETH or Goerli, we need to calculate refund value:
|
* If user withdraw non-native tokens on ETH or Goerli, we need to calculate refund value:
|
||||||
@ -106,11 +106,12 @@ export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
|||||||
*
|
*
|
||||||
* 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 {TransactionData} [tx] Transaction data (object in web3 / ethers format)
|
* @param {TransactionData} [tx] Transaction data (object in web3 / ethers format)
|
||||||
* @param {TxType} [type] Tornado transaction type: withdrawal by user, withdrawal by relayer, relayer fee check or 'other'
|
* @returns {Promise<string>} Refund amount in WEI (hexed number)
|
||||||
* @returns {Promise<BigNumber>} Refund amount in WEI
|
|
||||||
*/
|
*/
|
||||||
async calculateRefundInETH(tx?: TransactionData, type?: TxType): Promise<BigNumber> {
|
async calculateRefundInETH(tx?: TransactionData): Promise<string> {
|
||||||
return (await this.getGas(tx, type)).mul(2);
|
// In Tornado we need to calculate refund only on user side, relayer get refund value in proof
|
||||||
|
const gas = await this.getGas(tx, 'user_withdrawal');
|
||||||
|
return BigNumber.from(gas).mul(2).toHexString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,17 +119,15 @@ export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
|||||||
* @param {BigNumberish} tokenPriceInEth Token price in WEI in native currency
|
* @param {BigNumberish} tokenPriceInEth Token price in WEI in native currency
|
||||||
* @param {string | number} tokenDecimals Token (currency) decimals
|
* @param {string | number} tokenDecimals Token (currency) decimals
|
||||||
* @param {TransactionData} [tx] Transaction data (object in web3 / ethers format)
|
* @param {TransactionData} [tx] Transaction data (object in web3 / ethers format)
|
||||||
* @param {TxType} [type] Tornado transaction type: withdrawal by user, withdrawal by relayer, relayer fee check or 'other'
|
* @returns {Promise<string>} Refund amount in WEI in selected token (hexed number)
|
||||||
* @returns {Promise<BigNumber>} Refund amount in WEI in selected token
|
|
||||||
*/
|
*/
|
||||||
async calculateRefundInToken(
|
async calculateRefundInToken(
|
||||||
tokenPriceInEth: BigNumberish,
|
tokenPriceInEth: BigNumberish,
|
||||||
tokenDecimals: string | number,
|
tokenDecimals: string | number,
|
||||||
tx?: TransactionData,
|
tx?: TransactionData,
|
||||||
type?: TxType,
|
): Promise<string> {
|
||||||
): Promise<BigNumber> {
|
const refundInEth = await this.calculateRefundInETH(tx);
|
||||||
const refundInEth = await this.calculateRefundInETH(tx, type);
|
return convertETHToToken(refundInEth, tokenDecimals, tokenPriceInEth).toHexString();
|
||||||
return convertETHToToken(refundInEth, tokenDecimals, tokenPriceInEth);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -143,7 +142,7 @@ export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
|||||||
* @param {number | string } decimals Token (currency) decimals
|
* @param {number | string } decimals Token (currency) decimals
|
||||||
* @param {BigNumberish} [refund=0] Refund in ETH, if withdrawed other tokens on Mainnet (not ETH)
|
* @param {BigNumberish} [refund=0] Refund in ETH, if withdrawed other tokens on Mainnet (not ETH)
|
||||||
* @param {BigNumberish} [tokenPriceInEth] If withdrawing other token on Mainnet or Goerli, need to provide token price in ETH (in WEI)
|
* @param {BigNumberish} [tokenPriceInEth] If withdrawing other token on Mainnet or Goerli, need to provide token price in ETH (in WEI)
|
||||||
* @returns {Promise<BigNumber>} Fee in WEI
|
* @returns {Promise<string>} Fee in WEI (hexed string)
|
||||||
*/
|
*/
|
||||||
async calculateWithdrawalFeeViaRelayer(
|
async calculateWithdrawalFeeViaRelayer(
|
||||||
type: TxType,
|
type: TxType,
|
||||||
@ -154,8 +153,8 @@ export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
|||||||
decimals: string | number,
|
decimals: string | number,
|
||||||
refund: BigNumberish = 0,
|
refund: BigNumberish = 0,
|
||||||
tokenPriceInEth?: BigNumberish,
|
tokenPriceInEth?: BigNumberish,
|
||||||
): Promise<BigNumber> {
|
): Promise<string> {
|
||||||
const gasCosts = await this.getGas(tx, type);
|
const gasCosts = BigNumber.from(await this.getGas(tx, type));
|
||||||
|
|
||||||
const relayerFee = parseUnits(amount.toString(), decimals)
|
const relayerFee = parseUnits(amount.toString(), decimals)
|
||||||
.mul(`${relayerFeePercent * 1e10}`)
|
.mul(`${relayerFeePercent * 1e10}`)
|
||||||
@ -164,13 +163,13 @@ export abstract class TornadoFeeOracle implements ITornadoFeeOracle {
|
|||||||
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) {
|
||||||
console.error('Token price is required argument, if not native chain token is withdrawed');
|
console.error('Token price is required argument, if not native chain token is withdrawed');
|
||||||
return BigNumber.from(0);
|
return '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
const feeInEth = gasCosts.add(refund);
|
const feeInEth = gasCosts.add(refund);
|
||||||
return convertETHToToken(feeInEth, decimals, tokenPriceInEth).add(relayerFee);
|
return convertETHToToken(feeInEth, decimals, tokenPriceInEth).add(relayerFee).toHexString();
|
||||||
}
|
}
|
||||||
|
|
||||||
return gasCosts.add(relayerFee);
|
return gasCosts.add(relayerFee).toHexString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,17 +17,18 @@ export class TornadoFeeOracleV4 extends TornadoFeeOracle implements ITornadoFeeO
|
|||||||
super(chainId, rpcUrl, gasPriceOracle);
|
super(chainId, rpcUrl, gasPriceOracle);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getGasLimit(tx?: TransactionData, type: TxType = 'other', bumpPercent?: number): Promise<BigNumber> {
|
async getGasLimit(tx?: TransactionData, type: TxType = 'other', bumpPercent?: number): Promise<number> {
|
||||||
if (type === 'user_withdrawal') return BigNumber.from(defaultWithdrawalGasLimit[this.chainId]);
|
if (type === 'user_withdrawal') return BigNumber.from(defaultWithdrawalGasLimit[this.chainId]).toNumber();
|
||||||
|
|
||||||
// Need to bump relayer gas limit for transaction, because predefined gas limit to small to be 100% sure that transaction will be sent
|
// Need to bump relayer gas limit for transaction, because predefined gas limit to small to be 100% sure that transaction will be sent
|
||||||
// This leads to fact that relayer often pays extra for gas from his own funds, however, this was designed by previous developers
|
// This leads to fact that relayer often pays extra for gas from his own funds, however, this was designed by previous developers
|
||||||
if (type === 'relayer_withdrawal') return bump(defaultWithdrawalGasLimit[this.chainId], bumpPercent || 25);
|
if (type === 'relayer_withdrawal')
|
||||||
|
return bump(defaultWithdrawalGasLimit[this.chainId], bumpPercent || 25).toNumber();
|
||||||
// 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);
|
if (type === 'relayer_withdrawal_check_v4') return bump(defaultWithdrawalGasLimit[this.chainId], -25).toNumber();
|
||||||
if (!tx) return BigNumber.from(21_000);
|
if (!tx) return 21_000;
|
||||||
|
|
||||||
return this.provider.estimateGas(tx);
|
return (await this.provider.estimateGas(tx)).toNumber();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
import { ChainId, defaultWithdrawalGasLimit } from './config';
|
import { ChainId } from './config';
|
||||||
import { TornadoFeeOracle } from './feeOracle';
|
import { TornadoFeeOracle } from './feeOracle';
|
||||||
import { ITornadoFeeOracle, GasPrice, TransactionData, TxType, LegacyGasPrices, LegacyGasPriceKey } from './types';
|
import {
|
||||||
|
ITornadoFeeOracle,
|
||||||
|
TransactionData,
|
||||||
|
TxType,
|
||||||
|
LegacyGasPrices,
|
||||||
|
LegacyGasPriceKey,
|
||||||
|
GasPriceParams,
|
||||||
|
} from './types';
|
||||||
import { GasPriceOracle } from '@tornado/gas-price-oracle';
|
import { GasPriceOracle } from '@tornado/gas-price-oracle';
|
||||||
import { BigNumber } from 'ethers';
|
|
||||||
import { bump } from './utils';
|
import { bump } from './utils';
|
||||||
import { TornadoFeeOracleV4 } from './feeOracleV4';
|
import { TornadoFeeOracleV4 } from './feeOracleV4';
|
||||||
|
|
||||||
@ -25,7 +31,7 @@ export class TornadoFeeOracleV5 extends TornadoFeeOracle implements ITornadoFeeO
|
|||||||
this.fallbackFeeOracle = new TornadoFeeOracleV4(chainId, rpcUrl, defaultGasPrices);
|
this.fallbackFeeOracle = new TornadoFeeOracleV4(chainId, rpcUrl, defaultGasPrices);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getGasLimit(tx?: TransactionData, type: TxType = 'other', bumpPercent: number = 20): Promise<BigNumber> {
|
async getGasLimit(tx?: TransactionData, type: TxType = 'other', bumpPercent: number = 20): Promise<number> {
|
||||||
if (!tx || Object.keys(tx).length === 0) return this.fallbackFeeOracle.getGasLimit(tx, type, bumpPercent);
|
if (!tx || Object.keys(tx).length === 0) return this.fallbackFeeOracle.getGasLimit(tx, type, bumpPercent);
|
||||||
|
|
||||||
/* Relayer gas limit must be lower so that fluctuations in gas price cannot lead to the fact that
|
/* Relayer gas limit must be lower so that fluctuations in gas price cannot lead to the fact that
|
||||||
@ -37,18 +43,17 @@ export class TornadoFeeOracleV5 extends TornadoFeeOracle implements ITornadoFeeO
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const fetchedGasLimit = await this.provider.estimateGas(tx);
|
const fetchedGasLimit = await this.provider.estimateGas(tx);
|
||||||
return bump(fetchedGasLimit, bumpPercent);
|
return bump(fetchedGasLimit, bumpPercent).toNumber();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (type.endsWith('withdrawal')) return bump(defaultWithdrawalGasLimit[this.chainId], bumpPercent);
|
return this.fallbackFeeOracle.getGasLimit(tx, type, bumpPercent);
|
||||||
return BigNumber.from(21_000);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getGasPrice(
|
async getGasPriceParams(
|
||||||
type: TxType = 'other',
|
type: TxType = 'other',
|
||||||
speed: LegacyGasPriceKey = 'fast',
|
speed: LegacyGasPriceKey = 'fast',
|
||||||
bumpPercent?: number,
|
bumpPercent?: number,
|
||||||
): Promise<GasPrice> {
|
): Promise<GasPriceParams> {
|
||||||
// Only if bump percent didn't provided (if user provides 0, no need to recalculate)
|
// Only if bump percent didn't provided (if user provides 0, no need to recalculate)
|
||||||
if (bumpPercent === undefined) {
|
if (bumpPercent === undefined) {
|
||||||
switch (this.chainId) {
|
switch (this.chainId) {
|
||||||
@ -65,6 +70,6 @@ export class TornadoFeeOracleV5 extends TornadoFeeOracle implements ITornadoFeeO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getGasPrice(type, speed, bumpPercent);
|
return super.getGasPriceParams(type, speed, bumpPercent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
import { bump } from './utils';
|
|
||||||
|
|
||||||
export * from './feeOracleV4';
|
export * from './feeOracleV4';
|
||||||
export * from './feeOracleV5';
|
export * from './feeOracleV5';
|
||||||
export * from './tokenPriceOracle';
|
export * from './tokenPriceOracle';
|
||||||
export { bump };
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { MultiCall } from './contracts/MulticallAbi';
|
import { MultiCall } from './contracts/MulticallAbi';
|
||||||
import { Token, TokenPrices, TokenSymbol } from './types';
|
import { ITornadoPriceOracle, Token, TokenPrices, TokenSymbol } from './types';
|
||||||
import { MulticallAbi, OffchainOracleAbi } from './contracts';
|
import { MulticallAbi, OffchainOracleAbi } from './contracts';
|
||||||
import { getMultiCallContract, getOffchainOracleContract } from './contracts/factories';
|
import { getMultiCallContract, getOffchainOracleContract } from './contracts/factories';
|
||||||
import { Provider } from '@ethersproject/abstract-provider';
|
import { Provider } from '@ethersproject/abstract-provider';
|
||||||
@ -34,7 +34,7 @@ const defaultTornadoTokenPrices: TokenPrices = {
|
|||||||
wbtc: '15659889148334216720',
|
wbtc: '15659889148334216720',
|
||||||
};
|
};
|
||||||
|
|
||||||
export class TokenPriceOracle {
|
export class TokenPriceOracle implements ITornadoPriceOracle {
|
||||||
private oracle: OffchainOracleAbi;
|
private oracle: OffchainOracleAbi;
|
||||||
private multiCall: MulticallAbi;
|
private multiCall: MulticallAbi;
|
||||||
private provider: Provider;
|
private provider: Provider;
|
||||||
@ -64,7 +64,7 @@ export class TokenPriceOracle {
|
|||||||
* @param {Token[]} tokens Tokens array
|
* @param {Token[]} tokens Tokens array
|
||||||
* @returns Valid structure to provide to MultiCall contract
|
* @returns Valid structure to provide to MultiCall contract
|
||||||
*/
|
*/
|
||||||
prepareCallData(tokens: Token[] = this.tokens): MultiCall.CallStruct[] {
|
private prepareCallData(tokens: Token[] = this.tokens): MultiCall.CallStruct[] {
|
||||||
return tokens.map((token) => ({
|
return tokens.map((token) => ({
|
||||||
to: this.oracle.address,
|
to: this.oracle.address,
|
||||||
data: this.oracle.interface.encodeFunctionData('getRateToEth', [token.tokenAddress, true]),
|
data: this.oracle.interface.encodeFunctionData('getRateToEth', [token.tokenAddress, true]),
|
||||||
|
27
src/types.ts
27
src/types.ts
@ -1,10 +1,9 @@
|
|||||||
import { BigNumber, BigNumberish, BytesLike } from 'ethers';
|
import { BigNumberish, BytesLike } from 'ethers';
|
||||||
import { GasPriceKey } from '@tornado/gas-price-oracle/lib/services';
|
import { GasPriceKey, GetTxGasParamsRes } from '@tornado/gas-price-oracle/lib/services';
|
||||||
import { AvailableTokenSymbols } from '@tornado/tornado-config';
|
import { AvailableTokenSymbols } from '@tornado/tornado-config';
|
||||||
|
|
||||||
export type LegacyGasPriceKey = GasPriceKey;
|
export type LegacyGasPriceKey = GasPriceKey;
|
||||||
// Gas Prices in WEI
|
export type GasPriceParams = GetTxGasParamsRes;
|
||||||
export type GasPrice = { maxFeePerGas: BigNumberish; maxPriorityFeePerGas: BigNumberish } | { gasPrice: BigNumberish };
|
|
||||||
export type LegacyGasPrices = {
|
export type LegacyGasPrices = {
|
||||||
[gasPriceType in LegacyGasPriceKey]: number;
|
[gasPriceType in LegacyGasPriceKey]: number;
|
||||||
};
|
};
|
||||||
@ -32,17 +31,16 @@ export interface TransactionData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ITornadoFeeOracle {
|
export interface ITornadoFeeOracle {
|
||||||
getGas: (tx?: TransactionData, type?: TxType) => Promise<BigNumber>;
|
getGas: (tx?: TransactionData, type?: TxType) => Promise<string>;
|
||||||
getGasPrice: (type?: TxType, speed?: LegacyGasPriceKey, bumpPercent?: number) => Promise<GasPrice>;
|
getGasPriceParams: (type?: TxType, speed?: LegacyGasPriceKey, bumpPercent?: number) => Promise<GasPriceParams>;
|
||||||
getGasPriceInHex: (type?: TxType, speed?: LegacyGasPriceKey, bumpPercent?: number) => Promise<string>;
|
getGasPrice: (type?: TxType, speed?: LegacyGasPriceKey, bumpPercent?: number) => Promise<string>;
|
||||||
getGasLimit: (tx?: TransactionData, type?: TxType, bumpPercent?: number) => Promise<BigNumber>;
|
getGasLimit: (tx?: TransactionData, type?: TxType, bumpPercent?: number) => Promise<number>;
|
||||||
calculateRefundInETH: (tx?: TransactionData, type?: TxType) => Promise<BigNumber>;
|
calculateRefundInETH: (tx?: TransactionData) => Promise<string>;
|
||||||
calculateRefundInToken: (
|
calculateRefundInToken: (
|
||||||
tokenPriceInEth: BigNumberish,
|
tokenPriceInEth: BigNumberish,
|
||||||
tokenDecimals: string | number,
|
tokenDecimals: string | number,
|
||||||
tx?: TransactionData,
|
tx?: TransactionData,
|
||||||
type?: TxType,
|
) => Promise<string>;
|
||||||
) => Promise<BigNumber>;
|
|
||||||
calculateWithdrawalFeeViaRelayer: (
|
calculateWithdrawalFeeViaRelayer: (
|
||||||
type: TxType,
|
type: TxType,
|
||||||
tx: TransactionData,
|
tx: TransactionData,
|
||||||
@ -52,7 +50,12 @@ export interface ITornadoFeeOracle {
|
|||||||
decimals: number,
|
decimals: number,
|
||||||
refund: BigNumberish,
|
refund: BigNumberish,
|
||||||
tokenPriceInEth?: BigNumberish,
|
tokenPriceInEth?: BigNumberish,
|
||||||
) => Promise<BigNumber>;
|
) => Promise<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ITornadoPriceOracle {
|
||||||
|
defaultPrices: TokenPrices;
|
||||||
|
fetchPrices: (tokens?: Token[]) => Promise<TokenPrices>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WithdrawalData = {
|
export type WithdrawalData = {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { serialize } from '@ethersproject/transactions';
|
import { serialize } from '@ethersproject/transactions';
|
||||||
import { GasPrice, TransactionData } from './types';
|
import { GasPriceParams, TransactionData } from './types';
|
||||||
import { BigNumber, BigNumberish } from 'ethers';
|
import { BigNumber, BigNumberish } from 'ethers';
|
||||||
import BigNumberFloat from 'bignumber.js';
|
import BigNumberFloat from 'bignumber.js';
|
||||||
BigNumberFloat.config({ EXPONENTIAL_AT: 100 });
|
BigNumberFloat.config({ EXPONENTIAL_AT: 100 });
|
||||||
@ -13,7 +13,7 @@ export function serializeTx(tx?: TransactionData | string): string {
|
|||||||
return serialize(tx);
|
return serialize(tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function calculateGasPriceInWei(gasPrice: GasPrice): BigNumber {
|
export function calculateGasPriceInWei(gasPrice: GasPriceParams): BigNumber {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return BigNumber.from(gasPrice.gasPrice || gasPrice.maxFeePerGas);
|
return BigNumber.from(gasPrice.gasPrice || gasPrice.maxFeePerGas);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user