Git Product home page Git Product logo

uniswapv3-book's Introduction

Uniswap V3 Development Book

Uniswap V3 Development Book cover

๐Ÿ‘‰ย READ ONLINEย ย |ย ย PRINT OR SAVE AS PDFย ๐Ÿ‘ˆ

This book will teach how to develop an advanced decentralized application! Specifically, we'll be building a clone of Uniswap V3, which is a decentralized exchange.

Why Uniswap?

  • It implements a very simple mathematical concept, x * y = k, which still makes it very powerful.
  • It's an advanced application that has a thick layer of engineering on top of the simple formula.
  • It's permissionless and battle-tested. Learning from an application that's been running in production for several years and handling billions of dollars will make you a better developer.

What we'll build

Front-end application screenshot

We'll build a full clone of Uniswap V3. It won't be an exact copy and it won't be production-ready because we'll do something in our own way and we'll definitely introduce multiple bugs. So, don't deploy this to the mainnet!

While our focus will primarily be on smart contracts, we'll also build a front-end application as a side hustle. ๐Ÿ™‚ I'm not a front-end developer and I cannot make a front-end application better than you, but I can show you how a decentralized exchange can be integrated into a front-end application.

The full code of what we'll build is stored in a separate repository:

https://github.com/Jeiwan/uniswapv3-code

You can read this book at:

https://uniswapv3book.com/

Questions?

Each milestone has its own section in the GitHub Discussions. Don't hesitate to ask questions about anything that's not clear in the book!

Table of Contents

  • Milestone 0. Introduction

    1. Introduction to markets
    2. Constant Function Market Makers
    3. Uniswap V3
    4. Development Environment
    5. What We'll Build
  • Milestone 1. First Swap

    1. Introduction
    2. Calculating Liquidity
    3. Providing Liquidity
    4. First Swap
    5. Manager Contract
    6. Deployment
    7. User Interface
  • Milestone 2. Second Swap

    1. Introduction
    2. Output Amount Calculation
    3. Math in Solidity
    4. Tick Bitmap Index
    5. Generalize Minting
    6. Generalize Swapping
    7. Quoter Contract
    8. User Interface
  • Milestone 3. Cross-tick Swaps

    1. Introduction
    2. Different Price Ranges
    3. Cross-Tick Swaps
    4. Slippage Protection
    5. Liquidity Calculation
    6. A Little Bit More on Fixed-point Numbers
    7. Flash Loans
    8. User Interface
  • Milestone 4. Multi-pool Swaps

    1. Introduction
    2. Factory Contract
    3. Swap Path
    4. Multi-pool Swaps
    5. User Interface
    6. Tick Rounding
  • Milestone 5. Fees and Price Oracle

    1. Introduction
    2. Swap Fees
    3. Flash Loan Fees
    4. Protocol Fees
    5. Price Oracle
    6. User Interface
  • Milestone 6: NFT positions

    1. Introduction
    2. ERC721 Overview
    3. NFT Manager
    4. NFT Renderer

Running locally

To run the book locally:

  1. Install Rust.
  2. Install mdBook:
    $ cargo install mdbook
    $ cargo install mdbook-katex
  3. Clone the repo:
    $ git clone https://github.com/Jeiwan/uniswapv3-book
    $ cd uniswapv3-book
  4. Run:
    $ mdbook serve --open
  5. Visit http://localhost:3000/ (or whatever URL the previous command outputs!)

uniswapv3-book's People

Contributors

6 avatar adeelhasan avatar apoorvlathey avatar eflatun avatar f3d0ss avatar j-vp avatar jeiwan avatar jikdo avatar jordanejl avatar larryob avatar leovct avatar majecty avatar pongib avatar rv12r avatar samlaf avatar samlior avatar uniyj avatar y1cunhui avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

uniswapv3-book's Issues

Constant Function Market Makers

Discussed in #54

Originally posted by said017 February 15, 2023
Hi,

I'm wondering if the statement number 4 in trade function explanation is true "The pool also takes a small fee (r) from the amount of token 0 we gave", should'nt it supposed to be r = 1 - swap fee ?

Create a pdf version

As the title, is it possible to create a pdf version of this wonderful book?

