-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
wip: refactor fetches, typescript iteration
Signed-off-by: wildmolasses <[email protected]> Signed-off-by: Matt Solomon <[email protected]>
- Loading branch information
1 parent
2ddf0c3
commit d8f89bc
Showing
5 changed files
with
113 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
|
||
/** | ||
* @notice Estimates the fee (in base token units) for a bundle | ||
* @param token Token in which fee will be expressed as units of | ||
* @param transferUpperBound Given upper bound gas fee (in Gwei) for transfer | ||
* @param approveUpperBound Given upper bound gas fee (in Gwei) for approve | ||
* @param swapUpperBound Given upper bound gas fee (in Gwei) for swap | ||
* @param flashbotsAdjustment Multiplier for flashbots bribing miner. | ||
* | ||
* @returns Estimated fee for miner in token base units | ||
*/ | ||
export const estimateFee = async ( | ||
token: string, | ||
transferUpperBound: number, | ||
approveUpperBound: number, | ||
swapUpperBound: number, | ||
flashbotsAdjustment: number | ||
): Promise<number> => { | ||
// get current gas price | ||
const gasPriceInWei = await getGasPrice(); | ||
const { tokenPrice, ethPrice } = await getTokenAndEthPriceInUSD(token); | ||
|
||
const bundleGasUsed = transferUpperBound + approveUpperBound + swapUpperBound; | ||
const initiallyCalculatedFee = bundleGasUsed * gasPriceInWei; | ||
const bundleGasEtimateinWei = initiallyCalculatedFee * flashbotsAdjustment; | ||
const amountOfEthUsedInGas = bundleGasEtimateinWei / 1e18; | ||
const dollarsNeededForBribe = amountOfEthUsedInGas / ethPrice; | ||
const tokensNeededForBribe = dollarsNeededForBribe * tokenPrice; | ||
|
||
console.log(`token: ${token}`); | ||
console.log(`gas price in wei: ${gasPriceInWei}`); | ||
console.log(`token price and eth price: ${tokenPrice}, ${ethPrice}`); | ||
console.log(`Bundle gas used is: ${bundleGasUsed}`); | ||
console.log(`Initially Estimated fee in Wei is: ${initiallyCalculatedFee}`); | ||
console.log(`Estimated fee in Wei (after flashbots adjustment): ${bundleGasEtimateinWei}`); | ||
console.log(`Amount of Eth used in Gas: ${amountOfEthUsedInGas}`); | ||
console.log(`Amount of dollars needed for bribe: ${dollarsNeededForBribe}`); | ||
console.log(`Amount of tokens needed for bribe: ${tokensNeededForBribe}`); | ||
|
||
return bundleGasEtimateinWei; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,65 @@ | ||
import axios from 'axios'; | ||
import { GasNowSpeed, GasNowResponse } from './types'; | ||
import { BigNumber } from '@ethersproject/bignumber'; | ||
|
||
/** | ||
* @notice Gets the current gas price via Gasnow API | ||
*/ | ||
export const getGasPrice = async (): Promise<number> => { | ||
const jsonFetch = (url: string) => fetch(url).then((res) => res.json()); | ||
|
||
// get current gas price from GasNow | ||
const gasPriceUrl = 'https://www.gasnow.org/api/v3/gas/price'; | ||
const gasPriceInWei = await axios | ||
.get(gasPriceUrl) | ||
.then((response) => response.data.data.rapid) // 99 percent likelihood of tx getting included in next block | ||
.catch((error) => { | ||
throw new Error(`Error on GasNow API: ${error.message}`); | ||
}); | ||
|
||
return gasPriceInWei | ||
const tokenAddressToCoinGeckoId = { | ||
'0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE': 'ethereum', | ||
'0x0D8775F648430679A709E98d2b0Cb6250d2887EF': 'basic-attention-token', | ||
'0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984': 'uniswap', | ||
'0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599': 'bitcoin', | ||
'0x6B3595068778DD592e39A122f4f5a5cF09C90fE2': 'sushi', | ||
'0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0': 'matic-network', | ||
'0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2': 'ethereum', | ||
'0xD56daC73A4d6766464b38ec6D91eB45Ce7457c44': 'panvala-pan', | ||
'0x536381a8628dBcC8C70aC9A30A7258442eAb4c92': 'pantos', | ||
'0x514910771AF9Ca656af840dff83E8264EcF986CA': 'chainlink', | ||
'0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD': 'loopring', | ||
}; | ||
|
||
const stablecoins = [ | ||
'0x6B175474E89094C44Da98b954EedeAC495271d0F', // DAI | ||
'0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC | ||
'0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDT | ||
]; | ||
|
||
function isSupportedToken(tokenAddress: string): tokenAddress is keyof typeof tokenAddressToCoinGeckoId { | ||
return Object.keys(tokenAddressToCoinGeckoId).includes(tokenAddress); | ||
} | ||
|
||
/** | ||
* @notice Gets the given token price and Eth price in USD via Coingecko API | ||
* @param token symbol of token of which to fetch price | ||
* @notice Takes a token address or 0xEeEEeeee... and returns the price | ||
* @param tokenAddress Checksummed token address | ||
*/ | ||
export const getTokenAndEthPriceInUSD = async (token: string): Promise<{tokenPrice: number, ethPrice: number}> => { | ||
|
||
// get current gas price from GasNow console.log("getting token and eth price") | ||
const coingeckoUrl = `https://api.coingecko.com/api/v3/simple/price?ids=${token},ethereum&vs_currencies=usd,usd`; | ||
let tokenPrice: number = 0; | ||
let ethPrice: number = 0; | ||
await axios | ||
.get(coingeckoUrl) | ||
.then((response) => { response.data.dai.usd, response.data.ethereum.usd | ||
ethPrice = response.data.ethereum.usd | ||
tokenPrice = response.data.dai.usd | ||
}) | ||
.catch((error: { message: any; }) => { | ||
throw new Error(`Error on coingecko API: ${error.message}`); | ||
}); | ||
return {tokenPrice, ethPrice} | ||
} | ||
export const getTokenPriceInUsd = async (tokenAddress: string): Promise<number> => { | ||
try { | ||
// Return 1 for all stablecoins | ||
if (stablecoins.includes(tokenAddress)) return 1; | ||
|
||
// Throw if token does not have a CoinGecko mapping | ||
if (!isSupportedToken(tokenAddress)) throw new Error(`Unsupported token address ${tokenAddress}`); | ||
|
||
// Otherwise fetch price and return it | ||
const coinGeckoId = tokenAddressToCoinGeckoId[tokenAddress]; | ||
const coingeckoUrl = `https://api.coingecko.com/api/v3/simple/price?ids=${coinGeckoId}&vs_currencies=usd`; | ||
const response: Record<string, { usd: number }> = await jsonFetch(coingeckoUrl); | ||
return response[coinGeckoId].usd; | ||
} catch (e) { | ||
throw new Error(`Error fetching price for ${tokenAddress}: ${e.message as string}`); | ||
} | ||
}; | ||
|
||
/** | ||
* @notice Gets the current gas price via Gasnow API | ||
* @param gasPriceSpeed string of gas price speed from GasNow (e.g. `'rapid'`) | ||
*/ | ||
export const getGasPrice = async (gasPriceSpeed: GasNowSpeed = 'rapid'): Promise<BigNumber> => { | ||
const gasPriceUrl = 'https://www.gasnow.org/api/v3/gas/price'; | ||
try { | ||
const response: GasNowResponse = await jsonFetch(gasPriceUrl); | ||
const gasPriceInWei = response.data[gasPriceSpeed]; | ||
return BigNumber.from(gasPriceInWei); | ||
} catch (e) { | ||
throw new Error(`Error on GasNow API: ${e.message as string}`); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters