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
2 changes: 1 addition & 1 deletion docs/contracts/liquidity-launchpad/01-introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ The Uniswap Liquidity Launchpad framework is built on three coordinated componen

1. **[Liquidity Launcher →](https://github.com/Uniswap/liquidity-launcher)** Central orchestration contract that coordinates distribution and liquidity deployment
2. **[Token Factory →](https://github.com/Uniswap/uerc20-factory)** (Optional) Creates new ERC-20 tokens with metadata, or integrates existing tokens
3. **Liquidity Strategies** - Modular contracts for different price discovery and liquidity mechanisms (prebuilt [LBP Strategy](https://github.com/Uniswap/liquidity-launcher) or [custom strategies](./05-strategies.md#writing-a-custom-strategy))
3. **Liquidity Strategies** - Modular contracts for different price discovery and liquidity mechanisms (prebuilt [LBP Strategy](./06-strategies.md#lbpstrategybase) or [custom strategies](./06-strategies.md#writing-a-custom-strategy))

Each component is designed to be composable and extensible, allowing you to customize your liquidity bootstrapping while maintaining security and fairness guarantees.

Expand Down
68 changes: 34 additions & 34 deletions docs/contracts/v4/guides/position-manager.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ At its core, the Position Manager works by executing a sequence of commands:
```solidity
// Example: Minting a new position requires two commands
bytes memory actions = abi.encodePacked(
Actions.MINT_POSITION, // Create the position
Actions.SETTLE_PAIR // Provide the tokens
uint8(Actions.MINT_POSITION), // Create the position
uint8(Actions.SETTLE_PAIR) // Provide the tokens
);
```

Expand Down Expand Up @@ -108,17 +108,17 @@ Understanding how operations create and resolve deltas helps in ordering them ef
```solidity
// Efficient: Group operations that create deltas, then resolve them together
bytes memory actions = abi.encodePacked(
Actions.MINT_POSITION, // First delta: -100 tokens
Actions.INCREASE_LIQUIDITY, // Second delta: -50 tokens
Actions.SETTLE_PAIR // Resolve total: -150 tokens at once
uint8(Actions.MINT_POSITION), // First delta: -100 tokens
uint8(Actions.INCREASE_LIQUIDITY), // Second delta: -50 tokens
uint8(Actions.SETTLE_PAIR) // Resolve total: -150 tokens at once
);

// Less efficient: Resolving deltas multiple times
bytes memory actions = abi.encodePacked(
Actions.MINT_POSITION, // Delta: -100 tokens
Actions.SETTLE_PAIR, // Resolve: -100 tokens
Actions.INCREASE_LIQUIDITY, // New delta: -50 tokens
Actions.SETTLE_PAIR // Resolve again: -50 tokens
uint8(Actions.MINT_POSITION), // Delta: -100 tokens
uint8(Actions.SETTLE_PAIR), // Resolve: -100 tokens
uint8(Actions.INCREASE_LIQUIDITY), // New delta: -50 tokens
uint8(Actions.SETTLE_PAIR) // Resolve again: -50 tokens
);
```

Expand Down Expand Up @@ -190,8 +190,8 @@ Define the sequence of operations needed for minting:
// 1. MINT_POSITION - Creates the position and calculates token requirements
// 2. SETTLE_PAIR - Provides the tokens needed
bytes memory actions = abi.encodePacked(
Actions.MINT_POSITION,
Actions.SETTLE_PAIR
uint8(Actions.MINT_POSITION),
uint8(Actions.SETTLE_PAIR)
);
```

Expand Down Expand Up @@ -249,18 +249,18 @@ Unlike minting where we always use SETTLE_PAIR, increasing liquidity has differe

```solidity
bytes memory actions = abi.encodePacked(
Actions.INCREASE_LIQUIDITY,
Actions.SETTLE_PAIR
uint8(Actions.INCREASE_LIQUIDITY),
uint8(Actions.SETTLE_PAIR)
);
```

**2. Fee Conversion**: When converting accumulated fees to liquidity

```solidity
bytes memory actions = abi.encodePacked(
Actions.INCREASE_LIQUIDITY,
Actions.CLOSE_CURRENCY, // For token0
Actions.CLOSE_CURRENCY // For token1
uint8(Actions.INCREASE_LIQUIDITY),
uint8(Actions.CLOSE_CURRENCY), // For token0
uint8(Actions.CLOSE_CURRENCY) // For token1
);
```

Expand Down Expand Up @@ -293,14 +293,14 @@ Choose the appropriate delta resolution based on whether we’re using fees:
bytes memory actions;
if (useFeesAsLiquidity) {
actions = abi.encodePacked(
Actions.INCREASE_LIQUIDITY, // Add liquidity
Actions.CLOSE_CURRENCY, // Handle token0 (might need to pay or receive)
Actions.CLOSE_CURRENCY // Handle token1 (might need to pay or receive)
uint8(Actions.INCREASE_LIQUIDITY), // Add liquidity
uint8(Actions.CLOSE_CURRENCY), // Handle token0 (might need to pay or receive)
uint8(Actions.CLOSE_CURRENCY) // Handle token1 (might need to pay or receive)
);
} else {
actions = abi.encodePacked(
Actions.INCREASE_LIQUIDITY, // Add liquidity
Actions.SETTLE_PAIR // Provide tokens
uint8(Actions.INCREASE_LIQUIDITY), // Add liquidity
uint8(Actions.SETTLE_PAIR) // Provide tokens
);
}
```
Expand Down Expand Up @@ -366,8 +366,8 @@ When decreasing liquidity, you’ll receive tokens, so it's most common to recei

```solidity
bytes memory actions = abi.encodePacked(
Actions.DECREASE_LIQUIDITY,
Actions.TAKE_PAIR
uint8(Actions.DECREASE_LIQUIDITY),
uint8(Actions.TAKE_PAIR)
);
```

Expand Down Expand Up @@ -452,8 +452,8 @@ function collectFees(
) external {
// Define the sequence of operations
bytes memory actions = abi.encodePacked(
Actions.DECREASE_LIQUIDITY, // Remove liquidity
Actions.TAKE_PAIR // Receive both tokens
uint8(Actions.DECREASE_LIQUIDITY), // Remove liquidity
uint8(Actions.TAKE_PAIR) // Receive both tokens
);

// Prepare parameters array
Expand Down Expand Up @@ -529,8 +529,8 @@ function burnPosition(
// 1. BURN_POSITION - Removes the position and creates positive deltas
// 2. TAKE_PAIR - Sends all tokens to the recipient
bytes memory actions = abi.encodePacked(
Actions.BURN_POSITION,
Actions.TAKE_PAIR
uint8(Actions.BURN_POSITION),
uint8(Actions.TAKE_PAIR)
);
```

Expand Down Expand Up @@ -607,9 +607,9 @@ function rebalanceLiquidity(
) external {
// Group liquidity operations first, then delta resolutions
bytes memory actions = abi.encodePacked(
Actions.BURN_POSITION, // Remove old position
Actions.MINT_POSITION, // Create new position
Actions.SETTLE_PAIR // Provide tokens for new position
uint8(Actions.BURN_POSITION), // Remove old position
uint8(Actions.MINT_POSITION), // Create new position
uint8(Actions.SETTLE_PAIR) // Provide tokens for new position
);
```

Expand Down Expand Up @@ -686,8 +686,8 @@ When you can’t predict whether you’ll need to pay or receive tokens, CLOSE_C
```solidity
// Example scenario: Converting fees to liquidity
bytes memory actions = abi.encodePacked(
Actions.INCREASE_LIQUIDITY,
Actions.CLOSE_CURRENCY // Will automatically settle or take based on final delta
uint8(Actions.INCREASE_LIQUIDITY),
uint8(Actions.CLOSE_CURRENCY) // Will automatically settle or take based on final delta
);

bytes[] memory params = new bytes[](2);
Expand Down Expand Up @@ -739,8 +739,8 @@ SWEEP helps recover any excess tokens sent to the PoolManager:

```solidity
bytes memory actions = abi.encodePacked(
Actions.YOUR_MAIN_OPERATION,
Actions.SWEEP // Add at the end to collect any excess
uint8(Actions.YOUR_MAIN_OPERATION),
uint8(Actions.SWEEP) // Add at the end to collect any excess
);

// Parameters for SWEEP
Expand Down
2 changes: 1 addition & 1 deletion docs/sdk/v3/guides/advanced/02-pool-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const USDC_TOKEN = new Token(
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
6,
'USDC',
'USD//C'
'USDC'
)
```

Expand Down
4 changes: 2 additions & 2 deletions docs/sdk/v3/guides/swaps/01-quoting.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ const USDC_TOKEN = new Token(
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
6,
'USDC',
'USD//C'
'USDC'
)
```

Expand Down Expand Up @@ -184,7 +184,7 @@ We get access to the contract's ABI through the [@uniswap/v3-periphery](https://
import Quoter from '@uniswap/v3-periphery/artifacts/contracts/lens/Quoter.sol/Quoter.json'
```

We get the QUOTE_CONTRACT_ADDRESS for our chain from [GitHub](https://github.com/Uniswap/v3-periphery/blob/main/deploys.md).
We get the QUOTER_CONTRACT_ADDRESS for our chain from [GitHub](https://github.com/Uniswap/v3-periphery/blob/main/deploys.md).

We can now use our Quoter contract to obtain the quote.

Expand Down
32 changes: 16 additions & 16 deletions docs/sdk/v4/guides/advanced/pool-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ export const CurrentConfig: ExampleConfig = {
},
...
poolKey: {
currency0: USDC_TOKEN.address,
currency1: ETH_TOKEN.address,
currency0: ETH_TOKEN.address,
currency1: USDC_TOKEN.address,
fee: FEE_AMOUNT_LOW,
tickSpacing: TICK_SPACING_TEN,
hooks: EMPTY_HOOK,
Expand Down Expand Up @@ -73,7 +73,7 @@ export const USDC_TOKEN = new Token(

## Computing the PoolId out of PoolKey

In this example, we will construct the **USDC - ETH** Pool with **LOW** fees and without hooks. The SDK provides a method to compute the `PoolId` for this pool:
In this example, we will construct the **ETH - USDC** Pool with **LOW** fees and without hooks. The SDK provides a method to compute the `PoolId` for this pool:

```typescript
import { Pool } from '@uniswap/v4-sdk';
Expand All @@ -85,7 +85,7 @@ const poolId = Pool.getPoolId(currency0, currency1, fee, tickSpacing, hooks);

## Referencing the StateView contract and fetching metadata

Now that we have the `PoolId` of a **USDC - ETH** Pool, we need to call [StateView](/contracts/v4/guides/state-view) contract to get the pool state. In v4 you need to use `StateLibrary` to read pool state, but offchain systems—such as frontends or analytics services—require a deployed contract with view functions. This is where `StateView` comes in.
Now that we have the `PoolId` of a **ETH - USDC** Pool, we need to call [StateView](/contracts/v4/guides/state-view) contract to get the pool state. In v4 you need to use `StateLibrary` to read pool state, but offchain systems—such as frontends or analytics services—require a deployed contract with view functions. This is where `StateView` comes in.
To construct the Contract we need to provide the address of the contract, its ABI and a provider connected to an RPC endpoint.

```typescript
Expand All @@ -103,7 +103,7 @@ const stateViewContract = new ethers.Contract(

We get the `STATE_VIEW_ADDRESS` for our chain from [Uniswap Deployments](/contracts/v4/deployments).
Once we have set up our reference to the contract, we can proceed to access its methods. To construct our offchain representation of the Pool, we need to fetch its liquidity, sqrtPrice, currently active tick and the full Tick data.
We get the **liquidity**, **sqrtPrice** and **tick** directly from the blockchain by calling `getLiquidity()`and `getSlot0()` on the StateView contract:
We get the **liquidity**, **sqrtPrice** and **tick** directly from the blockchain by calling `getLiquidity()` and `getSlot0()` on the StateView contract:

```typescript
const [slot0, liquidity] = await Promise.all([
Expand All @@ -127,12 +127,12 @@ For our use case, we only need the `sqrtPriceX96` and the currently active `tick
## Fetching all Ticks

v4 pools use ticks to [concentrate liquidity](/concepts/protocol/concentrated-liquidity) in price ranges and allow for better pricing of trades.
Even though most Pools only have a couple of **initialized ticks**, it is possible that a pools liquidity is defined by thousands of **initialized ticks**.
Even though most Pools only have a couple of **initialized ticks**, it is possible that a pool's liquidity is defined by thousands of **initialized ticks**.
In that case, it can be very expensive or slow to get all of them with normal RPC calls.

If you are not familiar with the concept of ticks, check out the [`introduction`](/concepts/protocol/concentrated-liquidity#ticks).

To access tick data, we will use the `getTickInfo` function of the State View contract:
To access tick data, we will use the `getTickInfo` function of the StateView contract:

```solidity
function getTickInfo(PoolId poolId, int24 tick)
Expand All @@ -148,7 +148,7 @@ To access tick data, we will use the `getTickInfo` function of the State View co

The `tick` parameter that we provide the function with is the **index** (memory position) of the Tick we are trying to fetch.
To get the indices of all initialized Ticks of the Pool, we can calculate them from the **tickBitmaps**.
To fetch a `tickBitmap` we use a `getTickBitmap` function of the State View contract:
To fetch a `tickBitmap` we use a `getTickBitmap` function of the StateView contract:

```solidity
function getTickBitmap(
Expand All @@ -159,7 +159,7 @@ To fetch a `tickBitmap` we use a `getTickBitmap` function of the State View cont

A pool stores lots of bitmaps, each of which contain the status of 256 Ticks.
The parameter `int16 wordPosition` the function accepts is the position of the bitMap we want to fetch.
We can calculate all the position of bitMaps (or words as they are sometimes called) from the `tickSpacing` of the Pool, which is in turn dependant on the Fee tier.
We can calculate all the position of bitMaps (or words as they are sometimes called) from the `tickSpacing` of the Pool, which is in turn dependent on the Fee tier.

So to summarise we need 4 steps to fetch all initialized ticks:

Expand All @@ -176,7 +176,7 @@ Multicall contracts **aggregate results** from multiple contract calls and there
This can improve the **speed** of fetching large amounts of data significantly and ensures that the data fetched is all from the **same block**.

We will use the Multicall2 contract by MakerDAO.
We use the `ethers-muticall` npm package to easily interact with the Contract.
We use the `ethers-multicall` npm package to easily interact with the Contract.

## Calculating all bitMap positions

Expand Down Expand Up @@ -207,7 +207,7 @@ One word contains 256 ticks, so we can compress the ticks by right shifting 8 bi

Knowing the positions of words, we can now fetch them using multicall.

First we initialize our multicall providers and State View Contract:
First we initialize our multicall providers and StateView Contract:

```typescript
import { ethers } from 'ethers'
Expand Down Expand Up @@ -245,7 +245,7 @@ const results: bigint[] = (await multicallProvider.all(calls)).map(
)
```

A great visualization of what the bitMaps look like can be found in the [Uniswap v3 development book](https://uniswapv3book.com/docs/milestone_2/tick-bitmap-index/](https://uniswapv3book.com/milestone_2/tick-bitmap-index.html):
A great visualization of what the bitMaps look like can be found in the [Uniswap v3 development book](https://uniswapv3book.com/milestone_2/tick-bitmap-index.html):

<img src={require('./images/tickBitmap_cut.png').default} alt="TickBitmap" box-shadow="none"/>

Expand All @@ -262,7 +262,7 @@ const bit = 1n
const initialized = (bitmap & (bit << BigInt(i))) !== 0n
```

If the tick is **initialized**, we revert the compression from tick to word we made earlier by multiplying the word index with 256, which is the same as left shifting by 8 bit, adding the position we are currently at, and multiplying with the tickSpacing:
If the tick is **initialized**, we revert the compression from tick to word we made earlier by multiplying the word index with 256, which is the same as left shifting by 8 bits, adding the position we are currently at, and multiplying with the tickSpacing:

```typescript
const tickIndex = (ind * 256 + i) * tickSpacing
Expand Down Expand Up @@ -333,9 +333,9 @@ We need to parse the response from our RPC provider to JSBI values that the v4-s
We have everything to construct our `Pool` now:

```typescript
const usdcWethPool = new Pool(
USDC,
WETH,
const usdcEthPool = new Pool(
USDC_TOKEN,
ETH_TOKEN,
feeAmount,
slot0.sqrtPriceX96,
liquidity,
Expand Down
2 changes: 1 addition & 1 deletion docs/sdk/v4/guides/liquidity/collecting-fees.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ async function verifyFeeCollection(receipt, userAddress, positionDetails, ethBal

### Check Your Token Balances

You can simply measuring the balance change in your wallet before vs. after the call. For example, read your token balances (and ETH balance) prior to calling, then after the transaction confirm the increases. Because v4 might auto-wrap or unwrap ETH, if one of the tokens was ETH you should check your ETH balance difference. In ETH pools, no ERC-20 transfer event will fire for the ETH – the ETH will be sent directly to you (as an internal transfer), which is why checking the balance or the transaction's internal traces is necessary to confirm the amount.
You can simply measure the balance change in your wallet before vs. after the call. For example, read your token balances (and ETH balance) prior to calling, then after the transaction confirm the increases. Because v4 might auto-wrap or unwrap ETH, if one of the tokens was ETH you should check your ETH balance difference. In ETH pools, no ERC-20 transfer event will fire for the ETH – the ETH will be sent directly to you (as an internal transfer), which is why checking the balance or the transaction's internal traces is necessary to confirm the amount.

```typescript
// Check native ETH balance changes
Expand Down
4 changes: 2 additions & 2 deletions docs/sdk/v4/guides/swaps/multi-hop-swapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@ const receipt = await tx.wait()
console.log('Multi-hop swap completed! Transaction hash:', receipt.transactionHash)
```

The token approvals for ERC20 token swaps remain the same as the [single-hop swapping guide](./02-single-hop-swapping.md).
The token approvals for ERC20 token swaps remain the same as the [single-hop swapping guide](./single-hop-swapping.md).

## Next Steps

Now that you're familiar with trading, consider checking out our next guides on [pooling liquidity](../liquidity/01-pool-data.md) to Uniswap!
Now that you're familiar with trading, consider checking out our next guides on [pooling liquidity](../advanced/pool-data.md) to Uniswap!
4 changes: 2 additions & 2 deletions docs/sdk/v4/guides/swaps/quoting.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const quoterContract = new ethers.Contract(
)
```

We get the `QUOTE_CONTRACT_ADDRESS` for our chain from [Uniswap Deployments](https://docs.uniswap.org/contracts/v4/deployments).
We get the `QUOTER_CONTRACT_ADDRESS` for our chain from [Uniswap Deployments](https://docs.uniswap.org/contracts/v4/deployments).

We can now use our Quoter contract to obtain the quote.

Expand All @@ -109,7 +109,7 @@ The result of the call is the number of output tokens you would receive for the
It should be noted that `quoteExactInputSingle` is only 1 of 4 different methods that the quoter offers:

1. `quoteExactInputSingle` - given an input amount, produce a quote of the output amount for a swap on a single pool
2. `quoteExactInput` - given an input amount, produce a quote for the output amount a swap over multiple pools
2. `quoteExactInput` - given an input amount, produce a quote for the output amount for a swap over multiple pools
3. `quoteExactOutputSingle` - given a desired output amount, produce a quote for the input amount on a swap over a single pool
4. `quoteExactOutput` - given a desired output amount, produce a quote for the input amount in for a swap over multiple pools

Expand Down
2 changes: 1 addition & 1 deletion docs/sdk/v4/guides/swaps/single-hop-swapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,4 @@ The rest of the swap process remains the same.

## Next Steps

Now that you understand single-hop swaps, you might want to explore [multi-hop swaps](./03-multi-hop-swapping.md) for trading between tokens without direct pools or enough liquidity.
Now that you understand single-hop swaps, you might want to explore [multi-hop swaps](./multi-hop-swapping.md) for trading between tokens without direct pools or enough liquidity.
Loading