UNPKG

@xspswap/smart-order-router

Version:
199 lines (140 loc) 9.74 kB
# Xswap Smart Order Router This repository contains routing logic for the Xswap 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. ## Testing ### Unit Tests First make sure you have run `npm install` and `npm run build`. ``` npm run test ``` ### Integration Tests Make sure the `.env` file is configured to connect to mainnet and other chains. See the [CLI](#cli) section below for more details. ``` npm run integ-test ``` ### Tenderly Simulations Quotes can be simulated on Tenderly Ensure you set the following environment variables: ``` process.env.TENDERLY_BASE_URL!, process.env.TENDERLY_USER!, process.env.TENDERLY_PROJECT!, process.env.TENDERLY_ACCESS_KEY!, ``` ### CLI The package can be run as a CLI for testing purposes. First create a `.env` file in the root of the project and configure: ``` JSON_RPC_PROVIDER = '<JSON_RPC_PROVIDER>' ``` To run on chains other than mainnet set up a connection by specifying the environment variable ``` JSON_RPC_PROVIDER_ROPSTEN = '<JSON_RPC_PROVIDER>' JSON_RPC_PROVIDER_RINKEBY = '<JSON_RPC_PROVIDER>' JSON_RPC_PROVIDER_GORLI = '<JSON_RPC_PROVIDER>' JSON_RPC_PROVIDER_KOVAN = '<JSON_RPC_PROVIDER>' JSON_RPC_PROVIDER_OPTIMISM = '<JSON_RPC_PROVIDER>' JSON_RPC_PROVIDER_OPTIMISM_GOERLI = '<JSON_RPC_PROVIDER>' JSON_RPC_PROVIDER_OPTIMISTIC_KOVAN = '<JSON_RPC_PROVIDER>' JSON_RPC_PROVIDER_ARBITRUM_ONE = '<JSON_RPC_PROVIDER>' JSON_RPC_PROVIDER_ARBITRUM_RINKEBY = '<JSON_RPC_PROVIDER>' JSON_RPC_PROVIDER_ARBITRUM_GOERLI = '<JSON_RPC_PROVIDER>' JSON_RPC_PROVIDER_POLYGON = '<JSON_RPC_PROVIDER>' JSON_RPC_PROVIDER_POLYGON_MUMBAI = '<JSON_RPC_PROVIDER>' JSON_RPC_PROVIDER_CELO = '<JSON_RPC_PROVIDER>' JSON_RPC_PROVIDER_CELO_ALFAJORES = '<JSON_RPC_PROVIDER>' JSON_RPC_PROVIDER_BSC = '<JSON_RPC_PROVIDER>' ``` Then from the root directory you can execute the CLI. ## Examples Some examples to use for manual CLI testing. ### Mainnet ``` ./bin/cli quote --tokenIn 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 --tokenOut 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984 --amount 1000 --exactIn --recipient 0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B --protocols v2,v3 Best Route: 100.00% = USDC -- 0.3% --> UNI Raw Quote Out: 35.72 Gas Adjusted Quote Out: 34.03 Gas Used Quote Token: 1.691772 Gas Used USD: 47.592951 Calldata: 0x414bf389000000000000... Value: 0x00 blockNumber: "13088815" estimatedGasUsed: "113000" gasPriceWei: "130000000000" ./bin/cli quote-to-ratio --token0 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 --token1 0xdac17f958d2ee523a2206206994597c13d831ec7 --feeAmount 3000 --recipient 0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B --token0Balance 1000 --token1Balance 2000 --tickLower -120 --tickUpper 120 Best Route: 100.00% = USDT -- 0.05% --> USDC Raw Quote Exact In: 392.68 Gas Adjusted Quote In}: 346.13 Gas Used Quote Token: 46.550010 Gas Used USD: 46.342899 Calldata: 0x414bf389000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000ab5801a7d398351b8be11c439e05c5b3259aec9b000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000176a736c000000000000000000000000000000000000000000000000000000001764f8650000000000000000000000000000000000000000000000000000000000000000 Value: 0x00 blockNumber: "13239188" estimatedGasUsed: "113000" gasPriceWei: "116690684398" ./bin/cli quote --tokenIn 0x0391D2021f89DC339F60Fff84546EA23E337750f --tokenOut 0x4d224452801ACEd8B2F0aebE155379bb5D594381 --amount 10000 --exactIn --recipient 0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B --protocols v2,v3,mixed Best Route: [V2 + V3] 100.00% = BOND -- [0x6591c4BcD6D7A1eb4E537DA8B78676C1576Ba244] --> USDC -- 0.3% [0xB07Fe2F407F971125D4EB1977f8aCEe8846C7324] --> APE Raw Quote Exact In: 10437.85 Gas Adjusted Quote In: 10433.83 Gas Used Quote Token: 4.018625 Gas Used USD: 29.669402 Calldata: 0x5ae401dc0000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000e4472b43f300000000000000000000000000000000000000000000021e19e0c9bab240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000391d2021f89dc339f60fff84546ea23e337750f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104b858183f00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000080000000000000000000000000ab5801a7d398351b8be11c439e05c5b3259aec9b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002358df5b3b4459a3f5b000000000000000000000000000000000000000000000000000000000000002ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb84d224452801aced8b2f0aebe155379bb5d59438100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 Value: 0x00 blockNumber: "15303839" estimatedGasUsed: "434000" gasPriceWei: "38218865879" Total ticks crossed: 7 ``` ## XDC Mainnet ``` XSP ./bin/cli quote --tokenIn 0x36726235dAdbdb4658D33E62a249dCA7c4B2bC68 --tokenOut 0xD4B5f10D61916Bd6E0860144a91Ac658dE8a1437 --amount 1000 --exactIn --minSplits 1 --protocols v2,v3,mixed --router alpha --chainId 50 SRX - USDT ./bin/cli quote --tokenIn 0x5d5f074837f5d4618b3916ba74de1bf9662a3fed --tokenOut 0xD4B5f10D61916Bd6E0860144a91Ac658dE8a1437 --amount 1000 --exactIn --minSplits 1 --protocols v2 --router alpha --chainId 50 SRX - WXDC ./bin/cli quote --tokenIn 0x5d5f074837f5d4618b3916ba74de1bf9662a3fed --tokenOut 0x951857744785e80e2de051c32ee7b25f9c458c42 --amount 1000 --exactIn --minSplits 1 --protocols v2,v3,mixed --router alpha --chainId 50 WXDC -> XTT ./bin/cli quote --tokenIn 0x951857744785e80e2de051c32ee7b25f9c458c42 --tokenOut 0x17476dc3eda45aD916cEAdDeA325B240A7FB259D --amount 10000 --exactIn --minSplits 1 --protocols v2,v3,mixed --router alpha --chainId 50 EURS -> WXDC ./bin/cli quote --tokenIn 0x1eBb2C8a71A9ec59bF558886a8Adf8F4a565814F --tokenOut 0x951857744785e80e2de051c32ee7b25f9c458c42 --amount 10000 --exactIn --minSplits 1 --maxSplits 5 --maxSwapsPerPath 5 --protocols v2,v3,mixed --router alpha --chainId 50 XSP -> FXD ./bin/cli quote --tokenIn 0x36726235dAdbdb4658D33E62a249dCA7c4B2bC68 --tokenOut 0x49d3f7543335cf38Fa10889CCFF10207e22110B5 --amount 10000000 --exactIn --minSplits 1 --maxSplits 5 --maxSwapsPerPath 5 --protocols v2,v3,mixed --router alpha --chainId 50 ``` ## Adding a new Chain The main components to complete are: - Deploy contracts on chain, add the pools to subgraph - Populate v3 providers in `src/providers/v3/subgraph-provider` and `src/providers/v3/static-subgraph-provider` - Populate chainId and addresses in `src/util/chains.ts` and `src/util/addresses.ts` - Populate token providers in `src/providers/caching-token-provider` and `src/providers/token-provider.ts` - Populate gas constants in `src/routers/alpha-router/gas-models/*` - Populate bases in `src/routers/legacy-router/bases.ts` - Populate `test/integ/routers/alpha-router/alpha-router.integration.test.ts` and `src/providers/v2/static-subgraph-provider.ts` - Populate `src/routers/alpha-router/*` - Add a log to `/CHANGELOG.md` - Run `npm run integ-test` successfully # Troubleshooting ## ProviderGasLimit errors The package sends many large multicall requests to nodes. You must ensure that your node provider's `eth_call` gas limit is high enough to succesfully process the RPC calls. By default each `eth_call` will consume up to: - 132,000,000 gas on Optimism - 120,000,000 gas on Arbitrum - 50,000,000 gas on Celo - 150,000,000 gas on every other network (Mainnet, Goerli, etc.) These parameters should work on Infura and Alchemy by default. This total amount of gas each `eth_call` can consume is equal to the `multicallChunk` config value multiplied by the `gasLimitPerCall` config value. If you are using a node provider with a lower gas limit per `eth_call` you will need to override the default `V3QuoteProvider` with an instance that lowers the `multicallChunk` and `gasLimitPerCall` parameters such that the multiplication is below your node providers limit. Lowering these values will cause each multicall to consume less gas. See [here](https://github.com/Xs/smart-order-router/blob/98c58bdee9981fd9ffac9e7d7a97b18302d5f77a/src/routers/alpha-router/alpha-router.ts#L415-L416) for examples of how to set these values. Note some providers have different limits per chain. If you are running your own node, we recommend you configure start your node with a higher gas limit per call. For example, on Geth you can use the command line argument `--rpc.gascap 150000000` to raise the limit to 150m, which is enough to run the default configuration of this package. If you are using Hardhat mainnet forking, you should add `blockGasLimit: 150_000_000` to your Hardhat config to use the default package configuration. # TODO 1) Check default gas limit for XDC 2) add v2 against ___ node version 15