Git Product home page Git Product logo

zuniswapv2's Introduction

ZUniswapV2, a clone of UniswapV2 made in educational purposes

Using this repo

  1. git clone [email protected]:Jeiwan/zuniswapv2.git
  2. Ensure you have installed Rust and Cargo: Install Rust
  3. Install Foundry: cargo install --git https://github.com/gakonst/foundry --bin forge --locked
  4. Install dependency contracts: git submodule update --init --recursive
  5. Run tests: forge test

Blog posts

  1. Part 1, architecture of UniswapV2, adding liquidity, first tests in Solidity, removing liquidity.
  2. Part 2, tokens swapping, re-entrancy attacks and protection, price oracle, integer overflow and underflow, safe transfer.
  3. Part 3, factory contract, CREATE2 opcode, Router contract, Library contract
  4. Part 4, LP-tokens burning bug, liquidity removal, output amount calculation, swapExactTokensForTokens, swapTokensForExactTokens, fixing swap fee bug, flash loans, fixing re-entrancy vulnerability, protocol fees

zuniswapv2's People

Contributors

jeiwan 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

zuniswapv2's Issues

wrong amounts index in swapTokensForExactTokens

    if (amounts[amounts.length - 1] > amountInMax)
        revert ExcessiveInputAmount();
        
    may need change to 
       
    if (amounts[0] > amountInMax)
        revert ExcessiveInputAmount();

thx for the tutorial, benefits a lot

Tests for Router failing

All 12 tests for Router are failing, the issues seems to be in the getReserves function in the ZuniswapV2Library, here is the trace error:
Screenshot 2022-12-30 at 16 21 22

A bunch of tests fail out of the box

Pulling from master and running according to instructions, the output from forge test -vv is:

Using forge 0.2.0 (5279f69 2022-06-29T00:03:58.834625889Z)
Using solc 0.8.13

[⠢] Compiling...
No files changed, compilation skipped

Running 4 tests for src/test/ZuniswapV2Factory.t.sol:ZuniswapV2FactoryTest
[PASS] testCreatePair() (gas: 1708029)
[PASS] testCreatePairIdenticalTokens() (gas: 13742)
[PASS] testCreatePairPairExists() (gas: 1713507)
[PASS] testCreatePairZeroAddress() (gas: 18542)
Test result: ok. 4 passed; 0 failed; finished in 14.30ms

Running 17 tests for src/test/ZuniswapV2Library.t.sol:ZuniswapV2LibraryTest
[PASS] testGetAmountIn() (gas: 4111)
[PASS] testGetAmountInZeroInputAmount() (gas: 9362)
[PASS] testGetAmountInZeroInputReserve() (gas: 9381)
[PASS] testGetAmountInZeroOutputReserve() (gas: 9388)
[PASS] testGetAmountOut() (gas: 3947)
[PASS] testGetAmountOutZeroInputAmount() (gas: 9265)
[PASS] testGetAmountOutZeroInputReserve() (gas: 9271)
[PASS] testGetAmountOutZeroOutputReserve() (gas: 9367)
[FAIL. Reason: Revert] testGetAmountsIn() (gas: 576611)
[PASS] testGetAmountsInInvalidPath() (gas: 14934)
[FAIL. Reason: Revert] testGetAmountsOut() (gas: 576678)
[PASS] testGetAmountsOutInvalidPath() (gas: 15088)
[FAIL. Reason: Revert] testGetReserves() (gas: 203882)
[FAIL] testPairFor() (gas: 24168)
Logs:
  Error: a == b not satisfied [address]
    Expected: 0x7ee0d4680a40bf8035e41d7d3dd2b89b8fe043eb
      Actual: 0x7dedb0778f3632828e120773699d68ff2cd0b882

[PASS] testPairForNonexistentFactory() (gas: 5213)
[FAIL] testPairForTokensSorting() (gas: 24134)
Logs:
  Error: a == b not satisfied [address]
    Expected: 0x7ee0d4680a40bf8035e41d7d3dd2b89b8fe043eb
      Actual: 0x7dedb0778f3632828e120773699d68ff2cd0b882

[PASS] testQuote() (gas: 5847)
Test result: FAILED. 12 passed; 5 failed; finished in 17.58ms

Running 12 tests for src/test/ZuniswapV2Router.t.sol:ZuniswapV2RouterTest
[FAIL. Reason: Revert] testAddLiquidityAmountBOptimalIsOk() (gas: 1956584)
[FAIL. Reason: Revert] testAddLiquidityAmountBOptimalIsTooHighAmountAOk() (gas: 1957367)
[FAIL. Reason: Revert] testAddLiquidityAmountBOptimalIsTooLow() (gas: 1963136)
[FAIL. Reason: Revert] testAddLiquidityAmountBOptimalTooHighAmountATooLow() (gas: 1963180)
[FAIL. Reason: Revert] testAddLiquidityCreatesPair() (gas: 1775581)
[FAIL. Reason: Revert] testAddLiquidityNoPair() (gas: 1775622)
[FAIL. Reason: Revert] testRemoveLiquidity() (gas: 1775604)
[FAIL. Reason: Revert] testRemoveLiquidityInsufficientAAmount() (gas: 1775582)
[FAIL. Reason: Revert] testRemoveLiquidityInsufficientBAmount() (gas: 1775583)
[FAIL. Reason: Revert] testRemoveLiquidityPartially() (gas: 1775605)
[FAIL. Reason: Revert] testSwapExactTokensForTokens() (gas: 1805362)
[FAIL. Reason: Revert] testSwapTokensForExactTokens() (gas: 1805361)
Test result: FAILED. 0 passed; 12 failed; finished in 17.96ms

