Skip to content
This repository has been archived by the owner on Apr 25, 2024. It is now read-only.

While adding liquidity to the pool uniswapv3-sdk gives the following error reverted with reason string 'LOK' #177

Open
Hareem-Saad opened this issue Jul 4, 2023 · 1 comment

Comments

@Hareem-Saad
Copy link

Packages & Versions

"devDependencies": {
    "@nomicfoundation/hardhat-toolbox": "^2.0.2",
    "hardhat": "^2.16.0"
  },
  "dependencies": {
    "@openzeppelin/contracts": "^4.9.2",
    "@uniswap/v3-sdk": "^3.8.3",
    "dotenv": "^16.3.1"
  }

Code

I am forking polygon mainnet on hardhat then running it locally, The pool created is betweem USDC and TokenA (a token i created)

const hre = require("hardhat");
const { ethers } = hre;
const {
  Pool,
  TickMath,
  nearestUsableTick,
  TICK_SPACINGS,
} = require("@uniswap/v3-sdk");
const {
  abi: poolAbi,
} = require("@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json");
const {
  abi: factoryAbi,
} = require("@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json");
const {
  abi: routerAbi,
} = require("@uniswap/v3-periphery/artifacts/contracts/SwapRouter.sol/SwapRouter.json");
const { abi: NonfungiblePositionManagerAbi } = require('@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json');

const { abi: usdcAbi } = require("./../contracts/abi/udsc.json");
const { abi: wmaticAbi } = require("./../contracts/abi/WMATIC.json");
const { abi: TokenAAbi } = require("./../contracts/abi/TokenA.json");
const dotenv = require("dotenv");
dotenv.config();

async function main() {

  // get signer
  const [signer] = await ethers.getSigners();

  // deploy tokenA
  //...
  await tokenA.deployed();

  // all addresses
  //...
  const provider = new ethers.providers.JsonRpcProvider(
    process.env.POLYGON_RPC_URL
  );

  // all connections
  //...

  /// STEP 1: GET USDC
  //...

  /// STEP 1: CREATE POOL

  const fee = 3000; // Fee in hundredths of a percent (e.g., 3000 is 3%)
  const tickSpacing = TICK_SPACINGS[fee];
  const initialSqrtPrice = TickMath.getSqrtRatioAtTick(0); // Set the initial price ratio
  const initialTick = nearestUsableTick(-887272, tickSpacing); // Set the initial tick

  console.log(0);

  // approve router contract to usdc
  const result = await usdc
    .connect(signer)
    .approve(routerAddress, ethers.constants.MaxUint256, {
      gasLimit: 30000000,
    });
  console.log("RESULT ::: ", result);
  //   await TokenA.approve(routerAddress, ethers.constants.MaxUint256);

  console.log(1);

  const createPoolTx = await factory
    .connect(signer)
    .createPool(USDC, TokenA.address, fee);
  console.log(2);
  const createPoolReceipt = await createPoolTx.wait();
  console.log(3);
  const poolAddress = createPoolReceipt.events[0].args.pool;
  console.log(4, poolAddress);
  const pool = new ethers.Contract(poolAddress, poolAbi);
  console.log(5);
  // const initializeTx = await pool.connect(signer).initialize(initialSqrtPrice, {gasLimit: 30000000});
  // console.log(6);
  // await initializeTx.wait();
  // console.log(7);
  console.log(createPoolReceipt, poolAddress);

  /// STEP 2: ADD LIQUIDITY

  // Define the amounts of tokens to add
  const amountUSDCDesired = ethers.utils.parseUnits('10000000000000000000000', 6); // 10,000 USDC
  const amountTokenADesired = ethers.utils.parseEther('10000000000000000000000', 18); // 10000 TokenA

  // tickLower = floor(log(0.99) / log(1.0001)) = -202
  // tickUpper = floor(log(1.01) / log(1.0001)) = 200
  // Define the range position
  const tickLower = -202;
  const tickUpper = 200;

  console.log(6);
  const approveUSDC = await usdc.connect(signer).approve(positionManager.address, amountUSDCDesired);
  console.log(7);
  const approveTokenA = await TokenA.connect(signer).approve(positionManager.address, amountTokenADesired);
  console.log(8);
  
  await approveUSDC.wait();
  await approveTokenA.wait();

   // ERROR
  // Add liquidity
  const tx = await positionManager.connect(signer).mint([
    USDC,
    TokenA.address,
    fee,
    tickLower,
    tickUpper,
    amountUSDCDesired,
    amountTokenADesired,
    0,
    0,
    signer.address,
    Math.floor(Date.now() / 1000) + 60 * 20 // 20 minutes from the current Unix time
  ]);
  console.log(11);

  await tx.wait();
  
  console.log('Liquidity added');
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

On await positionManager.connect(signer).mint it fails with the string LOK, which I cannot understand because there are no more calls calling to the pool, its just this code which executes line after line.

This error could be linked to this issue. When creating the pool, the pool gets created without any issue but I have to then close the node running the polygon mainnet fork to execute the same script again also the code does not initialize the pool (hence it is commented out)

@ford152
Copy link

ford152 commented Jan 26, 2024

I was having this issue on both Polygon and Mumbai. I created a new pool and then was getting the LOK error trying to mint the first LP position. I ended up resolving it by calling initialize() on the UniswapV3Pool contract. so in this order:
-create new pool
-initialize the pool
-mint new position using NonfungiblePositionManager

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants