SkillAgentSearch skills...

Nethereum.Uniswap

Uniswap V2, V3, V4 Universal Router, Permit2 get started to work with Nethereum

Install / Use

/learn @Nethereum/Nethereum.Uniswap
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Nethereum.Uniswap V2, V3, V4, Universal Router and Permit 2

Uniswap V2, V3, V4, Universal Router and Permit 2 integration with Nethereum.


Uniswap V4 Integration with Nethereum

Comprehensive examples for interacting with Uniswap V4 on Ethereum mainnet and testnets using Nethereum.

Setup

var url = "https://base-sepolia.drpc.org";
var privateKey = "0xYOUR_PRIVATE_KEY";
var web3 = new Web3.Web3(new Account(privateKey), url);

// Access Uniswap V4 services - defaults to Mainnet
var uniswap = web3.UniswapV4();

// Or specify a different network
var uniswap = web3.UniswapV4(UniswapV4Addresses.BaseSepolia);

// Access pool manager through service hierarchy
var poolManager = uniswap.Pools.Manager;
var usdc = "0x91D1e0b9f6975655A381c79fd6f1D118D1c5b958";

var pool = new PoolKey()
{
    Currency0 = AddressUtil.ZERO_ADDRESS,
    Currency1 = usdc,
    Fee = 500,
    TickSpacing = 10,
    Hooks = "0x24F7c9ea6B5be5227caAeB61366b56052386eae4"
};

Quoting Prices

var uniswap = web3.UniswapV4(UniswapV4Addresses.BaseSepolia);

// Access StateView and Quoter through service hierarchy
var stateViewService = uniswap.Positions.StateView;
var v4Quoter = uniswap.Pricing.Quoter;

var pathKeys = V4PathEncoder.EncodeMultihopExactInPath(new List<PoolKey> { pool }, AddressUtil.ZERO_ADDRESS);
var amountIn = Web3.Web3.Convert.ToWei(0.001);

var quoteExactParams = new QuoteExactParams()
{
    Path = pathKeys,
    ExactAmount = amountIn,
    ExactCurrency = AddressUtil.ZERO_ADDRESS
};

var quote = await v4Quoter.QuoteExactInputQueryAsync(quoteExactParams);
var quoteAmount = Web3.Web3.Convert.FromWei(quote.AmountOut, 6); // USDC has 6 decimals

Executing Swaps with Universal Router

var uniswap = web3.UniswapV4();
var universalRouter = uniswap.UniversalRouter;
var v4ActionBuilder = uniswap.GetUniversalRouterV4ActionsBuilder();

// Add swap action
var swapExactIn = new SwapExactIn()
{
    CurrencyIn = eth,
    AmountIn = amountIn,
    AmountOutMinimum = quote.AmountOut * 95 / 100, // 5% slippage
    Path = pathKeys.MapToActionV4()
};
v4ActionBuilder.AddCommand(swapExactIn);

// Settle input currency (ETH)
var settleAll = new SettleAll()
{
    Currency = eth,
    Amount = amountIn
};
v4ActionBuilder.AddCommand(settleAll);

// Take output currency (USDC)
var takeAll = new TakeAll()
{
    Currency = usdc,
    MinAmount = 0
};
v4ActionBuilder.AddCommand(takeAll);

var routerBuilder = new UniversalRouterBuilder();
routerBuilder.AddCommand(v4ActionBuilder.GetV4SwapCommand());

var executeFunction = routerBuilder.GetExecuteFunction(amountIn);
var receipt = await universalRouter.ExecuteRequestAndWaitForReceiptAsync(executeFunction);

Price Calculations and Math Utilities

Calculate Pool Prices from SqrtPriceX96

var uniswap = web3.UniswapV4();
var prices = uniswap.Pricing.PriceCalculator.CalculatePricesFromSqrtPriceX96(
    sqrtPriceX96,
    token0Decimals: 18,
    token1Decimals: 6);

var priceToken0InToken1 = prices.Item1; // Price of token0 in terms of token1
var priceToken1InToken0 = prices.Item2; // Price of token1 in terms of token0

Tick Math - Convert Between Ticks and Prices

var uniswap = web3.UniswapV4();