Running 21 tests for src/test/ZuniswapV2Pair.t.sol:ZuniswapV2PairTest
[PASS] testBurn() (gas: 208218)
[PASS] testBurnUnbalanced() (gas: 225865)
[PASS] testBurnUnbalancedDifferentUsers() (gas: 282096)
[PASS] testBurnZeroLiquidity() (gas: 206801)
[PASS] testBurnZeroTotalSupply() (gas: 31216)
[PASS] testCumulativePrices() (gas: 336666)
[PASS] testFlashloan() (gas: 489533)
[PASS] testMintBootstrap() (gas: 198283)
[PASS] testMintLiquidityUnderflow() (gas: 31425)
[PASS] testMintUnbalanced() (gas: 217888)
[PASS] testMintWhenTheresLiquidity() (gas: 266169)
[PASS] testMintZeroLiquidity() (gas: 139368)
[FAIL] testReservesPacking() (gas: 208736)
Logs:
  Error: a == b not satisfied [bytes32]
    Expected: 0x000000000000000000001bc16d674ec800000000000000000de0b6b3a7640000
      Actual: 0x000000010000000000001bc16d674ec800000000000000000de0b6b3a7640000

[PASS] testSwapBasicScenario() (gas: 218598)
[PASS] testSwapBasicScenarioReverseDirection() (gas: 218384)
[PASS] testSwapBidirectional() (gas: 226409)
[PASS] testSwapInsufficientLiquidity() (gas: 249592)
[PASS] testSwapOverpriced() (gas: 239887)
[PASS] testSwapUnderpriced() (gas: 218489)
[PASS] testSwapUnpaidFee() (gas: 235974)
[PASS] testSwapZeroOut() (gas: 224110)
Test result: FAILED. 20 passed; 1 failed; finished in 19.09ms

Failed tests:
[FAIL. Reason: Revert] testGetAmountsIn() (gas: 576611)
[FAIL. Reason: Revert] testGetAmountsOut() (gas: 576678)
[FAIL. Reason: Revert] testGetReserves() (gas: 203882)
[FAIL] testPairFor() (gas: 24168)
[FAIL] testPairForTokensSorting() (gas: 24134)
[FAIL] testReservesPacking() (gas: 208736)
[FAIL. Reason: Revert] testAddLiquidityAmountBOptimalIsOk() (gas: 1956584)
[FAIL. Reason: Revert] testAddLiquidityAmountBOptimalIsTooHighAmountAOk() (gas: 1957367)
[FAIL. Reason: Revert] testAddLiquidityAmountBOptimalIsTooLow() (gas: 1963136)
[FAIL. Reason: Revert] testAddLiquidityAmountBOptimalTooHighAmountATooLow() (gas: 1963180)
[FAIL. Reason: Revert] testAddLiquidityCreatesPair() (gas: 1775581)
[FAIL. Reason: Revert] testAddLiquidityNoPair() (gas: 1775622)
[FAIL. Reason: Revert] testRemoveLiquidity() (gas: 1775604)
[FAIL. Reason: Revert] testRemoveLiquidityInsufficientAAmount() (gas: 1775582)
[FAIL. Reason: Revert] testRemoveLiquidityInsufficientBAmount() (gas: 1775583)
[FAIL. Reason: Revert] testRemoveLiquidityPartially() (gas: 1775605)
[FAIL. Reason: Revert] testSwapExactTokensForTokens() (gas: 1805362)
[FAIL. Reason: Revert] testSwapTokensForExactTokens() (gas: 1805361)

Encountered a total of 18 failing tests, 36 tests succeeded

Bug: ZuniswapV2Router.sol swapTokensForExactTokens

function swapTokensForExactTokens(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to
    ) public returns (uint256[] memory amounts) {
        amounts = ZuniswapV2Library.getAmountsIn(
            address(factory),
            amountOut,
            path
        );
        if (amounts[amounts.length - 1] > amountInMax)
            revert ExcessiveInputAmount();
        _safeTransferFrom(
            path[0],
            msg.sender,
            ZuniswapV2Library.pairFor(address(factory), path[0], path[1]),
            amounts[0]
        );
        _swap(amounts, path, to);

for expression if (amounts[amounts.length - 1] > amountInMax)
I thought it would be if (amounts[0] > amountInMax)?

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.