Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/lp-sdk-gas-estimation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@uniswap/lp-sdk': minor
---

Introduce @uniswap/lp-sdk with LP gas-estimation helpers: pickPreEstimateIndependentAmount for choosing a representative simulation amount from wallet balances, and getV2/getV3/getV4AddLiquidityGasEstimateTransactions for building the ordered approval + create/increase transaction lists to run eth_estimateGas over.
60 changes: 53 additions & 7 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions sdks/lp-sdk/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module'
},
extends: [
'react-app',
'prettier',
'plugin:prettier/recommended'
],
settings: {
react: {
version: '999.999.999'
}
}
};

5 changes: 5 additions & 0 deletions sdks/lp-sdk/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# build
dist

# dependencies
node_modules
21 changes: 21 additions & 0 deletions sdks/lp-sdk/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2021 Uniswap Labs

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
29 changes: 29 additions & 0 deletions sdks/lp-sdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# @uniswap/lp-sdk

An SDK for building liquidity-provision flows on top of Uniswap v2, v3, and v4. It composes the
position calldata builders from `@uniswap/v2-sdk`, `@uniswap/v3-sdk`, and `@uniswap/v4-sdk` into
cross-version helpers, following the same pattern `@uniswap/router-sdk` uses for swaps.

Like all SDKs in this repository, it is chain-agnostic and makes no network calls: helpers take
onchain state (balances, allowances, pool state) as inputs and return transaction tuples
(`{ to, calldata, value }`).

## Gas estimation helpers

Estimating the real cost of an LP flow (instead of reserving a hardcoded native-token buffer)
requires estimating every transaction the user will send — token approvals included — before the
user has entered an amount. These helpers produce that transaction list:

- `pickPreEstimateIndependentAmount(balance0, balance1)` — picks which pool token (and how much of
it) to drive a representative simulation with, from the wallet's two token balances. Balances are
capped at 10^(decimals + 3) raw units; returns `null` when both are zero.
- `getV2AddLiquidityGasEstimateTransactions(params)` — approvals to the v2 router plus the
`addLiquidity`/`addLiquidityETH` transaction.
- `getV3AddLiquidityGasEstimateTransactions(params)` — approvals to the `NonfungiblePositionManager`
plus the mint/increase transaction (`NonfungiblePositionManager.addCallParameters`).
- `getV4AddLiquidityGasEstimateTransactions(params)` — ERC-20 approvals to Permit2, Permit2
approvals to the v4 position manager, plus the mint/increase transaction
(`V4PositionManager.addCallParameters`).

Callers run `eth_estimateGas` over the returned transactions in order (from the wallet's address)
and sum the results. Approvals are included pessimistically when no allowance state is provided.
64 changes: 64 additions & 0 deletions sdks/lp-sdk/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"name": "@uniswap/lp-sdk",
"version": "0.0.0",
"description": "An SDK for building liquidity-provision flows on top of Uniswap v2, v3, and v4",
"repository": "https://github.com/Uniswap/sdks.git",
"keywords": [
"uniswap",
"ethereum"
],
"license": "MIT",
"main": "./dist/cjs/src/index.js",
"typings": "./dist/types/src/index.d.ts",
"module": "./dist/esm/src/index.js",
"exports": {
".": {
"types": "./dist/types/src/index.d.ts",
"import": "./dist/esm/src/index.js",
"require": "./dist/cjs/src/index.js"
}
},
"sideEffects": false,
"files": [
"dist"
],
"engines": {
"node": ">=18"
},
"scripts": {
"build": "bun run clean && tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json && tsc -p tsconfig.types.json",
"clean": "rm -rf dist",
"lint": "eslint 'src/**/*.{js,ts,tsx}' --max-warnings 0",
"release": "changeset publish",
"test": "bun test"
},
"dependencies": {
"@ethersproject/abi": "^5.5.0",
"@uniswap/permit2-sdk": "workspace:*",
"@uniswap/sdk-core": "workspace:*",
"@uniswap/v2-sdk": "workspace:*",
"@uniswap/v3-sdk": "workspace:*",
"@uniswap/v4-sdk": "workspace:*",
"jsbi": "^3.1.4",
"tiny-invariant": "^1.1.0",
"tslib": "^2.3.0"
},
"devDependencies": {
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-config-react-app": "7.0.1",
"eslint-plugin-prettier": "^3.4.1",
"prettier": "^2.4.1",
"typescript": "^4.3.3"
},
"prettier": {
"printWidth": 120,
"semi": false,
"singleQuote": true
},
"publishConfig": {
"access": "public",
"provenance": true
}
}
14 changes: 14 additions & 0 deletions sdks/lp-sdk/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Percent } from '@uniswap/sdk-core'

