/Uniswap-V3-task

Primary LanguageSolidityMIT LicenseMIT

How to deploy contracts (defaulted to Mainnet Fork)

In the first terminal run

npx hardhat node

Open second terminal and run

npx hardhat test

Strategy

  • Here we are providing liquidity for the entire range such as in the Uniswap V2.
  • MockDAI address on Mumbai: 0x4d582295afB968eA3b9492c5ec594b830D180E8d
  • I need to get the PoolId of the pool.
  • I mostly need two things to calculate impermnent loss:
  1. I need to track the liquidity present the pool each time swaps happen, so that I can calculate how much the LP will get when he will withdraw his tokens.
  2. Then I need to calculate what is the current price of both the tokens. Using that impermanent loss can be calculated.
    (This is because it will help to tell how much the tokens would have been worth if the LP would have simply held the tokens instead of providing liquidity to the Uniswap Pair)
  • UniswapPool contract has liquidity variable which gives its total liquidity. Using NFT of a position, we can get the local liquidity of an LP. So if two LPs are present, then the ratio of local liquidity to total liquidity may tell how much percent of tokens will each LP get back (need to test this and verify).
  • Now if you know the percent of Liquidity provided by the LP. You now want how many tokens will he get if he withdraws now. For that simply check the balance of the UniswapPool using the ERC20 token contracts. Then let's say the LP has 10 percent of the liquidity share. Then he will get back 10 percent of the total tokens that the UniswapPool holds.

Additional

  • Maybe Chainlink External Adapter will be needed that queries the Uniswap subgraph and sends the necessary data to smart contract.
  • Maybe Uniswap SDK will do all the required stuff instead of an external adapter.

Uniswap SDK

Uniswap Subgraph

Uniswap Docs

References

Possible Errors

  • While writing the return values of the function, if there are multiple return values then you only need to declare them once in the returns statement of the function and not inside the function.

Goal

The goal is to

  • Continuously monitor the impermanent loss incurred for a position in Uniswap V3
  • If there is a loss, we need to exit the position Monitoring a position We can use the Uniswap V3's subgraph to know a position's details like tokens, price at the time of providing liquidity, etc. We will also know the current tick in the pool.

We can use the following Impermanent Loss Calculation.

When the loss crosses a threshold (like say 50%), we need to trigger the recovery process.

Exiting a position

We need to deploy a simple smart contract that wraps around Uniswap V3's LP exiting function and trigger this function when the above monitoring logic is executed. The output of this should result in the wallet having the LP tokens back with the position fuly exited.

Testing with MockDAI and UFO

Testing with MockDAI and SAND

Alice before removing liquidity

  • Aliceliquidity: BigNumber { value: "4627199995519345936797" } Ratio: BigNumber { value: "82" } PoolLiquidity: BigNumber { value: "5575930413013974886531" }

Alice after removing liquidity

  • Aliceliquidity: BigNumber { value: "0" } Ratio: BigNumber { value: "0" } PoolLiquidity: BigNumber { value: "948730417494628949734" }
  • Note: This remaining Pool liquidity is of Bob.

Caution

  • When you mint new position using the Liquidity Example contract, the positions NFT is actually minted to contract. So if you had manually added liquidity, you already have the positions NFT minted and hence you won't be able to add liquidity anymore using the contract(not even the increaseLiquidityCurrentRange works then)
  • tickLower and tickUpper should be properly set

Testing with MockDAI-GALA

Getting Price from Q64.96 number

-85200 sqrtPriceX96: 1119122402227839611194053926

-46080 sqrtPriceX96: 7912525539738091750091588668

  • Python console calculations
>>> (1119122402227839611194053926 ** 2) / (2**192)
0.00019952439899256438
>>> 7912525539738091750091588668 ** 2 / 2**192
0.009974039462202664
>>> 1/0.000999901
1000.0990098019703
>>> 1/0.00019952439899256438
5011.918367122944
>>> 1/0.009974039462202664
100.2602810816592

Continued testing with MockDAI-GALA

  • Alice adds mints liquidity from LiquidityExample contract