Managing Liquidity

Beyond trading, uniswap-python allows you to interact with Uniswap as a Liquidity Provider (LP).

Providing liquidity allows you to earn a share of the trading fees. However, it also exposes you to Impermanent Loss. Ensure you understand the financial mechanics of AMMs before provisioning capital.

Important Note: Uniswap V3 introduced Concentrated Liquidity, which radically changed how liquidity is provided compared to V1/V2. In V3, liquidity is provided within a specific price range (ticks) and represented as an NFT.

Uniswap V3 Liquidity

1. Determining Tick Ranges

In V3, you must specify the lower and upper price bounds (ticks) for your liquidity. If the current price moves outside this range, your capital stops earning fees.

To make this easier, uniswap-python provides utilities to calculate the absolute minimum and maximum ticks allowed for a specific fee tier.

from uniswap.util import default_tick_range
from uniswap.fee import FeeTier

# Get the absolute min and max ticks for the 0.3% fee tier
min_tick, max_tick = default_tick_range(FeeTier.TIER_3000)

2. Minting a New Position

To provide liquidity, you use the mint_liquidity method. This requires an instance of the specific pool contract you want to provide liquidity to.

# 1. Retrieve the pool contract instance
pool = uniswap.get_pool_instance(DAI, USDC, fee=FeeTier.TIER_3000)

# 2. Define the amounts you wish to provide
amount_dai = 1000 * 10**18
amount_usdc = 1000 * 10**6

# 3. Mint the position
# The library automatically handles approving the NonFungiblePositionManager
receipt = uniswap.mint_liquidity(
    pool=pool,
    amount_0=amount_dai,
    amount_1=amount_usdc,
    tick_lower=min_tick,
    tick_upper=max_tick
)

print("Liquidity added successfully!")

3. Viewing Your Positions

Because V3 positions are non-fungible, they are minted as ERC721 tokens (NFTs). You can retrieve an array of Token IDs owned by your configured wallet address.

# Returns a list of integers (Token IDs)
position_ids = uniswap.get_liquidity_positions()
print(f"You own positions: {position_ids}")

4. Closing a Position & Collecting Fees

The close_position method executes three operations in a single atomic transaction:

  1. It removes 100% of the liquidity from the specified position.
  2. It collects all accumulated trading fees.
  3. It burns the NFT.
# Close the position using its NFT Token ID
token_id = 123456
receipt = uniswap.close_position(tokenId=token_id)

print("Position closed, capital and fees returned to wallet.")

Uniswap V1 / V2 Liquidity (Legacy)

In V1 and V2, liquidity is provided across the entire price curve from 0 to infinity. In return, you receive fungible ERC20 LP tokens representing your share of the pool.

Note: V1 and V2 liquidity methods in this library are considered legacy. They are fully functional for V1, but V2 wrapper updates are ongoing. Use with caution.

Adding Liquidity (V1)

# Add liquidity to the BAT/ETH pool
# You specify the max ETH you are willing to deposit.
# The contract calculates the required BAT based on current reserves.
uniswap.add_liquidity(token=BAT, max_eth=1 * 10**18, min_liquidity=1)

Removing Liquidity (V1)

# Remove liquidity by burning your LP tokens
# Provide the exact amount of LP tokens to burn
uniswap.remove_liquidity(token=BAT, max_token=100 * 10**18)