// Get sqrt price from tick
var sqrtPriceX96 = uniswap.Math.Tick.GetSqrtRatioAtTick(tick);

// Get tick from sqrt price
var tick = uniswap.Math.Tick.GetTickAtSqrtRatio(sqrtPriceX96);

Liquidity Math - Calculate Token Amounts

var uniswap = web3.UniswapV4();
var amounts = uniswap.Positions.LiquidityCalculator.GetAmountsForLiquidityByTicks(
    sqrtPriceX96,
    tickLower,
    tickUpper,
    liquidity);

var amount0 = amounts.Item1;
var amount1 = amounts.Item2;

Slippage and Price Impact Protection

Calculate Slippage-Protected Amounts

var uniswap = web3.UniswapV4();

// For exact input swaps (you know input, calculate min output)
var tolerance = new BigDecimal(0.5m); // 0.5% slippage

var minAmountOut = uniswap.Pricing.SlippageCalculator.CalculateMinimumAmountOut(
    expectedAmountOut,
    tolerance);

// For exact output swaps (you know output, calculate max input)
var maxAmountIn = uniswap.Pricing.SlippageCalculator.CalculateMaximumAmountIn(
    expectedAmountIn,
    tolerance);

Calculate and Monitor Price Impact

var uniswap = web3.UniswapV4();
var calculator = uniswap.Pricing.PriceImpactCalculator;

// Calculate price impact percentage
var priceImpact = calculator.CalculatePriceImpact(
    inputAmount,
    outputAmount,
    midPrice);

// Classify impact level
var impactLevel = calculator.ClassifyPriceImpact(priceImpact);
// Returns: Low (<1%), Medium (1-3%), High (3-5%), Critical (>5%)

// Get user-friendly warning message
var warning = calculator.GetPriceImpactWarning(impactLevel);

Pool Discovery and Caching

Access Pool Cache Service

var uniswap = web3.UniswapV4();
var poolCache = uniswap.Pools.Cache;

Fetch and Cache Pool Data

// Get or fetch pool (uses cache if available)
var pool = await poolCache.GetOrFetchPoolAsync(
    currency0: eth,
    currency1: usdc,
    fee: 500,
    tickSpacing: 10);

// Access pool information
var poolId = pool.PoolId;
var sqrtPriceX96 = pool.SqrtPriceX96;
var currentTick = pool.Tick;
var exists = pool.Exists;

Event-Based Pool Discovery

var uniswap = web3.UniswapV4();

// Find all pools containing a specific token using Initialize events
var latestBlock = await web3.Eth.Blocks.GetBlockNumber.SendRequestAsync();
var startBlock = latestBlock.Value - 100_000; // look back ~100k blocks

var pools = await uniswap.Pools.Cache.FindPoolsForTokenAsync(
    token: usdc,
    fromBlockNumber: startBlock,
    toBlockNumber: latestBlock.Value);

// Pools are automatically cached for future use
foreach (var pool in pools)
{
    Console.WriteLine($"Pool: {pool.Currency0}/{pool.Currency1}, Fee: {pool.Fee}");
}

Manage Cache

var uniswap = web3.UniswapV4();

// Refresh specific pool
var updatedPool = await uniswap.Pools.Cache.RefreshPoolAsync(poolId);

// Get all cached pools
var allPools = await uniswap.Pools.Cache.GetAllCachedPoolsAsync();

// Clear cache
await uniswap.Pools.Cache.ClearCacheAsync();

Position Management

Creating a New Position

var uniswap = web3.UniswapV4();
var positionManager = uniswap.Positions.Manager;

var poolKey = new PoolKey()
{
    Currency0 = AddressUtil.ZERO_ADDRESS,
    Currency1 = usdc,
    Fee = 500,
    TickSpacing = 10,
    Hooks = AddressUtil.ZERO_ADDRESS
};

var actionsBuilder = uniswap.Positions.CreatePositionManagerActionsBuilder();

