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

hardhat-uniswap

v1.1.0

Published

Complete Uniswap V2 and V3 Uniswap library to enable more efficient use with developing with Uniswap functionality

Downloads

120

Readme

hardhat-uniswap

The easiest way to integrate Uniswap into your smart contracts

Are you tired of spending hours debugging Uniswap contracts whenever you need to use them in your tests? Frustrated with that annoying V3 addLiquidity bytecode issue? What even is sqrtPriceX96 ? Yeah, we get it. That's why we created this package -- to enable the most efficient way to integrate the whole Uniswap suite into your project.

Features

  • Complete V2 and V3 deployments
  • Efficient JS Wrappers around core functionality
  • pass in either number or BigNumbers
  • Automatic approvals - Test ERC20s created will approve all necessary contracts upon deployment
  • Eliminate hours of setup for test environments, deploy all necessary contracts for either v2 or v3 with one function!
  • TypeScript
  • Default (but overridable) behind-the-scenes handling of difficult Uniswap concepts (ticks, LP fees, LP conversions, etc)

Installation

npm

$ npm install hardhat-uniswap

yarn

$ yarn add hardhat-uniswap

then import it to your hardhat.config.ts

import { HardhatUserConfig } from "hardhat/config";
import "hardhat-uniswap";
// ... other imports

const config: HardhatUserConfig = {
  solidity: "0.8.17",
};
export default config;

Usage

hardhat-uniswap extends the HardhatRunTimeEnvironment. Therefore, you can access the package through hre.UniswapV2Deployer or hre.UniswapV3Deployer, whichever version of Uniswap you are using. You can use it in your deploy scripts and in your tests. UniswapV2Deployer uses the singleton pattern to create many of its contracts, which allows the package to manage the Uniswap state for you.

Examples

deploy Uniswap Contracts in main deploy script and attach router

import { ethers } from "hardhat";
import hre from "hardhat";

async function main() {
  const [signer] = await ethers.getSigners();

  // Deploy your contract
  const MyContract = await ethers.getContractFactory("MyContract");
  const myContract = await MyContract.deploy();
  await myContract.deployed();

  // Deploy uniswap contracts
  const {router} = await hre.UniswapV2Deployer.deploy(signer)
  
  // Set router on your contract!
  await myContract.receiveLiquidity(router)
}

V2 create tokens and add liquidity in a test environment

import { expect } from "chai";
import { ethers } from "hardhat";
import hre from 'hardhat';
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
import { Contract } from "ethers";


describe("Hardhat Uniswap Demo", function () {
    let testA: Contract;
    let testB: Contract;
    let signer: SignerWithAddress;
    let pair: Contract;

    beforeEach("Setup Liquidity Pool", async function () {
        [signer] = await ethers.getSigners();
        await hre.UniswapV2Deployer.deploy(signer);

        testA = await hre.UniswapV2Deployer.createERC20(signer, "TestA", "TESTA");
        testB = await hre.UniswapV2Deployer.createERC20(signer, "TestB", "TESTB");

        const addLiquidityOptions = {
            signer: signer,
            tokenA: testA.address,
            tokenB: testB.address,
            amountTokenA: 100,
            amountTokenB: 100
        }

        await hre.UniswapV2Deployer.addLiquidity(addLiquidityOptions)
    })

    it("should receive LP", async function () {
        const MyContract = await ethers.getContractFactory("MyContract");
        const myContract = await MyContract.deploy();
        await myContract.deployed();

        pair = await hre.UniswapV2Deployer.getPair(signer, testA.address, testB.address)
        await pair.connect(signer).approve(myContract.address, ethers.constants.MaxInt256);
        const pairBalanceBefore = await pair.balanceOf(signer.address);
        await myContract.receiveLiquidity(pair.address, ethers.utils.parseEther("1"));
        // confirm the lp was transferred
        expect(pairBalanceBefore).to.eq((await pair.balanceOf(signer.address)).add(ethers.utils.parseEther("1")))
        
    })
})

V3 create tokens and add liquidity in a test environment

import { expect } from "chai";
import { ethers } from "hardhat";
import hre from 'hardhat';
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
import { Contract } from "ethers";


describe("Hardhat Uniswap Demo", function () {
    let testA: Contract;
    let testB: Contract;
    let signer: SignerWithAddress;
    let pair: Contract;

    beforeEach("Setup Liquidity Pool", async function () {
        [signer] = await ethers.getSigners();
        await hre.UniswapV3Deployer.deploy(signer);

        const test1 = await hre.UniswapV3Deployer.createERC20(signer, "Test1", "TEST1")
        const test2 = await hre.UniswapV3Deployer.createERC20(signer, "Test2", "TEST2")
        const mintOptions: MintOptions = {
            signer: signer,
            token0: test1.address,
            token1: test2.address,
            fee: 3000,
            amount0Desired: 1000,
            amount1Desired: 1000,
            price: 1
        }
        const tokenId = await hre.UniswapV3Deployer.mintPosition(mintOptionsaddLiquidityOptions)
    })
})

V2 Functions

function async deploy(signer: SignerWithAddress): Promise<{
    weth9: Contract;
    WETH9: ContractFactory;
    factory: Contract;
    Factory: ContractFactory;
    router: Contract;
    Router: ContractFactory;
}>;

function async getWeth(signer: SignerWithAddress): Promise<Contract>;

