npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@sushiswap/tines

v1.0.11

Published

Sushiswap multirouter

Downloads

5,378

Readme

Tines

Sushiswap multirouter

Current features:

- Supports Trident pools and Uniswap-style ConstantProduct pools
- Supports Stargate bridging
- Takes gas prices into account
- Makes both Exact In and Exact Out multiroutes
- Routes in the multiroute can be split or merged at arbitrary points
- Has internal pricing calculation

Basics

The main idea of multirouting in Tines is:

1. split input Tokens for several streams (up to 100 in the current implementation)
2. make single route of each stream one by one using Dijkstra algorithm. Each stream changes pools' states on its way and this change should be taken into account during the next streams route
3. merge all single routes back into one multiroute

Pros:

- Single routing is much easier than multirouting
- Almost all features can be supported:
    - Any kind of pools
    - Bridges
    - Metapools
    - Multitoken pools
    - Limit orders

Cons:

- Routing many single routes is potentially resource consuming

How optimal is this approach

Pretty much. Potentially, it finds the optimal multiroute, but with several caveats:

    - Transaction price = gas price. It is the most difficult part for optimization. It is difficult to predict when it starts to be profitable to use another pool in parallel with one that is already being used by multiroute. The absolute optimal decision for this task is almost impossible, as it is difficult to predict the gas consumption of a swap. Different pools with different tokens feed different quantities of gas in different conditions. So, Tines solves this task only approximately, and this is the first source of inoptimality. But rather a low one
    - Finite quantity of route streams. Tests show that using 100 streams makes multirouting about 0.01%-0.05% close to the optimal one, so it is a very good tradeoff between result optimality and time of processing
    - Pools imbalancing. Prices in pools that Tines uses for routing can be imbalanced. That means that there is an arbitrage opportunity. Real optimal multirouting MUST (by definition) use this opportunity, because it makes output higher. But Tines ignores such opportunities because:
        1. Really large imbalances are resolved by arbitrage bots, a regular user is unlikely to catch them
        2. Making full use of big imbalances necessitates the use of circular routes that are not supported by neigher on-chain routes (aka route processors).
        3. Small imbalances are edges with negative weights from the point of view of Dijkstra algorithm that is used by Tines for single routing. This algorithm doesn't find the optimal path in graphs that have edges with negative weights. So, such imbalances can be found and used in route occasionally, Tines doesn't guarantee finding and using all of them

Interface

Each pool for Tines is presented by an instance that extends RPool

class RPool {
  // Calculates pool's output having input amount
  // amountIn - input amount
  // direction - direction of swap. true for Token 0 to Token 1, false otherwise
  // Returns {out: output amount, gasSpent: gas consumption estimation for the swap}
  // Must throw if the rest of output liquidity is lesser than minLiquidity
  abstract calcOutByIn(amountIn: number, direction: boolean): { out: number; gasSpent: number }

  // Calculates pool's input having output amount
  // amountOut - output amount
  // direction - direction of swap. true for Token 0 to Token 1, false otherwise
  // Returns {inp: input amount, gasSpent: gas consumption estimation for the swap}
  // Must return Number.POSITIVE_INFINITY if amountOut is more than the pool can return
  abstract calcInByOut(amountOut: number, direction: boolean): { inp: number; gasSpent: number }

  // Returns current price in the pool without taking fee into account
  // direction = true - price(Token0)/price(Token1),
  // direction = false - price(Token1)/price(Token0)
  abstract calcCurrentPriceWithoutFee(direction: boolean): number
}

Tines interface:


// Creates multiroute with amountIn input tokens
function findMultiRouteExactIn(
  from: RToken,                                 // input token
  to: RToken,                                   // output token
  amountIn: bigint | number,                    // amount of input tokens
  pools: RPool[],                               // List of pools that could be used in the multiroute
  baseTokenOrNetworks: RToken | NetworkInfo[],  // If RToken, then the main token of the network, used for gas prices
                                                // For example, WETH for Ethereum.
                                                // If NetworkInfo[], then info about all used networks.
                                                // Used for making multiroutes between several networks using bridges
  gasPrice?: number,                            // If baseTokenOrNetworks is RToken, then gasPrice - price of gas,
                                                // in baseTokens. Otherwise undefined
  streams?: number | number[]                   // Number of streams. Usually shuld be ignored.
                                                // Default value is calculated, up to 100
): MultiRoute

// The same as findMultiRouteExactIn, just creates multiroute that returns exact amountOut output tokens
function findMultiRouteExactOut(
  from: RToken,
  to: RToken,
  amountOut: bigint | number,
  pools: RPool[],
  baseTokenOrNetworks: RToken | NetworkInfo[],
  gasPrice?: number,
  streams?: number | number[]
): MultiRoute

// The same as findMultiRouteExactIn, just creates single route
function findSingleRouteExactIn(
  from: RToken,
  to: RToken,
  amountIn: bigint | number,
  pools: RPool[],
  baseTokenOrNetworks: RToken | NetworkInfo[],
  gasPrice?: number
): MultiRoute

// The same as findMultiRouteExactOut, just creates single route
function findSingleRouteExactOut(
  from: RToken,
  to: RToken,
  amountOut: bigint | number,
  pools: RPool[],
  baseTokenOrNetworks: RToken | NetworkInfo[],
  gasPrice?: number
): MultiRoute

// Calculates all token prices to baseToken, judging by pools' balances
function calcTokenPrices(pools: RPool[], baseToken: RToken): Map<RToken, number>

Further improvements

- To add route postprocessing: legs rebalancing, low-liquidity legs removing