2

I have a Uniswap V3 pool of "token A" and "token B".

Holding 1,000 of token A, and 1,000 of token B on a wallet.

Current tick in the pool is 50,000, marking the price of ~148 tokens B for 1 token A (1.0001^50000).

Want to provide liquidity in range between 45,000 and 60,000.

How can I calculate the optimal amounts to provide the largest possible liquidity?

If I simply call LiquidityAmounts.getLiquidityForAmounts(), pool.mint(), nonfungiblePositionManager.mint() or any other provided function, passing it my values of 1,000 of token A and 1,000 of token B, there's going to be some excess amount (of either token A or token B) that won't be used.

So, I'm willing to swap some of the excess tokens to provide the best possible liquidity, so that all (or almost all) of the total value is used. But how to calculate the amount of tokens to swap?

1 Answer 1

3

You need to find out the proportion of the tokens in the desired position, and then convert your assets to that proportion.

One way to find the proportion is to rely on the liquidity balance maintained by the Uniswap v3 contracts - for an in-range position, the liquidity provided by the token A should be equal (ignoring numerical errors) to the liquidity provided by token B.

There are a couple preliminary steps:

  1. Convert the ticks to square roots of prices, since these are used in liquidity calculation. Let's denote the price range endpoints with p_a and p_b.
  2. Express the value of your holdings V_wallet using the relative price of A and B, and the amount x and y in your wallet (of tokens A and B, respectively).

Finding out the amounts. The proportion of assets is the same for a unit position, where liquidity L=1, and follows from the standard v3 math:

enter image description here

Now:

enter image description here

and:

enter image description here

The amounts to swap are (assuming some A need to be swapped for B - otherwise just revert the signs):

enter image description here

Advanced topics. The math above ignores price impact and other fees from swapping your tokens. Taking these into account would be important for complete realism. A special case is when you want to swap the tokens in the pool itself. Then the proportion to add is affected by the size of the swap. This case is solved here, by Dan Robinson.

Example. Here's Python code with the values from your example.

def example():
    sp = 1.0001 ** (50_000 // 2) # sqrt(P)
    sa = 1.0001 ** (45_000 // 2) # sqrt(P_a)
    sb = 1.0001 ** (60_000 // 2) # sqrt(P_b)
    p = sp ** 2

    x_unit = (sb - sp) / (sp * sb)
    y_unit = sp - sa

    x_wallet = 1000
    y_wallet = 1000

    v_wallet = x_wallet * p + y_wallet
    v_unit = x_unit * p + y_unit
    n_units = v_wallet / v_unit

    x_pos = n_units * x_unit
    y_pos = n_units * y_unit
    print(f"optimal position has {x_pos:.2f} A and {y_pos:.2f} B")

    dx = x_wallet - x_pos
    dy = y_pos - y_wallet
    print(f"sell {dx:.2f} A to get {dy:.2f} B")

Output:

optimal position has 644.45 A and 53755.40 B
sell 355.55 A to get 52755.40 B
3
  • Can you please assign values from the question (or some dummy values) into the formulas? I'm not sure I follow the math correctly.
    – Petr Hejda
    Commented Jul 29 at 11:48
  • 1
    @PetrHejda using an off-chain programming language it's straightforward to implement the math, but I added it anyway. For on-chain computation you'll have deal with implementation issues like Q96 numbers, but that's a separate question
    – kfx
    Commented Jul 29 at 17:33
  • Got it. Thank you
    – Petr Hejda
    Commented Jul 30 at 8:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.