/**
* Default slippage tolerance applied when none is provided. Matches the default used
* by the Uniswap Labs liquidity service so estimates line up with the transactions
* users actually sign.
*/
export const DEFAULT_LP_SLIPPAGE_TOLERANCE = new Percent(250, 10_000) // 2.5%

/**
* Default slippage tolerance for v4 pools with a native currency side. Matches the
* Uniswap Labs liquidity service default for native v4 pools.
*/
export const DEFAULT_NATIVE_V4_SLIPPAGE_TOLERANCE = new Percent(5, 10_000) // 0.05%
9 changes: 9 additions & 0 deletions sdks/lp-sdk/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export { DEFAULT_LP_SLIPPAGE_TOLERANCE, DEFAULT_NATIVE_V4_SLIPPAGE_TOLERANCE } from './constants'
export type { LpGasEstimateTransaction, Permit2AllowanceInput, TokenAllowanceInput } from './types'
export { pickPreEstimateIndependentAmount } from './utils/pickPreEstimateIndependentAmount'
export { getV2AddLiquidityGasEstimateTransactions } from './v2'
export type { V2AddLiquidityGasEstimateParams } from './v2'
export { getV3AddLiquidityGasEstimateTransactions } from './v3'
export type { V3AddLiquidityGasEstimateParams } from './v3'
export { getV4AddLiquidityGasEstimateTransactions } from './v4'
export type { V4AddLiquidityGasEstimateParams } from './v4'
48 changes: 48 additions & 0 deletions sdks/lp-sdk/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { BigintIsh } from '@uniswap/sdk-core'

/**
* A transaction to include in a gas-estimation batch.
*
* The SDK never talks to the chain: callers run `eth_estimateGas` over the returned
* list (in order, from the position owner's address) with their own client and sum
* the results to get the full cost of the flow.
*/
export interface LpGasEstimateTransaction {
to: string
calldata: string
value: string
}

/**
* The caller-provided allowance state for one pool token. All fields are optional:
* when omitted the token is assumed to have zero allowance, which yields the
* worst-case (most transactions) estimate.
*/
export interface TokenAllowanceInput {
/**
* Current ERC-20 allowance granted by the wallet to the relevant spender
* (v2 router / v3 position manager / Permit2 for v4). Assumed 0 when omitted.
*/
allowance?: BigintIsh
/**
* USDT-style tokens revert on approve when the current allowance is non-zero, so
* they need an approve(0) reset transaction first. Only relevant when `allowance`
* is non-zero but insufficient.
*/
requiresReset?: boolean
}

/**
* Allowance state for one pool token in a v4 flow, which pulls funds through Permit2.
*/
export interface Permit2AllowanceInput extends TokenAllowanceInput {
/**
* Current Permit2 allowance (token -> position manager) for the wallet. Assumed
* absent when omitted. The allowance counts as active when `amount` covers the
* required amount and `expiration` is at or after the flow's `deadline`.
*/
permit2Allowance?: {
amount: BigintIsh
expiration: BigintIsh
}
}
Loading
Loading