Regards

Addition of event mint is missing

Hello!
While following the miltestone_1 (https://uniswapv3book.com/docs/milestone_1/providing-liquidity/), at the end of the mint, we are expected to emit an event mint to inform the blockchain.
However, in the above code snippets/explanation, the declaration of the said event is missing.

    event Mint(
        address sender,
        address indexed owner,
        int24 indexed tickLower,
        int24 indexed tickUpper,
        uint128 amount,
        uint256 amount0,
        uint256 amount1
    );
    ```

An error in calculation

Hi, there seems to be an error in milestone1 first-swap.md. The calculation after this line is erroneous:
"Luckily, we already know all the values, so we can plug them in right away (this might not fit on your screen!):"

image

image

shouldTransferInCallback in setupTestCase should become before pool.mint()

In the following snippet, shouldTransferInCallback should be set before pool.mint()

Next, we're calling `setupTestCase` with the above parameters:
```solidity
function setupTestCase(TestCaseParams memory params)
internal
returns (uint256 poolBalance0, uint256 poolBalance1)
{
token0.mint(address(this), params.wethBalance);
token1.mint(address(this), params.usdcBalance);
pool = new UniswapV3Pool(
address(token0),
address(token1),
params.currentSqrtP,
params.currentTick
);
if (params.mintLiqudity) {
(poolBalance0, poolBalance1) = pool.mint(
address(this),
params.lowerTick,
params.upperTick,
params.liquidity
);
}
shouldTransferInCallback = params.shouldTransferInCallback;
}
.

Otherwise the callback will not send the funds from the test contract to the pool contract and the assertions will fail.

Chapter 18 missing reference to liquidity argument

In chapter 18 (generalized swapping), eventually swapMath.computeSwapStep is called with an argument: liquidity. Liquidity is not referenced / defined thus far. A look at the code indicates that liquidity should be an part of SwapState, yet SwapState, which is defined for the first time in this chapter does not have liquidity as a field.
As far as I understand it after looking at the code in the repo it is simply the current total liquidity in the pool. However the chapter does need revisions to clarify this for future readers so they don't need to go looking at the code.

The book has been a joy to follow along with btw :)

Thank you for a great job

Hello, your topics helped me a lot in my area of development and understanding of fundamental things. Looking forward for version 3 of Uniswap.

Build error when running server locally

Description

Unfortunately, it's not possible to launch the server locally due to an error when building the site.

$ hugo server -D
Watching for changes in /Users/leovct/Documents/learn/uniswap/uniswapv3-book/{archetypes,content,static}
Watching for config changes in /Users/leovct/Documents/learn/uniswap/uniswapv3-book/config.toml
Start building sites โ€ฆ 
hugo v0.118.2-da7983ac4b94d97d776d7c2405040de97e95c03d+extended darwin/amd64 BuildDate=2023-08-31T11:23:51Z VendorInfo=brew

Built in 27 ms
Error: error building site: assemble: "/Users/leovct/Documents/learn/uniswap/uniswapv3-book/content/docs/introduction/constant-function-market-maker.md:163:1": failed to extract shortcode: template for shortcode "katex" not found

Fix

Clone the repo and the theme submodule to make it work using:
git clone https://github.com/Jeiwan/uniswapv3-book --recurse-submodules.

Question about tick feeGrowthOutsideX128{0,1} initialization

hi @Jeiwan, thanks for the great book!

After dived into the book and the source code, i still can't figure out why tick.feeGrowthOutside0X128 and tick.feeGrowthOutside1X128 are initialized as follows:

    function update(
        mapping(int24 => Tick.Info) storage self,
        int24 tick,
        int24 tickCurrent,
        int128 liquidityDelta,
        uint256 feeGrowthGlobal0X128,
        uint256 feeGrowthGlobal1X128,
        uint160 secondsPerLiquidityCumulativeX128,
        int56 tickCumulative,
        uint32 time,
        bool upper,
        uint128 maxLiquidity
    ) internal returns (bool flipped) {
       // ......
        if (liquidityGrossBefore == 0) {
            // by convention, we assume that all growth before a tick was initialized happened _below_ the tick
            if (tick <= tickCurrent) {
                info.feeGrowthOutside0X128 = feeGrowthGlobal0X128;
                info.feeGrowthOutside1X128 = feeGrowthGlobal1X128;
                info.secondsPerLiquidityOutsideX128 = secondsPerLiquidityCumulativeX128;
                info.tickCumulativeOutside = tickCumulative;
                info.secondsOutside = time;
            }
            info.initialized = true;
        }
       // ......
    }