function async getFactory(signer: SignerWithAddress): Promise<Contract>;

function async getFactory(signer: SignerWithAddress): Promise<Contract>;

function async getRouter(signer: SignerWithAddress): Promise<Contract>;

function async getPair(signer: SignerWithAddress, tokenA: string, tokenB: string);

function async createERC20(signer: SignerWithAddress, name: string, symbol: string): Promise<Contract>;

function getERC20(address: string): Contract | undefined;

function async addLiquidity(options: AddLiquidityOptions);

function async addLiquidityETH(options: AddLiquidityETHOptions);

function async removeLiquidity(options: RemoveLiquidityOptions); 

function async removeLiquidityETH(options: RemoveLiquidityETHOptions);

function async swapExactTokensForTokens(options: SwapExactTokensForTokensOptions);

function async swapTokensForExactTokens(options: SwapTokensForExactTokensOptions);

function async quote(options: QuoteOptions): Promise<BigNumber>;

function async getLiquidityValueInTermsOfTokenA(options: GetLiquidityValueInTermsOfTokenAOptions): Promise<BigNumber>;

V2 Interfaces

interface AddLiquidityOptions {
    signer: SignerWithAddress;
    tokenA: string;
    tokenB: string;
    amountTokenA: number | BigNumber;
    amountTokenB: number | BigNumber;
}

interface RemoveLiquidityOptions {
    signer: SignerWithAddress;
    tokenA: string;
    tokenB: string;
    amountLiquidity: number | BigNumber;
}
interface RemoveLiquidityETHOptions {
    signer: SignerWithAddress;
    token: string;
    amountLiquidity: number | BigNumber;
}
interface SwapExactTokensForTokensOptions {
    signer: SignerWithAddress;
    amountIn: number | BigNumber;
    inputToken: string;
    outputToken: string;
}

interface SwapTokensForExactTokensOptions {
    signer: SignerWithAddress;
    amountOut: number | BigNumber;
    inputToken: string;
    outputToken: string;
}

interface QuoteOptions {
    signer: SignerWithAddress;
    tokenA: string;
    tokenB: string;
    amountA: number | BigNumber;
}

interface GetLiquidityValueInTermsOfTokenAOptions {
    signer: SignerWithAddress;
    tokenA: string;
    tokenB: string;
    amountLiquidity: number | BigNumber;
}
interface AddLiquidityETHOptions {
    signer: SignerWithAddress;
    token: string;
    amountToken: number | BigNumber;
    amountETH: number | BigNumber;
}

V3 Functions

function async deploy(signer: SignerWithAddress): Promise<{
    weth9: Contract;
    WETH9: ContractFactory;
    factory: Contract;
    Factory: ContractFactory;
    router: Contract;
    Router: ContractFactory;
    tokenDescriptor: Contract;
    TokenDescriptor: ContractFactory;
    nftDescriptorLibrary: Contract;
    NFTDescriptorLibrary: ContractFactory;
    positionManager: Contract;
    PositionManager: ContractFactory;
}>;

function async getWeth(signer: SignerWithAddress): Promise<Contract>;

function async getFactory(signer: SignerWithAddress): Promise<Contract>;

function async getFactory(signer: SignerWithAddress): Promise<Contract>;

function async getRouter(signer: SignerWithAddress): Promise<Contract>;

function async getPair(signer: SignerWithAddress, tokenA: string, tokenB: string);

function async createERC20(signer: SignerWithAddress, name: string, symbol: string): Promise<Contract>;

function getERC20(address: string): Contract | undefined;

function async exactInputSingle(options: ExactInputSingleOptions)

function async exactInput(options: ExactInputOptions);

function async exactOutputSingle(options: ExactOutputSingleOptions);

function async exactOutput(options: ExactOutputOptions);

function async mintPosition(options: MintOptions): Promise<Number>;

function async collectFees(options: CollectOptions): Promise<Number>;

function async increaseLiquidity(options: IncreaseLiquidityOptions);

function async decreaseLiquidity(options: DecreaseLiquidityOptions): Promise<Array<number>>;

V3 Interfaces

interface ExactInputSingleOptions {
    signer: SignerWithAddress;
    tokenIn: string;
    tokenOut: string;
    fee: number;
    amountIn: number | BigNumber;
}

interface ExactInputOptions {
    signer: SignerWithAddress;
    path: Array<string | number>;
    amountIn: number | BigNumber;
}

interface ExactOutputSingleOptions {
    signer: SignerWithAddress,
    tokenIn: string;
    tokenOut: string;
    fee: number;
    amountOut: number | BigNumber;
}

interface ExactOutputOptions {
    signer: SignerWithAddress;
    path: Array<string | number>;
    amountOut: number | BigNumber;
}


interface MintOptions {
    signer: SignerWithAddress;
    token0: string;
    token1: string;
    fee: number;
    amount0Desired: number | BigNumber;
    amount1Desired: number | BigNumber;
    price: number;
}

interface CollectOptions {
    signer: SignerWithAddress;
    tokenId: number;
}

interface IncreaseLiquidityOptions {
    signer: SignerWithAddress;
    tokenId: number;
    amount0Desired: number | BigNumber;
    amount1Desired: number | BigNumber;
}

interface DecreaseLiquidityOptions {
    signer: SignerWithAddress;
    tokenId: number;
    amountLiquidity: number | BigNumber;
}