-
Notifications
You must be signed in to change notification settings - Fork 0
Assignment 2
In this assignment we'll go through some simple interactions with the Uniswap V3 smart contracts. It'll give you a basic understanding of a DEX, Liquidity Pools and Automated Market Makers. The
Uniswap V3 smart contracts are divided into 2 repositories; Core smart contracts and Periphery smart contracts.
-
UniswapV3Factory: provide the interface for pool creation and tracking. -
UniswapV3Pool: provide the core functionalities, like swap, mint, burn.
-
SwapRouter: provide the interface for token trade. -
NonfungiblePositionManager: provide functionalities of adding/ removing/ modifying pool’s liquidity, and tokenize liquidity through NFT
In this assignement we have a contract called LiquidityCustodian. This smart contract acts like a Liquidity Locker although we are not doing any locking for this assignment. The contract will simply hold the token that represents the Liquidity Providers' liquidity. It can be extended to be a liquidity locking smart contract. The LiquidityCustodian smart contract is going to have logic for:
- Creating a liquidity pool for our MC/WETH token
- Mint or create liquidity for the liquidity pool
- Removing custody of the liquidity token and giving it back to the owner
To avoid the complexities in deploying the Uniswap V3 smart contracts locally, we will use a uniwap local deployment repository created specifically for that.
- On your terminal, navigate to a directory/folder of your choice using
cd example/directoryand run the following git command in your terminal:
git clone https://github.com/FinHubSA/hardhat-uniswapV3-deploy.git- Navigate into the
hardhat-uniswapV3-deploythen run the commandnpm installto install the nodejs libraries
cd hardhat-uniswapV3-deploy
npm installThis command will:
- Install the uniswap V3 core and periphery contract files.
- Install the uniswap V3 hardhat deploy scripts.
- Now you will be able to deploy Uniswap V3 smart contracts on your local hardhat network which we will do in the assignment.
We'll use the uniswap-pool branch for Part 2 of the assignment.
NOTE: We are using an earlier version of solidity and OpenZeppelin libraries. This is because we are using the @uniswap/v3-core and @uniswap/v3-periphery libraries (check packages/hardhat/package.json). These libraries require a lower version of OpenZeppelin and Solidity. We could have made our own interfaces for the Uniswap smart contracts we interact with and used latest versions of Solidity and OpenZeppelin.
- First fetch the
uniswap-poolbranch from upstream and create a new local branch using the remote branch you fetched:
git fetch upstream uniswap-pool
git checkout -b uniswap-pool upstream/uniswap-pool- Run
yarn installto make sure all dependencies are installed
yarn install- Start your local hardhat chain.
yarn chain- Deploy the Uniswap smart contracts.
- In a new VS code window, open up the
hardhat-uniswapV3-deployproject from thesetupstep. - Open a terminal in VS code and run the command below:
npx hardhat deploy-uniswapThis command will deploy the uniswap smart contracts on your local chain. So make sure
yarn chainis running in your project's VS code window i.e. the VS code project you are writing code in.
- After successfully going through step 4, the terminal will output the addresses of important Uniswap V3 smart contracts that you can interact with.
TODO: Copy the weth9, factory, router and positionManager addresses. Paste then in packages/hardhat/contracts/test/Assignment2.ts in the variables WETHTokenAddress, factoryAddress, swapRouterAddress and positionManagerAddress respectively
- Now in your project's VS code terminal, run the tests. The tests should all fail.
yarn test:local test/Assignment2.ts - We'll first fix the MemeCoin.sol smart contract
TODO: create a _totalSupply of 1000 tokens which have 18 decimal places
NOTE: ETH also has 18 decimal places for divisibility. The smallest unit is called Wei. All values in smart contracts are measured in the smallest units. This is true for tokens as well.
TODO: mint the _totalSupply of tokens to the owner
- We'll fix the LiquidityCustodian.sol smart contract
TODO: make the LiquidityCustodian contract an IERC721ReceiverTODO: create the onERC721Received function
NOTE: the function should create an NFT deposit for the sender of NFT to this smart contract
- We'll fix the _createDeposit method
TODO: get the details of the liquidity position from the uniswap NFT managerTODO: create Deposit object using the detail above and store it in the deposits mapping
NOTE: the owner of the deposit is whoever has created the liquidity position through this contract or elsewhere and sent this contract their NFT
TODO: store the tokenId in the owners' token array that is in the liquidityTokens mapping
- We'll fix the createPool method
TODO: assign WETH and MC addresses to new variables token0_ and token1_ addresses
NOTE: for a uniswap pool token0 address should be strictly less than token1 by sort order.
TODO: create a liquidity pool of WETH and MC token using the uniswap factoryTODO: assign the liquidityPoolAddressTODO: get the square of the price using at the _poolTick TickMath library from Uniswap
NOTE: sqrtPriceX96 is a A Fixed point number representing the square root of the ratio of the two assets (token1/token0)
TODO: initialize the liquidity pool with the sqrtPriceX96TODO: emit the PoolCreate event
- We'll fix the mintNewPosition method
TODO: transfer the token0, amount0ToMint, from the msg.sender to this contractTODO: transfer the token1, amount1ToMint, from the msg.sender to this contractTODO: approve the uniswap position manager to transfer amount0ToMint of token0TODO: approve the uniswap position manager to transfer amount1ToMint of token1TODO: mint the liquidity position in the uniswap position manager using the params above
NOTE: this returns the tokenId of the minted NFT that represents the liquidity position
TODO: create the deposit record for the minter/msg.sender
- We'll complete the _deleteLiquidityToken method
TODO: complete the functions _deleteLiquidityToken
NOTE: we implemented a similar method during tutorials
- Run the tests. They should all pass.
yarn test test/Assignment2.ts