Skip to content

Commit

Permalink
EIP 1559 gas parameterizable, comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Will Pote committed Aug 30, 2021
1 parent a75d1b1 commit 59d55c2
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 6 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ This repository contains routing logic for the Uniswap V3 protocol.

It searches for the most efficient way to swap token A for token B, considering splitting swaps across multiple routes and gas costs.

## CLI
## Testing
### Unit Tests

```
npm run test
```

### CLI

The package can be run as a CLI for testing purposes.

Expand Down
14 changes: 11 additions & 3 deletions src/providers/eip-1559-gas-price-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,23 @@ export type FeeHistoryResponse = {
};

// We get the Xth percentile of priority fees for transactions successfully included in previous blocks.
const PRIORITY_FEE_PERCENTILE = 50;
const DEFAULT_PRIORITY_FEE_PERCENTILE = 50;
// Infura docs say only past 4 blocks guaranteed to be available: https://infura.io/docs/ethereum#operation/eth_feeHistory
const BLOCKS_TO_LOOK_BACK = 4;

export class EIP1559GasPriceProvider extends IGasPriceProvider {
constructor(protected provider: providers.JsonRpcProvider) {
constructor(
protected provider: providers.JsonRpcProvider,
private priorityFeePercentile: number = DEFAULT_PRIORITY_FEE_PERCENTILE
) {
super();
}

public async getGasPrice(): Promise<GasPrice> {
const feeHistoryRaw = (await this.provider.send('eth_feeHistory', [
BLOCKS_TO_LOOK_BACK.toString(),
'latest',
[PRIORITY_FEE_PERCENTILE],
[this.priorityFeePercentile],
])) as RawFeeHistoryResponse;

const feeHistory: FeeHistoryResponse = {
Expand All @@ -56,6 +59,11 @@ export class EIP1559GasPriceProvider extends IGasPriceProvider {
{
feeHistoryRaw,
feeHistory,
feeHistoryReadable: {
baseFeePerGas: _.map(feeHistory.baseFeePerGas, (f) => f.toString()),
oldestBlock: feeHistory.oldestBlock.toString(),
reward: _.map(feeHistory.reward, (r) => r.toString()),
},
nextBlockBaseFeePerGas,
averagePriorityFeePerGas,
},
Expand Down
20 changes: 18 additions & 2 deletions src/routers/alpha-router/alpha-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,17 @@ export class AlphaRouter implements IRouter<AlphaRouterConfig> {
swapConfig?: SwapConfig,
routingConfig = DEFAULT_CONFIG
): Promise<SwapRoute<TTradeType> | null> {
const blockNumber =
routingConfig.blockNumber ?? this.provider.getBlockNumber();
const tokenIn = currencyIn.wrapped;
const tokenOut = currencyOut.wrapped;

// Get a block number to specify in all our calls. Ensures data we fetch from chain is
// from the same block.
const blockNumber =
routingConfig.blockNumber ?? this.provider.getBlockNumber();

// Fetch all the pools that we will consider routing via. There are thousands
// of pools, so we filter them to a set of candidate pools that we expect will
// result in good prices.
const { poolAccessor, candidatePools } = await getCandidatePools({
tokenIn,
tokenOut,
Expand All @@ -167,6 +173,7 @@ export class AlphaRouter implements IRouter<AlphaRouterConfig> {
});
const pools = poolAccessor.getAllPools();

// Get an estimate of the gas price to use when estimating gas cost of different routes.
const beforeGas = Date.now();
const { gasPriceWei } = await this.gasPriceProvider.getGasPrice();

Expand All @@ -185,18 +192,23 @@ export class AlphaRouter implements IRouter<AlphaRouterConfig> {
quoteToken
);

// Given all our candidate pools, compute all the possible ways to route from tokenIn to tokenOut.
const { maxSwapsPerPath } = routingConfig;
const routes = computeAllRoutes(tokenIn, tokenOut, pools, maxSwapsPerPath);

if (routes.length == 0) {
return null;
}

// Generate our distribution of amounts, i.e. fractions of the input amount.
// We will get quotes for fractions of the input amount for different routes, then
// combine to generate split routes.
const [percents, amounts] = this.getAmountDistribution(
amount,
routingConfig
);

// For all our routes, and all the fractional amounts, fetch quotes on-chain.
const quoteFn =
swapType == TradeType.EXACT_INPUT
? this.quoteProvider.getQuotesManyExactIn.bind(this.quoteProvider)
Expand All @@ -223,6 +235,7 @@ export class AlphaRouter implements IRouter<AlphaRouterConfig> {
MetricLoggerUnit.Count
);

// Given all the quotes for all the amounts for all the routes, find the best combination.
const beforeBestSwap = Date.now();
const swapRouteRaw = getBestSwapRoute(
amount,
Expand Down Expand Up @@ -250,6 +263,7 @@ export class AlphaRouter implements IRouter<AlphaRouterConfig> {
estimatedGasUsedUSD,
} = swapRouteRaw;

// Build Trade object that represents the optimal swap.
const trade = this.buildTrade<TTradeType>(
currencyIn,
currencyOut,
Expand All @@ -259,6 +273,8 @@ export class AlphaRouter implements IRouter<AlphaRouterConfig> {

let methodParameters: MethodParameters | undefined;

// If user provided recipient, deadline etc. we also generate the calldata required to execute
// the swap and return it too.
if (swapConfig) {
methodParameters = this.buildMethodParameters(trade, swapConfig);
}
Expand Down

0 comments on commit 59d55c2

Please sign in to comment.