actionsBuilder.AddCommand(new MintPosition()
{
    PoolKey = poolKey,
    TickLower = -600,
    TickUpper = 600,
    Liquidity = Web3.Web3.Convert.ToWei(0.01m),
    Amount0Max = Web3.Web3.Convert.ToWei(0.1m),
    Amount1Max = Web3.Web3.Convert.ToWei(300, UnitConversion.EthUnit.Mwei),
    Recipient = account,
    HookData = new byte[0]
});

actionsBuilder.AddCommand(new SettlePair() { Currency0 = eth, Currency1 = usdc });

var receipt = await positionManager.ModifyLiquiditiesRequestAndWaitForReceiptAsync(
    new ModifyLiquiditiesFunction
    {
        UnlockData = actionsBuilder.GetUnlockData(),
        Deadline = DateTimeOffset.UtcNow.ToUnixTimeSeconds() + 60,
        AmountToSend = Web3.Web3.Convert.ToWei(0.1m)
    });

var tokenId = V4PositionReceiptHelper.GetMintedTokenId(receipt, UniswapAddresses.MainnetPositionManagerV4);

Querying Position Information

// Get position liquidity
var liquidity = await positionManager.GetPositionLiquidityQueryAsync(tokenId);

// Get pool key and position info
var positionInfo = await positionManager.GetPoolAndPositionInfoQueryAsync(tokenId);
Console.WriteLine($"Pool: {positionInfo.PoolKey.Currency0}/{positionInfo.PoolKey.Currency1}");
Console.WriteLine($"Fee: {positionInfo.PoolKey.Fee}");

// Decode position details
var uniswap = web3.UniswapV4();
var positionInfoBytes = await positionManager.PositionInfoQueryAsync(tokenId);
var decodedInfo = uniswap.Positions.PositionInfoDecoder.DecodePositionInfo(positionInfoBytes);
Console.WriteLine($"Range: {decodedInfo.TickLower} to {decodedInfo.TickUpper}");

// Get position owner
var owner = await positionManager.OwnerOfQueryAsync(tokenId);

Increasing Liquidity

var uniswap = web3.UniswapV4();
var actionsBuilder = uniswap.Positions.CreatePositionManagerActionsBuilder();

actionsBuilder.AddCommand(new IncreaseLiquidity()
{
    TokenId = tokenId,
    Liquidity = Web3.Web3.Convert.ToWei(0.005m),
    Amount0Max = Web3.Web3.Convert.ToWei(0.05m),
    Amount1Max = Web3.Web3.Convert.ToWei(150, UnitConversion.EthUnit.Mwei),
    HookData = new byte[0]
});

actionsBuilder.AddCommand(new SettlePair() { Currency0 = eth, Currency1 = usdc });

var receipt = await positionManager.ModifyLiquiditiesRequestAndWaitForReceiptAsync(
    new ModifyLiquiditiesFunction
    {
        UnlockData = actionsBuilder.GetUnlockData(),
        Deadline = DateTimeOffset.UtcNow.ToUnixTimeSeconds() + 60,
        AmountToSend = Web3.Web3.Convert.ToWei(0.05m)
    });

Decreasing Liquidity

var uniswap = web3.UniswapV4();
var actionsBuilder = uniswap.Positions.CreatePositionManagerActionsBuilder();

actionsBuilder.AddCommand(new DecreaseLiquidity()
{
    TokenId = tokenId,
    Liquidity = Web3.Web3.Convert.ToWei(0.005m),
    Amount0Min = 0,
    Amount1Min = 0,
    HookData = new byte[0]
});

actionsBuilder.AddCommand(new TakePair() { Currency0 = eth, Currency1 = usdc, Recipient = account });

var receipt = await positionManager.ModifyLiquiditiesRequestAndWaitForReceiptAsync(
    new ModifyLiquiditiesFunction
    {
        UnlockData = actionsBuilder.GetUnlockData(),
        Deadline = DateTimeOffset.UtcNow.ToUnixTimeSeconds() + 60
    });

Atomic Position Rebalancing

var uniswap = web3.UniswapV4();
var actionsBuilder = uniswap.Positions.CreatePositionManagerActionsBuilder();

// Close old position
View on GitHub
GitHub Stars37
CategoryDevelopment
Updated22d ago
Forks19

Languages

Solidity

Security Score

90/100

Audited on Mar 8, 2026

No findings