tornado-oracles/lib/esm/feeOracle.js

71 lines
4.5 KiB
JavaScript

import { Transaction, parseUnits } from 'ethers';
import { OptimismL1FeeOracle__factory } from './contracts';
import { getProvider } from './providers';
import { convertETHToTokenAmount } from './utils';
const DUMMY_ADDRESS = '0x1111111111111111111111111111111111111111';
const DUMMY_NONCE = '0x1111111111111111111111111111111111111111111111111111111111111111';
const DUMMY_WITHDRAW_DATA = '0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111';
export class TornadoFeeOracle {
constructor(netId, rpcUrl, config) {
const { optimismL1FeeOracleAddress } = config;
if (optimismL1FeeOracleAddress) {
const provider = getProvider(netId, rpcUrl, config);
this.optimismL1FeeOracle = OptimismL1FeeOracle__factory.connect(optimismL1FeeOracleAddress, provider);
}
}
/**
* Calculate L1 fee for op-stack chains
*
* This is required since relayers would pay the full transaction fees for users
*/
fetchL1OptimismFee(tx) {
if (!this.optimismL1FeeOracle) {
return new Promise((resolve) => resolve(BigInt(0)));
}
if (!tx) {
// this tx is only used to simulate bytes size of the encoded tx so has nothing to with the accuracy
// inspired by the old style classic-ui calculation
tx = {
type: 0,
gasLimit: 1000000,
nonce: Number(DUMMY_NONCE),
data: DUMMY_WITHDRAW_DATA,
gasPrice: parseUnits('1', 'gwei'),
from: DUMMY_ADDRESS,
to: DUMMY_ADDRESS,
};
}
return this.optimismL1FeeOracle.getL1Fee.staticCall(Transaction.from(tx).unsignedSerialized);
}
/**
* We don't need to distinguish default refunds by tokens since most users interact with other defi protocols after withdrawal
* So we default with 1M gas which is enough for two or three swaps
* Using 30 gwei for default but it is recommended to supply cached gasPrice value from the UI
*/
defaultEthRefund(gasPrice, gasLimit) {
return (gasPrice ? BigInt(gasPrice) : parseUnits('30', 'gwei')) * BigInt(gasLimit || 1000000);
}
/**
* Calculates token amount for required ethRefund purchases required to calculate fees
*/
calculateTokenAmount(ethRefund, tokenPriceInEth, tokenDecimals) {
return convertETHToTokenAmount(ethRefund, tokenPriceInEth, tokenDecimals);
}
/**
* Warning: For tokens you need to check if the fees are above denomination
* (Usually happens for small denomination pool or if the gas price is high)
*/
calculateRelayerFee({ gasPrice, gasLimit = 600000, l1Fee = 0, denomination, ethRefund = BigInt(0), tokenPriceInWei, tokenDecimals = 18, relayerFeePercent = 0.33, isEth = true, premiumPercent = 20, }) {
const gasCosts = BigInt(gasPrice) * BigInt(gasLimit) + BigInt(l1Fee);
const relayerFee = (BigInt(denomination) * BigInt(Math.floor(10000 * relayerFeePercent))) / BigInt(10000 * 100);
if (isEth) {
// Add 20% premium
return ((gasCosts + relayerFee) * BigInt(premiumPercent ? 100 + premiumPercent : 100)) / BigInt(100);
}
const feeInEth = gasCosts + BigInt(ethRefund);
return (((convertETHToTokenAmount(feeInEth, tokenPriceInWei, tokenDecimals) + relayerFee) *
BigInt(premiumPercent ? 100 + premiumPercent : 100)) /
BigInt(100));
}
}
//# sourceMappingURL=feeOracle.js.map