Uniswap V3 whitepaper section 6

whitepaper

fees

i tried to verify the swap fee accumulating process in my head, everything goes well until new ticks are initialized.

I must have misunderstood something!

thank you!

Wrong Calculation in Q64.96 number of sqrt Price

In book you use lower price 4545$, so sqrt from P * 2 * * 96 will be 5341294542274603406682713227264 (in book it is 5314786713428871004159001755648)
import math
q96 = 2**96
def price_to_sqrtp(p):
return int(math.sqrt(p) * q96)
print (price_to_sqrtp(4545))

5341294542274603406682713227264

I don't know, mb error in define lower price. If you want assign it to 4500, then it will be correct.
import math
q96 = 2**96
def price_to_sqrtp(p):
return int(math.sqrt(p) * q96)
print (price_to_sqrtp(4500))

5314786713428871004159001755648

Correct Price Range

In the bottom of this page, price range should be corrected from [ $2^{-128}$, $2^{128}$ ] to ( $2^{-128}$, $2^{128}$ )

If I understand correctly, since $\sqrt{P}$ is expressed as a fixed point Q64.96 number, the actual price P could not be exactly $2^{-128}$ nor $2^{128}$ by nature of floating point numbers.

(Edit for correct math expression.)

Calculating liquidity

Hello, thank you for a great work!

Could you please explain why are you multiplying the USDC amount by ETH decimals (10^18) in the line 58 of unimath.py example?

amount_usdc = 5000 * eth

And not by 10*(18-6)=10^12?

I tested it on actual Uniswap position and the numbers matched with 10*12.

Clarify that the tick bitmap only indexes spaced ticks

I have been using the v3 Book a lot recently and I really appreciate the effort put in.

I recently spend some time integrating the tick bitmap and tick bitmap lens, and I spent some time confused by the results I was getting from the queries. I was able to clarify my misunderstanding by looking at the tick lens code, but thought some clarification in the book might help others. The issue I had was the following:

I was trying to use the bitmap and the bitmap lens to find initialized ticks around the current price tick. I was taking the current tick from the slot0 query and trying to find the associated word in the bitmap by integer dividing by 256; when I did this, I was always getting 0 for the bitmap result (no initialized ticks in word) even thought I knew there were initialized ticks around the current tick. In reality, the bitmap only indexes spaced ticks (i.e. ticks evenly divisible by tickSpacing) and I had to first integer divide the current tick by tickSpacing before dividing by 256.

The Tick Bitmap Index page does a great job of explaining the bitmap, but since the explainer uses a tick spacing of 1, I think this step gets a little bit lost. Also, since the width of the tick index is 24 bits and the word index (16 bits) and bit array (8 bits) sum to that, I think it's easy to assume the bitmap is sparse. There is a disclaimer that the tick spacing is 1, but I think readers could benefit from an explanation that tick spacing must be collapsed to find the correct bitmap index.

I am happy to give it a shot if the maintainers would prefer a pull request over an issue. Thanks for the good work!

Advice: Add a section about the difference between our final implementation and the v3-core&v3-periphery repo

After following the whole book, I can almost understand all the code in the uniswapv3-code repo. But when reading the real uniswap v3 code repo, I found there is still some difference between it and our implementation, and there are some contracts we don't have(like V3Migrate, MultiCall, PeripheryPaymentWithFee, difference between QuoterV1&V2... etc.)

I'm wondering if it's convenient to add a section about the structure of the real V3 contracts, some contracts we do not have and their function, analyze some real transactions on Uniswap V3, etc. This would bring us closer to the real-world.

(And I know the repo is just for learning and not ready for deployment in real world. So maybe want some advice about wahat else we need to do&consider to make it a real system?)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.