Skip to content

Commit

Permalink
Update integration tests and gas estimates logic (#34)
Browse files Browse the repository at this point in the history
* feat: removed ethgasstation gas price provider

* feat: add blocknative gas price provider using their api

* feat: add basic high gas price provider

* feat: export providers

* feat: instatiates alpha router using new gas price providers

* feat: changed USDT to EUROC for swap tests

* only use USDC in gas model

* remove console logs

* update whale address

* update integration tests

* small optimization

* remove comments

* update gas price provider and tests

* add blocknative api key

* fix import

* cleaning up

* add more comments

---------

Co-authored-by: Papa Smurf <chris@violet.co>
  • Loading branch information
ra-phael and 0xpApaSmURf authored Oct 18, 2023
1 parent 1be9fc9 commit 21eac30
Show file tree
Hide file tree
Showing 12 changed files with 296 additions and 394 deletions.
90 changes: 90 additions & 0 deletions src/providers/blocknative-gas-price-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { BigNumber } from '@ethersproject/bignumber';
import retry from 'async-retry';
import axios from 'axios';

import { log } from '../util/log';

import { GasPrice, IGasPriceProvider } from './gas-price-provider';

export type BlockNativeGasPriceResponse = {
system: string;
network: string;
unit: string;
maxPrice: number;
currentBlockNumber: number;
msSinceLastBlock: number;
blockPrices: BlockPrice[];
estimatedBaseFees: { [block: string]: BaseFeeEstimate };
};

interface BlockPrice {
blockNumber: number;
estimatedTransactionCount: number;
baseFeePerGas: number;
estimatedPrices: PriceEstimate[];
}

interface PriceEstimate {
confidence: number;
price: number;
maxPriorityFeePerGas: number;
maxFeePerGas: number;
}

interface BaseFeeEstimate {
confidence: number;
baseFee: number;
}

export class BlockNativeGasPriceProvider extends IGasPriceProvider {
private apiKey: string;
private url: string;
constructor(apiKey: string) {
super();
this.apiKey = apiKey;
this.url = 'https://api.blocknative.com/gasprices/blockprices';
}

public async getGasPrice(): Promise<GasPrice> {
log.info(`About to get gas prices from gas station ${this.url}`);
const response = await retry(
async () => {
return axios.get<BlockNativeGasPriceResponse>(this.url, {
headers: { Authorization: `${this.apiKey}` },
});
},
{ retries: 1 }
);

const { data: gasPriceResponse, status } = response;

if (status != 200) {
log.error({ response }, `Unabled to get gas price from ${this.url}.`);

throw new Error(`Unable to get gas price from ${this.url}`);
}

log.info(
{ gasPriceResponse },
'Gas price response from API. About to parse "fast" to big number'
);

const baseFee = BigNumber.from(
Math.ceil(gasPriceResponse.blockPrices[0]!.baseFeePerGas)
);
const priorityFee = BigNumber.from(
Math.ceil(
gasPriceResponse.blockPrices[0]!.estimatedPrices[0]!
.maxPriorityFeePerGas
)
);

log.info(
`Base gas price in wei: ${baseFee} and max priority fee: ${priorityFee} as of block ${
gasPriceResponse.blockPrices[0]!.blockNumber
}`
);

return { gasPriceWei: baseFee.add(priorityFee) };
}
}
64 changes: 0 additions & 64 deletions src/providers/eth-gas-station-info-gas-price-provider.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/providers/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
export * from './blocknative-gas-price-provider';
export * from './cache';
export * from './cache-node';
export * from './caching-gas-provider';
export * from './caching-token-list-provider';
export * from './caching-token-provider';
export * from './eip-1559-gas-price-provider';
export * from './eth-estimate-gas-provider';
export * from './eth-gas-station-info-gas-price-provider';
export * from './gas-price-provider';
export * from './legacy-gas-price-provider';
export * from './multicall-provider';
Expand Down
37 changes: 21 additions & 16 deletions src/routers/alpha-router/alpha-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ import _ from 'lodash';
import NodeCache from 'node-cache';

import {
BlockNativeGasPriceProvider,
CachingGasStationProvider,
CachingTokenProviderWithFallback,
CachingV3PoolProvider,
EIP1559GasPriceProvider,
ETHGasStationInfoProvider,
IOnChainQuoteProvider,
ISwapRouterProvider,
LegacyGasPriceProvider,
Expand Down Expand Up @@ -79,10 +79,7 @@ import {
V3Route,
} from '../router';

import {
DEFAULT_ROUTING_CONFIG_BY_CHAIN,
ETH_GAS_STATION_API_URL,
} from './config';
import { BLOCKNATIVE_APIKEY, DEFAULT_ROUTING_CONFIG_BY_CHAIN } from './config';
import {
RouteWithValidQuote,
V3RouteWithValidQuote,
Expand Down Expand Up @@ -463,21 +460,26 @@ export class AlphaRouter implements IRouter<AlphaRouterConfig> {
this.v3SubgraphProvider = new V3SubgraphProvider(chainId);
}

this.gasPriceProvider =
gasPriceProvider ??
new CachingGasStationProvider(
if (gasPriceProvider) {
this.gasPriceProvider = gasPriceProvider;
} else if (this.provider instanceof JsonRpcProvider) {
this.gasPriceProvider = new CachingGasStationProvider(
chainId,
this.provider instanceof JsonRpcProvider
? new OnChainGasPriceProvider(
chainId,
new EIP1559GasPriceProvider(this.provider),
new LegacyGasPriceProvider(this.provider)
)
: new ETHGasStationInfoProvider(ETH_GAS_STATION_API_URL),
new OnChainGasPriceProvider(
chainId,
new EIP1559GasPriceProvider(this.provider),
new LegacyGasPriceProvider(this.provider)
),
new NodeJSCache<GasPrice>(
new NodeCache({ stdTTL: 15, useClones: false })
)
);
} else {
this.gasPriceProvider = new BlockNativeGasPriceProvider(
BLOCKNATIVE_APIKEY
);
}

this.v3GasModelFactory =
v3GasModelFactory ?? new V3HeuristicGasModelFactory();

Expand Down Expand Up @@ -793,7 +795,9 @@ export class AlphaRouter implements IRouter<AlphaRouterConfig> {
)
);
} else {
throw new Error('Invalid protocolsSet specified');
throw new Error(
`Invalid protocolsSet specified: ${JSON.stringify(protocolsSet)}`
);
}

const routesWithValidQuotesByProtocol = await Promise.all(quotePromises);
Expand Down Expand Up @@ -910,6 +914,7 @@ export class AlphaRouter implements IRouter<AlphaRouterConfig> {
: undefined,
{ blockNumber }
);

metric.putMetric(
'SimulateTransaction',
Date.now() - beforeSimulate,
Expand Down
4 changes: 2 additions & 2 deletions src/routers/alpha-router/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,5 @@ export const DEFAULT_ROUTING_CONFIG_BY_CHAIN = (
};
}
};
export const ETH_GAS_STATION_API_URL =
'https://ethgasstation.info/api/ethgasAPI.json';

export const BLOCKNATIVE_APIKEY = 'bba51317-1a55-4e83-9ea5-7a6dc3014795';
4 changes: 1 addition & 3 deletions src/routers/alpha-router/gas-models/gas-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
DAI_ARBITRUM_RINKEBY,
DAI_GOERLI,
DAI_KOVAN,
DAI_MAINNET,
DAI_OPTIMISM,
DAI_OPTIMISM_GOERLI,
DAI_OPTIMISTIC_KOVAN,
Expand All @@ -32,7 +31,6 @@ import {
USDT_ARBITRUM_RINKEBY,
USDT_GOERLI,
USDT_KOVAN,
USDT_MAINNET,
USDT_OPTIMISM,
USDT_OPTIMISM_GOERLI,
USDT_OPTIMISTIC_KOVAN,
Expand All @@ -56,7 +54,7 @@ import {
} from '../entities/route-with-valid-quote';

export const usdGasTokensByChain: { [chainId in ChainId]?: Token[] } = {
[ChainId.MAINNET]: [DAI_MAINNET, USDC_MAINNET, USDT_MAINNET],
[ChainId.MAINNET]: [USDC_MAINNET],
[ChainId.RINKEBY]: [DAI_RINKEBY_1, DAI_RINKEBY_2],
[ChainId.ARBITRUM_ONE]: [DAI_ARBITRUM, USDC_ARBITRUM, USDT_ARBITRUM],
[ChainId.OPTIMISM]: [DAI_OPTIMISM, USDC_OPTIMISM, USDT_OPTIMISM],
Expand Down
20 changes: 13 additions & 7 deletions src/util/gas-factory-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,19 @@ export async function getHighestLiquidityV3USDPool(
);
}

const usdPools = _([
FeeAmount.HIGH,
FeeAmount.MEDIUM,
FeeAmount.LOW,
FeeAmount.LOWER,
FeeAmount.LOWEST,
])
// This prevents fetching data for all fee tiers since we only have 1 USDC/WETH pool deployed at the moment.
const feeAmounts =
chainId == ChainId.MAINNET
? [FeeAmount.LOWER]
: [
FeeAmount.HIGH,
FeeAmount.MEDIUM,
FeeAmount.LOW,
FeeAmount.LOWER,
FeeAmount.LOWEST,
];

const usdPools = _(feeAmounts)
.flatMap((feeAmount) => {
return _.map<Token, [Token, Token, FeeAmount]>(usdTokens, (usdToken) => [
wrappedCurrency,
Expand Down
Loading

0 comments on commit 21eac30

Please sign in to comment.