Skip to content

Extend multi-callee with auto router #527

@valiafetisov

Description

@valiafetisov

Goal

Automatic router is used for tokens exchangeable via UniswapV3Callee as a separate exchange config.

Context

After

We're finally ready to add full support of the uniswap automatic router. The idea is to add them as a new separate exchange config, eg:

  exchanges: {
+     'Uniswap V3 auto router': {
+         callee: 'UniswapV3Callee',
+         automaticRouter: true,
+     },
      'Uniswap V3': {
          callee: 'UniswapV3Callee',
          route: ['ETH'],
      },
      'Uniswap V2': {
          callee: 'UniswapV2CalleeDai',
          route: ['ETH'],
      },
  },

And then get quote and the route in the getMarketPrice (or some higher level function). Then, route will become part of the marketData object inside marketDataRecords['Uniswap V3 auto router'] during the auction enrichment and will be picked up from there by the getCalleeData during auction execution.

Note: we currently store routes as just a list of intermediate collateralSymbols through which the exchange should be made eg:

const route = [ 'ETH' ]

While the callees accept array of token addresses + pools, eg:

const path = [
  '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9', // AAVE address
  3000, // AAVE+WETH uniswap pool
  '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH address
  3000, // WETH+DAI uniswap pool
  '0x6B175474E89094C44Da98b954EedeAC495271d0F' // DAI address
]

While we might want to store this data in this format:

const pools = [
  {
    names: ['AAVE', 'WETH'],
    addresses: ['0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9', '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'],
    fee: 3000,
  },
  {
    names: ['WETH', 'DAI'],
    addresses: ['0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', '0x6B175474E89094C44Da98b954EedeAC495271d0F'],
    fee: 3000,
  }
]

Therefore, we should:

  • Keep exchange[marketId].route config as now
  • Transform route format into pools format during enrichment and store it under marketDataRecords[marketId].pools instead of route
  • We should expect that intermediate tokens might be tokens that are not part of the collateral config
    • So that we need to store their address in the marketDataRecords[marketId].pools
    • So that we might need to fetch the symbol name from the chain (if it's not provided with the route)

Assets

  • getUniswapAutoRoute
    export const getUniswapAutoRoute = async function (
    network: string,
    collateralSymbol: string,
    inputAmount: string | number = 1,
    walletAddress?: string
    ) {
    const collateralConfig = getCollateralConfigBySymbol(collateralSymbol);
    const provider = await getProvider(network);
    const router = new AlphaRouter({ chainId: 1, provider });
    const inputToken = await getUniswapTokenBySymbol(network, collateralConfig.symbol);
    const outputToken = await getUniswapTokenBySymbol(network, 'DAI');
    const inputAmountInteger = new BigNumber(inputAmount).shiftedBy(collateralConfig.decimals).toFixed(0);
    const inputAmountWithCurrency = CurrencyAmount.fromRawAmount(inputToken, inputAmountInteger);
    // get auto route
    const route = await router.route(
    inputAmountWithCurrency,
    outputToken,
    TradeType.EXACT_INPUT,
    {
    recipient: walletAddress || '0x000000000000000000000000000000000000dEaD', // use given address or "dead" address as fallback
    slippageTolerance: new Percent(10, 100),
    deadline: Math.floor(Date.now() / 1000 + 1800),
    },
    {
    maxSplits: 0,
    }
    );
    if (!route) {
    throw new Error(`Could not get auto route for collateral "${collateralSymbol}".`);
    }
    return route;
    };

Implementation proposal

  • Refactor route->pools:
    • Generate a new pools value during enrichment instead of route
    • Use pools on the frontend
    • Use pools value during execution (ie create encodePools instead of using encodeRoute)
    • Check that old routes still working
    • (optional) Merge enrichAuctionWithMarketDataRecords and enrichMarketDataRecordsWithValues into one function, but without a loop getMarketDataById which returns both fetched values, calculated values and pools
  • Add new automaticRouter markets to the collateral config
  • Handle new automaticRouter type when the callee is UniswapV3Callee via calling getUniswapAutoRoute
    • Transform output of the getUniswapAutoRoute into the pools format
    • Include estimated exchange fees into marketUnitPrice via using route.quoteGasAdjusted
    • Do not reapply hardcoded fees when automaticRouter is present

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions