Convert Figma logo to code with AI

Uniswap logov3-core

🦄 🦄 🦄 Core smart contracts of Uniswap v3

4,334
2,654
4,334
63

Top Related Projects

Sushi 2.0 🍣

Quick Overview

Uniswap v3-core is the core smart contracts for the Uniswap v3 protocol, a decentralized exchange (DEX) on the Ethereum blockchain. It introduces concentrated liquidity, allowing liquidity providers to allocate their capital within specific price ranges, potentially increasing capital efficiency and reducing slippage for traders.

Pros

  • Improved capital efficiency through concentrated liquidity
  • Flexible fee tiers for different trading pairs
  • Enhanced price oracle functionality
  • Increased customization options for liquidity providers

Cons

  • Higher complexity compared to previous versions
  • Potential for increased gas costs in certain scenarios
  • Steeper learning curve for users and developers
  • Risk of impermanent loss still present, potentially amplified in some cases

Code Examples

  1. Creating a new pool:
function createPool(
    address tokenA,
    address tokenB,
    uint24 fee
) external noDelegateCall returns (address pool) {
    require(tokenA != tokenB);
    (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
    require(token0 != address(0));
    int24 tickSpacing = fee2tickSpacing[fee];
    require(tickSpacing != 0);
    require(getPool[token0][token1][fee] == address(0));
    pool = deploy(address(this), token0, token1, fee, tickSpacing);
    getPool[token0][token1][fee] = pool;
    getPool[token1][token0][fee] = pool;
    emit PoolCreated(token0, token1, fee, tickSpacing, pool);
}

This function creates a new Uniswap v3 pool for a given pair of tokens and fee tier.

  1. Adding liquidity to a pool:
function mint(
    address recipient,
    int24 tickLower,
    int24 tickUpper,
    uint128 amount,
    bytes calldata data
) external override lock returns (uint256 amount0, uint256 amount1) {
    require(amount > 0);
    (, int256 amount0Int, int256 amount1Int) = _modifyPosition(
        ModifyPositionParams({
            owner: recipient,
            tickLower: tickLower,
            tickUpper: tickUpper,
            liquidityDelta: int256(amount).toInt128()
        })
    );

    amount0 = uint256(amount0Int);
    amount1 = uint256(amount1Int);

    uint256 balance0Before;
    uint256 balance1Before;
    if (amount0 > 0) balance0Before = balance0();
    if (amount1 > 0) balance1Before = balance1();
    IUniswapV3MintCallback(msg.sender).uniswapV3MintCallback(amount0, amount1, data);
    if (amount0 > 0) require(balance0Before.add(amount0) <= balance0(), 'M0');
    if (amount1 > 0) require(balance1Before.add(amount1) <= balance1(), 'M1');

    emit Mint(msg.sender, recipient, tickLower, tickUpper, amount, amount0, amount1);
}

This function allows liquidity providers to add liquidity to a specific price range in a Uniswap v3 pool.

  1. Swapping tokens:
function swap(
    address recipient,
    bool zeroForOne,
    int256 amountSpecified,
    uint160 sqrtPriceLimitX96,
    bytes calldata data
) external override noDelegateCall returns (int256 amount0, int256 amount1) {
    require(amountSpecified != 0, 'AS');

    Slot0 memory slot0Start = slot0;

    SwapCache memory cache = SwapCache({
        liquidityStart: liquidity,
        blockTimestamp: _blockTimestamp(),
        feeProtocol: zeroForOne ? (slot0Start.feeProtocol %

Competitor Comparisons

Sushi 2.0 🍣

Pros of Sushiswap

  • More extensive feature set, including yield farming and token launchpad
  • Community-driven governance model
  • Easier to integrate with other DeFi protocols

Cons of Sushiswap

  • Less optimized for gas efficiency
  • Lower liquidity in some trading pairs
  • Potentially higher vulnerability to exploits due to more complex codebase

Code Comparison

Sushiswap (Router contract):

function swapExactTokensForTokens(
    uint amountIn,
    uint amountOutMin,
    address[] calldata path,
    address to,
    uint deadline
) external virtual override ensure(deadline) returns (uint[] memory amounts) {
    amounts = SushiswapLibrary.getAmountsOut(factory, amountIn, path);
    require(amounts[amounts.length - 1] >= amountOutMin, 'SushiswapRouter: INSUFFICIENT_OUTPUT_AMOUNT');
    TransferHelper.safeTransferFrom(path[0], msg.sender, SushiswapLibrary.pairFor(factory, path[0], path[1]), amounts[0]);
    _swap(amounts, path, to);
}

Uniswap v3-core (SwapMath library):

function computeSwapStep(
    uint160 sqrtRatioCurrentX96,
    uint160 sqrtRatioTargetX96,
    uint128 liquidity,
    int256 amountRemaining,
    uint24 feePips
) internal pure returns (uint160 sqrtRatioNextX96, uint256 amountIn, uint256 amountOut, uint256 feeAmount) {
    bool zeroForOne = sqrtRatioCurrentX96 >= sqrtRatioTargetX96;
    bool exactIn = amountRemaining >= 0;

    if (exactIn) {
        uint256 amountRemainingLessFee = FullMath.mulDiv(uint256(amountRemaining), 1e6 - feePips, 1e6);
        amountIn = zeroForOne
            ? SqrtPriceMath.getAmount0Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, true)
            : SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, true);
        if (amountRemainingLessFee >= amountIn) sqrtRatioNextX96 = sqrtRatioTargetX96;
        else
            sqrtRatioNextX96 = SqrtPriceMath.getNextSqrtPriceFromInput(
                sqrtRatioCurrentX96,
                liquidity,
                amountRemainingLessFee,
                zeroForOne
            );
    } else {
        amountOut = zeroForOne
            ? SqrtPriceMath.getAmount1Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, false)
            : SqrtPriceMath.getAmount0Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, false);
        if (uint256(-amountRemaining) >= amountOut) sqrtRatioNextX96 = sqrtRatioTargetX96;
        else
            sqrtRatioNextX96 = SqrtPriceMath.getNextSqrtPriceFromOutput(
                sqrtRatioCurrentX96,
                liquidity,
                uint256(-amountRemaining),
                zeroForOne
            );
    }

    bool max = sqrtRatioTargetX96 == sqrtRatioNextX96;

    // get the input/output amounts
    if (zeroForOne) {
        amountIn = max && exactIn
            ? amountIn
            : SqrtPriceMath.getAmount0Delta(sqrtRatioNextX96

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Uniswap V3

Lint Tests Fuzz Testing Mythx npm version

This repository contains the core smart contracts for the Uniswap V3 Protocol. For higher level contracts, see the uniswap-v3-periphery repository.

Bug bounty

This repository is subject to the Uniswap V3 bug bounty program, per the terms defined here.

Local deployment

In order to deploy this code to a local testnet, you should install the npm package @uniswap/v3-core and import the factory bytecode located at @uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json. For example:

import {
  abi as FACTORY_ABI,
  bytecode as FACTORY_BYTECODE,
} from '@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json'

// deploy the bytecode

This will ensure that you are testing against the same bytecode that is deployed to mainnet and public testnets, and all Uniswap code will correctly interoperate with your local deployment.

Using solidity interfaces

The Uniswap v3 interfaces are available for import into solidity smart contracts via the npm artifact @uniswap/v3-core, e.g.:

import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';

contract MyContract {
  IUniswapV3Pool pool;

  function doSomethingWithPool() {
    // pool.swap(...);
  }
}

Licensing

The primary license for Uniswap V3 Core is the Business Source License 1.1 (BUSL-1.1), see LICENSE. However, some files are dual licensed under GPL-2.0-or-later:

  • All files in contracts/interfaces/ may also be licensed under GPL-2.0-or-later (as indicated in their SPDX headers), see contracts/interfaces/LICENSE
  • Several files in contracts/libraries/ may also be licensed under GPL-2.0-or-later (as indicated in their SPDX headers), see contracts/libraries/LICENSE

Other Exceptions

  • contracts/libraries/FullMath.sol is licensed under MIT (as indicated in its SPDX header), see contracts/libraries/LICENSE_MIT
  • All files in contracts/test remain unlicensed (as indicated in their SPDX headers).

NPM DownloadsLast 30 Days